|
OpenType GSUB Substitution Engine Glyph substitution capability surface (v2.119.43 - v2.119.50)
|
Arabic Shaping CFF / OpenType Subsetting |
|
Pogon OpenType GSUB (Glyph SUBstitution) v HotPDF klicateljem omogoča poizvedovanje, upravljanje in vdelavo vsake vrste zamenjave glifov, ki jo določa pisava OpenType - ligature, slogovne alternative, kontekstne različice, arabske / indijske oblike oblikovanja, alternativne oblike CJK in tako naprej. Vse poizvedbe OpenType GSUB LookupType 1 do 8 so implementirane in izpostavljene kot poizvedovalni vmesnik samo za zmožnosti; klicatelj vodi izpis besedila in odloči, kateri nadomestni glif bo zapisal v tok vsebine strani.
Public API 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);
Description Pogon se aktivira potem, ko
Zaščitna pogodba povsod: pisave brez tabele GSUB, oznake funkcij, ki niso 4-bajtne, zmožnosti, ki jih izbrana pisava / jezik ne oglašujeta, GID-ji, ki jih ne pokriva nobena podtabela, in vhodni glifi, ki jih LookupFlag prezre, vsi vrnejo varen no-op (False / OutGID = InputGID / prazni OutGIDs / ConsumedCount = 1), tako da klicatelji nikoli ne vidijo izjem za običajne primere "ni uporabe nadomestitve"
LookupType matrix LookupType 1 (Single Substitution) - en glif se preslika v en nadomestni glif. Kanonične zmožnosti: salt, ss01-ss20, smcp, onum, liga, kadar je LookupType 1 vezan, plus arabske pozicijske oblike init / medi / fina / isol v pisavah, ki jih poganjajo prek GSUB. Uporabite GetSingleSubstituteGlyph LookupType 2 (večkratna zamenjava) - en glif se razdeli v zaporedje nadomestnih glifov. Kanonična uporaba: LookupType 3 (Alternate Substitution) - en glif se preslika v enega od N nadomestkov. Kanonične zmožnosti: aalt (Access All Alternates), salt, kadar je vezan kot Type 3, titl (Titling Alternates), slogovni nizi ss01-ss20, kadar oblikovalec pisave ponudi več kot en nadomestek na reži. Uporabite GetAlternateGlyphCount + GetAlternateGlyph LookupType 4 (Ligature Substitution) - N input glyphs fold into one ligature. Canonical features: LookupType 5 (Contextual Substitution) + LookupType 6 (Chained Contextual Substitution) - ujame vhodno zaporedje glifov in sproži ugnezdene poizvedbe na določenih položajih znotraj ujema. Implementirane so vse tri različice Format (1 literalno zaporedje, 2 zaporedje ClassDef, 3 zaporedje Coverage); razpošiljalnik SequenceLookupRecord ponovno vstopi v LookupList in obravnava ugnezdene poizvedbe Single / Multiple / Alternate (prvi) / Ligature z živim sledenjem MatchPositions. Kanonične zmožnosti: rclt (Required Contextual Alternates - arabske oblike init/medi/fina/isol, kadar jih poganja GSUB), clig, calt, indijsko oblikovanje pres / blws / psts / half / pstf / cjct. Uporabite ApplyContextualSubst (ena vstopna točka pokrije LookupType 5 in 6) LookupType 7 (Extension Substitution) - čista plast posredovanja, ki jo specifikacija OpenType določa za pisave, katerih podtabela nadomestitve presega 16-bitni doseg LookupList. Vsak javni API transparentno sledi 32-bitnemu posredovanju Offset32 do dejanske podtabele LookupType 1 / 2 / 3 / 4 / 5 / 6 / 8. Odklepa težke pisave CJK / Indic (Noto Sans CJK, Noto Sans Devanagari), katerih GSUB presega 64 KB. Ni ločenega API - razpakiranje je samodejno LookupType 8 (Reverse Chained Contextual Single Substitution) - context-aware 1:1 substitution whose distinguishing feature is that callers must apply it in REVERSE scan order over a multi-glyph run (end -> start) because each substitute may depend on FUTURE lookahead context that must not have been substituted yet. Canonical use: Arabic / Syriac / N'Ko / Indic contextual alternates whose final form depends on the following glyph. Use
Script / LangSys selection Privzeto pogon daje prednost skriptu
Semantika strict-vs-fallback: neznani ScriptTag povzroči, da nadaljnje poizvedbe vrnejo prazne no-op rezultate (tako lahko klicatelji zaznajo, da izbrana pisava ni na voljo); neznani LangTag se po konvenciji OpenType vrne na privzeti LangSys pisave. GetGSUBScripts / GetGSUBLanguages / GetGSUBFeatures naštejejo, kaj naložena pisava dejansko oglašuje
LookupFlag honor and GDEF Vsaka poizvedba prebere LookupFlag vsake tabele Lookup (in neobvezni trailing markFilteringSet uint16, kadar je nastavljeno useMarkFilteringSet) ter preskoči vhodne glife, označene za ignoriranje. Upoštevani so biti, določeni s specifikacijo: ignoreBaseGlyphs (0x0002, preskoči razred GDEF 1), ignoreLigatures (0x0004, preskoči razred 2), ignoreMarks (0x0008, preskoči razred 3), useMarkFilteringSet (0x0010) in zgornji bajt markAttachmentType. Razčlenjena sta oba zapisa ClassDef Format 1 + 2; glave GDEF v1.0 / v1.1 / v1.2 so vse sprejete. Pisave brez tabele GDEF se vrnejo na "noben glif ni ignoriran", tako da izhod ostane bajtno enak za klicatelje, ki uporabljajo pisave brez GDEF
TTF subsetter closure (MarkUnicodeGlyphUsed) HotPDFov podnaborovalnik TTF v2.84.0 izpelje svoj nabor uporabljenih glifov iz FUnicodeUsedCps prek cmap. Nadomestni glifi GSUB (slogovne alternative, ligature, kontekstualne različice - vse, kar vrne zgornjih 7 API-jev poizvedb) običajno nimajo nobene kodne točke, ki bi do njih prišla prek cmap, zato so bili prej podnaborovalniku nevidni in je bralnik potrošnika namesto njih izrisal .notdef
Po izpisu katerega koli GID, ki ga vrne GetSingleSubstituteGlyph / GetMultipleSubstituteGlyphs / GetAlternateGlyph / ApplyLigatureSubstitution / ApplyContextualSubst / ApplyReverseChainedContextualSubst, v tok besedila PDF pokličite MarkUnicodeGlyphUsed(GID) enkrat na izpisan GID, da ga potegnete v vdelani podnabor. Pomočnik je idempotenten, zaščiten (GID-ji zunaj obsega se tiho zavržejo) in se poveže z zaključnim prehodom sestavljenih glifov v2.84.0: klicatelj mora označiti le najvišji nadomestni GID - sestavni deli se samodejno potegnejo
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]; // GID-ji po cmap if PDF.ApplyLigatureSubstitution(Run, 0, 'rlig', LigGID, ConsumedCount) then begin // emit LigGID + advance by ConsumedCount PDF.MarkUnicodeGlyphUsed(LigGID); end;
Obseg in omejitve Pogon je poizvedovalni vmesnik samo za zmožnosti: odgovori na vprašanje "kaj bi GSUB naredil tukaj", vendar ne izvaja samodejnega cevovoda oblikovanja (postavitev razreda Harfbuzz, preurejanje z upoštevanjem grozdov za indic, razreševanje BiDi, pozicioniranje GPOS, pritrjevanje oznak). Klicatelji morajo sami voditi zanko pregleda, izbrati, kateri nadomestni / alternativni glif bodo izpisali, poklicati
Producer-side Arabic / Persian / Urdu shaping (LAM-ALEF mandatory ligature + Arabic Presentation Forms-A) is implemented as a separate built-in pipeline that runs automatically during text emission - see Arabic / Persian / Urdu Shaping.
Version trace v2.119.43 enokoraka zamenjava + Faza 1. v2.119.44 večkratna + alternativna (Faza 2). v2.119.45 ligatura (Faza 3). v2.119.46 razširitev + GDEF + upoštevanje LookupFlag (Faza 4). v2.119.47 kontekstualna + verižna kontekstualna + usmerjevalnik SequenceLookupRecord (Faza 5). v2.119.48 obrnjena verižna kontekstualna - zaprta matrika LookupType 1-8 (Faza 6). v2.119.49 API za izbiro skripta / jezikovnega sistema (Faza 7). v2.119.50 zaključek TTF podnabora prek
See also: Arabic / Persian / Urdu Shaping, CFF / OpenType Font Subsetting Functions, THotPDF.EnableFontSubsetting |