|
موتور جایگزینی OpenType GSUB سطح قابلیتهای جایگزینی glyph (v2.119.43 - v2.119.50)
|
شکلدهی عربی CFF / زیرمجموعهسازی OpenType |
|
موتور OpenType GSUB (Glyph SUBstitution) داخل HotPDF به فراخواننده اجازه میدهد همه نوع جایگزینی گلیف را که یک فونت OpenType اعلام میکند پرسوجو، هدایت و صادر کند - لیگاتورها، جایگزینهای سبکی، واریانتهای وابسته به متن، فرمهای شکلدهی عربی / Indic، فرمهای جایگزین CJK و غیره. همه LookupTypeهای 1 تا 8 در OpenType GSUB پیادهسازی شدهاند و بهصورت یک سطح پرسوجوی صرفاً قابلیتی در دسترساند؛ فراخواننده خروجی متن را هدایت میکند و تصمیم میگیرد کدام گلیف جایگزین در جریان محتوای صفحه نوشته شود
رابط عمومی type TGSUBStringArray = array of AnsiString;
// LookupType 1 - Single Substitution (one glyph -> one glyph) function GetSingleSubstituteGlyph(InputGID: Word; const FeatureTag: AnsiString): Word;
// LookupType 2 - Multiple Substitution (one glyph -> sequence of glyphs) function GetMultipleSubstituteGlyphs(InputGID: Word; const FeatureTag: AnsiString; var OutGIDs: array of Word): Boolean;
// LookupType 3 - Alternate Substitution (one glyph -> one of N alternates) function GetAlternateGlyphCount(InputGID: Word; const FeatureTag: AnsiString): Integer; function GetAlternateGlyph(InputGID: Word; const FeatureTag: AnsiString; AlternateIndex: Integer): Word;
// LookupType 4 - Ligature Substitution (N glyphs -> one ligature) function ApplyLigatureSubstitution(const InputGIDs: array of Word; StartIndex: Integer; const FeatureTag: AnsiString; out OutGID: Word; out ConsumedCount: Integer): Boolean;
// LookupType 5 + 6 - Contextual / Chained Contextual Substitution function ApplyContextualSubst(const InputGIDs: array of Word; StartIndex: Integer; const FeatureTag: AnsiString; var OutGIDs: array of Word; out ConsumedLen: Integer): Boolean;
// LookupType 8 - Reverse Chained Contextual Single Substitution function ApplyReverseChainedContextualSubst(const InputGIDs: array of Word; StartIndex: Integer; const FeatureTag: AnsiString; out OutGID: Word): Boolean;
// Script / LangSys selection (Phase 7) procedure SetGSUBScript(const ScriptTag: AnsiString); procedure SetGSUBLanguage(const LangTag: AnsiString); function GetGSUBScripts: TGSUBStringArray; function GetGSUBLanguages(const ScriptTag: AnsiString): TGSUBStringArray; function GetGSUBFeatures(const ScriptTag, LangTag: AnsiString): TGSUBStringArray;
// TTF subsetter closure (Phase 9) procedure MarkUnicodeGlyphUsed(GID: Word);
توضیح این موتور بعد از آن فعال میشود که
قرارداد دفاعی در سراسر مسیر برقرار است: فونتهای بدون جدول GSUB، feature tagهای غیرچهاربایتی، featureهایی که script / language انتخابشده اعلام نمیکند، GIDهایی که هیچ subtableی پوشش نمیدهد، و input glyphهایی که LookupFlag نادیده میگیرد، همگی یک no-op امن برمیگردانند (False / OutGID = InputGID / OutGIDs خالی / ConsumedCount = 1) تا فراخوانندهها برای حالتهای معمول «هیچ substitutionی اعمال نمیشود» exception نبینند
ماتریس LookupType LookupType 1 (Single Substitution) - یک glyph به یک substitute نگاشت میشود. featureهای رایج: LookupType 2 (Multiple Substitution) - یک glyph به دنبالهای از glyphهای جایگزین شکسته میشود. کاربرد رایج: LookupType 3 (Alternate Substitution) - یک glyph به یکی از N alternate نگاشت میشود. featureهای رایج: LookupType 4 (Ligature Substitution) - N glyph ورودی به یک ligature fold میشوند. featureهای رایج: LookupType 5 (Contextual Substitution) + LookupType 6 (Chained Contextual Substitution) - با یک دنبالهٔ glyph ورودی match میشوند و nested lookupها را در موقعیتهای مشخص داخل همان match dispatch میکنند. هر سه variant قالب (1 دنبالهٔ literal، 2 دنبالهٔ ClassDef، 3 دنبالهٔ Coverage) پیادهسازی شدهاند؛ dispatcherِ LookupType 7 (Extension Substitution) - یک لایهٔ pure indirection که spec OpenType برای فونتهایی تعریف میکند که subtable جایگزینی آنها فراتر از دسترس 16 بیتی LookupList قرار دارد. هر API عمومی بهطور شفاف indirection 32 بیتی Offset32 را تا subtable واقعی LookupType 1 / 2 / 3 / 4 / 5 / 6 / 8 دنبال میکند. این سازوکار فونتهای سنگین CJK / Indic مثل Noto Sans CJK و Noto Sans Devanagari را که GSUB آنها از 64 KB فراتر میرود، باز میکند. API جداگانهای ندارد - unwrap بهصورت خودکار انجام میشود LookupType 8 (Reverse Chained Contextual Single Substitution) - substitution 1:1 آگاه از زمینه که ویژگی متمایز آن این است که فراخواننده باید آن را در ترتیب reverse scan روی یک run چندglyphی (end -> start) اعمال کند، چون هر substitute ممکن است به زمینهٔ lookahead آینده وابسته باشد؛ زمینهای که هنوز نباید substitution شده باشد. کاربرد رایج: alternateهای contextual عربی / سریانی / N'Ko / Indic که form نهایی آنها به glyph بعدی وابسته است. از
انتخاب Script / LangSys بهطور پیشفرض موتور GSUB اسکریپت
معنای strict-vs-fallback: یک
رعایت LookupFlag و GDEF هر پرسوجو
بستن subsetterِ TTF (MarkUnicodeGlyphUsed) subsetterِ TTF نسخهٔ v2.84.0 در HotPDF مجموعهٔ glyphهای استفادهشده را از طریق cmap و بر پایهٔ
پس از صدور هر GID برگشتی از
گردشکار معمول (حروف کوچک لاتین)
PDF.RegisterUnicodeTTF('myFont', 'C:\\Windows\\Fonts\\arial.ttf'); PDF.SetGSUBScript('latn'); PDF.SetGSUBLanguage(''); // default LangSys SmallCapGID := PDF.GetSingleSubstituteGlyph(InputGID, 'smcp'); if SmallCapGID <> InputGID then begin // emit SmallCapGID into the page content stream.. PDF.MarkUnicodeGlyphUsed(SmallCapGID); // pull into subset end;
گردشکار معمول (لیگاتور Arabic LAM-ALEF)
PDF.SetGSUBScript('arab'); Run := [LamGID, FathaGID, AlefGID]; // post-cmap GIDs if PDF.ApplyLigatureSubstitution(Run, 0, 'rlig', LigGID, ConsumedCount) then begin // emit LigGID + advance by ConsumedCount PDF.MarkUnicodeGlyphUsed(LigGID); end;
دامنه و محدودیتها این موتور فقط یک سطح پرسوجوی قابلیتی است: به سؤال «GSUB اینجا چه میکرد» پاسخ میدهد، اما یک خط لوله شکلدهی خودکار را اجرا نمیکند (چیدمان در سطح Harfbuzz، بازآرایی آگاه از خوشه برای Indic، حل BiDi، موقعیتدهی GPOS، اتصال mark). مسئولیت اجرای حلقه اسکن، انتخاب اینکه کدام substitute / alternate صادر شود، فراخوانی
شکلدهی عربی / فارسی / اردو در سمت تولیدکننده (ligature اجباری LAM-ALEF + Arabic Presentation Forms-A) بهصورت یک خط لولهٔ داخلی جداگانه پیادهسازی شده است که هنگام text emission بهطور خودکار اجرا میشود - شکلدهی عربی / فارسی / اردو را ببینید
رد نسخه v2.119.43 Single Substitution + Phase 1. v2.119.44 Multiple + Alternate (Phase 2). v2.119.45 Ligature (Phase 3). v2.119.46 Extension + GDEF + LookupFlag honor (Phase 4). v2.119.47 Contextual + Chained Contextual + SequenceLookupRecord dispatcher (Phase 5). v2.119.48 Reverse Chained Contextual - ماتریس LookupType 1-8 کامل شد (Phase 6). v2.119.49 API انتخاب Script / LangSys (Phase 7). v2.119.50 بستن subsetterِ TTF از طریق
همچنین ببینید: شکلدهی عربی / فارسی / اردو, CFF / OpenType Font Subsetting Functions, THotPDF.EnableFontSubsetting |