Arabic / Persian / Urdu Shaping Support

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

 

OpenType GSUB Engine  CFF / OpenType Subsetting

HotPDF rulează un pipeline de shaping pe partea producătorului care pliază segmentele de intrare Unicode pentru arabă, persană și urdu în Arabic Presentation Forms în timpul emiterii textului PDF, astfel încât readerele consumatoare primesc glyph-uri poziționale / de ligatură gata de randat fără a necesita propriul shaper de clasă Harfbuzz.

 

Ce face pipeline-ul

Shaping pozițional (v2.85.0): fiecare literă arabă de bază are până la patru forme poziționale - izolată (isol), inițială (init), mediană (medi), finală (fina). HotPDF analizează clasa de alipire a fiecărui caracter arab și clasele de alipire ale vecinilor imediat apropiați, apoi mapează codepointul de intrare la gliful potrivit din Arabic Presentation Forms-B (U+FE70 - U+FEFC) înainte de emitere. Literele nealipite, caracterele de legătură, caracterele transparente (semne de combinare) și kashida Tatweel sunt tratate conform algoritmului Unicode Arabic Shaping

 

Ligatura obligatorie LAM-ALEF (v2.119.32): specificația Arabic Unicode Shaping impune ca orice LAM (U+0644) urmat imediat de un ALEF (U+0627 simplu, U+0622 cu madda deasupra, U+0623 cu hamza deasupra, U+0625 cu hamza dedesubt) să se unească într-un singur glif ligatură (U+FEFB - U+FEFC forme izolată / finală cu variantele corespunzătoare de hamza / madda). Aceasta este una dintre foarte puținele ligaturi neopționale din tipografia arabă și este necesară pentru corectitudine; redarea lor ca glife separate produce text pe care cititoarele native îl recunosc imediat ca fiind greșit. HotPDF face îmbinarea în timpul emiterii, astfel încât apelanții nu au nevoie de un shaper de clasă Harfbuzz în propriul flux de lucru

 

9 litere de bază pentru persană / urdu (v2.119.35): persana și urdu extind araba cu litere care nu se află în blocul Arabic Presentation Forms-B (U+FE70 - U+FEFC). Cele 9 litere cele mai folosite - inclusiv 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) și HEH GOAL (U+06C1) - au forme de prezentare în Arabic Presentation Forms-A (U+FB50 - U+FDFF). HotPDF le mapează acum la gliful Forms-A potrivit în timpul shapingului pozițional, astfel încât textul persan și urdu se redă cu formele corecte init / medi / fina / isol în orice cititor PDF

 

Arabic Extended-A + Supplement (v2.119.52, v2.119.56): tabelul claselor de alipire acoperă acum caracterele Arabic Extended-A rămase (variante ALEF WASLA / NOON GHUNNA / HEH), Arabic Supplement U+0750-U+077F și intervalul mai înalt Arabic Extended-A U+08A0-U+08FF. Caracterele cu o codare statică Presentation Forms-A sunt mapate prin shaperul existent cu 4 poziții; caracterele fără această codare (majoritatea din Extended-A) primesc doar clasificare după clasa de alipire, astfel încât vecinii se formează corect chiar când caracterul în sine trece mai departe neschimbat. v2.119.56 a corectat două mapări Forms-A greșite introduse de v2.119.52 (U+06C2 / U+06C3)

 

Acoperire completă Persian / Urdu Form-B (v2.119.57): tabelul claselor de alipire a fost extins pentru a acoperi întregul interval U+0672-U+06D5 (aproximativ 80 de caractere care acoperă variantele REH / DAL / SEEN / SAD / TAH / AIN / FEH / QAF / KAF / GAF / LAM / NOON / HEH / WAW / YEH), iar 26 de mapări noi Presentation Forms-A au fost adăugate (15 din clasa D cu 4 forme + 11 din clasa R cu 2 forme). În special, HEH DOACHASHMEE standard din urdu (U+06BE → FBAA-FBAD) și yeh-ul final de cuvânt din urdu YEH BARREE (U+06D2 → FBAE-FBAF) sunt acum mapate corect la sloturile Forms-A folosite greșit de corecția temporară ALEF WASLA / NOON GHUNNA din v2.119.52. Acoperirea statică Forms-A ajunge acum la peste 40 de caractere sursă

 

Post-pass YEH-HAMZA + ligatură vocalică (v2.119.58): un post-pass adăugat în _ApplyArabicShaping după shapingul pozițional acoperă cele 8 perechi de ligaturi din blocul Forms-A U+FBEA-U+FBFB - YEH-HAMZA + ALEF / AE / WAW / U / OE / YU / E / ALEF MAKSURA. Fiecare pereche emite forma izolată (FBEA / FBEC / FBEE / FBF0 / FBF2 / FBF4 / FBF6 / FBF9) plus forma finală base+1. Sloturile pentru formele inițială / mediană FBF8 / FBFB sunt lăsate motorului GSUB prin opt-in-ul sfArabicGSUB. Construit pe aceeași schemă ca v2.119.32 LAM-ALEF

 

Ligatura Allah (v2.119.60): secvența de patru caractere ALEF + LAM + LAM + HEH se îmbină în U+FDF2 ARABIC LIGATURE ALLAH ISOLATED FORM. Implementată ca un post-pass static la nivel de codepoint după v2.119.32 LAM-ALEF și v2.119.58 YEH-HAMZA în lanțul _ApplyArabicShaping

 

Ligatura frazei Bismillah (v2.119.62): fraza standard Bismillah cu 22 de codepointuri "بسم الله الرحمن الرحيم" se îmbină într-un singur glif U+FDFD ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM. Rulează ca primul pre-pass din _ApplyArabicShaping (înainte de LAM-ALEF), astfel încât gliful Bismillah rezultat ajunge la restul pipeline-ului ca un singur codepoint și nu mai este atins de substituțiile ulterioare

 

Helper-e publice de interogare

GetArabicJoiningClass returnează clasa Unicode de alipire folosită de shaperul static arab. GetArabicPosition rezolvă un caracter dintr-un șir la poziția izolată, inițială, mediană sau finală, astfel încât apelanții să poată inspecta sau replica aceleași decizii de shaping înainte de emiterea textului

 

Cum îl apelează consumatorii

Pipeline-ul de shaping rulează automat în metodele de emitere a textului Unicode - nu este nevoie de un apel explicit de tipul "shape this". Transmiteți șiruri Unicode în arabă / persană / urdu către THPDFPage.UnicodeTextOut sau THPDFPage.RtLTextOut, iar HotPDF mapează fiecare codepoint de intrare la forma sa de prezentare înainte de a scrie operatorul PDF de afișare a textului. Octeții Unicode originali sunt de asemenea capturați în FUnicodeUsedCps pentru generarea CMap ToUnicode, astfel încât copy / paste-ul și cititoarele de ecran de pe partea cititorului văd în continuare încărcătura Unicode originală

 

Cerințe pentru font

Fontul înregistrat prin RegisterUnicodeTTF trebuie să conțină glife atât pentru blocul Arabic Presentation Forms-B (U+FE70 - U+FEFC), cât și, pentru persană / urdu, pentru intervalul relevant Arabic Presentation Forms-A (U+FB50 - U+FDFF). Fonturi recomandate care livrează setul complet:

 

Noto Sans Arabic (latină + arabă; Forms-A + Forms-B + Arabic Extended-A)

Noto Naskh Arabic, Noto Naskh Arabic UI

Amiri (Naskh tradițional, acoperire completă Forms-A + Forms-B)

Scheherazade New (SIL, proiectat pentru limbile lumii musulmane)

Microsoft Arabic Typesetting / Tahoma / Times New Roman (incluse în Windows, Forms-B complete; unele au acoperire Forms-A)

 

Atunci când fontului înregistrat îi lipsește un glif pentru o formă de prezentare derivată, HotPDF revine la codepointul Unicode de bază și îl emite neschimbat; cititoarele pot apoi încerca propriul shaping (Acrobat, Foxit) sau pot reda .notdef

 

Flux tipic

 

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;

 

Integrarea automată a pipeline-ului Phase 8 (v2.119.59 - v2.119.68)

v2.119.59 a introdus proprietatea opt-in ShapingFeatures: THPDFShapingFeatures și enumul THPDFShapingFeature, care ridică pipeline-ul de shaping dincolo de plierea statică de post-pass și îl transformă în substituție automată specifică fontului, condusă de GSUB. Setați PDF.ShapingFeatures := [sfArabicGSUB] pentru a aplica lookup-urile native arabe ale fontului înregistrat init, medi, fina, isol, rlig, calt și rclt și pentru a emite GID-urile contextuale rezultate; adăugați sfCursiveAttachment pentru a aplica ancorele cursive de intrare / ieșire GPOS acelui șir format; adăugați sfStandardLigatures pentru Latin Standard Ligatures (FB00-FB06 ff / fi / fl / ffi / ffl / ſt / st prin v2.119.65 ApplyLatinLigatureRefinement); adăugați sfIndicShaping pentru a activa reorder-ul pre-pass Devanagari (v2.119.67). Valoarea implicită [] păstrează o ieșire identică la nivel de octeți pentru apelanții care depind de pipeline-ul static

 

Când sfArabicGSUB este setat, shaperul static Unicode Presentation Forms este ocolit în favoarea propriilor reguli GSUB ale fontului. HotPDF emite GID-uri contextuale native prin codepointuri sintetice atunci când acele glife nu sunt accesibile din cmap-ul fontului, păstrează subsetul încorporat închis și scrie mapări inverse ToUnicode pentru copy / paste. Apelanții care vor ca shaperul static să continue pentru acoperirea de codepointuri dincolo de ce declară GSUB-ul fontului ar trebui să lase sfArabicGSUB dezactivat și să se bazeze pe lanțul static de post-pass

 

Mapare inversă ToUnicode CMap pentru ligaturi (v2.119.61, v2.119.62, v2.119.65)

CMap-ul Adobe-Identity-UCS ToUnicode emis de RegisterUnicodeTTF include intrări bfchar de mapare inversă pentru fiecare codepoint de ligatură pe care îl poate produce lanțul de post-pass-uri. v2.119.61 a adăugat 27 de intrări (8 LAM-ALEF + 18 din familia YEH-HAMZA + 1 Allah); v2.119.62 a adăugat Bismillah (U+FDFD); v2.119.65 a adăugat 7 intrări Latin Standard Ligature (FB00-FB06). Copy / paste-ul din cititorul PDF rezolvă orice glif ligatură înapoi la secvența sursă de codepointuri, astfel încât PDF-ul randat rămâne accesibil

 

Emiterea de codepointuri sintetice PUA (v2.119.68)

AssignSyntheticCodepointForGID(GID; out CP): Boolean + GetSyntheticCodepointForGID(GID): Word le permit codului producător să emită GID-uri de substituție GSUB care nu au un codepoint Unicode natural accesibil prin cmap-ul fontului. Alocatorul repartizează codepointuri din Private Use Area (U+E000 - U+F8FF, 6400 sloturi) și oglindește atribuirea în FUnicodeCpToGid (astfel încât /CIDToGIDMap să rezolve CP-ul sintetic înapoi la GID-ul țintă în cititorul PDF), FAcroFormUnicodeAdvances (astfel încât word-wrap-ul din v2.65 să găsească fracția em corectă) și într-un tabel de reverse-lookup per GID (astfel încât cererile repetate de atribuire să fie idempotente). Folosiți asta pentru forme de cluster Devanagari, alternative stilistice și secvențe de variație ideografică CJK introduse de GSUB, dar inaccesibile prin cmap

 

Relația cu motorul OpenType GSUB

Shaperul static de post-pass descris mai sus (v2.85.0 + v2.119.32 / 58 / 60 / 62) este independent, în mod implicit, de motorul OpenType GSUB. Când sfArabicGSUB este activat prin ShapingFeatures, motorul GSUB devine parte a traseului de emitere pe partea producătorului: HotPDF consultă cmap-ul pentru a construi o matrice GID de bază, aplică lookup-uri GSUB native de poziționare și contextualizare pentru araba pe acel șir de glife, atribuie codepointuri sintetice pentru GID-urile de substituție care nu au o formă Unicode de prezentare și apelează MarkUnicodeGlyphUsed pentru a păstra glifele de substituție în subsetul de font încorporat

 

Pentru glifele de substituție fără codepoint Unicode, apelanții combină ShapingFeatures cu alocatorul de codepointuri sintetice PUA din v2.119.68, astfel încât GID-ul de substituție să rămână accesibil prin pipeline-ul hex standard. Lanțul static de post-pass rămâne fallback-ul implicit pentru codepointurile pe care declarațiile GSUB ale fontului nu le acoperă

 

Domeniu și limitări

Algoritmul BiDi rămâne în afara acestei pagini: apelanții trebuie tot să ordoneze singuri secvențele mixte LTR și RTL sau să folosească o bibliotecă BiDi separată. Suportul pentru GPOS, Indic/Tibetan/Mongolian, Hebrew, N'Ko, Adlam, Thai/Lao și Javanese se află acum pe pagini separate de tip opt-in pentru steaguri de shaping și API-uri, așa că această pagină se concentrează doar pe shapingul arab static și bazat pe 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