|
Open型 GSUB 置換エンジン グリフ置換機能サーフェス (v2.119.43 - v2.119.50)
|
アラビア文字シェーピング CFF / Open型 サブセット化 |
|
HotPDF内のOpen型 GSUB(グリフ置換)エンジンを使用すると、呼び出し元は、Open型フォントが宣言するすべての種類のグリフ置換(合字、文体による代替、コンテキストのバリアント、アラビア語/インド系文字のシェーピングフォーム、CJKの代替フォームなど)を照会、駆動、および埋め込むことができます。Open型 GSUB Lookup型 1 から 8 のすべてが実装され、機能のみのクエリサーフェスとして公開されています。呼び出し元はテキストの出力を駆動し、どの置換グリフをページコンテンツストリームに書き込むかを決定します。
パブリックAPI type TGSUBStringArray = array of AnsiString;
// Lookup型 1 - 単一置換 (1グリフ -> 1グリフ) function GetSingleSubstituteGlyph(InputGID: Word; const FeatureTag: AnsiString): Word;
// Lookup型 2 - 複数置換 (1グリフ -> グリフのシーケンス) function GetMultipleSubstituteGlyphs(InputGID: Word; const FeatureTag: AnsiString; var OutGIDs: array of Word): Boolean;
// Lookup型 3 - 代替置換 (1グリフ -> N個の代替のいずれか) function GetAlternateGlyphCount(InputGID: Word; const FeatureTag: AnsiString): Integer; function GetAlternateGlyph(InputGID: Word; const FeatureTag: AnsiString; AlternateIndex: Integer): Word;
// Lookup型 4 - 合字置換 (Nグリフ -> 1合字) function ApplyLigatureSubstitution(const InputGIDs: array of Word; StartIndex: Integer; const FeatureTag: AnsiString; out OutGID: Word; out ConsumedCount: Integer): Boolean;
// Lookup型 5 + 6 - コンテキスト / 連鎖コンテキスト置換 function ApplyContextualSubst(const InputGIDs: array of Word; StartIndex: Integer; const FeatureTag: AnsiString; var OutGIDs: array of Word; out ConsumedLen: Integer): Boolean;
// Lookup型 8 - 逆連鎖コンテキスト単一置換 function ApplyReverseChainedContextualSubst(const InputGIDs: array of Word; StartIndex: Integer; const FeatureTag: AnsiString; out OutGID: Word): Boolean;
// スクリプト / 言語システムの選択 (フェーズ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 サブセッタークロージャ (フェーズ9) procedure MarkUnicodeGlyphUsed(GID: Word);
説明 エンジンは、
全体を通して防御的な契約です。GSUBテーブルのないフォント、4バイトではない機能タグ、選択したスクリプト/言語が通知しない機能、サブテーブルがカバーしないGID、およびLookupFlagによって無視される入力グリフはすべて、安全なno-op (False / OutGID = InputGID / 空のOutGIDs / ConsumedCount = 1) を返すため、呼び出し元は「置換が適用されない」日常的なケースで例外を見ることがありません。
Lookup型 マトリックス Lookup型 1 (単一置換) - 1つのグリフが1つの置換にマッピングされます。一般的な機能: Lookup型 2 (複数置換) - 1つのグリフが置換グリフのシーケンスに分割されます。一般的なユーザー: Lookup型 3 (代替置換) - 1つのグリフがN個の代替のいずれかにマッピングされます。一般的な機能: Lookup型 4 (合字置換) - N個の入力グリフが1つの合字に折りたたまれます。一般的な機能: Lookup型 5 (コンテキスト置換) + Lookup型 6 (連鎖コンテキスト置換) - 入力グリフシーケンスと一致し、一致の内部の特定の位置でネストされたルックアップをディスパッチします。3つのFormatバリアント (1 リテラルシーケンス、2 ClassDefシーケンス、3 Coverageシーケンス) はすべて実装されています。SequenceLookupレコードディスパッチャはLookupListに再入し、ライブのMatchPositionsトラッキングを使用して、単一 / 複数 / 代替 (最初) / 合字のネストされたルックアップを処理します。一般的な機能: Lookup型 7 (拡張置換) - Open型仕様が定義する純粋な間接レイヤーであり、置換サブテーブルがLookupListの16ビットの到達範囲を超えるフォント向けです。すべてのパブリックAPIは透過的に、実際のLookup型 1 / 2 / 3 / 4 / 5 / 6 / 8 サブテーブルへの32ビットOffset32の間接性をたどります。GSUBが64 KBを超える重いCJK / インド系フォント (Noto Sans CJK、Noto Sans Devanagari) のブロックを解除します。個別のAPIはありません。アンラップは自動的に行われます。 Lookup型 8 (逆連鎖コンテキスト単一置換) - コンテキストを認識する1:1置換であり、各置換はまだ置換されていない将来の先読みコンテキストに依存する可能性があるため、呼び出し元が複数のグリフのランにわたって「逆」のスキャン順序 (末尾 -> 先頭) で適用する必要があるという特徴があります。一般的な使用法:最終形式が次のグリフに依存するアラビア語 / シリア語 / ンコ語 / インド系のコンテキスト代替。
スクリプト / LangSys の選択 デフォルトでは、エンジンは
厳密とフォールバックのセマンティクス:不明な
LookupFlag の考慮と GDEF すべてのクエリは各LookupテーブルのLookupFlag(および
TTF サブセッタークロージャ (MarkUnicodeGlyphUsed) HotPDFのv2.84.0 TTFサブセッターは、cmapを通じて
一般的なワークフロー (ラテン文字のスモールキャップス)
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;
一般的なワークフロー (アラビア語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クラスのレイアウト、インド系向けのクラスター対応の並べ替え、BiDi解決、GPOSの配置、マークの添付) は実行しません。呼び出し元はスキャンループを駆動し、出力する置換/代替を選択し、出力される置換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 アラビア語 / ペルシア語 / ウルドゥー語 シェーピング.
バージョン履歴 v2.119.43 単一置換 + フェーズ 1。v2.119.44 複数 + 代替 (フェーズ 2)。v2.119.45 合字 (フェーズ 3)。v2.119.46 拡張 + GDEF + LookupFlag の考慮 (フェーズ 4)。v2.119.47 コンテキスト + 連鎖コンテキスト + SequenceLookupレコード ディスパッチャ (フェーズ 5)。v2.119.48 逆連鎖コンテキスト - Lookup型 1-8 マトリックスの完了 (フェーズ 6)。v2.119.49 スクリプト/LangSys 選択API (フェーズ 7)。v2.119.50
See also: アラビア語 / ペルシア語 / ウルドゥー語 シェーピング, CFF / Open型 フォント サブセット化関数, THotPDF.EnableFontSubsetting |