THotPDF.AssignSyntheticCodepointForGID / GetSyntheticCodepointForGID

THotPDF PUA synthetic codepoint allocator (v2.119.68)

 

GSUB Engine  Auto Shaping Pipeline  Arabic Shaping

Виділяє та запитує синтетичні кодові точки Private Use Area (U+E000 - U+F8FF) для гліфів GID заміни OpenType GSUB, які не мають природної кодової точки Unicode, досяжної через cmap шрифту; закриває пропуск виведення на рівні GID з боку генератора, залишений API запитів та уточнення GSUB версії v2.119.43-66

 

Синтаксис Delphi:

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

function GetSyntheticCodepointForGID(GID: Word): Word;

 

Чому існує цей API

Producer-side automatic shaping pipeline v2.119.32-67 (Arabic / Latin / Devanagari) потребує, щоб substitute GIDs, returned by GSUB engine, були reachable through Unicode codepoint - existing hex-encoded text pipeline emits codepoints, not GIDs, а consumer reader resolves codepoint back to GID через embedded /CIDToGIDMap Для substitute GIDs, що мають natural Unicode codepoint через cmap font (Arabic Presentation Forms, Latin Standard Ligatures FB00-FB06), existing pipeline works fine

 

Але специфічні для шрифту заміни, які потрапляють на внутрішні GID шрифту — більшість форм кластерів деванагарі, стилістичні варіанти, які дизайнер шрифту постачає лише як пронумеровані GID, послідовності ідеографічних варіацій CJK (IVS), дискреційні лігатури без відповідної форми представлення — взагалі не мають кодової точки в cmap шрифту; до версії v2.119.68 ці GID були недосяжними через шістнадцятковий конвеєр з боку генератора, версія v2.119.68 закриває цей пропуск, дозволяючи викликачам виділяти синтетичну кодову точку в Private Use Area для будь-ного GID

 

Семантика AssignSyntheticCodepointForGID

Виділяє наступну доступну кодову точку PUA (починаючи з U+E000) для наданого GID і дзеркально відображає призначення в кожен кеш, від якого залежить існуючий шістнадцятковий конвеєр з боку генератора та ланцюжок розв'язання переглядача споживача:

 

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

 

Повертає True on success з SyntheticCP set to allocated codepoint Повертає False (і leaves SyntheticCP at 0) за будь-якої defensive condition: no font registered (RegisterUnicodeTTF never called або called with empty arguments to reset state), invalid GID (zero або beyond cmap glyph count), exhausted PUA range (all 6400 slots U+E000 - U+F8FF allocated), cache uninitialised on entry

 

Семантика GetSyntheticCodepointForGID

Pure-functional query будь-якого existing assignment Повертає synthetic codepoint, allocated for GID, якщо AssignSyntheticCodepointForGID(GID, ...) викликали раніше; інакше returns 0 (not valid PUA codepoint, тому also sentinel «no assignment») Не allocate Безпечно call before any AssignSyntheticCodepointForGID has run

 

Життєвий цикл стану алокатора

FUnicodeSyntheticCpForGID і cursor FUnicodeNextSyntheticCp створюються lazy під час першого AssignSyntheticCodepointForGID Cursor starts at 0 і під час першого allocation переходить до $E000; наступні allocations рухаються через $E001, $E002, ..., $F8FF Обидва fields reset to empty / 0 on every RegisterUnicodeTTF('', nil) разом із рештою per-font subset state, тому reused THotPDF instance починає кожен document з fresh PUA cursor

 

Типовий робочий процес (форма кластера деванагарі)

 

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

PDF.ShapingFeatures := [sfIndicShaping];

PDF.SetGSUBScript('deva');

 

// Отримання внутрішнього GID кластера шрифту через рушій GSUB

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;

 

Приклад ідемпотентності

 

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 бачить PUA codepoint у text-showing operator і resolves it through document-embedded /CIDToGIDMap to target GID, потім renders that GID using embedded font program З perspective reader немає difference між «natural» Unicode codepoint, який cmap routes to GID, і PUA synthetic codepoint, який /CIDToGIDMap routes to GID - both produce same rendered glyph

 

Поведінка copy / paste: PUA codepoints round-trip as themselves, коли ToUnicode CMap declares identity mappings Якщо callers хочуть round-trip source Unicode characters, що produced substitute, вони можуть register reverse mapping через RegisterToUnicodeReverseMapping або author ActualText marked-content properties through BeginTaggedContent і emit synthetic codepoints inside bracketed content HotPDF автоматично uses same internal-CID pattern для RegisterUnicodeTTF-backed AcroForm appearance streams з supplementary-plane Unicode characters

 

Закриття дорожньої карти фази 8

v2.119.68 / Phase 8c.6 завершує roadmap Phase 8 GSUB engine: query API LookupType 1-8, Script / LangSys selection API, TTF subsetter closure entry point, static post-pass ligature folding, opt-in automatic pipeline, автоматичне виведення Arabic rlig і Latin liga / clig / rclt, ToUnicode reverse-mapping, advance query, Devanagari Indic reorder pre-pass і PUA synthetic codepoint GID-level emit тепер інтегровано в єдину producer-side shaping surface для кожного substitute glyph, який може створити OpenType font

 

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