THotPDF.SetFormUnicodeFontDict Method

 

THotPDF.SetFormUnicodeFontDict

THotPDF

 

بالا

یک فونت Unicode که فراخوان می‌دهد را در واژه‌نامه منابع پیش‌فرض AcroForm ثبت می‌کند تا مولد auto-appearance-stream در HotPDF (PDF 1.7 ISO 32000-1 12.7.4.3) بتواند مقدارهای اولیه non-ASCII برای widgetهای Tx را مستقیم در /AP رندر کند، نه اینکه placeholder خالی AP مربوط به v2.46.0 را emit کند. برای ساختن واژه‌نامه فونت غیرمستقیم و پر کردن آن، این روش را با CreateIndirectFontDict همراه کنید

 

Delphi syntax:

procedure SetFormUnicodeFontDict(const LogicalName: AnsiString; FontDict: THPDFDictionaryObject);

 

C++ syntax:

void SetFormUnicodeFontDict(const AnsiString& LogicalName, THPDFDictionaryObject* FontDict);

 

توضیح

وقتی LogicalName و FontDict هر دو پر شده باشند، سه چیز در emission بعدی تغییر می‌کند: (a) رشته /DA در سطح AcroForm از '/Helv 12 Tf 0 0 0 rg' به '/<LogicalName> 12 Tf 0 0 0 rg' می‌رود؛ (b) زیرواژه‌نامه /DR /Font در AcroForm یک ورودی /<LogicalName> <FontDict-indirect-ref> کنار /Helv و /ZaDb می‌گیرد؛ (c) هر widget از نوع Tx که از طریق AddTextField یا AddRichTextField اضافه می‌شود، /DA مخصوص خودش را به همان شکل می‌گیرد. وقتی AutoFormAppearances روشن باشد و مقدار اولیه widget شامل هر بایتی بزرگ‌تر یا مساوی 0x80 باشد، GenerateTextFieldAP یک /AP /N Form XObject واقعی emit می‌کند که content stream آن فونت ثبت‌شده را با Tf انتخاب می‌کند و متن را به‌صورت operator Tj رشته hex از نوع CID رندر می‌کند؛ زیرواژه‌نامه /Resources/Font همان فونت غیرمستقیم را ارجاع می‌دهد تا AP مستقل باشد

وقتی فونت ثبت‌شده از RegisterUnicodeTTF آمده باشد، نویسه‌های Unicode در planeهای supplementary (برای نمونه U+1F600) از طریق یک CID واحد که درونی تخصیص یافته emit می‌شوند، نه اینکه surrogate pair UTF-16 به دو CID از نوع Identity-H شکسته شود. HotPDF در زمان finalization، streamهای تولیدشده /CIDToGIDMap، /W و /ToUnicode را تازه می‌کند تا CID داخلی به glyph واقعی فونت نگاشت شود و استخراج متن به surrogate pair اصلی UTF-16BE برگردد

فیلدهای ASCII Tx همچنان از /Helv استفاده می‌کنند و خروجی /AP را به‌صورت byte-identical برای فراخوان‌های v2.46.0 emit می‌کنند. برای پاک کردن ثبت و برگشت به رفتار فقط /Helv، LogicalName خالی همراه با nil FontDict بدهید. گردش‌کار معمول این است که SetFormUnicodeFontDict را یک‌بار بلافاصله بعد از BeginDoc و پیش از هر AddTextField صدا بزنید؛ widgetهایی که قبلاً ساخته شده‌اند retroactive به‌روز نمی‌شوند

 

LogicalName - نام PDF که به‌عنوان کلید در /DR/Font و به‌عنوان operand برای Tf داخل رشته /DA استفاده می‌شود. نمونه معمول: 'F0'. هنگام ثبت نباید خالی باشد؛ نام خالی همراه با FontDict غیرخالی خطا می‌دهد

FontDict - یک THPDFDictionaryObject غیرمستقیم که یک منبع فونت معتبر PDF را نگه می‌دارد. ساخت درست واژه‌نامه فونت بر عهده فراخوان است، معمولاً یک composite font از نوع Type 0 / CIDFontType2 + Identity-H + ToUnicode CMap؛ برای نمایش ساده یا فقط stroked، زیرمجموعه Type 1 / TrueType هم جواب می‌دهد. HotPDF محتوا را validate نمی‌کند؛ فقط reference را serialize می‌کند

 

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