THotPDF.AssignSyntheticCodepointForGID / GetSyntheticCodepointForGID

THotPDF PUA sentetik codepoint ayırıcısı (v2.119.68)

 

GSUB Engine  Auto Shaping Pipeline  Arabic Shaping

Fontun cmap üzerinden erişilebilen doğal Unicode codepointi olmayan OpenType GSUB substitute GIDleri için Private Use Area (U+E000 - U+F8FF) sentetik codepointlerini ayırır ve sorgular. v2.119.43-66 GSUB sorgu ve refinement APIlerinin bıraktığı producer taraflı GID düzeyi emission boşluğunu kapatır

 

Delphi sözdizimi:

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

function GetSyntheticCodepointForGID(GID: Word): Word;

 

API neden var

v2.119.32-67 producer taraflı otomatik shaping pipelineı (Arabic / Latin / Devanagari), GSUB engine tarafından döndürülen substitute GIDlerin bir Unicode codepoint üzerinden erişilebilir olmasını gerektirir - mevcut hex-encoded text pipelineı codepointleri yayar, GIDleri değil, consumer reader da gömülü /CIDToGIDMap üzerinden codepointi tekrar GIDye çözer. Fontun cmap üzerinden doğal Unicode codepointi olan substitute GIDler için (Arabic Presentation Forms, Latin Standard Ligatures FB00-FB06) mevcut pipeline sorunsuz çalışır

 

Ancak font içi GIDlere düşen fonta özgü substitutelar - çoğu Devanagari cluster şekli, font tasarımcısının yalnızca numaralı GID olarak sunduğu stylistic alternate öğeleri, CJK ideographic variation sequence (IVS) öğeleri, karşılık gelen Presentation Form olmayan discretionary ligature öğeleri - fontun cmap içinde hiç codepoint taşımaz. v2.119.68 öncesinde bu GIDlere producer taraflı hex pipeline üzerinden ulaşılamıyordu; v2.119.68, çağıranların herhangi bir GID için Private Use Area içinde sentetik codepoint ayırmasına izin vererek bu boşluğu kapatır

 

AssignSyntheticCodepointForGID semantiği

Sağlanan GID için (U+E000 başlangıçlı) sonraki kullanılabilir PUA codepointini ayırır ve atamayı mevcut producer taraflı hex pipeline + consumer-reader çözümleme zincirinin bağlı olduğu her cache içine yansıtır:

 

1. FUnicodeCpToGid[SyntheticCP] := GID - böylece üretici tarafı hex hattı metin gösterme operatörüne SyntheticCP yazar ve okuyucu, işleme zamanında /CIDToGIDMap üzerinden SyntheticCP'yi GID'ye geri çözer

2. FAcroFormUnicodeAdvances[SyntheticCP] := em-fraction - böylece v2.65 kelime sarma hesaplayıcısı, sentetik kod noktası AcroForm metin alanı içeriğinde göründüğünde doğru hmtx genişliğini bulur

3. FUnicodeSyntheticCpForGID[GID] := SyntheticCP - GetSyntheticCodepointForGID'in yinelenen AssignSyntheticCodepointForGID çağrılarını idempotent kılmak için kullandığı GID başına ters arama tablosu (aynı GID ile ikinci çağrı, halihazırda ayrılmış SyntheticCP'yi döndürür)

 

Başarılı olduğunda SyntheticCP ayrılan codepoint değerine ayarlanmış olarak True döndürür. Şu savunmacı koşullardan herhangi birinde False döndürür (ve SyntheticCP değerini 0 bırakır): kayıtlı font yok (RegisterUnicodeTTF hiç çağrılmadı veya durumu sıfırlamak için boş argümanlarla çağrıldı), geçersiz GID (sıfır veya cmap glyph sayısının ötesinde), PUA aralığı tükendi (U+E000 - U+F8FF aralığındaki 6400 slotun tamamı ayrıldı), girişte cache başlatılmamış

 

GetSyntheticCodepointForGID semantiği

Mevcut herhangi bir atama için saf işlevsel sorgu. Daha önce AssignSyntheticCodepointForGID(GID, ...) çağrılmışsa GID için ayrılan sentetik codepointi döndürür; aksi halde 0 döndürür (geçerli bir PUA codepointi olmadığı için “atama yok” sentinel değeri olarak da kullanılır). Ayırma yapmaz. Herhangi bir AssignSyntheticCodepointForGID çalışmadan önce çağrılması güvenlidir

 

Ayırıcı durum yaşam döngüsü

FUnicodeSyntheticCpForGID ve sonraki kullanılabilir PUA cursorı (FUnicodeNextSyntheticCp) ilk AssignSyntheticCodepointForGID çağrısında lazy olarak ayrılır. Cursor 0 (başlatılmamış) değerinden başlar ve ilk ayırmada $E000 değerine çıkar; sonraki ayırmalar onu $E001, $E002, ..., $F8FF boyunca ilerletir. Her iki alan da her RegisterUnicodeTTF('', nil) çağrısında font başına subset durumunun geri kalanıyla birlikte boş / 0 olarak sıfırlanır, bu yüzden bir THotPDF instanceını birden çok belge arasında yeniden kullanan çağıranlar her belgeye taze bir PUA cursorı ile başlar

 

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)

 

Consumer-reader davranışı

Consumer reader, text-showing operator içindeki PUA codepointini görür ve bunu belgeye gömülü /CIDToGIDMap üzerinden hedef GIDye çözer, ardından gömülü font programını kullanarak bu GIDyi render eder. Reader açısından cmap tarafından GID değerine yönlendirilen “doğal” Unicode codepoint ile /CIDToGIDMap tarafından GID değerine yönlendirilen PUA sentetik codepoint arasında fark yoktur - ikisi de aynı render edilmiş glyphi üretir

 

Kopyala / yapıştır davranışı: ToUnicode CMap bunları identity mapping olarak bildirdiğinde PUA codepointleri kopyala / yapıştır üzerinden kendileri olarak round-trip yapar. Bunun yerine kaynak Unicode karakterlerinin round-trip yapmasını isteyen çağıranlar RegisterToUnicodeReverseMapping ile ters mapping kaydedebilir veya BeginTaggedContent üzerinden ActualText marked-content sequence özellikleri yazıp sentetik codepointleri köşeli içerik içinde yayabilir. HotPDF, supplementary-plane Unicode karakterleri içeren RegisterUnicodeTTF destekli AcroForm appearance streamleri için aynı internal-CID desenini otomatik kullanır

 

Phase 8 yol haritası kapanışı

v2.119.68 / Phase 8c.6, Phase 8 GSUB engine yol haritasını kapatır: her LookupType 1-8 sorgu APIsi (Phase 1-6), Script / LangSys seçim APIsi (Phase 7), TTF subsetter kapanış giriş noktası (Phase 9), statik post-pass ligature folding (v2.119.32 / 58 / 60 / 62), opt-in automatic pipeline (v2.119.59), Arabic rlig + Latin liga / clig + rclt automatic emission (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) ve artık PUA sentetik codepoint GID düzeyi emission (v2.119.68), OpenType fontun üretebileceği her substitute glyph türünü işleyen tek bir producer taraflı shaping yüzeyinde bütünleşir

 

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