|
רושם פונט Unicode שסיפק הקורא במילון default-resources של AcroForm כך שמחולל auto-appearance-stream של HotPDF (PDF 1.7 ISO 32000-1 12.7.4.3) יוכל לרנדר ערכי Tx widget התחלתיים שאינם ASCII ישירות לתוך /AP, במקום לפלוט את placeholder ה-empty-AP של v2.46.0. שלב עם CreateIndirectFontDict כדי להקצות את מילון הפונט indirect למילוי
Delphi syntax:
procedure SetFormUnicodeFontDict(const LogicalName: AnsiString; FontDict: THPDFDictionaryObject);
C++ syntax:
void SetFormUnicodeFontDict(const AnsiString& LogicalName, THPDFDictionaryObject* FontDict);
תיאור
Once both LogicalName and FontDict are populated, three things change in subsequent emission: (a) the AcroForm-level /DA string switches from '/Helv 12 Tf 0 0 0 rg' to '/<LogicalName> 12 Tf 0 0 0 rg'; (b) the AcroForm /DR /Font sub-dict gains an entry /<LogicalName> <FontDict-indirect-ref> alongside the existing /Helv + /ZaDb; (c) every Tx widget added through AddTextField or AddRichTextField gets its per-field /DA set the same way. When AutoFormAppearances is on and the widget's initial value contains any byte >= 0x80, GenerateTextFieldAP emits a real /AP /N Form XObject whose content stream selects the registered font via Tf and renders the text as a CID hex-string Tj operator; the Form's /Resources/Font sub-dict references the same indirect font so the AP is self-contained.
כאשר הפונט הרשום מגיע מ-RegisterUnicodeTTF, תווי Unicode ב-supplementary-plane, למשל U+1F600, נפלטים דרך CID פנימי יחיד שהוקצה, במקום לפצל את זוג ה-surrogate של UTF-16 לשני CIDs של Identity-H. HotPDF מרעננת בזמן finalization את זרמי /CIDToGIDMap, /W ו-/ToUnicode שנוצרו, כך שה-CID הפנימי ממפה ל-glyph האמיתי בפונט וחילוץ הטקסט ממפה חזרה לזוג ה-surrogate המקורי ב-UTF-16BE
שדות Tx מסוג ASCII ממשיכים להשתמש ב-/Helv ופולטים /AP זהה ברמת byte לקוראי v2.46.0. העבר LogicalName ריק + nil FontDict כדי לנקות את הרישום ולחזור להתנהגות /Helv בלבד. תהליך טיפוסי: קרא ל-SetFormUnicodeFontDict פעם אחת מיד אחרי BeginDoc, לפני כל AddTextField; widgets שנוצרו קודם אינם מתעדכנים בדיעבד
LogicalName - שם PDF המשמש כמפתח ב-/DR/Font וכ-operand ל-Tf בתוך מחרוזת /DA. טיפוסי: 'F0'. אסור שיהיה ריק בעת רישום; שם ריק עם FontDict שאינו nil מעלה חריגה
FontDict - an indirect THPDFDictionaryObject holding a valid PDF Font resource. The caller is responsible for building the font dict correctly - typically a Type 0 / CIDFontType2 + Identity-H + ToUnicode CMap composite font; for stroked-only or simple display use a Type 1 / TrueType subset works too. HotPDF does not validate the contents; it just serializes the reference.
Scope - v2.56.0 covers single-line Tx widgets only. Multi-line (ffMultiline) and comb (ffComb) Tx widgets with non-ASCII initial values still emit the v2.46.0 empty-AP placeholder; the Unicode-AP extension for those branches is scheduled for v2.57.0+. RTL bidi shaping (Arabic / Hebrew) requires Unicode Bidi Algorithm (UAX #9) + Arabic contextual joining; also v2.57.0+ scope.
Code Example
// Register a Type 0 / CIDFontType2 + Identity-H composite font for
// AcroForm Tx widget AP rendering. (Real production code adds a
// /FontFile2 stream and a ToUnicode CMap so the glyphs actually
// render - omitted here for brevity.)
var
F0, Descendant, FontDescriptor, CIDSysInfo: THPDFDictionaryObject;
Descendants: THPDFArrayObject;
R: TRect;
begin
HPDF.BeginDoc;
HPDF.AutoFormAppearances := True;
F0 := HPDF.CreateIndirectFontDict; // empty indirect dict
F0.AddNameValue('Type', 'Font');
F0.AddNameValue('Subtype', 'Type0');
F0.AddNameValue('BaseFont', 'MyCJK');
F0.AddNameValue('Encoding', 'Identity-H');
CIDSysInfo := THPDFDictionaryObject.Create(nil);
CIDSysInfo.AddStringValue('Registry', 'Adobe');
CIDSysInfo.AddStringValue('Ordering', 'Identity');
CIDSysInfo.AddNumericValue('Supplement', 0);
FontDescriptor := THPDFDictionaryObject.Create(nil);
FontDescriptor.AddNameValue('Type', 'FontDescriptor');
// ... fill required Ascent / Descent / FontBBox / etc
Descendant := THPDFDictionaryObject.Create(nil);
Descendant.AddNameValue('Type', 'Font');
Descendant.AddNameValue('Subtype', 'CIDFontType2');
Descendant.AddNameValue('BaseFont', 'MyCJK');
Descendant.AddValue('CIDSystemInfo', CIDSysInfo);
Descendant.AddValue('FontDescriptor', FontDescriptor);
Descendant.AddNumericValue('DW', 1000);
Descendants := THPDFArrayObject.Create(nil);
Descendants.AddObject(Descendant);
F0.AddValue('DescendantFonts', Descendants);
HPDF.SetFormUnicodeFontDict('F0', F0);
R.Left := 60; R.Top := 60; R.Right := 280; R.Bottom := 100;
HPDF.CurrentPage.AddTextField('Greeting', '你好世界', R);
HPDF.EndDoc;
end;
See Also
CreateIndirectFontDict, AutoFormAppearances, AddTextField, AddRichTextField, Version
|