Arabic / Persian / Urdu Shaping Support

Producer-side shaping pipeline (v2.85.0 - v2.119.68)

 

OpenType GSUB Engine  CFF / OpenType Subsetting

O HotPDF executa um pipeline de formação do lado do produtor que converte trechos árabes, persas e urdu em entrada Unicode nas respetivas Arabic Presentation Forms durante a emissão de texto PDF, para que os leitores consumidores recebam glifos posicionais / de ligadura prontos a renderizar sem precisarem do seu próprio formador ao nível de Harfbuzz

 

O que o pipeline faz

Formação posicional (v2.85.0): cada letra base árabe tem até quatro formas posicionais - isolada (isol), inicial (init), medial (medi) e final (fina). O HotPDF inspeciona a classe de junção de cada carácter árabe e as classes de junção dos seus vizinhos imediatos e depois mapeia o codepoint de entrada para o glifo Arabic Presentation Forms-B (U+FE70 - U+FEFC) adequado antes da emissão. Letras não ligantes, ligadores, caracteres transparentes (marcas de combinação) e a kashida Tatweel são todos tratados de acordo com o algoritmo Unicode Arabic Shaping

 

Ligadura obrigatória LAM-ALEF (v2.119.32): a especificação Arabic Unicode Shaping determina que qualquer LAM (U+0644) imediatamente seguida de um ALEF (U+0627 simples, U+0622 com madda acima, U+0623 com hamza acima, U+0625 com hamza abaixo) se funde num único glifo de ligadura (U+FEFB - U+FEFC formas isolada / final com as variantes de hamza / madda adequadas). Esta é uma das poucas ligaduras não opcionais na tipografia árabe e é necessária para a correção; representá-las como glifos separados produz texto que os leitores nativos reconhecem de imediato como mal formado. O HotPDF faz esta fusão durante a emissão, pelo que os chamadores não precisam de um formador ao nível de Harfbuzz no seu próprio caminho de código

 

9 letras nucleares do persa / urdu (v2.119.35): o persa e o urdu estendem o árabe com letras que não existem no bloco Arabic Presentation Forms-B (U+FE70 - U+FEFC). As 9 letras mais usadas - incluindo PEH (U+067E), TCHEH (U+0686), JEH (U+0698), KEH (U+06A9 / U+06AF), GAF (U+06AF), NOON GHUNNA (U+06BA), HEH DOACHASHMEE (U+06BE), YEH BARREE (U+06D2) e HEH GOAL (U+06C1) - têm formas de apresentação em Arabic Presentation Forms-A (U+FB50 - U+FDFF). O HotPDF mapeia agora estas letras para o glifo Forms-A adequado durante a formação posicional, para que o texto persa e urdu seja renderizado com as formas init / medi / fina / isol corretas em qualquer leitor consumidor

 

Arabic Extended-A + Supplement (v2.119.52, v2.119.56): a tabela de classes de junção cobre agora os restantes caracteres Arabic Extended-A (ALEF WASLA / NOON GHUNNA / variantes de HEH), Arabic Supplement U+0750-U+077F e o intervalo mais alto Arabic Extended-A U+08A0-U+08FF. Os caracteres com codificação estática em Presentation Forms-A são mapeados através do formador de 4 posições já existente; os que não têm essa codificação (a maior parte do Extended-A) recebem apenas classificação de classe de junção, para que os vizinhos sejam formados corretamente mesmo quando o carácter em si é passado sem alterações. A v2.119.56 corrigiu dois mapeamentos Forms-A errados introduzidos pela v2.119.52 (U+06C2 / U+06C3)

 

Cobertura completa Persian / Urdu Form-B (v2.119.57): a tabela de classes de junção foi alargada para abranger todo o intervalo U+0672-U+06D5 (cerca de 80 caracteres que cobrem variantes de REH / DAL / SEEN / SAD / TAH / AIN / FEH / QAF / KAF / GAF / LAM / NOON / HEH / WAW / YEH), e foram adicionados 26 novos mapeamentos Presentation Forms-A (15 de classe D com 4 formas + 11 de classe R com 2 formas). Em particular, o HEH DOACHASHMEE «h» standard do urdu (U+06BE → FBAA-FBAD) e o yeh final de palavra do urdu YEH BARREE (U+06D2 → FBAE-FBAF) estão agora corretamente mapeados para as posições Forms-A que foram mal usadas pela correção temporária ALEF WASLA / NOON GHUNNA da v2.119.52. A cobertura estática Forms-A abrange agora mais de 40 caracteres de origem

 

YEH-HAMZA + pós-passagem de ligadura vocálica (v2.119.58): uma pós-passagem acrescentada a _ApplyArabicShaping após a formação posicional cobre os 8 pares de ligadura no bloco Forms-A U+FBEA-U+FBFB - YEH-HAMZA + ALEF / AE / WAW / U / OE / YU / E / ALEF MAKSURA. Cada par emite a forma isolada (FBEA / FBEC / FBEE / FBF0 / FBF2 / FBF4 / FBF6 / FBF9) mais a forma final base+1. As posições de forma inicial / medial FBF8 / FBFB ficam para o motor GSUB através da ativação opcional sfArabicGSUB. Construído sobre a mesma estrutura da LAM-ALEF da v2.119.32

 

Ligadura Allah (v2.119.60): a sequência de quatro caracteres ALEF + LAM + LAM + HEH funde-se em U+FDF2 ARABIC LIGATURE ALLAH ISOLATED FORM. Implementada como uma pós-passagem estática ao nível do codepoint depois da LAM-ALEF da v2.119.32 e da YEH-HAMZA da v2.119.58 na cadeia _ApplyArabicShaping

 

Ligadura da expressão Bismillah (v2.119.62): a expressão Bismillah standard de 22 codepoints "بسم الله الرحمن الرحيم" funde-se num único glifo U+FDFD ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM. Corre como a primeira pré-passagem em _ApplyArabicShaping (antes de LAM-ALEF), pelo que o glifo Bismillah fundido chega ao resto do pipeline como um só codepoint e não é retocado por substituições posteriores

 

Auxiliares de consulta públicos

GetArabicJoiningClass devolve a classe de junção Unicode usada pelo formador árabe estático. GetArabicPosition resolve um carácter num trecho para posição isolada, inicial, medial ou final, para que os chamadores possam inspecionar ou espelhar as mesmas decisões de formação antes de emitir texto

 

Como os chamadores o invocam

O pipeline de formação é executado automaticamente dentro dos métodos de emissão de texto Unicode - não é necessária qualquer chamada explícita para «dar forma a este texto». Passe cadeias árabes / persas / urdu em entrada Unicode para THPDFPage.UnicodeTextOut ou THPDFPage.RtLTextOut e o HotPDF mapeia cada codepoint de entrada para a respetiva forma de apresentação antes de escrever o operador de apresentação de texto no PDF. Os bytes Unicode originais também são capturados em FUnicodeUsedCps para geração da ToUnicode CMap, pelo que a cópia / colagem no lado do leitor e os leitores de ecrã continuam a ver a carga Unicode original

 

Requisitos do tipo de letra

O tipo de letra registado através de RegisterUnicodeTTF tem de conter glifos tanto para o bloco Arabic Presentation Forms-B (U+FE70 - U+FEFC) como, para persa / urdu, para o intervalo relevante Arabic Presentation Forms-A (U+FB50 - U+FDFF). Tipos de letra recomendados que fornecem o conjunto completo:

 

Noto Sans Arabic (Latin + Arabic; Forms-A + Forms-B + Arabic Extended-A).

Noto Naskh Arabic, Noto Naskh Arabic UI.

Amiri (traditional Naskh, full Forms-A + Forms-B coverage).

Scheherazade New (SIL, designed for languages of the Muslim world).

Microsoft Arabic Typesetting / Tahoma / Times New Roman (Windows-bundled, full Forms-B; some have Forms-A coverage).

 

Quando ao tipo de letra registado falta um glifo para uma forma de apresentação derivada, o HotPDF recua para o codepoint Unicode base e emite-o sem alterações; os leitores consumidores podem então tentar a sua própria formação (Acrobat, Foxit) ou desenhar .notdef

 

Typical workflow

 

PDF.RegisterUnicodeTTF('NotoArab', 'NotoSansArabic-Regular.ttf');

PDF.BeginDoc;

PDF.CurrentPage.SetFont('NotoArab', [], 14);

PDF.CurrentPage.RtLTextOut(100, 700, 0,

  UnicodeString(#$0645#$0631#$062D#$0628#$0627));  // "marhaba" (hello)

PDF.EndDoc;

 

Integração automática do pipeline da Fase 8 (v2.119.59 - v2.119.68)

v2.119.59 introduced the opt-in ShapingFeatures: THPDFShapingFeatures property and the THPDFShapingFeature enum, which elevates the shaping pipeline beyond static post-pass folding into automatic GSUB-driven font-specific substitution. Set PDF.ShapingFeatures := [sfArabicGSUB] to apply the registered font's native Arabic init, medi, fina, isol, rlig, calt, and rclt lookups and emit the resulting contextual glyph IDs; add sfCursiveAttachment to apply GPOS cursive entry/exit anchors to that shaped run; add sfStandardLigatures for Latin Standard Ligatures (FB00-FB06 ff / fi / fl / ffi / ffl / ſt / st via v2.119.65 ApplyLatinLigatureRefinement); add sfIndicShaping to enable the Devanagari pre-pass reorder (v2.119.67). Default [] preserves byte-identical output for callers who depend on the static pipeline.

 

Quando sfArabicGSUB está ativo, o formador estático de Unicode Presentation Forms é contornado em favor das próprias regras GSUB do tipo de letra. O HotPDF emite IDs de glifos contextuais nativos através de codepoints sintéticos quando esses glifos não são alcançáveis a partir da cmap do tipo de letra, mantém fechado o subconjunto incorporado e escreve mapeamentos reversos ToUnicode para cópia e colagem. Os chamadores que pretendam que o formador estático continue a correr para cobertura de codepoints fora do que a GSUB do tipo de letra declara devem deixar sfArabicGSUB desligado e confiar na cadeia estática de pós-passagem

 

ToUnicode CMap ligature reverse mapping (v2.119.61, v2.119.62, v2.119.65)

A ToUnicode CMap Adobe-Identity-UCS emitida por RegisterUnicodeTTF fornece entradas de mapeamento reverso bfchar para cada codepoint de ligadura que a cadeia de pós-passagem pode produzir. A v2.119.61 adicionou 27 entradas (8 LAM-ALEF + 18 da família YEH-HAMZA + 1 Allah); a v2.119.62 adicionou Bismillah (U+FDFD); a v2.119.65 adicionou 7 entradas Latin Standard Ligature (FB00-FB06). A cópia / colagem no leitor consumidor resolve qualquer glifo de ligadura de volta para a sequência de codepoints de origem, pelo que o PDF apresentado continua acessível

 

PUA synthetic codepoint emit (v2.119.68)

AssignSyntheticCodepointForGID(GID; out CP): Boolean + GetSyntheticCodepointForGID(GID): Word permitem ao código produtor emitir GIDs substitutos GSUB que não têm nenhum codepoint Unicode natural alcançável através da cmap do tipo de letra. O alocador distribui codepoints na Private Use Area (U+E000 - U+F8FF, 6400 slots) e espelha a atribuição em FUnicodeCpToGid (para que /CIDToGIDMap resolva o CP sintético de volta para o GID-alvo no leitor consumidor), FAcroFormUnicodeAdvances (para que o word-wrap v2.65 encontre a fração de em correta) e numa tabela de reverse lookup por GID (para que pedidos de atribuição repetidos sejam idempotentes). Use isto para formas de cluster devanágari, alternates estilísticos e sequências de variação ideográfica CJK que o GSUB introduz mas a cmap não alcança

 

Relationship to the OpenType GSUB engine

O formador estático de pós-passagem descrito acima (v2.85.0 + v2.119.32 / 58 / 60 / 62) é independente do motor OpenType GSUB por predefinição. Quando sfArabicGSUB é ativado através de ShapingFeatures, o motor GSUB passa a fazer parte do caminho de emissão do lado do produtor: o HotPDF consulta a cmap para construir uma matriz base de GIDs, aplica pesquisas GSUB árabes posicionais e contextuais nativas a esse conjunto de glifos, atribui codepoints sintéticos para IDs de glifo substitutos que não têm Forma de Apresentação Unicode e chama MarkUnicodeGlyphUsed para manter os glifos substitutos dentro do subconjunto de tipo de letra incorporado

 

Para glifos substitutos sem codepoint Unicode, os chamadores combinam ShapingFeatures com o alocador de codepoints sintéticos PUA da v2.119.68 para que o GID substituto continue acessível através do pipeline hexadecimal standard. A cadeia estática de pós-passagem continua a ser a alternativa predefinida para codepoints que as declarações GSUB do tipo de letra não cobrem

 

Scope and limitations

O algoritmo BiDi continua fora desta página: os chamadores ainda têm de ordenar por si próprios os trechos mistos LTR e RTL ou usar uma biblioteca BiDi separada. O suporte para GPOS, Indic/Tibetano/Mongol, Hebraico, N'Ko, Adlam, Tailandês/Lao e Javanês passa agora a residir em páginas separadas de sinalizadores e APIs opt-in de formação, pelo que esta página se concentra apenas na formação árabe estática e baseada em GSUB

 

See also: OpenType GSUB Substitution Engine, Automatic Shaping Pipeline (Phase 8), Syriac / Mongolian / Devanagari Shaping, THotPDF.AssignSyntheticCodepointForGID, THPDFPage.RtLTextOut, THPDFPage.UnicodeTextOut, CFF / OpenType Font Subsetting