|
OpenType GSUB Substitution Engine Glyph substitution capability surface (v2.119.43 - v2.119.50)
|
Arabic Shaping CFF / OpenType Subsetting |
|
HotPDF 내부의 OpenType GSUB(Glyph SUBstitution) engine은 OpenType font가 선언하는 모든 glyph substitution, 즉 ligature, stylistic alternate, contextual variant, Arabic / Indic shaping form, CJK alternate form 등을 호출자가 조회하고 구동하며 포함할 수 있게 합니다. OpenType GSUB LookupType 1부터 8까지 모두 구현되어 capability-only query surface로 노출됩니다. 텍스트 방출은 호출자가 구동하며, page content stream에 어떤 substitute glyph를 쓸지 호출자가 결정합니다
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);
설명 engine은
전체 defensive contract: GSUB table이 없는 font, 4바이트가 아닌 feature tag, 선택한 script / language가 광고하지 않는 feature, 어떤 subtable도 덮지 않는 GID, LookupFlag로 ignore된 input glyph는 모두 안전한 no-op(False / OutGID = InputGID / empty OutGIDs / ConsumedCount = 1)을 반환합니다. 따라서 호출자는 일반적인 "적용할 substitution 없음" 상황에서 예외를 보지 않습니다
LookupType matrix LookupType 1(Single Substitution) - 하나의 glyph가 하나의 substitute로 매핑됩니다. 대표 feature는 salt, ss01-ss20, smcp, onum, LookupType 1로 연결된 liga, 그리고 GSUB로 구동하는 font의 init / medi / fina / isol Arabic positional form입니다. LookupType 2(Multiple Substitution) - 하나의 glyph가 substitute glyph sequence로 분리됩니다. 대표 사용자는 ccmp Glyph Composition / Decomposition으로, precomposed accented Latin letter를 downstream mark positioning을 위해 base + combining mark로 분해합니다. LookupType 3(Alternate Substitution) - 하나의 glyph가 N개 alternate 중 하나로 매핑됩니다. 대표 feature는 aalt(Access All Alternates), Type 3로 연결된 salt, titl(Titling Alternates), font designer가 slot당 여러 alternate를 제공하는 ss01-ss20 stylistic set입니다. LookupType 4 (Ligature Substitution) - N input glyphs fold into one ligature. Canonical features: LookupType 5(Contextual Substitution) + LookupType 6(Chained Contextual Substitution) - input glyph sequence를 매칭하고 match 내부 특정 위치에서 nested lookup을 dispatch합니다. 세 가지 Format variant(1 literal sequence, 2 ClassDef sequence, 3 Coverage sequence)를 모두 구현했습니다. LookupType 7(Extension Substitution) - substitution subtable이 LookupList의 16비트 범위를 넘어가는 font를 위해 OpenType spec이 정의한 순수 indirection layer입니다. 모든 public API는 32비트 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 기본적으로 engine은 DFLT script(또는 font가 선언한 첫 script)와 default LangSys를 선호합니다.
strict-vs-fallback 의미: 알 수 없는
LookupFlag honor and GDEF 모든 query는 각 Lookup table의
TTF subsetter closure (MarkUnicodeGlyphUsed) HotPDF v2.84.0 TTF subsetter는 cmap을 통해
PDF text stream에
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;
Scope and limitations engine은 capability-only query surface입니다. 즉 "여기에서 GSUB가 무엇을 할 것인가"에 답하지만, Harfbuzz급 layout, Indic cluster-aware reordering, BiDi resolution, GPOS positioning, mark attachment 같은 automatic shaping pipeline을 실행하지 않습니다. 호출자는 scan loop를 구동하고, 어떤 substitute / alternate를 방출할지 선택하며, 방출된 각 substitute GID에 대해
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 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 matrix closed(Phase 6). v2.119.49 Script / LangSys selection API(Phase 7). v2.119.50 TTF subsetter closure via
참조: Arabic / Persian / Urdu Shaping, CFF / OpenType Font Subsetting Functions, THotPDF.EnableFontSubsetting |