THotPDF.AssignSyntheticCodepointForGID / GetSyntheticCodepointForGID

THotPDF allokerare för syntetiska PUA-kodpunkter (v2.119.68)

 

GSUB Engine  Auto Shaping Pipeline  Arabic Shaping

Allokerar och frågar syntetiska kodpunkter i Private Use Area (U+E000 - U+F8FF) för OpenType GSUB-ersättnings-GID:er som saknar en naturlig Unicode-kodpunkt som kan nås via fontens cmap. Stänger emissionsluckan på GID-nivå på producentsidan som lämnades av GSUB-fråge- och förfinings-API:erna i v2.119.43-66

 

Delphi syntax:

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

function GetSyntheticCodepointForGID(GID: Word): Word;

 

Varför API:t finns

Den automatiska shaping-pipelinen på producentsidan i v2.119.32-67 (Arabic / Latin / Devanagari) kräver att ersättnings-GID:er som returneras av GSUB-motorn kan nås via en Unicode-kodpunkt - den befintliga hexkodade textpipelinen emitterar kodpunkter, inte GID:er, och konsumentläsaren löser tillbaka kodpunkten till ett GID via den inbäddade /CIDToGIDMap. För ersättnings-GID:er som har en naturlig Unicode-kodpunkt via fontens cmap (Arabic Presentation Forms, Latin Standard Ligatures FB00-FB06) fungerar den befintliga pipelinen

 

Men fontspecifika ersättningar som landar på fontinterna GID:er - de flesta Devanagari-klusterformer, stilistiska alternativ som fontdesignern bara levererar som numrerade GID:er, CJK-ideografiska variationssekvenser (IVS), diskretionära ligaturer utan motsvarande Presentation Form - har ingen kodpunkt alls i fontens cmap. Före v2.119.68 var dessa GID:er onåbara via hexpipelinen på producentsidan; v2.119.68 stänger luckan genom att låta anropare allokera en syntetisk kodpunkt i Private Use Area för valfritt GID

 

Semantik för AssignSyntheticCodepointForGID

Allokerar nästa tillgängliga PUA-kodpunkt (med start vid U+E000) för angivet GID och speglar tilldelningen till varje cache som den befintliga hexpipelinen på producentsidan + konsumentläsarens upplösningskedja beror på:

 

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)

 

Returnerar True vid lyckat resultat med SyntheticCP satt till den allokerade kodpunkten. Returnerar False (och lämnar SyntheticCP som 0) under något av dessa defensiva villkor: ingen font registrerad (RegisterUnicodeTTF har aldrig anropats eller anropats med tomma argument för att återställa tillstånd), ogiltigt GID (noll eller utanför cmapens glyph-antal), PUA-intervallet uttömt (alla 6400 platser U+E000 - U+F8FF allokerade), cache oinitierad vid ingång

 

Semantik för GetSyntheticCodepointForGID

Ren funktionsfråga mot en befintlig tilldelning. Returnerar den syntetiska kodpunkt som allokerats för GID om AssignSyntheticCodepointForGID(GID, ...) har anropats tidigare; annars returneras 0 (vilket inte är en giltig PUA-kodpunkt och därför också fungerar som sentinel för ”ingen tilldelning”). Allokerar inte. Säker att anropa innan något AssignSyntheticCodepointForGID har körts

 

Livscykel för allokerartillstånd

FUnicodeSyntheticCpForGID och markören för nästa tillgängliga PUA (FUnicodeNextSyntheticCp) allokeras lazy vid det första AssignSyntheticCodepointForGID-anropet. Markören börjar på 0 (oinitierad) och flyttas till $E000 vid första allokeringen; efterföljande allokeringar flyttar den genom $E001, $E002, ..., $F8FF. Båda fälten återställs till tomt / 0 vid varje RegisterUnicodeTTF('', nil) tillsammans med resten av subset-tillståndet per font, så anropare som återanvänder en THotPDF-instans över flera dokument börjar varje dokument med en färsk PUA-markör

 

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)

 

Konsumentläsarens beteende

Konsumentläsaren ser PUA-kodpunkten i textvisningsoperatorn och löser den via dokumentets inbäddade /CIDToGIDMap till mål-GID, och renderar sedan detta GID med det inbäddade fontprogrammet. Ur läsarens perspektiv finns ingen skillnad mellan en ”naturlig” Unicode-kodpunkt som cmap dirigerar till GID och en syntetisk PUA-kodpunkt som /CIDToGIDMap dirigerar till GID - båda ger samma renderade glyph

 

Kopiera / klistra in-beteende: PUA-kodpunkter går runt som sig själva genom kopiera / klistra in när ToUnicode CMap deklarerar dem som identitetsmappningar. Anropare som i stället vill att källans Unicode-tecken ska gå runt kan registrera en omvänd mappning med RegisterToUnicodeReverseMapping eller skapa egenskaper för markerat innehåll med ActualText via BeginTaggedContent och emittera de syntetiska kodpunkterna inuti det hakparentesomslutna innehållet. HotPDF använder automatiskt samma internal-CID-mönster för AcroForm-appearance streams som stöds av RegisterUnicodeTTF och innehåller Unicode-tecken från tilläggsplan

 

Avslutning av Phase 8-färdplanen

v2.119.68 / Phase 8c.6 stänger färdplanen för Phase 8 GSUB-motorn: varje LookupType 1-8-fråge-API (Phase 1-6), API:t för Script / LangSys-val (Phase 7), TTF-subsetterns closure-ingångspunkt (Phase 9), statisk post-pass-ligaturvikning (v2.119.32 / 58 / 60 / 62), den opt-in automatiska pipelinen (v2.119.59), automatisk emission av Arabic rlig + Latin liga / clig + rclt (Phase 8b / 8c.2 / 8b / GSUB 'rclt'), omvänd ToUnicode-mappning (v2.119.61 / 62 / 65), advance-fråga (v2.119.64), Devanagari Indic reorder pre-pass (v2.119.67), och nu PUA syntetisk kodpunktsemission på GID-nivå (v2.119.68) integreras alla i en enda shaping-yta på producentsidan som hanterar varje typ av ersättningsglyph som en OpenType-font kan producera

 

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