THotPDF.AssignSyntheticCodepointForGID / GetSyntheticCodepointForGID

THotPDF PUA synthetic codepoint allocator (v2.119.68)

 

GSUB Engine  Auto Shaping Pipeline  Arabic Shaping

Alloca e interroga codepoint sintetici nella Private Use Area (U+E000 - U+F8FF) per GID sostitutivi OpenType GSUB che non hanno un codepoint Unicode naturale raggiungibile tramite la cmap del font. Chiude il divario di emissione a livello GID lato produttore lasciato dalle API di query e raffinamento GSUB v2.119.43-66

 

Sintassi Delphi:

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

function GetSyntheticCodepointForGID(GID: Word): Word;

 

Why the API exists

La pipeline di shaping automatico lato produttore v2.119.32-67 (Arabic / Latin / Devanagari) richiede che i GID sostitutivi restituiti dal motore GSUB siano raggiungibili tramite un codepoint Unicode - la pipeline testuale esistente codificata in esadecimale emette codepoint, non GID, e il reader consumer risolve il codepoint di nuovo in un GID tramite la /CIDToGIDMap incorporata. Per i GID sostitutivi che hanno un codepoint Unicode naturale tramite la cmap del font (Arabic Presentation Forms, Latin Standard Ligatures FB00-FB06), la pipeline esistente funziona correttamente

 

Ma i sostituti specifici del font che finiscono su GID interni al font - la maggior parte delle forme cluster Devanagari, varianti stilistiche distribuite dal progettista del font solo come GID numerati, sequenze di variazione ideografica CJK (IVS), legature discrezionali senza Presentation Form corrispondente - non hanno alcun codepoint nella cmap del font. Prima della v2.119.68 questi GID erano irraggiungibili tramite la pipeline esadecimale lato produttore; v2.119.68 chiude tale divario consentendo ai chiamanti di allocare un codepoint sintetico nella Private Use Area per qualsiasi GID that land on font-internal GIDs - most Devanagari cluster shapes, stylistic alternates the font designer ships only as numbered GIDs, CJK ideographic variation sequences (IVS), discretionary ligatures with no corresponding Presentation Form - have no codepoint at all in the font's cmap. Pre-v2.119.68 these GIDs were unreachable through the producer-side hex pipeline; v2.119.68 closes that gap by letting callers allocate a synthetic codepoint in the Private Use Area for any GID.

 

AssignSyntheticCodepointForGID semantics

Alloca il successivo codepoint PUA disponibile (a partire da U+E000) per il GID fornito e replica l'assegnazione in ogni cache da cui dipende la catena esistente pipeline esadecimale lato produttore + risoluzione reader consumer:

 

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).

 

Restituisce True in caso di successo con SyntheticCP impostato sul codepoint allocato. Restituisce False (e lascia SyntheticCP a 0) in una di queste condizioni difensive: nessun font registrato (RegisterUnicodeTTF mai chiamato o chiamato con argomenti vuoti per reimpostare lo stato), GID non valido (zero o oltre il conteggio glyph della cmap), intervallo PUA esaurito (tutti i 6400 slot U+E000 - U+F8FF allocati), cache non inizializzata all'ingresso

 

GetSyntheticCodepointForGID semantics

Query puramente funzionale di qualsiasi assegnazione esistente. Restituisce il codepoint sintetico allocato per GID se AssignSyntheticCodepointForGID(GID, ...) e gia stato chiamato; altrimenti restituisce 0 (che non e un codepoint PUA valido, quindi funge anche da sentinella "nessuna assegnazione"). Non alloca. Sicura da chiamare prima di qualsiasi esecuzione di AssignSyntheticCodepointForGID. Returns the synthetic codepoint allocated for GID if AssignSyntheticCodepointForGID(GID, ...) has been called previously; otherwise returns 0 (which is not a valid PUA codepoint, so it doubles as a "no assignment" sentinel). Does not allocate. Safe to call before any AssignSyntheticCodepointForGID has run.

 

Allocator state lifecycle

FUnicodeSyntheticCpForGID e il cursore next-available-PUA (FUnicodeSuccessivoSyntheticCp) vengono allocati in modo lazy alla prima chiamata AssignSyntheticCodepointForGID. Il cursore parte da 0 (non inizializzato) e passa a $E000 alla prima allocazione; le allocazioni successive lo spostano attraverso $E001, $E002, ..., $F8FF. Entrambi i campi vengono reimpostati a vuoto / 0 a ogni RegisterUnicodeTTF('', nil) insieme al resto dello stato subset per-font, cosi i chiamanti che riusano una istanza THotPDF su piu documenti iniziano ogni documento con un cursore PUA fresco

 

Workflow tipico (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

Il reader consumer vede il codepoint PUA nell'operatore di visualizzazione testo e lo risolve tramite la /CIDToGIDMap incorporata nel documento verso il GID target, quindi rende quel GID usando il programma font incorporato. Dal punto di vista del reader non c'e differenza tra un codepoint Unicode "naturale" che la cmap instrada a GID e un codepoint sintetico PUA che /CIDToGIDMap instrada a GID - entrambi producono lo stesso glifo renderizzato

 

Comportamento copia / incolla: i codepoint PUA fanno round-trip come se stessi tramite copia / incolla quando la ToUnicode CMap li dichiara come mapping identity. I chiamanti che vogliono invece il round-trip dei caratteri Unicode sorgente (la run di input che ha prodotto il sostituto) possono registrare un mapping inverso con RegisterToUnicodeReverseMapping oppure creare proprieta di sequenza marked-content ActualText tramite BeginTaggedContent ed emettere i codepoint sintetici dentro il contenuto tra parentesi. HotPDF usa automaticamente lo stesso pattern internal-CID per gli appearance stream AcroForm basati su RegisterUnicodeTTF che contengono caratteri Unicode del piano supplementare

 

Phase 8 roadmap closure

v2.119.68 / Phase 8c.6 chiude la roadmap del motore GSUB Phase 8: ogni API query LookupType 1-8 (Phase 1-6), l'API di selezione Script / LangSys (Phase 7), il punto di ingresso del subsetter TTF (Phase 9), la piegatura legature post-pass statica (v2.119.32 / 58 / 60 / 62), la pipeline automatica opt-in (v2.119.59), l'emissione automatica Arabic rlig + Latin liga / clig + rclt (Phase 8b / 8c.2 / 8b / GSUB 'rclt'), ToUnicode reverse-mapping (v2.119.61 / 62 / 65), query advance (v2.119.64), pre-pass reorder Indic Devanagari (v2.119.67) e ora emissione GID-level tramite codepoint sintetico PUA (v2.119.68) si integrano tutti in una singola superficie di shaping lato produttore che gestisce ogni tipo di glifo sostitutivo che un font OpenType puo produrre

 

Vedi anche: OpenType GSUB Substitution Engine, Automatic Shaping Pipeline (Phase 8), Supporto shaping arabo / persiano / urdu, Syriac / Mongolian / Devanagari Shaping, THotPDF.BeginTaggedContent