|
Registra una fuente Unicode suministrada por el llamador en el dict de recursos predeterminados de AcroForm para que el generador automático de appearance streams de HotPDF (PDF 1.7 ISO 32000-1 12.7.4.3) pueda renderizar valores iniciales de widgets Tx no ASCII directamente en /AP, en lugar de emitir el placeholder /AP vacío de v2.46.0. Combínelo con CreateIndirectFontDict para asignar el dict de fuente indirecto que se va a rellenar
Sintaxis Delphi:
procedure SetFormUnicodeFontDict(const LogicalName: AnsiString; FontDict: THPDFDictionaryObject);
Sintaxis C++:
void SetFormUnicodeFontDict(const AnsiString& LogicalName, THPDFDictionaryObject* FontDict);
Descripción
Cuando LogicalName y FontDict están poblados, cambian tres cosas en la emisión posterior: (a) la cadena /DA a nivel AcroForm pasa de '/Helv 12 Tf 0 0 0 rg' a '/<LogicalName> 12 Tf 0 0 0 rg'; (b) el sub-dict /DR /Font de AcroForm recibe una entrada /<LogicalName> <FontDict-indirect-ref> junto a los existentes /Helv + /ZaDb; (c) cada widget Tx agregado mediante AddTextField o AddRichTextField obtiene su /DA por campo configurado de la misma forma. Cuando AutoFormAppearances está activado y el valor inicial del widget contiene cualquier byte >= 0x80, GenerateTextFieldAP emite un Form XObject /AP /N real cuyo content stream selecciona la fuente registrada mediante Tf y renderiza el texto como operador Tj de hex-string CID; el sub-dict /Resources/Font del Form referencia la misma fuente indirecta, por lo que el AP queda autocontenido
Cuando la fuente registrada proviene de RegisterUnicodeTTF, los caracteres Unicode del plano suplementario (por ejemplo U+1F600) se emiten mediante un único CID asignado internamente en lugar de dividir el par sustituto UTF-16 en dos CIDs Identity-H. HotPDF refresca los streams generados /CIDToGIDMap, /W y /ToUnicode durante la finalización para que el CID interno se mapee al glifo real de la fuente y la extracción de texto vuelva al par sustituto UTF-16BE original
Los campos Tx ASCII siguen usando /Helv y emiten salida /AP byte-idéntica a los llamadores de v2.46.0. Pase LogicalName vacío + FontDict nil para limpiar el registro y volver al comportamiento solo /Helv. Flujo de trabajo típico: llame a SetFormUnicodeFontDict una vez inmediatamente después de BeginDoc, antes de cualquier AddTextField; los widgets creados antes no se actualizan retroactivamente
LogicalName - PDF Name usado como clave en /DR/Font y como operando de Tf dentro de la cadena /DA. Típico: 'F0'. No debe estar vacío al registrar; un nombre vacío con FontDict no nil lanza una excepción
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 serialises 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.
Ejemplo de código
// 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;
Véase también
CreateIndirectFontDict, AutoFormAppearances, AddTextField, AddRichTextField, Version
|