"Please wait... If this message is not eventually replaced by the proper contents of the document, your PDF viewer may not be able to display this type of document." If your document pipeline has ever ingested government or insurance forms, you have met this page. It is not corruption; it is the placeholder a dynamic XFA form shows to any viewer that lacks an XFA processor, which today means nearly every viewer except desktop Acrobat. Archives, web viewers, and automated extraction all see one useless page. HotPDF, the losLab PDF library for Delphi and C++Builder, addresses this with a conversion path that turns XFA forms into native AcroForm documents any conforming reader can display.
Two form models that only look similar
AcroForm, defined in ISO 32000-1 §12.7, stores each field as a PDF object with a widget annotation and an appearance stream; the page you see is real PDF content, and the form data rides on top of it. XFA takes the opposite approach: the form is an XML document, an XDP package carried in the /XFA entry of the AcroForm dictionary, and the visible pages are generated at open time by an XFA layout engine. In a dynamic XFA form, the PDF pages in the file are nothing but the "Please wait" placeholder, because the real content never existed as PDF at all.
The two models are mutually exclusive in practice: a document is processed either as XFA or as AcroForm, and tools that ignore the /XFA entry see only the placeholder shell. ISO 32000-2 settled the argument by deprecating XFA from PDF 2.0 entirely, which is why "convert it to AcroForm while we still can" has become a standard ingestion requirement rather than an exotic one.
Not every XFA form shows the placeholder, which is why ingestion pipelines should classify before they convert. Static XFA forms carry pre-rendered PDF pages alongside the XML, so they display everywhere and merely behave inconsistently when filled; dynamic forms carry only the placeholder and must be converted to be usable at all. The reliable discriminator is the document itself, not the file extension or the sender: a form that renders real content in a non-Adobe viewer but still carries an /XFA entry is static or hybrid, and one that shows the warning page is dynamic. Classify each intake file into one of those buckets and record the classification, because the two kinds fail differently downstream and a support ticket about a blank archived form is answered in seconds when the intake record says "dynamic XFA, converted, 47 fields mapped, 2 warnings".
Flattening a loaded XFA document into native fields
HotPDF's conversion entry point operates on a loaded document. FlattenLoadedXFA parses the XFA template and data packets, lays the form out, and rebuilds it as real AcroForm fields on real PDF pages:
var
Pdf: THotPDF;
MappedCount, I: Integer;
Warnings: TStrings;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.LoadFromFile('dynamic_xfa.pdf');
MappedCount := Pdf.FlattenLoadedXFA(True); // True = fields stay editable
Warnings := Pdf.XFAFlattenWarnings;
for I := 0 to Warnings.Count - 1 do
Log('XFA flatten warning: ' + Warnings[I]); // unmapped elements
Pdf.SaveLoadedDocument('native_acroform.pdf');
Log(Format('Mapped %d fields', [MappedCount]));
finally
Pdf.Free;
end;
end;
Treat the return value and the warning list as part of the output, not as debug noise. The conversion is inherently lossy: XFA scripting, calculated fields, and dynamic subform behavior have no AcroForm equivalent, and XFAFlattenWarnings enumerates exactly which template elements could not be mapped. A pipeline that archives the converted file without archiving the warning list will eventually face the question "why is the totals box empty in the archived copy" with no recorded answer. The Editable parameter decides whether the resulting AcroForm fields remain fillable; pass True when downstream users continue working with the form, False-equivalent policies when the goal is a fixed record.
Verification of a conversion is necessarily visual as well as structural. Open the source form in desktop Acrobat, the one viewer that still runs the XFA engine, next to the converted file in any ordinary viewer, and compare field values and layout for at least one representative filled form per template. Structural checks confirm the field count matches MappedCount; only eyes confirm that a date that XFA formatted as 2026-06-11 did not arrive in the AcroForm copy as a raw unformatted value.
Working from the XDP side
Sometimes the input is not a populated PDF but the XDP package itself, exported from a form design tool or received from a partner system. ApplyXFAAsAcroForm skips the load step and applies the package to the current document directly:
XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);
The same family of calls also covers the authoring direction, when you need to produce XFA rather than consume it: AddXFAPacket attaches individual named packets such as 'xdp' or 'config', SetXFADocument installs a complete single-stream XFA payload, ClearXFAPackets resets the registration, and AddXFASignaturePacket embeds XAdES signature material for workflows that sign the XML form data itself. Generating XFA in 2026 is a niche requirement, usually driven by one legacy consumer, but when a contract demands it these calls keep it a configuration detail instead of a separate tool.
The other flattening: AcroForm content, stated honestly
"Flatten" carries a second meaning that causes recurring confusion: burning AcroForm field appearances into the page content stream so that no interactive objects remain. HotPDF does not currently provide an API for that operation, and it is better to plan around the fact than to discover it mid-project. What the library does offer is field-level locking at creation time, plus document permissions:
// Lock the value at field creation: read-only text field
Pdf.CurrentPage.AddTextField('CaseNumber', 'BC-2026-0117',
Rect(50, 700, 220, 720), 0, [ffReadOnly]);
// Belt and suspenders: restrict form filling document-wide
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.OwnerPassword := 'records-owner';
Pdf.ProtectOptions := [prPrint, prInformationCopy, prExtractContent];
// fill permission withheld: prFillAnnotations is absent from the set
Understand what this does and does not achieve. A read-only field still exists as a form object: it appears in a viewer's field panel, its value is extractable through the form API, and a tool that rewrites the file can clear the flag. Permission flags raise the bar further but rest on viewer cooperation, as ISO 32000-1 itself acknowledges. If a regulator requires that an archived record contain no form objects whatsoever, the honest engineering answer with HotPDF today is to regenerate the document, render the field values as ordinary TextOut content on a fresh document using the loaded values, rather than to pretend read-only flags are flattening. Remember CryptKeyLength must be set before BeginDoc when you take the permissions route; the details live in our AES-256 encryption and permissions article.
Archival consequences: XFA and the compliance standards
PDF/A and PDF/X both reject XFA outright, so an ingestion pipeline that feeds an ISO 19005 archive must convert before it validates, and the order of operations is fixed: load, FlattenLoadedXFA, save, then run the archival generation or validation pass on the AcroForm result. Validate the converted output with veraPDF rather than assuming conversion implies compliance; the conversion fixes the form model, not fonts, color, or metadata. Field behavior on the AcroForm side, JavaScript triggers, submit actions, and validation scripts, has its own toolbox, covered in the HotPDF AcroForm fields and actions article.
FAQ
Why does my PDF form show only a "Please wait" page?
It is a dynamic XFA form, and your viewer has no XFA processor. The visible PDF content is just a placeholder; convert the document with FlattenLoadedXFA to obtain pages and fields every viewer can render.
Does FlattenLoadedXFA preserve calculations and scripts?
No. XFA scripting and dynamic layout logic are not convertible to AcroForm; computed values present in the form data are carried over as static values, and XFAFlattenWarnings lists every element that could not be mapped. Review that list before trusting the output.
Can HotPDF make a form completely non-interactive?
Not through a one-call flatten: there is no AcroForm content-flattening API. Combine ffReadOnly fields with permission restrictions for tamper resistance, or regenerate the document with values drawn as plain text when zero form objects is a hard requirement.
Product reference
The XFA registration, conversion, and form APIs in this article are part of the HotPDF Component for Delphi and C++Builder; its documentation tracks the XFA feature set as it has grown across recent releases.