|
Engine Substitusi OpenType GSUB Permukaan kapabilitas substitusi glyph (v2.119.43 - v2.119.50)
|
Arabic Shaping CFF / OpenType Subsetting |
|
Engine OpenType GSUB (Glyph SUBstitution) di dalam HotPDF memungkinkan pemanggil menanyakan, menggerakkan, dan menyematkan semua jenis substitusi glyph yang dideklarasikan font OpenType - ligature, stylistic alternates, varian kontekstual, bentuk shaping Arabic / Indic, bentuk alternatif CJK, dan seterusnya. Setiap OpenType GSUB LookupType 1 hingga 8 diimplementasikan dan diekspos sebagai permukaan query yang hanya berisi kapabilitas; pemanggil menggerakkan emisi teks dan memutuskan glyph pengganti mana yang akan ditulis ke content stream halaman
API publik 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);
Deskripsi Engine aktif setelah
Kontrak defensif berlaku di seluruh bagian: font tanpa tabel GSUB, feature tag yang bukan 4 byte, fitur yang tidak diiklankan script / language terpilih, GID yang tidak dicakup subtabel mana pun, dan glyph masukan yang diabaikan LookupFlag semuanya mengembalikan no-op aman (False / OutGID = InputGID / empty OutGIDs / ConsumedCount = 1) sehingga pemanggil tidak pernah melihat exception untuk kasus rutin "no substitution applies"
Matriks LookupType LookupType 1 (Single Substitution) - satu glyph dipetakan ke satu substitute. Fitur kanonis: LookupType 2 (Multiple Substitution) - satu glyph dipecah menjadi rangkaian substitute glyph. Penggunaan kanonis: LookupType 3 (Alternate Substitution) - satu glyph dipetakan ke salah satu dari N alternates. Fitur kanonis: LookupType 4 (Ligature Substitution) - N glyph masukan dilipat menjadi satu ligature. Fitur kanonis: LookupType 5 (Contextual Substitution) + LookupType 6 (Chained Contextual Substitution) - mencocokkan rangkaian glyph masukan dan men-dispatch lookup bersarang pada posisi tertentu di dalam kecocokan. Ketiga varian Format (1 sequence literal, 2 sequence ClassDef, 3 sequence Coverage) diimplementasikan; dispatcher SequenceLookupRecord masuk lagi ke LookupList dan menangani nested lookup Single / Multiple / Alternate (pertama) / Ligature dengan pelacakan MatchPositions aktif. Fitur kanonis: LookupType 7 (Extension Substitution) - lapisan indirection murni yang didefinisikan spesifikasi OpenType untuk font yang subtabel substitusinya berada di luar jangkauan 16-bit LookupList. Setiap API publik secara transparan mengikuti indirection Offset32 32-bit menuju subtabel LookupType 1 / 2 / 3 / 4 / 5 / 6 / 8 yang sebenarnya. Membuka jalan untuk font CJK / Indic yang berat (Noto Sans CJK, Noto Sans Devanagari) dengan GSUB yang melebihi 64 KB. Tidak ada API terpisah - unwrap berlangsung otomatis LookupType 8 (Reverse Chained Contextual Single Substitution) - substitusi 1:1 yang peka konteks dengan ciri pembeda bahwa pemanggil harus menerapkannya dalam urutan pemindaian REVERSE pada run multi-glyph (akhir -> awal) karena setiap substitute dapat bergantung pada konteks lookahead MASA DEPAN yang belum boleh tersubstitusi. Penggunaan kanonis: alternates kontekstual Arabic / Syriac / N'Ko / Indic yang bentuk finalnya bergantung pada glyph berikutnya. Gunakan
Script / LangSys selection Secara default engine lebih memilih skrip
Semantik strict-vs-fallback:
LookupFlag honor and GDEF Setiap query membaca LookupFlag milik setiap tabel Lookup (dan trailing
TTF subsetter closure (MarkUnicodeGlyphUsed) TTF subsetter v2.84.0 milik HotPDF menurunkan set glyph terpakai dari
Setelah memancarkan GID apa pun yang dikembalikan
Typical workflow (Latin small caps)
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;
Typical workflow (Arabic LAM-ALEF ligature)
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;
Cakupan dan batasan Engine ini adalah permukaan query yang hanya berisi kapabilitas: ia menjawab "what would GSUB do here", tetapi tidak menjalankan pipeline shaping otomatis (layout kelas Harfbuzz, reordering peka cluster untuk Indic, resolusi BiDi, positioning GPOS, attachment mark). Pemanggil bertanggung jawab mengendalikan scan loop, memilih substitute / alternate mana yang akan dipancarkan, memanggil
Shaping Arabic / Persian / Urdu sisi producer (ligatur wajib LAM-ALEF + Arabic Presentation Forms-A) diimplementasikan sebagai pipeline bawaan terpisah yang berjalan otomatis selama text emission - lihat Arabic / Persian / Urdu Shaping
Version trace 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 + penghormatan LookupFlag (Phase 4). v2.119.47 Contextual + Chained Contextual + dispatcher SequenceLookupRecord (Phase 5). v2.119.48 Reverse Chained Contextual - matriks LookupType 1-8 tertutup (Phase 6). v2.119.49 API pemilihan Script / LangSys (Phase 7). v2.119.50 closure TTF subsetter lewat
Lihat juga: Arabic / Persian / Urdu Shaping, CFF / OpenType Font Subsetting Functions, THotPDF.EnableFontSubsetting |