|
Bộ máy thay thế OpenType GSUB Bề mặt năng lực thay thế glyph (v2.119.43 - v2.119.50)
|
Arabic Shaping CFF / OpenType Subsetting |
|
Bộ máy OpenType GSUB (Glyph SUBstitution) bên trong HotPDF cho phép bên gọi truy vấn, điều khiển và nhúng mọi kiểu thay thế glyph mà một phông OpenType khai báo - ligature, biến thể kiểu chữ, biến thể theo ngữ cảnh, các dạng tạo hình Arabic / Indic, các dạng thay thế CJK, và nhiều hơn nữa. Mọi OpenType GSUB LookupType từ 1 đến 8 đều được cài đặt và phơi ra như một bề mặt chỉ để truy vấn năng lực; bên gọi điều khiển việc phát văn bản và quyết định glyph thay thế nào sẽ được ghi vào luồng nội dung trang
API công khai 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);
Mô tả Bộ máy này hoạt động sau khi
Hợp đồng phòng thủ xuyên suốt: phông không có bảng GSUB, feature tag không đủ 4 byte, feature mà script / language đã chọn không công bố, các GID không subtable nào bao phủ, và các glyph đầu vào bị LookupFlag bỏ qua đều trả về no-op an toàn (False / OutGID = InputGID / OutGIDs rỗng / ConsumedCount = 1) để bên gọi không bao giờ thấy ngoại lệ cho các trường hợp thường nhật "không có phép thay thế nào áp dụng"
LookupType matrix LookupType 1 (Single Substitution) - một glyph ánh xạ sang một substitute. Feature điển hình: LookupType 2 (Multiple Substitution) - một glyph tách thành một dãy glyph thay thế. Trường hợp điển hình: LookupType 3 (Alternate Substitution) - một glyph ánh xạ sang một trong N biến thể. Feature điển hình: LookupType 4 (Ligature Substitution) - N glyph đầu vào gộp thành một ligature. Feature điển hình: LookupType 5 (Contextual Substitution) + LookupType 6 (Chained Contextual Substitution) - khớp một dãy glyph đầu vào và chuyển vào các lookup lồng nhau tại những vị trí cụ thể bên trong phần khớp. Cả ba biến thể Format (1 literal sequence, 2 ClassDef sequence, 3 Coverage sequence) đều đã được cài; bộ dispatch của SequenceLookupRecord quay lại LookupList và xử lý các lookup lồng Single / Multiple / Alternate (lần đầu) / Ligature với việc theo dõi MatchPositions trực tiếp. Feature điển hình: LookupType 7 (Extension Substitution) - lớp gián tiếp thuần túy mà đặc tả OpenType định nghĩa cho những phông có subtable thay thế nằm ngoài tầm với 16-bit của LookupList. Mọi API công khai đều lần theo lớp gián tiếp Offset32 32-bit để tới subtable thật thuộc LookupType 1 / 2 / 3 / 4 / 5 / 6 / 8. Gỡ nút thắt cho các phông CJK / Indic nặng (Noto Sans CJK, Noto Sans Devanagari) có GSUB vượt quá 64 KB. Không có API riêng - việc bóc lớp là tự động LookupType 8 (Reverse Chained Contextual Single Substitution) - phép thay thế 1:1 có nhận biết ngữ cảnh, với điểm khác biệt là bên gọi phải áp dụng nó theo thứ tự quét NGƯỢC trên một dải nhiều glyph (cuối -> đầu) vì mỗi substitute có thể phụ thuộc vào ngữ cảnh nhìn trước ở TƯƠNG LAI chưa được thay thế. Cách dùng điển hình: các alternate ngữ cảnh của Arabic / Syriac / N'Ko / Indic mà dạng cuối phụ thuộc vào glyph theo sau. Dùng
Chọn Script / LangSys Mặc định bộ máy ưu tiên script
Ngữ nghĩa strict-vs-fallback: một
Tôn trọng LookupFlag và GDEF Mỗi truy vấn đều đọc LookupFlag của từng bảng Lookup (và markFilteringSet uint16 tùy chọn ở cuối khi
Khép lại TTF subsetter (MarkUnicodeGlyphUsed) Bộ chia nhỏ TTF v2.84.0 của HotPDF lấy tập glyph đã dùng từ
Sau khi phát bất kỳ GID nào do
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;
Phạm vi và giới hạn Bộ máy này chỉ là một bề mặt truy vấn năng lực: nó trả lời câu hỏi "GSUB sẽ làm gì ở đây", nhưng không chạy một pipeline tạo hình tự động (bố cục cỡ Harfbuzz, reorder có nhận biết cụm cho Indic, phân giải BiDi, định vị GPOS, gắn mark). Bên gọi tự chịu trách nhiệm điều khiển vòng quét, chọn substitute / alternate nào sẽ phát, gọi
Tạo hình Arabic / Persian / Urdu phía producer (ligature bắt buộc LAM-ALEF + Arabic Presentation Forms-A) được cài như một pipeline dựng sẵn riêng và chạy tự động trong lúc phát văn bản - xem Hỗ trợ tạo hình Arabic / Persian / Urdu
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 - matrix LookupType 1-8 được khép kín (Phase 6). v2.119.49 API chọn Script / LangSys (Phase 7). v2.119.50 đóng vòng bộ chia nhỏ TTF qua
Xem thêm: Arabic / Persian / Urdu Shaping, CFF / OpenType Font Subsetting Functions, THotPDF.EnableFontSubsetting |