THotPDF.AssignSyntheticCodepointForGID – metoda

Alokátor syntetických kódových bodů PUA pro THotPDF (v2.119.68)

 

GSUB Engine  Auto Shaping Pipeline  Arabic Shaping

Alokuje a dotazuje syntetické kódové body z Private Use Area (U+E000 - U+F8FF) pro náhradní GID OpenType GSUB, které nemají přirozený kódový bod Unicode dosažitelný přes cmap písma. Uzavírá mezeru ve výstupu na úrovni GID na straně producenta, kterou ponechala dotazovací a zpřesňující API GSUB z verzí v2.119.43-66

 

Syntaxe Delphi:

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

function GetSyntheticCodepointForGID(GID: Word): Word;

 

Proč API existuje

Automatický pipeline tvarování na straně producenta z verzí v2.119.32-67 (arabské / latinské / dévanágarí) vyžaduje, aby náhradní GID vrácené enginem GSUB bylo dosažitelné přes kódový bod Unicode - existující pipeline hexadecimálně kódovaného textu vypisuje kódové body, nikoli GID, a spotřebitelský reader převede kódový bod zpět na GID přes vloženou /CIDToGIDMap. Pro náhradní GID, která mají přirozený kódový bod Unicode přes cmap písma (Arabic Presentation Forms, Latin Standard Ligatures FB00-FB06), existující pipeline funguje správně

 

Náhrady specifické pro písmo, které končí na interních GID písma - většina tvarů klastrů dévanágarí, stylistické alternativy dodané autorem písma pouze jako číslované GID, ideografické variační sekvence CJK (IVS) nebo volitelné ligatury bez odpovídající Presentation Form - však v cmap písma nemají žádný kódový bod. Před v2.119.68 byla tato GID přes hexadecimální pipeline na straně producenta nedosažitelná; v2.119.68 tuto mezeru uzavírá tím, že volajícím dovoluje alokovat syntetický kódový bod v Private Use Area pro libovolné GID

 

Sémantika AssignSyntheticCodepointForGID

Alokuje další dostupný kódový bod PUA (počínaje U+E000) pro dodané GID a promítne přiřazení do každé cache, na které závisí existující hexadecimální pipeline na straně producenta i řetězec řešení ve spotřebitelském readeru:

 

1. FUnicodeCpToGid[SyntheticCP] := GID - aby hexadecimální pipeline na straně producenta vypsala SyntheticCP do operátoru zobrazení textu a spotřebitelský reader při vykreslení vyřešil SyntheticCP zpět na GID přes /CIDToGIDMap

2. FAcroFormUnicodeAdvances[SyntheticCP] := em-fraction - aby kalkulátor zalamování slov z v2.65 našel správný hmtx advance pro syntetický kódový bod, když se objeví v obsahu textového pole AcroForm

3. FUnicodeSyntheticCpForGID[GID] := SyntheticCP - reverzní tabulka podle GID používaná metodou GetSyntheticCodepointForGID, díky níž jsou opakovaná volání AssignSyntheticCodepointForGID idempotentní (druhé volání se stejným GID vrátí již alokované SyntheticCP)

 

Při úspěchu vrací True a nastaví SyntheticCP na alokovaný kódový bod. Vrací False (a ponechá SyntheticCP na 0) při kterékoli z těchto obranných podmínek: není registrováno žádné písmo (RegisterUnicodeTTF nebylo nikdy voláno nebo bylo voláno s prázdnými argumenty pro reset stavu), neplatné GID (nula nebo za počtem glyfů v cmap), vyčerpaný rozsah PUA (alokováno všech 6400 slotů U+E000 - U+F8FF), cache není při vstupu inicializovaná

 

Sémantika GetSyntheticCodepointForGID

Čistě funkční dotaz na existující přiřazení. Vrátí syntetický kódový bod alokovaný pro GID, pokud bylo dříve zavoláno AssignSyntheticCodepointForGID(GID, ...); jinak vrátí 0 (což není platný kódový bod PUA, takže zároveň slouží jako sentinel „bez přiřazení“). Nealokuje. Je bezpečné ji volat ještě před spuštěním jakéhokoli AssignSyntheticCodepointForGID

 

Životní cyklus stavu alokátoru

FUnicodeSyntheticCpForGID a kurzor dalšího dostupného PUA (FUnicodeNextSyntheticCp) se líně alokují při prvním volání AssignSyntheticCodepointForGID. Kurzor začíná na 0 (neinicializováno) a při první alokaci se posune na $E000; další alokace jej posouvají přes $E001, $E002, ..., $F8FF. Obě pole se resetují na prázdné / 0 při každém RegisterUnicodeTTF('', nil) spolu se zbytkem stavu podmnožiny pro dané písmo, takže volající, kteří znovu používají instanci THotPDF napříč více dokumenty, začínají každý dokument s čerstvým kurzorem PUA

 

Typické workflow (tvar klastru dévanágarí)

 

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

PDF.ShapingFeatures := [sfIndicShaping];

PDF.SetGSUBScript('deva');

 

// Získání interního GID klastru písma přes engine GSUB

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

if ClusterGID <> BaseGID then

begin

  // Zkontrolujte, zda cmap dosáhne na náhradu - u indických

  // klastrů obvykle ne, protože GID klastrů jsou interní pro písmo

  // Alokujte syntetický kódový bod, který může hexadecimální

  // pipeline na straně producenta vypsat

  if PDF.AssignSyntheticCodepointForGID(ClusterGID, SyntheticCP) then

  begin

    // SyntheticCP je teď v rozsahu U+E000-F8FF; vypište jej

    // přes UnicodeTextOut stejně jako běžný kódový bod

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

    PDF.MarkUnicodeGlyphUsed(ClusterGID);

  end;

end;

 

Příklad idempotence

 

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

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

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

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

CP5 := PDF.GetSyntheticCodepointForGID(999);  // CP5 = 0 (bez přiřazení)

 

Chování spotřebitelského readeru

Spotřebitelský reader uvidí kódový bod PUA v operátoru zobrazení textu a přes dokumentem vloženou /CIDToGIDMap jej vyřeší na cílové GID, potom toto GID vykreslí pomocí vloženého programu písma. Z pohledu readeru není rozdíl mezi „přirozeným“ kódovým bodem Unicode, který cmap směruje na GID, a syntetickým kódovým bodem PUA, který /CIDToGIDMap směruje na GID - oba vytvoří stejný vykreslený glyf

 

Chování při kopírování / vložení: kódové body PUA při copy / paste projdou jako samy sebe, když je ToUnicode CMap deklaruje jako identitní mapování. Volající, kteří chtějí místo toho zachovat zdrojové znaky Unicode (vstupní běh, který vytvořil náhradu), mohou zaregistrovat reverzní mapování pomocí RegisterToUnicodeReverseMapping nebo vytvořit vlastnosti sekvence marked content ActualText přes BeginTaggedContent a vypsat syntetické kódové body uvnitř závorkovaného obsahu. HotPDF používá stejný vzor interních CID automaticky pro appearance streamy AcroForm založené na RegisterUnicodeTTF, které obsahují znaky Unicode z doplňkové roviny

 

Uzavření roadmapy Phase 8

v2.119.68 / Phase 8c.6 uzavírá roadmapu enginu GSUB v Phase 8: každé dotazovací API LookupType 1-8 (Phase 1-6), API výběru Script / LangSys (Phase 7), vstupní bod uzávěru subsetteru TTF (Phase 9), statické skládání ligatur po průchodu (v2.119.32 / 58 / 60 / 62), volitelný automatický pipeline (v2.119.59), automatický výstup arabského rlig + latinských liga / clig + rclt (Phase 8b / 8c.2 / 8b / GSUB 'rclt'), reverzní mapování ToUnicode (v2.119.61 / 62 / 65), dotaz na advance (v2.119.64), předprůchod přeřazení dévanágarí Indic (v2.119.67) a nyní i výstup syntetických kódových bodů PUA na úrovni GID (v2.119.68) jsou integrovány do jednoho tvarovacího rozhraní na straně producenta, které zvládá každý druh náhradního glyfu, jaký může písmo OpenType vytvořit

 

Viz také: Substituční engine OpenType GSUB, Automatický tvarovací pipeline (Phase 8), Podpora tvarování arabštiny / perštiny / urdštiny, Tvarování syrštiny / mongolštiny / dévanágarí, THotPDF.BeginTaggedContent