Arabic / Persian / Urdu Shaping Support

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

 

OpenType GSUB Engine  CFF / OpenType Subsetting

HotPDF изпълнява producer-side shaping pipeline, която сгъва последователности Unicode-input за Arabic, Persian и Urdu в техните Arabic Presentation Forms по време на PDF текст emission, така че consumer readers да получават готови positional / ligature glyphs без да използват собствен Harfbuzz-class shaper

 

What the pipeline does

Позиционно оформяне (v2.85.0): всеки арабски базов знак има до четири позиционни форми - изолирана (isol), начална (init), средна (medi), крайна (fina). HotPDF проверява join class-а на всеки арабски знак и join class-овете на непосредствените му съседи, след което съпоставя входния codepoint с подходящия glyph от Arabic Presentation Forms-B (U+FE70 - U+FEFC) преди излъчване. Незвързващите букви, свързващите знаци, прозрачните символи (combining marks) и Tatweel kashida се обработват според алгоритъма Unicode Arabic Shaping

 

Задължителна лигатура LAM-ALEF (v2.119.32): спецификацията Arabic Unicode Shaping изисква всеки LAM (U+0644), непосредствено следван от ALEF (U+0627 plain, U+0622 с madda отгоре, U+0623 с hamza отгоре, U+0625 с hamza отдолу), да се слее в един glyph на лигатура (U+FEFB - U+FEFC изолирани / крайни форми със съответните варианти с hamza / madda). Това е една от малкото незадължителни лигатури в арабската типография и е необходима за коректност; изобразяването им като отделни glyph-ове веднага се разпознава от родните читатели като неправилно. HotPDF извършва сливането по време на излъчване, така че на извикващите не им е нужен shaper от клас Harfbuzz в собствения им кодов път

 

9-те основни букви за персийски / урду (v2.119.35): персийският и урду разширяват арабската азбука с букви, които не са в блока Arabic Presentation Forms-B (U+FE70 - U+FEFC). 9-те най-често използвани такива букви - включително 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) и HEH GOAL (U+06C1) - имат presentation форми в Arabic Presentation Forms-A (U+FB50 - U+FDFF). HotPDF вече съпоставя тези букви с подходящия Forms-A glyph по време на позиционното оформяне, така че текстът на персийски и урду да се изобразява с правилните init / medi / fina / isol форми във всеки consumer reader

 

Arabic Extended-A + Supplement (v2.119.52, v2.119.56): таблицата за join class вече покрива останалите знаци от Arabic Extended-A (ALEF WASLA / NOON GHUNNA / варианти на HEH), Arabic Supplement U+0750-U+077F и по-високия диапазон Arabic Extended-A U+08A0-U+08FF. Знаците със статично encoding към Presentation Forms-A се съпоставят чрез съществуващия 4-позиционен shaper; знаците без такова encoding (повечето от Extended-A) получават само join-class класификация, така че съседите да се оформят правилно, дори самият знак да бъде предаден без промяна. v2.119.56 коригира две грешни Forms-A съпоставяния, въведени от v2.119.52 (U+06C2 / U+06C3)

 

Пълно покритие на Persian / Urdu Form-B (v2.119.57): таблицата за join class беше разширена да обхване целия диапазон U+0672-U+06D5 (около 80 знака, включително варианти на REH / DAL / SEEN / SAD / TAH / AIN / FEH / QAF / KAF / GAF / LAM / NOON / HEH / WAW / YEH), а бяха добавени 26 нови съпоставяния към Presentation Forms-A (15 D-class с 4 форми + 11 R-class с 2 форми). По-специално стандартното за урду 'h' HEH DOACHASHMEE (U+06BE → FBAA-FBAD) и крайната в дума yeh YEH BARREE (U+06D2 → FBAE-FBAF) вече са съпоставени правилно към Forms-A слотовете, които бяха неправилно използвани от временния fix за v2.119.52 ALEF WASLA / NOON GHUNNA. Статичното покритие на Forms-A вече обхваща 40+ изходни знака

 

Пост-процес за YEH-HAMZA + vowel ligatures (v2.119.58): добавен post-pass след позиционното оформяне към _ApplyArabicShaping покрива 8-те двойки лигатури в блока Forms-A U+FBEA-U+FBFB - YEH-HAMZA + ALEF / AE / WAW / U / OE / YU / E / ALEF MAKSURA. Всяка двойка излъчва изолирана форма (FBEA / FBEC / FBEE / FBF0 / FBF2 / FBF4 / FBF6 / FBF9) плюс крайната форма base+1. Слотовете за начална / междинна форма FBF8 / FBFB се оставят на GSUB engine-а чрез opt-in sfArabicGSUB. Изградено е върху същия skeleton като v2.119.32 LAM-ALEF

 

Лигатура Allah (v2.119.60): четиризнаковата последователност ALEF + LAM + LAM + HEH се слива в U+FDF2 ARABIC LIGATURE ALLAH ISOLATED FORM. Реализирана е като статичен post-pass на ниво codepoint след v2.119.32 LAM-ALEF и v2.119.58 YEH-HAMZA във веригата _ApplyArabicShaping

 

Лигатура на фразата Bismillah (v2.119.62): стандартната 22-codepoint фраза Bismillah "بسم الله الرحمن الرحيم" се слива в един glyph U+FDFD ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM. Работи като първи pre-pass в _ApplyArabicShaping (преди LAM-ALEF), така че сгънатият glyph на Bismillah достига останалата част от конвейера като един codepoint и не се променя от последващи substitutions

 

Public Query Helpers

GetArabicJoiningClass връща Unicode joining class-а, използван от статичния Arabic shaper. GetArabicPosition определя позицията на един знак в низ като isolated, initial, medial или final, така че извикващите да могат да проверят или да възпроизведат същите shaping решения преди излъчване на текст

 

How callers invoke it

Конвейерът за шейпинг се изпълнява автоматично вътре в методите за извеждане на Unicode текст - не е необходимо изрично извикване „shape this“. Подайте арабски / персийски / урду низове като Unicode вход към THPDFPage.UnicodeTextOut или THPDFPage.RtLTextOut и HotPDF съпоставя всяка входна кодова точка с нейната представна форма преди да запише оператора за извеждане на PDF текст. Оригиналните Unicode байтове също се запазват във FUnicodeUsedCps за генериране на ToUnicode CMap, така че копирането / поставянето от страна на четеца и екранните четци все още виждат оригиналния Unicode товар

 

Font requirements

Шрифтът, регистриран чрез RegisterUnicodeTTF, трябва да съдържа глифове както за блока Arabic Presentation Forms-B (U+FE70 - U+FEFC), така и, за персийски / урду, за съответния диапазон Arabic Presentation Forms-A (U+FB50 - U+FDFF) Препоръчани шрифтове, които включват пълния набор:

 

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).

 

Когато регистрираният шрифт няма глиф за производна представна форма, HotPDF се връща към базовата Unicode кодова точка и я извежда непроменена; потребителските четци може тогава да приложат собствено шейпиране (Acrobat, Foxit) или да рендерират .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;

 

Automatic Phase 8 pipeline integration (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.

 

Когато sfArabicGSUB е зададен, статичният шейпър за Unicode Presentation Forms се заобикаля в полза на собствените GSUB правила на шрифта. HotPDF извежда собствени контекстни ID-та на глифове чрез синтетични кодови точки, когато тези глифове не са достижими от cmap на шрифта, държи вградения поднабор затворен и записва обратни съпоставяния в ToUnicode за копиране и поставяне. Ползвателите, които искат статичният шейпър да продължи да работи за покритие на кодови точки извън това, което GSUB на шрифта декларира, трябва да оставят sfArabicGSUB изключен и да разчитат на статичната верига за следпроцесна обработка

 

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

ToUnicode CMap с кодировка Adobe-Identity-UCS, изходящ от RegisterUnicodeTTF, включва записи bfchar за обратно съпоставяне за всяка лигатурна кодова точка, която може да произведе веригата за следпроцесна обработка. v2.119.61 добави 27 записа (8 LAM-ALEF + 18 от семейството YEH-HAMZA + 1 Allah); v2.119.62 добави Bismillah (U+FDFD); v2.119.65 добави 7 записа за Latin Standard Ligatures (FB00-FB06). Копирането / поставянето от страна на четеца връща всяка лигатурна глифова форма обратно към изходната последователност от кодови точки, така че визуализираният PDF остава достъпен

 

PUA synthetic codepoint emit (v2.119.68)

AssignSyntheticCodepointForGID(GID; out CP): Boolean + GetSyntheticCodepointForGID(GID): Word позволяват на producer кода да излъчва GSUB substitute GID-ове, които нямат естествен Unicode codepoint, достижим през cmap-а на шрифта. Allocator-ът раздава codepoint-и в Private Use Area (U+E000 - U+F8FF, 6400 slots) и отразява assignment-а във FUnicodeCpToGid (така /CIDToGIDMap връща synthetic CP обратно към target GID при consumer reader-а), FAcroFormUnicodeAdvances (така v2.65 word-wrap намира правилния em-fraction) и per-GID reverse-lookup таблица (така повторните assignment requests са идемпотентни). Използвайте това за Devanagari cluster shapes, stylistic alternates и CJK ideographic variation sequences, които GSUB въвежда, но cmap не достига

 

Relationship to the OpenType GSUB engine

Описаният по-горе статичен шейпър за следпроцесна обработка (v2.85.0 + v2.119.32 / 58 / 60 / 62) е независим от двигателя OpenType GSUB engine по подразбиране. Когато sfArabicGSUB е включен чрез ShapingFeatures, GSUB двигателят става част от производствения път на извеждане: HotPDF се обръща към cmap, за да изгради масив от базови GID, прилага собствените позиционни и контекстни GSUB lookup-и за този глифов ред, присвоява синтетични кодови точки за заместващи GID на глифове, които нямат Unicode Presentation Form, и извиква MarkUnicodeGlyphUsed, за да задържи заместващите глифове вътре във вградения поднабор на шрифта

 

За заместващи глифове без Unicode кодова точка ползвателите комбинират ShapingFeatures с allocator-а за синтетични кодови точки от PUA във v2.119.68, така че заместващият GID да остане достижим през стандартния hex pipeline. Статичната верига за следпроцесна обработка остава подразбираният резервен вариант за кодови точки, които GSUB декларациите на шрифта не покриват

 

Обхват и ограничения

Алгоритъмът BiDi остава извън тази страница: ползвателите все още трябва сами да подреждат смесени LTR и RTL пасажи или да използват отделна BiDi библиотека. Поддръжката за GPOS, Indic/Tibetan/Mongolian, Hebrew, N'Ko, Adlam, Thai/Lao и Javanese вече е на отделни страници за флагове и API за шейпинг, така че тази страница се фокусира само върху статично и 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