|
OpenType GSUB-substitusjonsmotor Flate for glyferstatning (v2.119.43 - v2.119.50)
|
Arabic Shaping CFF / OpenType Subsetting |
|
OpenType GSUB-motoren (Glyph SUBstitution) i HotPDF lar kallere spørre om, styre og bygge inn alle typer glyferstatning som en OpenType-font erklærer - ligaturer, stilistiske alternativer, kontekstuelle varianter, arabiske / indiske shaping-former, alternative CJK-former og så videre. Hver OpenType GSUB LookupType 1 til 8 er implementert og eksponert som en ren spørreflate for funksjoner; kalleren styrer tekstutdata og bestemmer hvilken substituert glyf som skal skrives til sideinnholdsstrømmen
Offentlig 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);
Beskrivelse Motoren aktiveres etter at
Defensiv kontrakt hele veien: fonter uten en GSUB-tabell, funksjonstagger som ikke er 4 byte, funksjoner som det valgte skriptet / språket ikke annonserer, GID-er som ingen undertabell dekker, og inngangsglyfer som ignoreres av LookupFlag, returnerer alle en trygg no-op (False / OutGID = InputGID / tomme OutGIDs / ConsumedCount = 1) slik at kallere aldri ser unntak i de vanlige tilfellene der ingen substitusjon gjelder
LookupType-matrise LookupType 1 (enkelt substitusjon) - én glyf mappes til én erstatning. Kanoniske funksjoner: LookupType 2 (flergangs substitusjon) - én glyf deles i en sekvens av erstatningsglyfer. Kanonisk bruk: LookupType 3 (alternativ substitusjon) - én glyf mappes til én av N alternativer. Kanoniske funksjoner: LookupType 4 (ligatursubstitusjon) - N inngående glyfer foldes inn i én ligatur. Kanoniske funksjoner: LookupType 5 (kontekstuell substitusjon) + LookupType 6 (kjedet kontekstuell substitusjon) - matcher en inngående glyfsekvens og sender nestede oppslag til bestemte posisjoner inne i treffet. Alle tre Format-variantene, 1 literal sequence, 2 ClassDef sequence og 3 Coverage sequence, er implementert; SequenceLookupRecord-dispatcheren går inn i LookupList på nytt og håndterer nestede oppslag av typen Single / Multiple / Alternate (first) / Ligature med levende MatchPositions-sporing. Kanoniske funksjoner: LookupType 7 (utvidelses-substitusjon) - et rent indireksjonslag som OpenType-spesifikasjonen definerer for fonter der substitusjons-undertabellen ligger utenfor den 16-bit store rekkevidden til LookupList. Hver offentlige API følger den 32-bit store Offset32-indireksjonen transparent til den virkelige LookupType 1 / 2 / 3 / 4 / 5 / 6 / 8-undertabellen. Låser opp tunge CJK / Indic-fonter (Noto Sans CJK, Noto Sans Devanagari) der GSUB overstiger 64 KB. Ingen separat API - avviklingen skjer automatisk LookupType 8 (omvendt kjedet kontekstuell enkelt substitusjon) - kontekstbevisst 1:1-substitusjon der det avgjørende er at kalleren må bruke den i REVERSE skanrekkefølge over en fler-glyf-streng, fra slutt til start, fordi hver erstatning kan avhenge av fremtidig forhåndskikk-kontekst som ennå ikke må være substituert. Kanonisk bruk: arabiske / syriske / N'Ko / indiske kontekstuelle alternativer der sluttformen avhenger av den påfølgende glyfen. Bruk
Valg av Script / LangSys Som standard foretrekker motoren
Streng-versus-fallbakke-semantikk: en ukjent
LookupFlag-oppførsel og GDEF Hvert spørsmål leser LookupFlag i hver Lookup-tabell, og den valgfrie avsluttende markFilteringSet uint16 når
Lukking av TTF-underinndeler (MarkUnicodeGlyphUsed) HotPDFs v2.84.0 TTF-underinndeler utleder settet med brukte glyfer fra
Etter at du har sendt ut en hvilken som helst GID som returneres av
Typisk arbeidsflyt (latinske små kapitéler)
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;
Typisk arbeidsflyt (arabisk LAM-ALEF-ligatur)
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;
Omfang og begrensninger Motoren er en ren spørreflate for funksjoner: den svarer på "hva ville GSUB gjort her", men den kjører ikke en automatisk shaping-pipeline (Harfbuzz-klasse layout, klyngebasert omorganisering for indisk, BiDi-oppløsning, GPOS-posisjonering, marktilknytning). Kallere har ansvar for å styre skanneløkken, velge hvilken substitusjon / alternativ som skal sendes ut, kalle
Forming på produsentsiden for arabisk / persisk / urdu (obligatorisk LAM-ALEF-ligatur + Arabic Presentation Forms-A) er implementert som en egen innebygd pipeline som kjøres automatisk under tekstutdata - se arabisk / persisk / urdu-forming
Versjonsspor v2.119.43 Enkelt substitusjon + fase 1. v2.119.44 Multiple + Alternate (fase 2). v2.119.45 Ligatur (fase 3). v2.119.46 Extension + GDEF + LookupFlag-håndtering (fase 4). v2.119.47 Kontekstuell + kjedet kontekstuell + SequenceLookupRecord-dispatcher (fase 5). v2.119.48 Omvendt kjedet kontekstuell - LookupType 1-8-matrisen er lukket (fase 6). v2.119.49 API for valg av Script / LangSys (fase 7). v2.119.50 TTF-subsetteren lukkes via
Se også: Arabisk / persisk / urdu shaping, CFF / OpenType skriftdelsinnsettingsfunksjoner, THotPDF.EnableFontSubsetting |