THotPDF.AssignSyntheticCodepointForGID / GetSyntheticCodepointForGID

THotPDF PUA synthetic codepoint allocator (v2.119.68)

 

GSUB Engine  Auto Shaping Pipeline  Arabic Shaping

Wijst synthetische codepoints toe in de Private Use Area (U+E000 - U+F8FF) en haalt ze op voor OpenType GSUB-vervangings-GID's die geen natuurlijk Unicode-codepoint hebben dat via de cmap van het lettertype bereikbaar is. Sluit de emissiekloof aan producerzijde op GID-niveau die overbleef na de v2.119.43-66 GSUB-query- en refine-API's

 

Delphi-syntaxis:

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

function GetSyntheticCodepointForGID(GID: Word): Word;

 

Waarom de API bestaat

De automatische vormingspijplijn aan producerzijde v2.119.32-67 (Arabisch / Latijn / Devanagari) vereist dat vervangings-GID's die door de GSUB-engine worden teruggegeven, bereikbaar zijn via een Unicode-codepoint - de bestaande hex-gecodeerde tekstpijplijn geeft codepoints uit, geen GID's, en de lezer lost het codepoint via de ingebedde /CIDToGIDMap weer op naar een GID. Voor vervangings-GID's die via de cmap van het lettertype een natuurlijk Unicode-codepoint hebben (Arabic Presentation Forms, Latin Standard Ligatures FB00-FB06) werkt de bestaande pijplijn prima

 

Maar letterspecifieke substituten die op interne GID's van het lettertype landen - de meeste Devanagari-clustervormen, stilistische alternatieven die de ontwerper alleen als genummerde GID's levert, CJK-ideografische variantiesequenties (IVS), discretionaire ligaturen zonder bijbehorende Presentation Form - hebben helemaal geen codepoint in de cmap van het lettertype. Voor v2.119.68 waren deze GID's onbereikbaar via de hex-pijplijn aan producerzijde; v2.119.68 sluit dat gat door aanroepers voor elke GID een synthetisch codepoint in de Private Use Area te laten toewijzen

 

Semantiek van AssignSyntheticCodepointForGID

Wijst het eerstvolgende beschikbare PUA-codepoint toe, beginnend bij U+E000, voor de opgegeven GID en spiegelt die toewijzing naar elke cache waarop de bestaande producer-side hex-pijplijn en de resolutieketen van de reader vertrouwen:

 

1. FUnicodeCpToGid[SyntheticCP] := GID - zodat de hex-pijplijn aan producerzijde SyntheticCP in de tekstweergave-operator uitstuurt en de reader SyntheticCP bij renderen via /CIDToGIDMap terugoplost naar GID

2. FAcroFormUnicodeAdvances[SyntheticCP] := em-fraction - zodat de woordafbreekcalculator van v2.65 de juiste hmtx-advance vindt voor het synthetische codepoint wanneer het in AcroForm-tekstveldinhoud verschijnt

3. FUnicodeSyntheticCpForGID[GID] := SyntheticCP - de reverse-lookup tabel per GID die door GetSyntheticCodepointForGID wordt gebruikt om herhaalde AssignSyntheticCodepointForGID-aanroepen idempotent te maken, waarbij de tweede aanroep met dezelfde GID het al toegewezen SyntheticCP teruggeeft

 

Geeft True terug bij succes met SyntheticCP ingesteld op het toegewezen codepoint. Geeft False terug en laat SyntheticCP op 0 in deze defensieve gevallen: geen font geregistreerd (RegisterUnicodeTTF nooit aangeroepen of aangeroepen met lege argumenten om de toestand te resetten), ongeldige GID (nul of voorbij de glyph-telling van de cmap), PUA-bereik uitgeput (alle 6400 slots U+E000 - U+F8FF toegewezen), cache niet geïnitialiseerd bij binnenkomst

 

Semantiek van GetSyntheticCodepointForGID

Zuivere query van een bestaande toewijzing. Geeft het synthetische codepoint terug dat voor GID is toegewezen als AssignSyntheticCodepointForGID(GID, ...) eerder is aangeroepen; anders 0, wat geen geldig PUA-codepoint is en dus als sentinel voor "geen toewijzing" dient. Wijst niets toe. Veilig aan te roepen voordat AssignSyntheticCodepointForGID ooit is uitgevoerd

 

Levenscyclus van de allocatorstatus

FUnicodeSyntheticCpForGID en de cursor voor het eerstvolgende beschikbare PUA-codepoint (FUnicodeNextSyntheticCp) worden lazy aangemaakt bij de eerste AssignSyntheticCodepointForGID-aanroep. De cursor begint op 0 (niet geïnitialiseerd) en springt bij de eerste toewijzing naar $E000; latere toewijzingen verplaatsen hem via $E001, $E002, ..., $F8FF. Beide velden worden bij elke RegisterUnicodeTTF('', nil) samen met de rest van de subsetstatus per font gereset naar leeg / 0, zodat aanroepers die één THotPDF-instantie over meerdere documenten hergebruiken, elk document met een verse PUA-cursor starten

 

Typische 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;

 

Voorbeeld van idempotentie

 

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)

 

Gedrag van de consumer-reader

De consumer-reader ziet het PUA-codepoint in de tekstweergave-operator en lost het via de in het document ingebedde /CIDToGIDMap op naar de doel-GID, waarna die GID met het ingebedde fontprogramma wordt gerenderd. Vanuit het perspectief van de reader is er geen verschil tussen een "natuurlijk" Unicode-codepoint waar de cmap naar GID routeert en een PUA-synthetisch codepoint waar /CIDToGIDMap naar GID routeert - beide leveren hetzelfde gerenderde glyf op

 

Kopiëer- en plakgedrag: PUA-codepoints doorlopen kopiëren en plakken als zichzelf wanneer de ToUnicode CMap ze als identiteitsmappings declareert. Aanroepers die willen dat de bron-Unicodekarakters (de invoerreeks die de substitutie produceerde) in plaats daarvan mee teruggaan, kunnen een omgekeerde mapping registreren met RegisterToUnicodeReverseMapping of ActualText-eigenschappen voor gemarkeerde inhoud opstellen via BeginTaggedContent en de synthetische codepoints binnen de tussen haakjes geplaatste inhoud uitgeven. HotPDF gebruikt automatisch hetzelfde interne-CID-patroon voor op RegisterUnicodeTTF gebaseerde AcroForm-appearance streams die Unicode-tekens uit het supplementaire vlak bevatten

 

Afsluiting van de Phase 8-roadmap

v2.119.68 / Phase 8c.6 sluit de roadmap van de Phase 8-GSUB-engine af: elke LookupType 1-8-query-API (Phase 1-6), de Script / LangSys-selectie-API (Phase 7), het afsluitpunt voor de TTF-subsetter (Phase 9), de statische post-pass ligature folding (v2.119.32 / 58 / 60 / 62), de opt-in automatische pijplijn (v2.119.59), automatische emissie van Arabische rlig + Latijnse liga / clig + rclt (Phase 8b / 8c.2 / 8b / GSUB 'rclt'), ToUnicode reverse-mapping (v2.119.61 / 62 / 65), advance query (v2.119.64), Devanagari Indic reorder pre-pass (v2.119.67) en nu de emissie van PUA-synthetische codepoints op GID-niveau (v2.119.68) samen in één producer-side vormgevingsvlak dat elk type vervangingsglyf van een OpenType-lettertype kan verwerken

 

Zie ook: OpenType GSUB-vervangingsengine, Automatische vormingspijplijn (fase 8), Ondersteuning voor Arabische / Perzische / Urdu-vorming, Syrische / Mongoolse / Devanagari-vorming, THotPDF.BeginTaggedContent