|
OpenType GSUB Substitution Engine Glyph substitution capability surface (v2.119.43 - v2.119.50)
|
Arabic Shaping CFF / OpenType Subsetting |
|
HotPDF 내부의 OpenType GSUB(Glyph SUBstitution) 엔진을 사용하면 OpenType 글꼴이 선언한 모든 종류의 글리프 치환을 조회하고, 구동하고, 임베드할 수 있습니다. 합자, 스타일 대체 글리프, 문맥 변형, Arabic / Indic 셰이핑 형태, CJK 대체 글리프 등이 여기에 해당합니다. OpenType GSUB LookupType 1부터 8까지 모두 구현되어 있으며 조회 전용 인터페이스로 노출됩니다. 텍스트 출력은 호출자가 구동하고, 페이지 콘텐츠 스트림에 어떤 대체 글리프를 쓸지도 호출자가 결정합니다
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 이 엔진은
전반적으로 방어적인 계약을 따릅니다. GSUB 테이블이 없는 글꼴, 4바이트가 아닌 feature 태그, 선택된 스크립트 / 언어가 제공하지 않는 기능, 어떤 서브테이블도 다루지 않는 GID, LookupFlag로 무시되는 입력 글리프는 모두 안전한 no-op(False / OutGID = InputGID / 빈 OutGIDs / ConsumedCount = 1)을 반환하므로, "적용할 치환이 없는" 일상적인 경우에 호출자가 예외를 볼 일은 없습니다
LookupType matrix LookupType 1 (Single Substitution) - 글리프 하나가 대체 글리프 하나로 매핑됩니다. 대표 기능은 LookupType 2 (Multiple Substitution) - 글리프 하나가 대체 글리프 시퀀스로 분리됩니다. 대표 사용처는 LookupType 3 (Alternate Substitution) - 글리프 하나가 N개의 대체 글리프 중 하나로 매핑됩니다. 대표 기능은 LookupType 4 (Ligature Substitution) - N input glyphs fold into one ligature. Canonical features: LookupType 5 (Contextual Substitution) + LookupType 6 (Chained Contextual Substitution) - 입력 글리프 시퀀스와 일치하는 부분을 찾고, 일치한 범위 안의 특정 위치에서 중첩된 lookup을 dispatch합니다. Format 변형 세 가지(1 literal 시퀀스, 2 ClassDef 시퀀스, 3 Coverage 시퀀스)가 모두 구현되어 있으며, SequenceLookupRecord dispatcher는 LookupList에 다시 진입하여 Single / Multiple / Alternate(첫 번째) / Ligature 중첩 lookup을 실시간 MatchPositions 추적과 함께 처리합니다. 대표 기능은 LookupType 7 (Extension Substitution) - 치환 서브테이블이 LookupList의 16비트 범위를 넘는 위치에 있는 글꼴을 위해 OpenType 규격이 정의한 순수 간접 참조 계층입니다. 모든 공개 API는 32비트 Offset32 간접 참조를 따라 실제 LookupType 1 / 2 / 3 / 4 / 5 / 6 / 8 서브테이블까지 투명하게 이동합니다. GSUB가 64 KB를 넘는 대형 CJK / Indic 글꼴(Noto Sans CJK, Noto Sans Devanagari)을 쓸 수 있게 해 줍니다. 별도의 API는 없으며 해제는 자동으로 이루어집니다 LookupType 8 (Reverse Chained Contextual Single Substitution) - 문맥을 인식하는 1:1 치환으로, 각 대체 글리프가 아직 치환되지 않아야 하는 뒤쪽(lookahead) 문맥에 의존할 수 있으므로, 호출자가 여러 글리프로 이루어진 런을 반드시 REVERSE 스캔 순서(끝 -> 시작)로 적용해야 한다는 점이 특징입니다. 대표 사용처는 어말형이 뒤따르는 글리프에 좌우되는 Arabic / Syriac / N'Ko / Indic 문맥 대체 글리프입니다.
Script / LangSys selection 기본적으로 엔진은
Strict 대 fallback 동작은 다음과 같습니다. 알 수 없는
LookupFlag honor and GDEF 모든 조회는 각 Lookup 테이블의 LookupFlag(그리고
TTF subsetter closure (MarkUnicodeGlyphUsed) HotPDF의 v2.84.0 TTF 서브셋터는 사용된 글리프 집합을 cmap을 거쳐
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 이 엔진은 조회 전용 인터페이스입니다. "여기서 GSUB가 무엇을 할 것인가"에는 답하지만, 자동 셰이핑 파이프라인(Harfbuzz급 레이아웃, Indic의 클러스터 인식 재정렬, BiDi 해석, GPOS 위치 지정, mark 부착)은 실행하지 않습니다. 스캔 루프를 구동하고, 어떤 대체 / 대안 글리프를 출력할지 선택하고, 출력한 각 대체 GID에 대해
Producer 측 Arabic / Persian / Urdu 셰이핑(LAM-ALEF 필수 합자 + Arabic Presentation Forms-A)은 텍스트 출력 중에 자동으로 실행되는 별도의 내장 파이프라인으로 구현되어 있습니다. 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 적용(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 Script / LangSys 선택 API(Phase 7). v2.119.50
See also: Arabic / Persian / Urdu Shaping, CFF / OpenType Font Subsetting Functions, THotPDF.EnableFontSubsetting |