AcroForm Support

Overview

Since HotPDF v2.5.0 the library can emit interactive forms (AcroForm) per PDF 1.7 ISO 32000-1 section 12.7. Each form field is created as a Widget annotation merged with the field dictionary and is automatically registered with the document so the global /AcroForm entry is added to the Catalog when the document is finalized in EndDoc.

Supported field types

  • Text fields (/FT /Tx) via THPDFPage.AddTextField. Supports single-line, multi-line, password, comb, file-select, rich-text, scroll and spell-check options through THPDFFormFieldFlags.
  • Check boxes (/FT /Btn, no Pushbutton/Radio bits) via THPDFPage.AddCheckBox with a configurable export value name and initial checked state.
  • Radio buttons (/FT /Btn /Ff Radio) via THPDFPage.AddRadioButton. Multiple calls with the same group name are merged under a shared parent field with a /Kids array, exactly as required by 12.7.4.2.
  • Combo boxes (/FT /Ch /Ff Combo) via THPDFPage.AddComboBox. Pass an open array of options.
  • List boxes (/FT /Ch) via THPDFPage.AddListBox. ffMultiSelect enables multi-select.
  • Push buttons (/FT /Btn /Ff Pushbutton) via THPDFPage.AddPushButton with optional caption (/MK /CA). Since HotPDF v2.31.0, THPDFPage.AddPushButtonWithAction attaches a PDF action dictionary to the widget so clicking the button runs /SubmitForm (post field values to a URL, PDF 1.2 12.7.5.2), /ResetForm (PDF 1.2 12.7.5.3), /JavaScript (run a JS snippet, PDF 1.3 12.6.4.16) or /URI (open a URL in the system browser, PDF 1.1 12.6.4.7).
  • Signature placeholder fields (/FT /Sig) via THPDFPage.AddSignatureField since HotPDF v2.12.0. The AcroForm dictionary automatically gains /SigFlags 3 (SignaturesExist + AppendOnly) when at least one signature field is present. The field is left unsigned so external tools (Adobe Acrobat, Foxit, dedicated CMS / PKCS#7 signing libraries) can attach the actual cryptographic signature after the file is saved.
  • In-place signing workflow via THPDFPage.AddSignedSignatureField + THotPDF.PreparePDFForSigning + THotPDF.InsertSignatureHex since HotPDF v2.23.0. The first call reserves a /V signature dictionary with /ByteRange and /Contents placeholders. After saving the document the host application calls PreparePDFForSigning to patch /ByteRange and learn which file ranges to hash. After producing a CMS / PKCS#7 detached signature externally (Windows CryptoAPI, OpenSSL, dedicated signing libraries), it calls InsertSignatureHex to drop the signature hex into the placeholder without disturbing any other byte in the file.

Creation-time field wrappers

Since HotPDF v2.292.12, the THPDFPage.CreateTextField, CreateCheckBox, CreateRadioButton, CreateComboBox, and CreateListBox helpers create the same AcroForm widgets as the existing Add... methods and return a lightweight THPDFAcroFormField wrapper for immediate configuration

Since HotPDF v2.292.26, THotPDF.SetFormFieldTooltip assigns the PDF /TU user hint by field name for fields created through the existing Add... methods, matching the wrapper-level THPDFAcroFormField.SetTooltip workflow

Since HotPDF v2.298.0, creation-time field APIs and loaded-document field-creation APIs reject duplicate root field names with a diagnostic exception before any widget is registered. Repeated AddRadioButton calls with the same group name remain valid because they share one parent field and add additional child widgets under its /Kids array

The wrapper exposes chainable setters for /TU tooltips, common field flags (SetReadOnly, SetRequired, SetNoExport), /DA default appearance strings, field-level additional actions such as /AA /K, /AA /F, /AA /V, /AA /C, and widget mouse or focus actions through THPDFActionBuilder

Creation-time wrapper Pascal example

Field := HPDF.CurrentPage.CreateTextField('Email', '', Rect(50, 80, 250, 104));
Action := THPDFActionBuilder.JavaScript('event.rc = event.value.indexOf("@") > 0;');
try
  Field.SetTooltip('Email address');
  Field.SetRequired(True);
  Field.SetReadOnly(False);
  Field.SetAdditionalAction(fatValidate, Action);
finally
  Action.Free;
  Field.Free;
end;

Loaded form-field inspection and updates

Since HotPDF v2.121.9, applications can load an existing AcroForm PDF with THotPDF.LoadFromFile, enumerate its fields, read their names, types and values, change field values, toggle the read-only flag, and save the loaded object graph with THotPDF.SaveLoadedDocument This path is intended for persisted edits to an already loaded document; do not call BeginDoc / EndDoc just to save loaded field-value changes.

The field helpers are GetFormFieldCount, GetFormFieldName, GetFormFieldType, GetFormFieldValue, SetFormFieldValue, and SetFormFieldReadOnly. Field lookup accepts either a zero-based field index or the fully qualified field name. The returned THPDFLoadedFormFieldType values are lfftText, lfftButton, lfftChoice, lfftSignature, or lfftUnknown.

Loaded-field Pascal example

HPDF.LoadFromFile('InputForm.pdf');
for I := 0 to HPDF.GetFormFieldCount - 1 do
  Writeln(HPDF.GetFormFieldName(I), ' = ', HPDF.GetFormFieldValue(I));

HPDF.SetFormFieldValue('CustomerName', 'Bob');
HPDF.SetFormFieldValue('Plan', 'Premium');
HPDF.SetFormFieldReadOnly('CustomerName', True);
HPDF.SaveLoadedDocument('UpdatedForm.pdf');

Field additional actions

The wrappers AttachFieldKeyStrokeAction, AttachFieldFormatAction, AttachFieldValidateAction, and AttachFieldCalculateAction attach JavaScript to a field's /AA dictionary for the PDF /K, /F, /V, and /C triggers. Use SetFormFieldAdditionalAction or its named THPDFActionBuilder wrappers when the same trigger must run a reusable action chain such as JavaScript, ResetForm, SubmitForm, URI, Hide, ImportData, or a chained /Next action. Widget-level mouse and focus triggers can also be installed by field name through SetFormFieldAnnotationAction and the named mouse / focus helpers, while the matching clear helpers remove one trigger without disturbing the rest of the /AA dictionary

Appearance generation

By default the emitted /AcroForm dictionary sets /NeedAppearances true and delegates appearance-stream rendering to the consuming viewer (Adobe Reader, Foxit, Chrome, browsers, Apple Preview). Set THotPDF.AutoFormAppearances to true before adding fields and HotPDF will pre-build /AP /N Form XObjects (PDF 1.7 8.10) for every text field, push button, choice (combo / list) and the Yes / Off states of every checkbox / radio kid. The AcroForm dictionary then carries /NeedAppearances false and a /DR default resources entry referencing the standard 14 base fonts (Helv Helvetica, ZaDb ZapfDingbats), so renderers that ignore /NeedAppearances still draw the field content correctly. Available since HotPDF v2.28.0.

Field flag reference (THPDFFormFieldFlags)

  • ffReadOnly, ffRequired, ffNoExport — common Table 227 flags applicable to every field type.
  • ffMultiline, ffPassword, ffFileSelect, ffDoNotSpellCheck, ffDoNotScroll, ffComb, ffRichText — Tx-specific (Table 228).
  • ffEdit, ffSort, ffMultiSelect, ffDoNotSpellCheck, ffCommitOnSelChange — Ch-specific (Table 230).

Pascal example

HPDF.BeginDoc;
HPDF.AddPage;
HPDF.CurrentPage.AddTextField('Name', '', Rect(50, 100, 250, 120));
HPDF.SetFormFieldTooltip('Name', 'Customer name');
HPDF.CurrentPage.AddCheckBox('Agree', 'Yes', Rect(50, 130, 70, 145), True);
HPDF.CurrentPage.AddRadioButton('Color', 'Red',   Rect(50, 160, 70, 175), True);
HPDF.CurrentPage.AddRadioButton('Color', 'Green', Rect(80, 160, 100, 175));
HPDF.CurrentPage.AddRadioButton('Color', 'Blue',  Rect(110, 160, 130, 175));
HPDF.CurrentPage.AddComboBox('Country', 'CN',
                             ['CN', 'US', 'JP'], Rect(50, 190, 250, 210));
HPDF.EndDoc;

Limitations

  • The AutoFormAppearances generator currently lays out ASCII / WinAnsi-encodable values only; for fields whose /V contains multi-byte (UTF-8) text the stored /AP renders an empty rectangle until the host viewer regenerates the appearance.
  • Down (/D) and rollover (/R) sub-states are not generated; only the normal (/N) state is produced.
  • Field names are checked for duplicate root entries when new AcroForm widgets are created; hierarchical partial-name construction beyond the radio parent / widget pattern remains the caller's responsibility.

See Also