Loaded PDF to PDF/A-4 with Text and Vector Preservation
HPDFArchivalConversion offers a preservation profile for loaded documents whose visible fonts, colour spaces, and rendering resources can satisfy PDF/A-4 without replacing their page content
The converter retains original text operators, vector paths, images, page geometry, and existing OCR text layers, flattens visible normal annotation and widget appearances into vector Form XObjects, repairs supported metadata and structural issues, and validates the serialised result before publication
This profile never rasterises a page: RasterizedPages remains zero, including when OCR renders a temporary recognition bitmap and appends invisible searchable text
Runtime acceptance covers Delphi Win32 and Win64; Windows FPC compiles the implementation from fresh sources, and the generated public headers compile with C++Builder Win32 and Win64x
Entry points
function HPDFConvertLoadedToPDFA4Preserving(Source: THotPDF;
Destination: TStream; const SRGBProfile: TBytes;
const Options: THPDFArchivalPreservationOptions;
out Report: THPDFArchivalPreservationReport): Boolean;
function HPDFConvertLoadedToPDFA4PreservingFile(Source: THotPDF;
const TargetFileName: string; const SRGBProfile: TBytes;
const Options: THPDFArchivalPreservationOptions;
out Report: THPDFArchivalPreservationReport): Boolean;
Load the source first, keep any caller-owned input stream alive, and give the converter exclusive access to the document during the operation
Options := THPDFArchivalPreservationOptions.Default;
if not HPDFConvertLoadedToPDFA4PreservingFile(Source, TargetFileName,
SRGBProfile, Options, Report) then
raise Exception.Create(Report.Conversion.Diagnostic);
Preservation proof
The converter snapshots the current edited source graph under a graph transaction and rolls the source back after serialisation, then performs all conversion work on an independent loaded clone
Original decoded page content streams must remain byte-identical and reachable from their original pages in their original order after output reload
Page resource trees and retained normal appearance resource trees are traversed with object and recursion limits; embedded font programs, ToUnicode maps, images, ICC profiles, and nested Form XObjects retain their original encoded payloads, verified with streaming SHA-256 and checked for continued reachability from output pages
Independent content streams bracket original page operators with graphics-state guards and hold appended appearance operators, avoiding the native single-stream append path that would rewrite an original content stream
TextAndVectorContentPreserved becomes true only after native output validation and preservation checks pass; it is cleared when conversion or file publication fails
Appearance handling
- Visible normal
AP/Nappearances are mapped from their Form BBox and Matrix to the annotation Rect using native annotation flattening, retaining their own fonts and resources - Invisible, Hidden, and NoView flags prevent painting even when an existing normal appearance is present; Popup annotations are removed without painting
- Borderless links without a normal appearance are removed without painting only when an explicit zero-width border establishes that they have no visible border
SynthesizeMissingAppearancesdefaults to true and invokes native markup or field appearance generation; unsupported subtypes, invalid rectangles, or failed generation reject the conversion- Missing textual appearances support ASCII values with a compatible native font encoding; hexadecimal, Unicode, or masked textual values require an explicit normal appearance
- Synthesised textual appearances are checked against their source values in reloaded searchable text after whitespace normalisation; an incompatible font encoding rejects publication
Supplying an existing normal appearance supports arbitrary embedded-font text that is already represented correctly in that appearance, including Unicode; the converter retains that appearance instead of substituting a system font
Flattening removes annotation interaction, editable fields, calculations, actions, and signature fields whilst keeping visible appearances; each affected annotation and each synthesised appearance produces a loss entry with its source page, annotation index, and object number when available
Colour, fonts, and explicit losses
The required ICC argument is an sRGB matrix/TRC profile accepted by the existing archival validator; every existing output profile must have exactly the same decoded bytes as the supplied profile, otherwise conversion is rejected to avoid reinterpreting the existing output condition
The converter adds an sRGB PDF/A output intent only when needed, synchronises the actual serialiser to a PDF 2.0 header, and invokes bounded base PDF/A-4 metadata and structural repair
It does not embed missing visible font programs, recode original text, recolour DeviceCMYK operators, replace an existing output condition, or flatten page transparency into a bitmap; unresolved native preflight findings reject publication
Encrypted sources must be decrypted before conversion; signature fields require explicit AllowSignatureInvalidation, and existing embedded files require explicit RemoveEmbeddedFiles because this profile targets base PDF/A-4
Losses also reports signature invalidation, embedded-file removal, removal of legacy Info dictionaries, and removal of forbidden catalog or presentation metadata
Existing XMP is retained when supported; when metadata is generated, supported title, author, subject, and keyword information is transferred, whilst arbitrary legacy Info fields are not promised to survive
OCR and budgets
AddOCRToImagePages defaults to false; enabling it recognises pages that have no extractable text and appends invisible text without replacing original content or existing OCR layers
Set OCREngine to an application engine or leave it nil for the built-in bounded ASCII OCR engine, whose language and typography coverage remains that of the built-in recognition profile
OCROptions controls recognition resolution and word budgets, whilst the converter forces skip-pages-with-text, retention of existing OCR layers, and omission of a new optional-content group
Limits uses THPDFArchivalConversionOptions.Default for page count, object count, staged output bytes, individual stream work, cumulative stream work, cancellation, and synchronous checkpoints; raster pixel limits apply only when OCR renders recognition bitmaps
Additional defaults are 1,024 loss entries, 1,048,576 extracted or expected text code units, and 4,000,000 content tokens per native validation pass
Resource payload hashing counts encoded bytes against the same stream-work budgets; source and output verification both consume cumulative work, so large scan collections may require an explicitly increased MaxTotalDecodedBytes even though resource verification uses a fixed 64 KiB hash buffer
Budgets apply after source loading and bound converter-owned snapshots and staged output separately; configure loader limits when accepting untrusted input
Publication and validation
The stream API requires an empty seekable destination at position zero and rejects source aliases; it copies staged bytes only after reloading, native validation, preservation checks, and cancellation checks succeed
A destination write failure triggers a best-effort reset; an arbitrary custom stream may reject that reset, so use the file entry point for atomic file publication
The file API probes for source aliases, creates an exclusive temporary file beside the target, flushes it, and replaces the target with MoveFileEx only after all checks pass; earlier failures retain an existing target and remove the temporary file
InitialValidationIssues, Repair, Conversion.ValidationIssues, OCR details, stream counts, extracted text counts, and explicit losses remain available for inspection
Native validation covers the supported HotPDF PDF/A-4 rules and is not a blanket certification of arbitrary PDFs; regression acceptance additionally uses independent pypdf and MuPDF checks plus veraPDF PDF/A-4 validation on generated appearance and native OCR artefacts
Real corpus regression includes embedded-font Word and library guides and a 380-page Chinese scan collection, whilst a trade report with unembedded fonts and DeviceCMYK content is an explicit rejection case
Regression commands
powershell -File Tests/Delphi/Run-ArchivalPreservationTests.ps1 -Platform Win32
powershell -File Tests/Delphi/Run-ArchivalPreservationTests.ps1 -Platform Win64
python Tests/Delphi/Fixtures/ArchivalPreservation/verify_preserving_output.py
verapdf --format xml --flavour 4 Tests/Delphi/generated/ArchivalPreservation/appearance.pdf Tests/Delphi/generated/ArchivalPreservation/ocr.pdf Tests/Delphi/generated/ArchivalPreservation/native-appearance.pdf
The Delphi runner suppresses viewer launch and includes both preservation and existing raster regression fixtures; independent veraPDF acceptance uses the actual PDF/A-4 validation profile
Related topics
Raster archival conversion provides a separate profile with explicit loss of original text and vectors when native rendering is supported