THotPDF.AssignSyntheticCodepointForGID / GetSyntheticCodepointForGID

THotPDF PUA synthetic codepoint allocator (v2.119.68)

 

GSUB Engine  Auto Shaping Pipeline  Arabic Shaping

Prideľuje a dopytuje syntetické codepointy oblasti Private Use Area (U+E000 - U+F8FF) pre náhradné GID OpenType GSUB, ku ktorým nevedie žiadny prirodzený Unicode codepoint cez cmap písma. Uzatvára medzeru na strane producenta pri emitovaní na úrovni GID, ktorú zanechali API dopytov a rafinácie GSUB v2.119.43-66

 

Delphi syntax:

function AssignSyntheticCodepointForGID(GID: Word; out SyntheticCP: Word): Boolean;

function GetSyntheticCodepointForGID(GID: Word): Word;

 

Why the API exists

Automatická tvarovacia pipeline na strane producenta v2.119.32-67 (Arabic / Latin / Devanagari) vyžaduje, aby boli substitučné GID vrátené GSUB engine dosiahnuteľné cez Unicode codepoint - existujúca hex-kódovaná textová pipeline emituje codepointy, nie GID, a spotrebiteľská čítačka mapuje codepoint späť na GID cez vložený /CIDToGIDMap. Pre substitučné GID s prirodzeným Unicode codepointom cez cmap fontu (Arabic Presentation Forms, Latin Standard Ligatures FB00-FB06) existujúca pipeline funguje bez problémov

 

Ale substitúty špecifické pre font, ktoré končia na interných GID fontu - väčšina tvarov devanagárskych klastrov, štýlové alternatívy dodávané návrhárom fontu len ako očíslované GID, CJK ideografické sekvencie variácií (IVS), diskrétne ligatúry bez zodpovedajúcej Presentation Form - nemajú v cmap fontu vôbec žiadny codepoint. Pred v2.119.68 boli tieto GID nedosiahnuteľné cez producentom používanú hex pipeline; v2.119.68 túto medzeru uzatvára tým, že dovoľuje volajúcim priradiť syntetický codepoint v Private Use Area pre ľubovoľné GID

 

AssignSyntheticCodepointForGID semantics

Prideľuje ďalší dostupný codepoint PUA (začínajúc na U+E000) pre dodané GID a zrkadlí priradenie do každej cache, od ktorej závisí existujúca producer-side hex pipeline + consumer-reader resolution chain:

 

1. FUnicodeCpToGid[SyntheticCP] := GID - so the producer-side hex pipeline emits SyntheticCP into the text-showing operator and the consumer reader resolves SyntheticCP back to GID through /CIDToGIDMap at render time.

2. FAcroFormUnicodeAdvances[SyntheticCP] := em-fraction - so the v2.65 word-wrap calculator finds the correct hmtx advance for the synthetic codepoint when it appears in AcroForm text-field content.

3. FUnicodeSyntheticCpForGID[GID] := SyntheticCP - the per-GID reverse-lookup table used by GetSyntheticCodepointForGID to make repeat AssignSyntheticCodepointForGID calls idempotent (the second call with the same GID returns the already-allocated SyntheticCP).

 

Vracia True pri úspechu s SyntheticCP nastaveným na pridelený codepoint. Vracia False (a necháva SyntheticCP na 0) pri ktorejkoľvek z týchto obranných podmienok: nie je zaregistrovaný žiadny font (RegisterUnicodeTTF nebolo nikdy zavolané alebo bolo zavolané s prázdnymi argumentmi na reset stavu), neplatné GID (nula alebo za počtom glyfov v cmap), vyčerpaný rozsah PUA (všetkých 6400 slotov U+E000 - U+F8FF pridelených), cache neinitializovaná pri vstupe

 

GetSyntheticCodepointForGID semantics

Čisto funkčný dotaz na akékoľvek existujúce priradenie. Vracia syntetický codepoint pridelený pre GID, ak bolo AssignSyntheticCodepointForGID(GID, ...) zavolané predtým; inak vracia 0 (čo nie je platný PUA codepoint, takže slúži aj ako sentinel „bez priradenia“). Neprideľuje. Bezpečné na volanie pred spustením akéhokoľvek AssignSyntheticCodepointForGID

 

Allocator state lifecycle

FUnicodeSyntheticCpForGID a kurzor next-available-PUA (FUnicodeNextSyntheticCp) sa alokujú lenivo pri prvom volaní AssignSyntheticCodepointForGID. Kurzor začína na 0 (neinitializovaný) a pri prvom pridelení sa posunie na $E000; ďalšie pridelenia ho vedú cez $E001, $E002, ..., $F8FF. Obe polia sa pri každom RegisterUnicodeTTF('', nil) resetujú na prázdne / 0 spolu so zvyškom stavov podmnožiny na úrovni písma, takže volajúci, ktorí znovu používajú THotPDF cez viac dokumentov, začínajú každý dokument s čerstvým PUA kurzorom

 

Typical workflow (Devanagari cluster shape)

 

PDF.RegisterUnicodeTTF('NotoDeva', 'NotoSansDevanagari-Regular.ttf');

PDF.ShapingFeatures := [sfIndicShaping];

PDF.SetGSUBScript('deva');

 

// Get a font-internal cluster GID through the GSUB engine

ClusterGID := PDF.GetSingleSubstituteGlyph(BaseGID, 'nukt');

if ClusterGID <> BaseGID then

begin

  // Check if cmap reaches the substitute - usually no for Indic

  // clusters, since cluster GIDs are font-internal

  // Allocate a synthetic codepoint that the producer-side

  // hex pipeline can emit

  if PDF.AssignSyntheticCodepointForGID(ClusterGID, SyntheticCP) then

  begin

    // SyntheticCP is now in the U+E000-F8FF range; emit it

    // through UnicodeTextOut just like a normal codepoint

    PDF.CurrentPage.UnicodeTextOut(X, Y, 0, UnicodeChar(SyntheticCP));

    PDF.MarkUnicodeGlyphUsed(ClusterGID);

  end;

end;

 

Idempotency example

 

PDF.AssignSyntheticCodepointForGID(150, CP1);  // CP1 = $E000

PDF.AssignSyntheticCodepointForGID(151, CP2);  // CP2 = $E001

PDF.AssignSyntheticCodepointForGID(150, CP3);  // CP3 = $E000 (idempotent)

CP4 := PDF.GetSyntheticCodepointForGID(150);  // CP4 = $E000

CP5 := PDF.GetSyntheticCodepointForGID(999);  // CP5 = 0 (no assignment)

 

Consumer-reader behavior

Spotrebiteľská čítačka vidí PUA codepoint v operátore text-showing a rozrieši ho cez dokumentom vložený /CIDToGIDMap na cieľový GID, potom tento GID vykreslí pomocou vloženého fontového programu. Z pohľadu čítačky nie je rozdiel medzi "prirodzeným" Unicode codepointom, ktorý cmap smeruje na GID, a PUA syntetickým codepointom, ktorý /CIDToGIDMap smeruje na GID - oba vytvoria ten istý vykreslený glyf

 

Správanie copy / paste: codepointy PUA sa pri copy / paste vracajú ako samy seba, keď ToUnicode CMap deklaruje identity mapovania. Volajúci, ktorí chcú, aby sa namiesto toho vrátili zdrojové Unicode znaky (vstupný beh, ktorý vytvoril substitút), môžu zaregistrovať reverzné mapovanie cez RegisterToUnicodeReverseMapping alebo vytvoriť vlastnosti označeného obsahu ActualText cez BeginTaggedContent a emitovať syntetické codepointy vo vnútri zátvorkovaného obsahu. HotPDF používa ten istý pattern interného CID automaticky pre AcroForm appearance streamy viazané na RegisterUnicodeTTF, ktoré obsahujú Unicode znaky zo suplementárnej roviny

 

Phase 8 roadmap closure

v2.119.68 / Phase 8c.6 uzatvára roadmap GSUB enginu Phase 8: každé query API LookupType 1-8 (Phase 1-6), API výberu Script / LangSys (Phase 7), uzáverový vstupný bod TTF subsetteru (Phase 9), statické skladanie ligatúr post-pass (v2.119.32 / 58 / 60 / 62), voliteľnú automatickú pipeline (v2.119.59), automatické emitovanie arabského rlig + latin liga / clig + rclt (Phase 8b / 8c.2 / 8b / GSUB 'rclt'), reverzné mapovanie ToUnicode (v2.119.61 / 62 / 65), dopyt na advance (v2.119.64), pre-pass preusporiadania Devanagari Indic (v2.119.67) a teraz emitovanie syntetického codepointu PUA na úrovni GID (v2.119.68) sa všetko integruje do jedinej producer-side shaping plochy, ktorá zvláda každý druh substitute glyfu, ktorý môže OpenType font vytvoriť

 

See also: OpenType GSUB Substitution Engine, Automatic Shaping Pipeline (Phase 8), Arabic / Persian / Urdu Shaping Support, Syriac / Mongolian / Devanagari Shaping, THotPDF.BeginTaggedContent