|
Registra una fuente Unicode suministrada por el llamador en el diccionario de recursos predeterminados de AcroForm para que el generador de flujos de apariencia automática de HotPDF (PDF 1.7 ISO 32000-1 12.7.4.3) pueda renderizar valores iniciales no ASCII de widgets Tx directamente en /AP, en lugar de emitir el marcador de posición AP vacío de v2.46.0. Combínalo con CreateIndirectFontDict para asignar el diccionario de fuente indirecta que se va a poblar
Sintaxis Delphi:
procedure SetFormUnicodeFontDict(const LogicalName: AnsiString; FontDict: THPDFDictionaryObject);
Sintaxis C++:
void SetFormUnicodeFontDict(const AnsiString& LogicalName, THPDFDictionaryObject* FontDict);
Descripción
Una vez que LogicalName y FontDict están poblados, cambian tres cosas en la emisión posterior: (a) la cadena /DA de nivel AcroForm pasa de '/Helv 12 Tf 0 0 0 rg' a '/<LogicalName> 12 Tf 0 0 0 rg'; (b) el subdiccionario /DR /Font de AcroForm agrega una entrada /<LogicalName> <FontDict-indirect-ref> junto con las existentes /Helv + /ZaDb; (c) cada widget Tx agregado mediante AddTextField o AddRichTextField obtiene su /DA por campo de la misma forma. Cuando AutoFormAppearances está activado y el valor inicial del widget contiene cualquier byte >= 0x80, GenerateTextFieldAP emite un verdadero /AP /N Form XObject cuyo flujo de contenido selecciona la fuente registrada mediante Tf y renderiza el texto como un operador Tj de cadena hex CID; el subdiccionario /Resources/Font del Form referencia la misma fuente indirecta, así 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 actualiza al final los flujos generados /CIDToGIDMap, /W y /ToUnicode para que el CID interno se asigne 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 una salida /AP idéntica a nivel de byte para los llamadores de v2.46.0. Pasa LogicalName vacío + nil FontDict para borrar el registro y volver al comportamiento solo con /Helv. Flujo de trabajo típico: llama a SetFormUnicodeFontDict justo después de BeginDoc, antes de cualquier AddTextField; los widgets creados antes no se actualizan de forma retroactiva
LogicalName - el nombre PDF 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 un FontDict no nulo genera 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
|