|
OpenType GSUB Substitution Engine Glyph substitution capability surface (v2.119.43 - v2.119.50)
|
Arabic Shaping CFF / OpenType Subsetting |
|
Le moteur OpenType GSUB (Glyph SUBstitution) intégré à HotPDF permet aux appelants d’interroger, de piloter et d’embarquer tout type de substitution de glyphe déclaré par une police OpenType - ligatures, variantes stylistiques, variantes contextuelles, formes de façonnage Arabic / Indic, formes alternatives CJK, et ainsi de suite. Tous les LookupType OpenType GSUB de 1 à 8 sont implémentés et exposés comme surface de requête de capacités uniquement ; l’appelant pilote l’émission du texte et décide quel glyphe substitut écrire dans le flux de contenu de la page
API publique 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 Le moteur s’active après que
Contrat défensif partout : les polices sans table GSUB, les balises de fonctionnalité non codées sur 4 octets, les fonctionnalités que le script / la langue sélectionnés ne déclarent pas, les GID qu’aucune sous-table ne couvre et les glyphes d’entrée ignorés par LookupFlag renvoient tous un comportement sans effet sûr (
Tableau des LookupType LookupType 1 (Single Substitution) - un glyphe est remplacé par un seul glyphe de substitution. Fonctions canoniques : LookupType 2 (Multiple Substitution) - un glyphe se découpe en une séquence de glyphes de substitution. Cas d’usage canonique : LookupType 3 (Alternate Substitution) - un glyphe est remplacé par l’une des N alternatives. Fonctions canoniques : LookupType 4 (Ligature Substitution) - N glyphes d’entrée se fondent en une seule ligature. Fonctions canoniques : LookupType 5 (Contextual Substitution) + LookupType 6 (Chained Contextual Substitution) - fait correspondre une séquence de glyphes d’entrée et déclenche des lookups imbriqués à des positions spécifiques dans la correspondance. Les trois variantes de format (1 séquence littérale, 2 séquence ClassDef, 3 séquence Coverage) sont implémentées ; le répartiteur SequenceLookupRecord réentre dans LookupType 7 (Extension Substitution) - couche d’indirection pure définie par la spec OpenType pour les polices dont la sous-table de substitution se trouve au-delà de la portée 16 bits de LookupType 8 (Reverse Chained Contextual Single Substitution) - substitution contextuelle 1:1 dont la particularité est que les appelants doivent l’appliquer en ordre d’analyse inversé sur une séquence multi-glyphe (fin -> début) car chaque substitution peut dépendre d’un contexte de regard en avant futur qui ne doit pas encore avoir été substitué. Cas d’usage canonique : alternatives contextuelles arabe / syriaque / N'Ko / Indic dont la forme finale dépend du glyphe suivant. Utilisez
Sélection du script / LangSys Par défaut, le moteur privilégie le script
Sémantique strict versus repli: un
Prise en compte de LookupFlag et GDEF Chaque requête lit le LookupFlag de chaque table Lookup (ainsi que le markFilteringSet uint16 optionnel en fin de table lorsque
Clôture du sous-ensemble TTF ( Le sous-ensemble TTF v2.84.0 de HotPDF déduit son ensemble de glyphes utilisés à partir de
Après avoir émis dans un flux texte PDF tout GID renvoyé par
Type de flux (petites capitales latines)
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;
Workflow type (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;
Portée et limites Le moteur reste une surface de requête de capacités uniquement : il répond à la question "que ferait GSUB ici", mais n’exécute pas de pipeline de façonnage automatique (mise en page de type Harfbuzz, réordonnancement sensible aux clusters pour Indic, résolution BiDi, positionnement GPOS, attache des marques). Les appelants doivent piloter la boucle de balayage, choisir quelle substitution / variante émettre, appeler
Le façonnage côté producteur pour l’arabe / le persan / l’ourdou (ligature obligatoire LAM-ALEF + Arabic Presentation Forms-A) est implémenté comme un pipeline intégré distinct qui s’exécute automatiquement pendant l’émission du texte - voir 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 + respect de LookupFlag (Phase 4). v2.119.47 répartiteur Contextual + Chained Contextual + SequenceLookupRecord (Phase 5). v2.119.48 Reverse Chained Contextual - matrice LookupType 1-8 fermée (Phase 6). v2.119.49 API de sélection Script / LangSys (Phase 7). v2.119.50 clôture du sous-ensemble TTF via
Voir aussi: Arabic / Persian / Urdu Shaping, CFF / OpenType Font Subsetting Functions, THotPDF.EnableFontSubsetting |