|
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 ฝั่งผู้ผลิตที่เหลือจาก GSUB query และ refinement API ของ v2.119.43-66
Delphi syntax: function AssignSyntheticCodepointForGID(GID: Word; out SyntheticCP: Word): Boolean; function GetSyntheticCodepointForGID(GID: Word): Word;
Why the API exists pipeline automatic shaping ฝั่ง producer ใน v2.119.32-67 (Arabic / Latin / Devanagari) ต้องให้ substitute GIDs ที่ GSUB engine คืนมาเข้าถึงได้ผ่าน Unicode codepoint - pipeline ข้อความ hex-encoded เดิม emit codepoints ไม่ใช่ GIDs และ consumer reader resolve codepoint กลับเป็น GID ผ่าน
แต่ substitutes เฉพาะ font ที่ไปอยู่บน GIDs ภายใน font - เช่น Devanagari cluster shapes ส่วนใหญ่, stylistic alternates ที่ผู้ออกแบบ font ส่งมาเฉพาะเป็น GIDs แบบมีเลข, CJK ideographic variation sequences (IVS), discretionary ligatures ที่ไม่มี Presentation Form ตรงกัน - ไม่มี codepoint ใน cmap ของ font เลย ก่อน v2.119.68 GIDs เหล่านี้เข้าถึงผ่าน producer-side hex pipeline ไม่ได้; v2.119.68 ปิดช่องว่างนี้ด้วยการให้ callers จัดสรร synthetic codepoint ใน Private Use Area สำหรับ GID ใดก็ได้
AssignSyntheticCodepointForGID semantics จัดสรร PUA codepoint ถัดไปที่ว่าง (เริ่มที่ U+E000) สำหรับ GID ที่ส่งเข้ามา และ mirror assignment ลงใน cache ทุกตัวที่ producer-side hex pipeline เดิม + consumer-reader resolution chain ต้องพึ่งพา:
1. 2. 3.
คืน True เมื่อสำเร็จพร้อมตั้ง SyntheticCP เป็น codepoint ที่จัดสรร คืน False (และปล่อย SyntheticCP เป็น 0) ในเงื่อนไขป้องกันใด ๆ ต่อไปนี้: ยังไม่มี font registered (ไม่เคยเรียก RegisterUnicodeTTF หรือเรียกด้วย arguments ว่างเพื่อ reset state), GID ไม่ถูกต้อง (เป็นศูนย์หรือเกิน glyph count ของ cmap), ช่วง PUA หมด (จัดสรรครบทุก 6400 slots U+E000 - U+F8FF), cache ยังไม่ initialised ตอนเข้า method
GetSyntheticCodepointForGID semantics query แบบ pure-functional ของ assignment ที่มีอยู่ คืน synthetic codepoint ที่จัดสรรให้
Allocator state lifecycle FUnicodeSyntheticCpForGID และ cursor next-available-PUA (FUnicodeNextSyntheticCp) ถูก lazy-allocate เมื่อเรียก AssignSyntheticCodepointForGID ครั้งแรก cursor เริ่มที่ 0 (ยังไม่ initialised) และขยับเป็น $E000 ในการจัดสรรครั้งแรก; การจัดสรรถัดไปเดินผ่าน $E001, $E002, ..., $F8FF ทั้งสอง fields ถูก reset เป็น empty / 0 ในทุกครั้งที่ RegisterUnicodeTTF('', nil) ถูกเรียกพร้อมกับ state subset ราย font ที่เหลือ ดังนั้น callers ที่ reuse instance THotPDF ข้ามหลายเอกสารจะเริ่มแต่ละเอกสารด้วย allocator ใหม่
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 // จัดสรร synthetic codepoint ที่ฝั่ง producer // 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 consumer reader เห็น PUA codepoint ใน text-showing operator และ resolve ผ่าน
พฤติกรรม copy / paste: PUA codepoints round-trip เป็นตัวมันเองผ่าน copy / paste เมื่อ ToUnicode CMap ประกาศเป็น identity mappings callers ที่ต้องการให้ source Unicode characters (input run ที่สร้าง substitute) round-trip แทน สามารถ register reverse mapping ด้วย
Phase 8 roadmap closure v2.119.68 / Phase 8c.6 ปิด roadmap ของ Phase 8 GSUB engine: query API LookupType 1-8 ทั้งหมด (Phase 1-6), Script / LangSys selection API (Phase 7), entry point ของ TTF subsetter closure (Phase 9), static post-pass ligature folding (v2.119.32 / 58 / 60 / 62), opt-in automatic pipeline (v2.119.59), การ emit อัตโนมัติ Arabic
See also: OpenType GSUB Substitution Engine, Automatic Shaping Pipeline (Phase 8), Arabic / Persian / Urdu Shaping Support, Syriac / Mongolian / Devanagari Shaping, THotPDF.BeginTaggedContent |