PDFium Delphi Component Release Notes
Version history for PDFium Delphi Component user-visible features, fixes, viewer improvements, document generation, PDF/A output, rendering, and documentation updates
Last release
- Latest version: 3.137.1; Release date:
Version 3.137.1
Fixed
- OpenSSL online revocation checks preserve the preceding CRL status, reason, native error and affected certificate when no OCSP evidence or responder is available, retaining accurate expired-CRL diagnostics
Version 3.137.0
Added
- Native Free Pascal/LCL builds support Linux Qt6 and macOS Cocoa with platform font resolution, private temporary storage, document loading, editing, forms, saving and rendering
- macOS Keychain signing supports a query-local Keychain path and bounded offline certificate-chain export, with native Free Pascal and Delphi signing and timestamp transports
- Parallel rendering reports each worker's actual module path, initialization address and unload result, rejecting native loaders that reuse an existing PDFium image
Fixed
- Unix PDFium bindings preserve LP64 unsigned-long callback and buffer widths, including custom stream reads beyond 4 GiB
- Native LCL rendering respects bitmap byte order and channel layout, preserving colors in Cocoa output and device-context rendering
- Bitmap, tile and progressive rendering preserve transparent background alpha for clNone and clDefault independently of the native page transparency query
- Signing identifies certificate public-key algorithms correctly, including EC keys; macOS CMS verification preserves independent outer-signature and timestamp results and reports unsupported RSA-PSS verification explicitly
- PAdES timestamp validation requires a critical, exclusive id-kp-timeStamping EKU; OpenSSL evaluates basic TSA chains without incorrectly applying an S/MIME certificate purpose
- Unix atomic file commits retain the new incremental baseline when a directory flush fails after replacement, exposing the committed-output exception and incomplete durability result
Changed
- Delphi POSIX futures accept the default thread priority and reject unsupported priority requests before starting a worker
Version 3.136.0
Added
- Optional LittleCMS ICC transforms and document color conversion use original text, vector and 8-bit or 16-bit image components, preserve selected spot colors and report unsupported content explicitly
- Complex redaction preserves supported content in nested Form XObjects, filled curved paths and rotated, reflected or sheared images, with finite geometry budgets and detailed removal reports
- Active-object reading exposes independent object-body and compressed object-stream budgets before materialization and decoding
Security
- Redaction refuses Tagged replacement text, XFA, optional-content layers, text clipping and unverifiable paint states, including operators split across content streams, preventing export of unsupported sensitive-content semantics
Version 3.135.0
Added
- Annotation and AcroForm widget comparison reports property changes independently of page pixels, using stable names, explicit page mappings, ambiguity reports and before/after overlay bounds
- Table cells support mixed text styles and images with alternate text, optional spanning-cell continuation across pages, subtotal rows and continuation labels while preserving Tagged PDF relationships
Fixed
- Tagged layout generation initializes the native library before checking capabilities, allowing it to be the first operation on a new document component
- Multiple replacements in one text object are fitted once against its original bounds, enforcing the overall minimum horizontal scale and avoiding unnecessary intermediate edits
Version 3.134.0
Added
- Navigation merge preserves named destinations and internal page links through selected, reordered and repeated pages, with explicit collision policies and transactional verification
- Styled text replacement adds verified source plans, independent previews, native font reuse, explicit fallback, bounded horizontal fitting and rollback after failed or cancelled edits
- OpenSSL signing accepts explicitly configured private keys and certificate chains for RSA-PSS, RSA PKCS#1 v1.5 and ECDSA, including default signer resolution outside Windows
- OpenSSL verification adds authenticated offline and bounded online OCSP evidence, failing certificate identities and optional diagnostics for each CMS signer
- The FPC macOS Security.framework verifier reports independent cryptographic, chain-trust and revocation outcomes with explicit trust anchors and supplied OCSP evidence
Fixed
- Link annotation URI extraction supplies the complete native buffer, including its terminator, so valid targets are returned correctly
Version 3.133.0
Added
- Transactional AcroForm merging supports selected pages, field rejection, renaming, namespaces and compatible shared text/choice fields, with isolated resources, appearances and calculation order
- Optional barcode provider generates Code128, QR, DataMatrix and PDF417 and recognizes grayscale images, with explicit native dependencies and finite processing budgets
Fixed
- FormField reads inherited parent values and commits text edits consistently across shared widgets, with persistent save/reopen values and read-only checks
- Appearance regeneration for inherited text widgets restores their parent values without leaving a shadow widget value, and successful field assignment invalidates shared page caches
Version 3.132.0
Added
- Optional page alignment identifies inserted, deleted and moved pages, with bounded Unicode text changes, connected visual regions and exportable comparison overlays
- Transactional navigation merging preserves outline hierarchy, styles, URI actions and remapped destinations through selected, repeated and reordered page imports
- Optional Tesseract OCR provider supports explicit dependency diagnostics, Unicode word geometry, cancellation and recognition budgets, with searchable-layer save and reopen verification
Security
- RSA-PSS policy evaluates complete signature and restricted public-key parameters, rejecting malformed DER and incompatible hash, mask, salt or trailer restrictions
Fixed
- Outline save verification no longer rejects leaf bookmarks because of a branch-only expanded-state difference
Version 3.131.0
Added
- WatermarkStamp now accepts target and stamp PDFs, a target-page interval, and page-number-only output, with proportional placement for mixed page sizes
- MergePDF now previews each input's selected pages and destination interval before merging, and supports a single input for page extraction
Fixed
- MergePDF validates every source before importing and stops on unreadable inputs, invalid ranges, failed imports, or cancellation instead of saving an incomplete merge
- WatermarkStamp preserves its source and template files and reliably saves page numbers even when both stamp overlays are disabled
Changed
- Focused each native demo directory on 22 complete workflows and moved SecurityAudit and XfdfLab into Miscellaneous, with corrected project paths and navigation
Removed
- Removed the fixed AnnotationsLab walkthrough; annotation creation, inspection, and exchange remain covered by XFDF and content-extraction samples and API tests
Version 3.130.0
Changed
- Curated each native demo directory around 24 complete workflows, with nine focused API topics under Miscellaneous and separate guidance for choosing a first demo
- Kept focused annotation, accessibility, font, navigation, text export, page-image rendering, print-preference, interaction, and XFA examples available with their own source and bundled inputs
Removed
- Removed the minimal CJKTextLab and RTLTextLab projects; Unicode authoring remains available in CreatePDF, and the shaped-text APIs remain documented in the API reference
Fixed
- Fixed the C++Builder accessibility API walkthrough failing when exporting its speech script
- Fixed the C++Builder annotation example using incorrect array offsets for highlight coordinates
Version 3.129.0
Changed
- Made every native demo self-contained: moved sample logic into the projects that use it, bundled showcase PDFs with the relevant viewing and extraction projects, and removed the Demo/Shared directory
- Kept offline feature tours, live previews, editable forms, populated reports, attachments, navigation, print preferences, and static XFA inspection available when projects are copied independently
- FontProperties now opens with actual font and character metrics already displayed, and immediately analyzes the first text object after opening another document
Fixed
- Aligned the PDFViewer experience bar placement and background across the native variants, and made FontProperties release its viewer association before shutdown
Version 3.128.0
Added
- Added an offline six-page demo showcase with live text, vector charts, embedded images, a table, AcroForm fields, bookmarks, links, annotations, and attachments
- Added one-click viewing experiences for text search, two-page layouts, night reading, document inspection, and form exploration in all native PDFViewer variants
Changed
- CreatePDF now opens a live two-page preview with editable metadata and content options, real image and annotation objects, and an optional Unicode page before saving
- Focused viewing, search, extraction, forms, and navigation samples now open populated workflows; attachment, print-preference, and static XFA samples include actual feature-specific data
Fixed
- Fixed viewer lifecycle and focus handling during startup, document replacement, preview regeneration, and shutdown
- Fixed the Lazarus FormFill value editor remaining disabled after the first field was selected at startup
- Fixed SearchAndSelect document binding and extraction reports that omitted form fields on later pages or queried unavailable file headers for generated in-memory samples
Version 3.127.0
Changed
- The MultiPageViewer demos use the viewer's built-in text selection and clipboard APIs, keeping selection consistent across page layouts and removing the separate double-click selection mode
- The examples guide maps all 35 demo topics to their distinct workflows, and the Delphi and Lazarus accessibility, intake, and preflight console examples share their Pascal implementations
Added
- XfdfLab can save the PDF after importing XFDF: the Delphi GUI offers Save PDF, and the console variants accept an explicit second output path
Fixed
- The C++Builder and Lazarus MultiPageViewer demos open without unsupported form properties, and all MultiPageViewer demos disconnect their document before closing
- The Lazarus accessibility workbench generates JPEG page thumbnails for its HTML review report
- The ExtractImages demos create a two-page sample containing real embedded image objects, so the default extraction workflow produces four images
- The console XFDF round-trip sample preserves annotation contents and author data, and rejects conflicting or existing PDF output paths before writing output
Version 3.126.2
Fixed
- Full XFA viewing works with the default text-selection settings, replaces selected text during keyboard input, respects read-only fields and disabled form events, and refreshes displayed page handles after dynamic layout changes
- The Windows V8 libraries reject malformed XDP attributes, duplicate attributes, invalid namespace use and mismatched XML declarations before changing the saved XFA stream
Security
- Signature revision analysis preserves page-content ownership when widgets and appearance objects refer to the same object graph, preventing later page edits from being accepted as permitted form or annotation updates under DocMDP
- FieldMDP locks remain effective when a locked field and an annotation share an indirect value object
Version 3.126.1
Fixed
- Dynamic XFA repagination now updates
TPdf.PageCountandOnXfaPageCountChangedwith the actual total page count after pages are added or removed, keeping host navigation in sync with the form layout - The updated Windows V8 libraries refresh input-widget geometry after dynamic XFA layout changes, keeping text and input hit areas aligned when fields move to another page
Version 3.126.0
Added
- The updated Win32 and Win64 V8 libraries preserve XML comments and processing instructions outside live datasets and form packets when saving supported single-stream XFA documents, including UTF-8 and UTF-16 inputs
Fixed
- Single-stream XFA saving rejects invalid UTF-8 or UTF-16 encoding, incomplete tags, invalid entity references and malformed processing instructions instead of silently rewriting those inputs; unsupported constructs in live data packets, DTD declarations and XMLDSig remain explicit save failures
- Viewer copy, cut and form paste retry briefly when another thread or application holds the Windows clipboard, allowing transient contention to clear; a failed cut still preserves the original field text
Version 3.125.3
Fixed
- The updated Win32 and Win64 ordinary
pdfium.dlllibraries now report failure when the final buffered PDF write fails, matching the repair previously shipped in the V8 libraries
Version 3.125.2
Fixed
- The updated Windows V8 libraries preserve edited XFA text through saving and reopening, including empty values, original whitespace, line breaks and supplementary Unicode characters, for packet arrays and supported single-stream XDP documents
- XFA packet export errors and final buffered writer failures now report save failure in the updated V8 libraries, without clearing the document's modification state; single-stream documents containing unsupported XML constructs or XML signatures are rejected
- The updated V8 libraries preserve a host application's explicitly supplied V8 platform and isolate through PDFium initialization and destruction
- An explicit path in
LibraryNamenow selects that exact runtime in either engine mode, includingEnableV8Engine=True; a missing explicit path fails instead of loading another bundled library
Version 3.125.1
Fixed
ValidatePdfFilesParallelno longer corrupts the shared PDFium engine: worker threads used to open and inspect documents concurrently, which made some documents fail with load errors or access violations and could crash the process or break later PDF operations; the PDFium part of each document is now processed one at a time while rule evaluation still runs in parallel- A document that cannot be opened during batch validation now reports the actual load error instead of a follow-up "no active PDF document" message
Version 3.125.0
Added
PdfLibraryConfigurationSupportErrorreports whether aTPdfLibraryConfigurationcan be used with a PDFium build of given Skia and Fontations capabilities
Fixed
- Requesting
prpSkiaon a PDFium build without Skia, orpfbpFontationson a build without Fontations, now makes the library load raiseEPdfErrorinstead of hitting a native check that stopped the process or left PDFium half-initialized; the configuration stays unsealed so the application can choose other settings and load again
Version 3.124.0
Changed
- PAdES validation now applies the ETSI TS 119 312 signature suites to RSA signatures instead of accepting every RSA algorithm:
AlgorithmPolicyStatusispcsInvalidfor MD2, MD4 and MD5 digests andpcsIndeterminatefor SHA-1 and 112-bit digests such as SHA-224, which are no longer agreed for current validation; SHA-1 signatures keep their overall integrity result and are flagged for review rather than rejected - An RSA signature whose
digestAlgorithmdiffers from the digest fixed by its signature algorithm (for example sha256WithRSAEncryption over a SHA-1 digest) is now reported asppeiSignatureAlgorithmMismatchand fails integrity, as do RSA signature algorithms on a non-RSA signer key - RSA signatures whose signer certificate cannot be found now report
pcsIndeterminate, matching the existing ECDSA behaviour; unrecognised digests and non-signature RSA OIDs reportpcsUnsupported - RSA PKCS #1 v1.5 signatures with SHA3 digests and the legacy OIW sha1WithRSASignature identifier are now recognised as RSA
Version 3.123.0
Added
PdfNativeRendererTypereports which renderer aTPdfRendererPreferenceselects for a given PDFium build, withprpDefaultresolving to Skia for Skia-enabled runtimes and to AGG otherwise
Fixed
- Enabling
BrotliEnabledorIsolatePerDocumentinConfigurePdfLibraryno longer switches rendering from Skia to AGG when the renderer preference is left atprpDefault; the bundled Skia-enabled runtimes now keep their default renderer, so page output no longer changes with these unrelated options
Version 3.122.2
Fixed
- Free Pascal and Lazarus builds now pass file names and passwords to PDFium as UTF-8 in every load path (file, memory, custom stream and progressive loading), so documents in folders with Chinese, Japanese or other non-ASCII names, and encrypted documents with non-ASCII passwords, open even when the program does not use the Lazarus UTF-8 string mode
Version 3.122.1
Fixed
LastLoadReportis now replaced on every failed load: a failedActive:= True, which leaves the component inactive without raising, and failed plainLoadDocumentorLoadCustomDocumentcalls reportplsFailedwith the error text, so batch code reusing oneTPdfno longer sees the previous file reported as loaded- The
Activehelp page now describes the actual failure behaviour (no exception, component stays inactive, details inLastLoadReport) and thatFileNamecan only be changed while the component is inactive
Version 3.122.0
Added
EPdfAssocFilesErrorinFPdfAssocFilesreports whyInjectAssociateFilescould not inject: no readable trailer or catalog in the source, or aTargetPagethat is negative or names a page that does not exist; the destination stream is left unmodified
Changed
SaveAsWithAssociateFilesandSaveAsWithAssociateFilesToStreamnow raiseEPdfErrorwhenTAssocFilesOptions.TargetPageis outside0..PageCount; such values were previously attached to the document catalog instead, contrary to the documented behaviour
Fixed
SaveAsWithAssociateFilesandSaveAsWithAssociateFilesToStreamnow returnFalsewhen the saved document cannot be parsed for injection, instead of writing it unchanged and returningTruewithout the requested filesSaveAsWithAssociateFilesno longer truncates an existing target file before the output has been produced; a rejected or failed save leaves the file untouched
Version 3.121.4
Fixed
- Page-level associated files (
TAssocFilesOptions.TargetPage) now attach to the page at that position in the document page order; files could previously land on a different page when page objects were stored in the file in a different order than they are displayed, for example after pages were reordered or inserted
Version 3.121.3
Fixed
- Associated files saved with
SaveAsWithAssociateFilesnow keep Chinese, Japanese and other non-ASCII file names and descriptions intact:/UFand/Descare written as Unicode PDF text strings instead of being converted through the system ANSI code page (Delphi) or emitted as raw UTF-8 bytes (Free Pascal) - The legacy
/Ffile name is now always portable printable ASCII, with non-ASCII characters replaced by_, so readers that decode/Fwith their own code page no longer show mojibake
Version 3.121.2
Fixed
- Associated files now encode MIME types as valid PDF names, so values such as
text/plainno longer produce malformed embedded-file dictionaries or prevent PDF/A-3 validation
Version 3.121.1
Fixed
- Reading an annotation and writing back changes no longer creates empty rollover and down appearance streams when those streams are absent, preserving PDF/A annotation appearance requirements
Version 3.121.0
Added
- OpenSSL CMS verification can retrieve HTTP(S) AIA intermediate certificates and CRLs when
OnlineRetrievalis enabled, with shared timeout, request and response-size limits; downloaded certificates remain untrusted until the configured trust chain validates them - Online retrieval uses WinHTTP on Windows and available libcurl on FPC Unix, preserves HTTPS certificate validation, and exposes unsupported transport configurations through the existing capability diagnostics
Fixed
- Classic cross-reference rebuilding allocates its output table once and fills object slots directly, avoiding quadratic work for large sparse object numbers while retaining parser resource limits and the latest object generations
- PDF/X-1a output requires a structurally valid ICC v2 CMYK printer profile instead of silently embedding the default RGB profile; invalid profiles fail before an existing destination file is opened for replacement
- PDF/X-1a validation checks the embedded profile and its four-component declaration, and preflight reports identify invalid output profiles; default output-condition labels follow the supplied profile while explicit caller labels are preserved
Version 3.120.4
Fixed
- The table extraction demo batch mode processes every PDF in the folder again: the shared document instance stayed active across files, so the second and later files raised an assignment error and were reported as failed; each document now gets its own instance in the Delphi, Lazarus and C++Builder editions
- The watermark demo sample document keeps its pages in creation order (1, 2, 3, 4) instead of rotating the first page to the end through an insert-at-index call
- The XFA and XFDF demos report a failed document open as a message instead of an unhandled exception, the attachments demo can start a new document while one is already loaded, and the Lazarus viewer frees the bitmap it saves
- The Delphi print demo now applies the orientation, duplex, grayscale, quality and DPI controls to the print job, honors the copies chosen in the print dialog, skips pages that fail to render, and restores the preview after printing
- Interactive demos whose loader swallows open failures no longer show a misleading loaded state, extraction output files carry a UTF-8 BOM, the CJK and RTL console demos switch the console to UTF-8 before printing extracted text, and the confidence input parses decimals independently of the system locale
- The PAdES timestamp test now really asserts that the validator reaches level B-T after signature timestamp injection, with a self-consistent ByteRange test document
- API coverage and PDF/A tests no longer treat any load failure as an environment skip when pdfium.dll is loaded, and a new regression test covers decrypting documents whose string values are serialized as literal strings by third-party writers
Version 3.120.3
Fixed
EncryptDocumentBytesno longer drops every base-revision object when the source PDF was saved incrementally: the classic cross-reference chain is now walked through/Prevnewest-first with newer entries winning, the source is rejected when already encrypted, astreamkeyword must close a dictionary before it is treated as stream data, and the final object's extent is bounded by the source xref instead of the firstendobjinside its bytes- Encrypted documents whose string values are serialized as literal strings, produced by third-party writers, now decrypt instead of failing with an authentication error
- PDF/E marker injection no longer numbers the synthesized Info dictionary identically to the embedded ICC profile stream when the source trailer has no
/Info, which made the incremental xref point/DestOutputProfileat the wrong object - PDF/X validation compares the XMP
pdfxid:GTS_PDFXVersionvalue trimmed of surrounding white space, so legally padded element-form XMP no longer reports a false Info mismatch - PDF/UA validation recognizes attribute-form
pdfuaid:partXMP, expands object streams before its byte scans like the sibling standards validators, checks the encryption/Pbit for cross-reference-stream documents too, and requires a non-emptydc:titlevalue; marker injection no longer emits an empty title entry - PDF/VT marker injection no longer collects and rewrites every page object twice when the source carries a broken DPart hierarchy that failed validation after the page list was already filled
- Signing at PAdES level B-T or higher without a
TsaUrlnow raises instead of silently producing a B-B signature, and the B-LTA document time-stamp derives its own nonce instead of re-sending the caller's - CMS signature-time-stamp injection rejects multi-signer input instead of silently dropping every SignerInfo after the first, SignedData version becomes 3 with a subjectKeyIdentifier sid,
certReq FALSEis omitted from timestamp requests per DER, and a WinHTTP transport failure mid-body is reported as a transport error instead of a truncated DER body - System font embedding resolves the actual TrueType Collection face for the requested family and extracts it as a standalone font, so requesting a non-first face of a
.ttc(for example NSimSun) no longer embeds and renders face 0 BuildToUnicodeCMappairs glyphs with surrogate-pair characters correctly and emits supplementary mappings as bfchar entries, instead of shifting every entry after the first astral character- Shaped text, CID text and OCR insertion check the page-insert result before recording the object for rollback, so a failed insert can no longer leave a dangling handle that would be destroyed twice
- Stream keyword detection in the compressor and the ToUnicode repair accepts the lone CR line ending permitted by ISO 32000-1 7.3.8.1
Changed
- The trial Win64x C++Builder package build removes a stale COFF
PDFiumPas.libleft by a previous full build so the two import-library flavors cannot ship together, the FULL installer excludes local-only development files (packagefiles.xml, status documents) from its catch-all, and post-install demo builds pin the IDE root through thePDFiumPas_BDS_ROOTvariable the build scripts actually read
Version 3.120.2
Fixed
- Text placed with
AddText,SetText, layout generation and the OCR search layer now extracts with its exact code points from the live document as well as after a save: spaces no longer come back as U+00A0 and hyphens no longer as U+00AD under the current PDFium build - System fonts are embedded as CID fonts keyed by code point, with one CID per Unicode character and an explicit
CIDToGIDMap, so a glyph shared by several characters (space and no-break space, hyphen and soft hyphen, Omega and Ohm sign) round-trips each of them faithfully in any viewer; fonts without a Unicode cmap subtable keep the previous embedding path
Version 3.120.1
Fixed
- Documents saved with subset fonts no longer corrupt their extracted text on reload: the ToUnicode CMap that pdfium serialises could map one CID to two different code points (spaces as U+00A0, hyphens as U+00AD), and every full save now repairs those contradictory mappings in place while leaving the CMap structure byte-identical, so the PDFium reader, MuPDF and qpdf all extract the original characters
- Incremental saves, sparse updates and cross-reference-stream documents are never rewritten by the repair and pass through unchanged; files without a contradictory mapping are copied byte for byte
- The committed
sample.pdftest fixture was regenerated through the repaired save path, and the load-policy tests now locate xref entries dynamically instead of hard-coding fixture offsets
Version 3.120.0
Added
- Bookmarks report their outline text style:
TBookmark.Stylecarries the italic and bold flags read through the newFPDFBookmark_GetStylebinding, andBookmarkStyleFeaturesAvailabletells whether the loaded pdfium.dll exports it - Attachments expose their PDF 2.0 associated-file relationship:
AttachmentRelationship[], theRelationshipfield ofTPdfAttachmentMetadataand ofTPdfAnnotationAttachmentread the/AFRelationshipname through the newFPDFAttachment_GetAFRelationshipbinding, guarded byAttachmentRelationshipFeaturesAvailable GetObjectRenderedStrokePatternrasterises the tiling pattern a path object strokes with into a caller-owned bitmap through the newFPDFPageObj_GetRenderedStrokePatternbinding;StrokePatternRenderingFeaturesAvailablereports the exportTPdfLibraryConfiguration.IsolatePerDocumentmaps to theFPDF_LIBRARY_CONFIGversion 7m_IsolatePerDocumentflag so V8 builds can give every document its own isolate;ConfigurePdfLibraryrejects the flag together with an explicitV8Isolate
Changed
- All 476 public exports of the current PDFium headers are bound; the three new entry points load tolerantly so older pdfium.dll deployments keep working with the corresponding features reporting empty or
nilresults
Version 3.119.1
Fixed
- Windows offline trust validation also restricts revocation retrieval to cached data, preventing implicit CRL or OCSP network requests when online retrieval is disabled
- Windows revocation failures preserve the independent chain-trust error and expose revocation reasons and native diagnostics to PAdES results and evidence reports
Version 3.119.0
Added
- PAdES trust validation and evidence reports expose separate revocation reasons and native errors for document signatures and timestamps, including JSON fields and appended CSV columns
Version 3.118.0
Added
- CMS verification results expose
RevocationReasonandRevocationError, with OpenSSL diagnostics for expired, unavailable and invalid local CRLs
Fixed
- OpenSSL reports explicitly revoked certificates as invalid when chain trust succeeds and local CRL verification confirms revocation, while preserving separate signature and trust results
Version 3.117.1
Fixed
- Explicit-version saves accept valid multipage forms with predictor-compressed cross-reference streams instead of incorrectly reporting a malformed cross-reference section
Version 3.117.0
Added
- Table detection reads borders and shading drawn as filled rectangles: a filled box no thicker than the new
MaxRulingThicknessbecomes a ruling and a larger filled box contributes its edges, so tables exported from Word, Google Docs, and browsers are now found as ruled grids with merged caption rows instead of whitespace fragments.DetectFilledRulingsswitches the behaviour off - Ruling coordinates snap within
RulingSnapTolerancebefore grids are assembled, which joins per-cell border pieces, double borders, and shaded cells separated by a small gutter into one table - Rulings inside form XObjects take part in detection through the combined object matrices, controlled by
IncludeFormXObjects ExtractDocumentTableslinks continuation fragments that end where the page content ends and resume where the next page's content starts, not only fragments that touch the page edges, and keeps a single spilled row as part of its chain- TableExtractionLab exposes
DetectFilledRulingsin its options panel in the Delphi, Lazarus, and C++Builder variants
Changed
- Whitespace detection ignores words that already belong to a ruled grid and requires every column boundary to be a text-free corridor across the rows it separates, so justified paragraphs and bullet lists are no longer reported as tables
- A continuation candidate whose first row is one cell across the full width is treated as a new captioned table rather than the rest of the previous one
MinRowsaccepts 1 for ruled grids; whitespace detection keeps its two-row floor, and the defaultMaxRulingSegmentsbudget rises to 16384 because per-cell border boxes arrive in far greater numbers than stroked grid lines- Cell text is assembled line by line from overlapping word boxes, so words whose glyph boxes differ in height keep their left-to-right order
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata report 3.117.0
Version 3.116.4
Added
- TableExtractionLab gains folder batch processing:
Batch folderrunsExtractDocumentTablesover every PDF in a selected folder, lists per-document table counts, marks documents without a text layer for OCR, and keeps damaged or locked files from aborting the run Export all CSVwrites every detected table as<document>-<n>-page<p>-t<i>.csvunder atablessubfolder for batch runs, or beside the loaded document for a single file- A detection preset picker exposes tuned
TPdfTableExtractionOptions: Default, Compact columns (MinColumnGap4 withAlignmentTolerance5 for tight word-processor exports), and Compact + wide rows (MaxRowGapFactor6 for 1.5-2x line spacing) - Documents that yield no table under the Default preset are retried once with Compact columns in both single-document and batch extraction, and batch rows report which preset produced the result
Fixed
- Batch extraction opens each document in its own
TPdfinstance instead of reloading one shared component, which removes silent load failures that surfaced as inactive-component errors partway through a folder run
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata report 3.116.4
Version 3.116.3
Changed
- The TableExtractionLab sample in all three toolchains now writes its generated sample document to
TableExtractionSample.pdfbeside the demo executable instead of keeping it in memory only; when the folder is not writable the lab falls back to the previous in-memory behaviour and reports it in the status line TPdf.AboutInfo, Lazarus package metadata, and installer metadata report 3.116.3
Version 3.116.2
Fixed
- The library stopped compiling on older Delphi releases. The 64-bit tick helper and the trusted-list and production XML codecs called
GetTickCount64andCP_UTF8from RTL units that only newer compilers carry them in, the reflow HTML writer embedded a CSS string literal past the 255-element cap those compilers impose on a single literal, and the XFA datasets merge assigned betweenTBytesand a plain dynamic array field, which pre-XE7 compilers reject. Older compilers now bindGetTickCount64from kernel32 and declareCP_UTF8locally when the RTL does not, the style sheet ships as concatenated short literals, and the packet payload is copied element-wise
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata report 3.116.2
Version 3.116.1
Added
Demo\Delphi\TableExtractionLab,Demo\CBuilder\TableExtractionLab, andDemo\Lazarus\TableExtractionLabturn table detection into a single workflow. The lab builds a sample document with a ruled table carrying merged header cells, a whitespace-aligned table without ruling, and a long table that breaks across a page boundary, then runsExtractTablesorExtractDocumentTablesand lists rows, columns, spans, header flags, detection mode, confidence, and continuation groups- The lab exports the selected table through
TPdfTable.ToCsvandTPdfTable.ToJson, editsDetectRuledTables,DetectWhitespaceTables,DetectContinuations, andMinConfidencefrom the options panel, and copies the full report to the clipboard TPdf.AboutInfo, Lazarus package metadata, and installer version metadata report 3.116.1
Version 3.114.21
Fixed
- PDF/A validation reported an external file reference on any document containing an annotation. ISO 19005-1 §6.1.7 forbids
/F,/FFilterand/FDecodeParmsin a stream object dictionary, but the check searched the whole file for those names, and/Fis also the annotation flags key that §6.5.3 requires every annotation to carry. The check now looks only inside stream object dictionaries
Version 3.114.20
Fixed
- RSASSA-PSS signatures carried malformed algorithm parameters on all three signing backends. RFC 4055 tags all four fields of RSASSA-PSS-params; the salt length was written as a bare integer, which a parser reads as the start of a different field, and the trailer field was written out although its value equals the default that DER requires be omitted. A verifier either failed to parse the parameters or fell back to the default 20-byte salt while the signature used 32, so PSS signatures were rejected. PKCS#1 v1.5 and ECDSA signatures were unaffected
Version 3.114.19
Fixed
- Asking for a timestamp under a digest other than SHA-256 built a request that declared that algorithm while carrying a SHA-256 digest, which a timestamp authority either rejects or, worse, timestamps as given. Only SHA-256 is computed, so any other identifier is now refused outright; an empty identifier still selects the SHA-256 default. The PDF Viewer sample for Lazarus and C++Builder also bound a bookmark-expansion handler its form file names but its code did not define, which fails when the form is loaded; the handler is ported from the Delphi sample
Version 3.114.18
Fixed
- The XFA Lab and XFDF Lab samples for Delphi, and the XFA Lab sample for Lazarus, failed at startup. Each builds its controls from its form's create handler, but the form resource was neither present nor linked, so creating the main form raised a resource-not-found error and the handler never ran. All three now carry the form file and the directive that embeds it
Version 3.114.17
Fixed
- Two native resources were mishandled when an operation failed part way. A failing thumbnail render freed the target bitmap before closing the native render, and when the render was drawing straight into that bitmap's own pixels the teardown then read memory that had already been released. A failing bitmap allocation in
AddBitmapleft the image object it had just created with no owner and no way to reach it again
Version 3.114.16
Fixed
- Reading FDF text produced the wrong characters above
0x7E. The PDFDocEncoding table in ISO 32000-1 Annex D.2 begins at0x80with the bullet, but the mapping started it at0x7F, so the whole block through0x9Fwas shifted by one place: a dagger read as a bullet, an em dash as an ellipsis, and so on down to zcaron, which fell off the end entirely. The Euro at0xA0was also missing and came back as a no-break space. Field names and values in imported FDF now decode correctly
Version 3.114.15
Fixed
- Validating trust on a document whose trailer or catalog cannot be read wrote past the end of an array. The compliance pass gives up without recording any signatures in that case, while the collector that runs next works straight off the byte stream and can still find signature dictionaries, so one entry was written per dictionary found into an array holding none. The count is now clamped to what the compliance pass produced
Version 3.114.14
Fixed
- Executing a PDF/A repair plan applied steps the planner had blocked. A step is blocked when the document carries signatures, the step would invalidate them, and the caller did not permit that; the executor only tested the step's safety level, which does not express the condition, so a signed document could have its signatures invalidated by an automatic repair the plan had already refused. Blocked steps are now skipped and counted as skipped
Version 3.114.13
Fixed
- Adding a signature timestamp to a CMS value whose certificate set was larger than 127 bytes, which is every real certificate, corrupted the result. The helper that locates the start of a nested structure walked backwards over the length octets and mistook the last one for the first, so the slice it cut began well before the structure it was asked for. The header length is now derived from the content length, which DER states unambiguously. Self-checks missed it because their fixture certificates were small enough to use the short form
Version 3.114.12
Fixed
- Signed attributes were emitted in the order they were built rather than sorted by their encodings, which X.690 §11.6 requires of a DER SET OF. A verifier that re-encodes the attribute set before digesting it, as OpenSSL and BouncyCastle both do, therefore computed a different digest and reported a sound PAdES signature as invalid. Signatures this library produces now verify in those stacks; validation through the Windows layer was unaffected because it digests the bytes as received
Version 3.114.11
Fixed
- A negative DER INTEGER wider than two content bytes was encoded with the wrong value. The writer emulates an arithmetic shift by re-injecting the sign after a logical shift, but the mask it used set every bit above the low byte instead of only the byte the shift had vacated, so the magnitude still held in the remaining bytes was overwritten. The value -100000 encoded as -34464, for instance. Timestamp request nonces and any other signed integer of that size now encode correctly
Version 3.114.10
Fixed
- PDF/A validation never reported the constant alpha part of the transparency rule in ISO 19005-1 §6.4. The helper builds its search key by prefixing a solidus, and the caller passed one too, so it looked for
//CAand matched nothing. Both alpha checks also accepted only the exact texts1and1.0, which flagged a fully opaque/CA 1.00as a violation; a value of one is now recognised whatever its spelling
Version 3.114.9
Fixed
- The page-level URI action returned mangled text. The path comes back from the native layer as UTF-8 bytes and was written straight into a wide string, which pairs the bytes into 16-bit code units and leaves the rest of the buffer holding whatever memory was there.
GetPageActionURInow decodes the bytes the same way the document-level action path already did
Version 3.114.8
Security
- On targets other than Windows the random bytes behind every encryption key, salt and initialisation vector came from the runtime PRNG, whose seed is a constant unless the program calls
Randomize. Every process therefore produced the same file encryption key, the same/UEand/OEsalts, the same/Permsbytes and the same AES-GCM nonces, which makes encrypted output from a Free Pascal build on Linux or macOS trivially recoverable and repeats a GCM nonce under a fixed key. The bytes now come from/dev/urandom, and an unavailable kernel pool raises rather than falling back, the way an unavailableCryptGenRandomalready did on Windows
Version 3.114.7
Fixed
- A malformed object stream could make the compression and repair entry points read past the end of the decoded buffer. The member offsets a stream declares are now checked for range and ascending order as soon as the header is parsed, a declared member count larger than the header can hold is rejected before any memory is reserved, and the byte range of each member is validated before its trailing whitespace is trimmed rather than after
Version 3.114.6
Fixed
- Externalising inline images produced an unusable image XObject. The dictionary was written with a stray solidus before its first key, which opened an empty name and shifted every key onto the previous key's value, and the inline abbreviation table mapped Decode to
Ginstead ofD, so a/Darray was dropped and the DeviceGray value abbreviation was mistaken for a key. Images lifted out of a content stream now carry a well-formed dictionary and keep their Decode array
Version 3.114.5
Fixed
- The HarfBuzz shaper assigned cluster lengths to the wrong glyphs in right-to-left runs and gave glyphs that share a cluster, such as marks and ligature components, a length of one. Each glyph's
ClusterLengthnow spans from its cluster start to the next cluster in logical order, in either direction, so character-to-glyph mapping for Arabic and Hebrew text matches what the Uniscribe backend reports
Version 3.114.4
Fixed
- The libcurl timestamp transport passed its numeric options and read the HTTP status code as 32-bit values, while libcurl takes and returns a C
long, which is 64 bits on Linux and macOS. The status query could overwrite the four bytes next to its target on the stack, and option values depended on whatever the upper half of the register held. Both now use the platformlongwidth, soFPdfTsaFpcis sound on LP64 targets
Version 3.114.3
Fixed
- The PKCS#11 backend copied the raw bytes of a token object label straight into a string, which on Delphi lands UTF-8 bytes on UTF-16 code units. A certificate selected through
TPdfPkcs11Options.CertificateLabelcould therefore never match, andEnumerateCertificatesreported garbledLabelText. Labels are now decoded as the UTF-8 the standard defines, and the PIN handed toC_Loginis encoded as UTF-8 rather than narrowed through the host codepage, so a non-ASCII PIN reaches the token intact
Version 3.114.2
Fixed
- The macOS Keychain signer asked
SecKeyIsAlgorithmSupportedabout the wrong operation when deciding whether a key accepts RSASSA-PSS: the query named the decrypt operation instead of sign, so the answer was always no and every RSA signature silently fell back to PKCS#1 v1.5. A key that supports PSS now signs with PSS asTPadesSignerOptions.PaddingSchemerequests, and the operation argument is passed at the width the framework declares
Version 3.114.1
Fixed
- Nested bracket pairs in right-to-left text resolved to the wrong direction. UAX #9 rule BD16 processes pairs in the order their opening brackets appear, and a pair resolved by N0 becomes the preceding strong context for a pair that opens after it; the pairs were being processed in the order their closing brackets completed them instead, so an inner pair could follow the letter it encloses rather than the context the outer pair established. Text such as an Arabic or Hebrew sentence containing a parenthetical with a nested bracket now lays out the way a reader expects
Version 3.114.0
Added
FPdfCryptoSslverifies PDF signatures and timestamp tokens through OpenSSL, which closes the last platform gap in signature validation: Linux had no CMS verification backend at all.ConfigureSslCmsVerifierinstalls it, libcrypto is resolved by name at run time so nothing is linked against it, and both the 1.1 and 3.x series bind- The signature and the certificate chain are evaluated in separate passes, so a sound signature under a chain that does not reach a trust anchor is reported as a valid signature with invalid trust rather than as a broken signature
ConfigureSslTrustAnchorsadds DER trust anchors to the system store, andConfigureSslCrlssupplies the CRLs a revocation check may consult. Revocation counts as checked only when a CRL is actually present, because OpenSSL fetches none by itself; with none supplied the result says unsupported instead of passing an unchecked chainSslAvailable,SslMissingSymbols,SslLibraryPath,SslLibraryVersionandSslAbiLayoutreport what bound and what did not, andConfigureSslLibraryPathpoints the backend at a specific library when the platform defaults do not find one
Version 3.113.0
Added
TPdfKeychainCmsVerifierverifies PDF signatures and timestamp tokens on macOS throughCMSDecoderand SecTrust, so signature validation is no longer Windows-only.ConfigureKeychainCmsVerifierinstalls it, and the same unit now covers both halves of macOS support the wayFPdfCryptoWindoes for Windows- Revocation checking is honoured: when requested, a revocation policy joins the basic X.509 one, and turning off online retrieval restricts the evaluation to cached responses. Progress checkpoints fire for the signature, chain, online retrieval and revocation stages exactly as the Windows backend reports them
KeychainVerificationAvailablereports verification support separately from signing, since the two need different framework symbols and one can be present without the other
Version 3.112.0
Added
FPdfCryptoMacsigns PAdES with a macOS Keychain identity, the counterpart of the Windows certificate store: the certificate and its private key come from the Keychain and the signature is produced bySecKeyCreateSignature, so the key never leaves the system keystore.ConfigureKeychainSignerProviderinstalls it, and no module has to be deployed alongside the application as a PKCS#11 token backend would need- The signer follows the certificate: an EC key signs ECDSA, an RSA key signs RSASSA-PSS, and where PSS is unavailable - an older macOS, or a key that will not accept it - the padding falls back to PKCS#1 v1.5 and the emitted AlgorithmIdentifier says so rather than claiming PSS
KeychainMissingSymbolslists any framework symbol that failed to resolve, so a deployment that reports the backend unavailable can tell an absent framework from a name this binding got wrong
Version 3.111.0
Added
ConfigurePadesCmsVerifierinstalls the CMS verification backend the PAdES validator uses, so signature and timestamp verification is no longer tied to Windows.IPdfCmsVerifierdeclares the two operations a backend answers - detached for a PDF signature, attached for a timestamp token - andPadesCmsVerificationAvailablereports whether any backend is present
Changed
- The verification result and option records moved to
FPdfCryptoasTPdfCmsVerify*. TheTWinCmsVerify*names remain as aliases, so existing code keeps working and a plugged-in backend speaks the same types as the Windows one - Windows behaviour is unchanged: with no verifier installed it still uses CryptoAPI, and the progress checkpoints, revocation options and native error codes are the same. Where no backend answers, every verdict reports unsupported rather than being left unchecked
Version 3.110.0
Added
FPdfPkcs11signs PAdES with a key that stays inside a PKCS#11 token.ConfigurePkcs11SignerProviderinstalls it as the signing backend, the module is loaded at run time by path so nothing is linked, and the same code serves Windows, Linux and macOS. The token enumeration theIPdfPkcs11SignerProviderinterface declares is implemented alongside it: slots, tokens and the certificates each one holds- Signing off Windows no longer needs a host-supplied provider for the common case: a token module plus
TPdfPkcs11Optionsis enough. RSA PKCS#1 v1.5, RSASSA-PSS and ECDSA are all produced through the token FPdfSha1adds SHA-1 for one purpose, matching a certificate by the thumbprintTPadesSignerOptionscarries. Windows resolved that inside the certificate store; a token hands back certificate bytes and leaves the matching to the caller. It is not a signing digest and the PAdES stack continues to sign SHA-256 throughout
Changed
- The certificate DER helpers that read a public-key algorithm OID, extract issuer and serial, and rewrap a raw ECDSA signature moved from the Windows backend to
FPdfCms, where every signing backend can reach them
Version 3.109.0
Changed
- The native library loader is no longer Windows-only.
LibraryNamedefaults topdfium.dll,libpdfium.soorlibpdfium.dylibfor the target, the V8 build is looked for under the matching name, and loading and symbol binding go through the portable loader on Free Pascal. Windows behaviour is unchanged, including the Win32 and Win64 deployment layout and the architecture-mismatch diagnostic - Deployment directories on other targets follow the
<cpu>-<os>spelling the compiled units already use, soDLLs/x86_64-linux/libpdfium.sosits besideLib/FPC/x86_64-linux. The system-directory fallback stays Windows-only; elsewhere the loader search path covers it
Version 3.108.0
Added
TPdfHarfBuzzTextShapershapes bidirectional and complex-script text on Free Pascal targets that have no Uniscribe. It resolves the embedding levels withFPdfBidi, segments runs by script, shapes each run with libharfbuzz and places the runs in visual order. Install it withConfigureTextShaper; libharfbuzz is resolved at run time andHarfBuzzAvailablereports honestly when it is missing- The shaper does not enumerate fonts. Uniscribe reads the font binary out of a device context, which has no portable equivalent, so the host passes a
TPdfFontDataResolverthat maps a font name to the font file bytes and keeps that policy where it belongs
Version 3.107.0
Added
FPdfBidiimplements the Unicode Bidirectional Algorithm (UAX #9) in pure Pascal:PdfResolveBidiLevelsreturns one embedding level per UTF-16 code unit,PdfBidiVisualOrderapplies the L2 reordering, andPdfBidiClassOfexposes the Bidi_Class of a code point. Rules P2-P3, X1-X10, W1-W7, N0-N2, I1-I2 and L1-L2 are covered, including isolate initiators and BD16 bracket pairs- The unit is compiler and platform neutral, which is what lets bidirectional text be laid out where Uniscribe is not available. A shaping engine resolves glyphs for a run whose direction is already known, so this is the piece that has to decide the direction first
Version 3.106.0
Added
ConfigureTextShaperinstalls the text shaping backend the whole library routes through, withActiveTextShaper,ActiveTextShaperNameandClearTextShaperalongside it. BothShapePdfTextandTPdf.AddShapedTextnow use the installed shaper instead of creating a Uniscribe one directly, so a host can supply its own engine and a test can supply a deterministic one
Changed
FPdfTextShapingcompiles on targets other than Windows: the Uniscribe backend is now the platform default rather than the only implementation, and it is confined to the Windows build. Where no backend is available the shaping entry points report that instead of failing to compile
Version 3.105.1
Security
- A timestamp response is now bounded at 4 MB on both transports. A TSA that kept sending could previously grow the receive buffer without limit, turning a signing call into unbounded memory growth
Version 3.105.0
Added
- RFC 3161 timestamping works on Free Pascal targets other than Windows: the new libcurl backend posts the TimeStampReq and reads the TimeStampResp, so
PadesTsaAvailablereports True and PAdES B-T, B-LT and B-LTA can obtain tokens there. libcurl is resolved at run time and is not a build-time dependency; when it is absent the backend reports unavailable exactly as the WinHttp one does. Windows keeps using WinHttp and is unaffected - Signing on those targets still needs key material the library does not own: supply it through
ConfigurePadesSignerProviderwith anIPadesSignerProvider(orIPdfPkcs11SignerProviderfor token-backed keys), sinceFPdfCryptoWinis Windows-only
Version 3.104.1
Added
- The XFA inspection lab sample is now available for Lazarus as well, so the XFA capability probes, packet listing, packet export and the
OnXfaRuntimeMissingfallback can be exercised from the LCL build
Version 3.104.0
Changed
- The library compiles clean of avoidable diagnostics on Free Pascal 3.2: internal timing reads the millisecond tick from
GetTickCount64instead of the deprecated 32-bit call, the deprecated SSE control-word accessors are replaced byGetMXCSRandSetMXCSR, the content fingerprint offset basis is typed explicitly so it no longer trips a compile-time range check, and scanline addresses are compared as unsigned pointers when a bitmap is checked for top-down layout
Version 3.103.1
Fixed
- Document metadata carried into XMP keeps its non-ASCII characters on Free Pascal: titles, authors, subjects, keywords and creator names reaching
SaveAsPdfA,SaveAsPdfUa,SaveAsPdfE,SaveAsPdfX,SaveAsPdfRandSaveAsPdfVTare now converted through the string codepage instead of being copied byte for byte, so the metadata packet stays valid UTF-8 as ISO 19005-1 6.7.2 requires even when the host program does not run on a UTF-8 codepage - XFDF export, production metadata round-trips and trusted-list XML parsing use the same codepage-correct conversion, so text moving between
TBytesandstringno longer depends on the host codepage
Version 3.103.0
Added
TPdfEuropeanTrustedListparses authenticated European trusted lists, reloads checksummed caches through the same authenticator, accepts caller-supplied update sources, exposes current trust anchors, and evaluates qualified signature services at a requested validation timeTPadesTrustValidationOptions.QualifiedTrustEvaluatorapplies an offline qualified-trust policy to each validated signer without adding network access to the PAdES validator
Version 3.102.0
Added
BeginIncrementalSaveandCommitIncrementalSavenow append authenticated revisions to AES-256 encrypted documents while preserving the original/Encryptreference, security parameters, exact object generations, and prior bytes
Changed
- The file commit overload now durably flushes and strictly reopens a same-directory side file, verifies its revision boundary, and atomically replaces the target while rolling the session back after any failure
Version 3.101.0
Changed
SaveAsRedactednow preserves safe portions of partially intersecting text, rectangular paths, and axis-aligned images, then removes resource names no longer referenced by page, Form XObject, pattern, appearance, and nested resource scopes
Version 3.100.0
Changed
OptimizeImagesnow selects box, bilinear, bicubic, Lanczos, or bilevel resampling from scale, content class, measured detail, and caller quality, with alpha-aware filtering and a strict working-memory budget
Version 3.99.0
Added
GraftPdfAcroFormimports hierarchical AcroForm fields, widgets, appearances, calculation order, default resources, actions, and values through explicit page mappings and collision policiesTPdfCrossDocumentGraftMapreuses imported indirect objects by source identity while preserving cycles, shared references, exact source generations, and transactional failure semantics
Version 3.98.0
Added
TPdfOutlineEditorcreates, moves, deletes, styles, expands, and retargets outline items, remaps explicit destinations through page-plan results, and appends an independently verified incremental revision
Version 3.97.0
Added
TPdfTreeEditorreads, validates, updates, balances, splits, merges, serializes, and incrementally saves arbitrary PDF NameTree and NumberTree structures while preserving reusable indirect references and raw entry values
Version 3.96.0
Added
TPdfParserResourceBudgetprovides one thread-safe process policy for recursion, tokens, objects, decoded bytes, expansion ratio, allocation, and deadlines across custom PDF parsers, with immutable per-operation snapshots and configurable defaults
Version 3.95.0
Changed
ValidatePdfXnow validates active PDF/X dictionaries, metadata, output intents, fonts, prohibited features, transparency, colour spaces, and page boxes through bounded sparse reads on valid-xref unencrypted documents
Version 3.94.0
Changed
ValidatePdfRnow validates active PDF/R dictionaries, pages, image filters, metadata, and footer markers through bounded sparse and windowed reads on valid-xref unencrypted documents
Version 3.93.0
Changed
ValidatePdfEnow validates active PDF/E dictionaries, metadata, output intents, forms, and prohibited features through bounded sparse reads on valid-xref documents
Version 3.92.0
Changed
ValidatePdfVTnow performs advanced recurring-XObject scope, visibility, encapsulation, and nested Form usage analysis through bounded sparse reads on valid-xref documents
Version 3.91.0
Added
TPdfSparseDictionaryReadercan resolve the active generation of an object and decode a direct stream under a caller-supplied byte limit
Changed
ValidatePdfVTnow uses bounded sparse reads for PDF/VT metadata, DPart, OutputIntent, Info, page, and ordinary dictionary checks on the normal valid-xref path
Version 3.90.0
Added
TPdfSparseDictionaryReaderkeeps one sparse xref and object-stream index open for repeated bounded indirect-object dictionary reads
Changed
InjectPdfVTMarkersnow validates and preserves an existing PDF/VT DPart hierarchy with bounded source reads, while malformed hierarchies continue through the rebuilding fallback
Version 3.89.0
Added
ReadPdfSparsePageDictionariesreturns page object identities and bounded dictionary bytes in page-tree order through the sparse object index
Changed
InjectPdfVTMarkersnow synthesizes the PDF/VT DPart hierarchy and appends marker objects with bounded source reads when the saved PDF does not already contain a DPart hierarchy
Version 3.88.0
Added
ReadPdfSparseCatalogSubDictreads a direct or indirect catalog sub-dictionary through the sparse object index, used by PDF/UA marker injection forMarkInfoandViewerPreferences
Changed
InjectPdfUaMarkersnow resolves catalogMarkInfoandViewerPreferencesthrough sparse lookup and appends the PDF/UA revision with bounded source reads on the normal xref path
Version 3.87.0
Added
AppendPdfSparseUpdatestreams one sparse revision onto a saved PDF: source bytes verbatim, caller-supplied object bodies at recorded offsets, and a single incremental xref/trailer block chained through/PrevNormalizePageViewRectnormalizes two mapped page-space corners into the page-clamped visible rectangle, or reports that nothing of the page is visible- PDF/E marker injection synthesises a fresh Info object with
/ISO_PDFEVersionwhen the source document has no Info dictionary
Changed
- PDF/E, PDF/X, and PDF/R marker injection now resolves the catalog, Info, and trailer through sparse lookup and appends revisions through
AppendPdfSparseUpdatewith bounded source reads on the normal xref path - The form-fill
FFI_GetPageViewRectcallback now reports the part of the page actually visible in the attachedTPdfViewinstead of always the whole page box, falling back to the page dimensions for headless documents TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.87.0 consistently
Fixed
- Path segment control points exposed since the
FPDFPath_GetBezierControlPointsbinding were never populated: the native export only answers for the endpoint index of each three-entry cubic, so the query now happens once per curve and all three entries carry the curve's control points
Version 3.86.0
Added
ReadPdfSparseRevisionInfoexposes bounded latest-revision, catalog, encryption, document ID, and tagged-structure facts for stream postprocessorsComposePdfSparseUpdateIdpreserves or derives incremental-update document identifiers without materialising the complete source PDF
Changed
InjectPdfAMarkersnow resolves the catalog and trailer through sparse lookup, copies large inputs in bounded chunks, and appends the PDF/A revision without allocating a source-sized byte array on the normal xref path- PDF/A marker injection preserves classic or xref-stream output style, catalog and Info generations, trailer identifiers, encryption refusal behaviour, and Level A downgrade rules
Version 3.85.0
Added
SanitiseActiveContentPdfStreamaccepts a caller-owned prune workspace for custom bounded or disk-backed storage
Changed
- Active-content sanitisation now updates the catalog and trailer through sparse lookup, bounded parser windows, and fixed-size range copying instead of reading the complete PDF into one byte array on the normal xref path
TPdf.SaveAsSanitisedappliesSaveMemoryLimitandSaveTemporaryDirectoryto its pruning workspace and reports its spill diagnostics
Fixed
StripMetadata=Truenow removes a trailer/Inforeference even when the catalog has no/Metadataentry
Version 3.84.0
Changed
TPdf.PdfVersionnow reuses PDFium parser state throughFPDF_GetFileVersioninstead of reparsing the complete source PDF- Version queries read at most the eight-byte PDF header to prevent a malformed catalog declaration from downgrading the effective version
Version 3.83.0
Changed
PageLabelledPdfStreamnow resolves and updates the catalog through bounded stream windows and the sparse lazy object index- Page-label output copies large source PDFs in fixed-size ranges instead of allocating a complete document byte array on the normal xref path
Version 3.82.0
Changed
ApplyDefaultOpenActionnow reads classic, xref-stream, hybrid, and object-stream revisions through a sparse lazy object index, including documents with very high object numbers- Default open-action processing uses fixed-size windows and bounded range copying instead of loading the complete PDF into one byte array
Version 3.81.0
Added
PostProcessSavedPdfaccepts three caller-owned seekable workspaces for custom memory ceilings and disk-backed processing
Changed
TPdf.SaveAsappliesSaveMemoryLimitandSaveTemporaryDirectoryto every saved-PDF post-processing workspace and includes their spills in diagnostics- Native incremental xref-stream repair uses fixed-size tail and dictionary windows with bounded range copying instead of whole-file byte arrays and repeated full-file reallocations
Version 3.80.0
Added
ReadAttachmentMetadatacaptures attachment names, descriptions, MIME subtypes, decoded sizes, and readability in one bounded native enumerationExtractAttachmentsToStreamswrites a batch to caller-owned streams with per-file and aggregate byte limits, configurable write chunks, cancellation, and per-item results
Changed
- Batch extraction retains at most one decoded attachment in PDFium Delphi Component memory instead of materialising every payload in the batch
Version 3.79.0
Added
TPdfCacheGovernor,TPdf.CacheBudgetBytes, per-kind usage queries, and telemetry coordinate retained cache memory through one thread-safe global LRU byte budgetTPdfTileCacheand the process-wide system-font cache can join a caller-selected governor with exact bitmap and font-byte accounting
Changed
- Parsed page scenes, thumbnails, structure data, text snapshots, and page-object snapshots now compete under a default 256 MiB
TPdfbudget while preserving their existing entry-count limits - Active page scenes remain pinned until rendering completes, and opaque native page scenes use an explicit estimated charge because PDFium exposes no configurable total-cache byte API
Version 3.78.0
Added
TPdfLayoutPagedPlan,TPdfLayoutDocument.BuildPagedPlan, andTPdf.GeneratePagedLayoutstream layout commands into caller-selected seekable storage and materialise one page at a time
Changed
- Large generated layouts can spill commands to temporary storage, retain a configurable LRU page cache, restore non-contiguous header and footer segments, and release wrapped text after each flow item
Version 3.77.0
Added
TPdfLayoutTable, rows, cells, and table options add cross-page tables with resolved grid tracks, captions, repeated header rows, splittable body rows, links, and configurable borders
Changed
- Generated tagged tables preserve one continuous Table / TR / TH / TD structure across pages, keep row-spanning groups atomic, and associate data cells with header IDs automatically
Version 3.76.0
Added
TPdfLayoutConstraintsandSetLastItemConstraintsadd keep-together, keep-with-next, physical page-break-before / after, and configurable widow / orphan line control to generated layouts
Changed
BuildPlanreuses each wrapped text result for pagination prediction and command emission, preventing keep-with-next from repeating text measurement
Version 3.75.0
Added
TPdf.InspectPdfUaUnicodeCoveragereports bounded object-level evidence for direct Unicode mappings,ActualTextreplacements, mapping errors, missing Unicode values, and unresolved source objects
Changed
TPdf.ValidatePdfUanow reuses a single object-scoped character scan that excludes Artifact and generated characters and prevents one text object'sActualTextfrom masking adjacent content
Version 3.74.0
Changed
ValidatePdfUaPageContentTaggingandTPdf.ValidatePdfUanow reportpvuaiArtifactInStructureTreewhen an Artifact page object is claimed by a structure-tree MCID, including path-based pagination artifacts- PDF/UA page-content scanning now short-circuits only after both untagged real content and invalid Artifact containment have been detected, preserving cross-page coverage without repeating completed checks
Version 3.73.0
Added
TPdf.InspectPdfUaLanguageCoveragereports bounded page-object and structure-string evidence for natural-language spans, including effective language, declaration source, MCID, structure index, and text excerptsResolvePdfUaEffectiveLanguageresolves marked-content, nearest structure-ancestor, and catalog language declarations with explicit validity evidence
Changed
TPdf.ValidatePdfUanow reportspvuaiNaturalLanguageUncoveredwhen non-artifact text or accessibility strings have no valid effective/Langdeclaration
Version 3.72.0
Added
TPdf.InspectPdfAMetadatareports typed per-field equivalence evidence for all eight ISO 19005-1 Info-to-XMP mappings, including explicit empty values and date parse failuresTPdf.NormalizePdfAMetadatarepairs only mismatched mapped XMP properties while preserving unrelated namespaces and non-default language alternatives
Changed
TPdf.ValidatePdfAnow reportspvaiInfoXmpValueMismatchwhen PDFium-decoded Info values differ from correctly typed XMP values after Unicode or timezone-aware date comparison
Version 3.71.0
Added
InspectPdfVT2sStreamreturns printing-condition evidence for every PDF/VT MIME part, including OutputIntent identity, embedded or MIME profile provenance, ICC hashes and header facts, and DPart page and record countsFPdfIccProfileprovides bounded ICC header and tag-table inspection with MD5, SHA-256, colour-space, version, device-class, profile-ID, and multilingual profile-description support
Changed
- PDF/VT-2s validation now resolves earlier ICC MIME attachments through
DestOutputProfileRefURL file specifications and validatesCheckSum,ICCVersion,ProfileCS,ProfileName, device class, and allowed process colour spaces - All PDF/VT parts now require one authoritative
GTS_PDFXOutputIntent, PDF/X-base-appropriate embedded or external profile packaging, and the same characterized printing condition, while PDF/X-only attachments remain outside PDF/VT comparisons - Single-file PDF/VT-2 validation now recognises
DestOutputProfileRefas an external destination profile instead of reporting it as missing
Version 3.70.0
Changed
- PDF/VT validation now checks
GTS_Scope,GTS_XID,GTS_Env, andGTS_Encapsulateddirectly on each XObject instead of allowing nearby or nested dictionaries to satisfy hint requirements Recordscope now resolvesRecordLevelfrom the indirectDPartRootdictionary, whileStreamscope is rejected in PDF/VT-1 files- Decoded page and Form XObject content streams now validate
Doresource visibility,SingleUseoccurrence counts, and recipient-record ownership through effective inherited resources and the DPart hierarchy - Encapsulated XObjects now validate boolean shape, recommended scope, Image
Intent, isolated transparency groups, blending colour spaces, and direct or nested optional-content dependencies
Version 3.69.0
Changed
- PAdES validation now rejects duplicate
Contents,ByteRange,SubFilter,Filter, andTypeentries instead of accepting the parser-selected value - Signature discovery now uses a stream-aware linear dictionary scan, recognizes escaped PDF name tokens, and cannot be redirected by a closed nested dictionary placed before the real
ByteRange - Signature
ByteRangevalidation now requires the excluded gap to match the direct hexadecimalContentstoken exactly while still allowing later incremental revisions - Signature dictionaries now require one name-valued
Filterand enforce consistentSigorDocTimeStamptype and subfilter combinations
Version 3.68.0
Added
TPdf.BuildPadesEvidenceReportcorrelates PDFium signature facts, CMS policy, trust and timestamp status, certificate-path hashes, DSS/VRI coverage, and later revision decisions for every signatureTPadesEvidenceReportexports bounded multi-signature evidence as JSON or CSV and reports source, signature, DSS, revision, and truncation telemetry
Changed
- PAdES trust validation now records SHA-256 identities for the signer certificate and ordered Windows certificate path while preserving offline validation by default
- Evidence generation reuses one retained source-byte capture across compliance, trust, DSS, and revision analysis instead of copying the original PDF into a new stream for each stage
Version 3.67.0
Added
TPadesSignatureFieldOptionscreates configurable signature field names, required seed values, reason and legal-attestation lists, acceptable signer certificates, and field locks- Local and remote signing can author approval or certification signatures with ISO 32000-1
FieldMDPandDocMDPtransforms
Changed
- Certification signatures preserve existing catalog permissions while registering the new signature through
/Perms /DocMDP
Version 3.66.0
Added
RenderPageBandedToStreamwrites PNG or TIFF output directly to a caller stream with configurable band height, PNG compression, and output byte limitsRenderPageBandedToEncoderfeeds sequential page bands to caller-defined codecs and returns band, row, memory, completion, and output telemetry
Fixed
RenderPageBandednow preserves full-page render geometry and clips each requested band instead of rescaling the complete page into every band
Version 3.65.0
Added
TPdfParallelRenderReportnow reports source size, peak captured memory, storage backend, and shared backing kind
Changed
RenderPagesParallelshares the captured source through immutable memory, a read-only file mapping, orFPDF_LoadCustomDocumentrandom access instead of allocating a second full-document byte array- Spilled parallel-render sources remain under
SaveMemoryLimitand no longer require reloading the complete PDF into addressable process memory
Version 3.64.0
Added
ImportImposednow has an overload returningTPdfImpositionExecutionReportwith native import, unique source, blank slot, XObject template, form object, content generation, and output page counts
Changed
- Zero-geometry imposition sends every ordered source page through one
FPDF_ImportPagesByIndexcall before blank insertion and native N-up composition - Custom-geometry imposition reuses one native XObject template per unique source page, reads cached page metrics without changing the source page, and preallocates exact plan storage
Version 3.63.0
Added
BeginPageObjectEditTransaction,CommitPageObjectEditTransaction, andRollbackPageObjectEditTransactiongroup native page-object mutations into an atomic page-scoped batch with validated snapshot rollbackPageObjectEditTransactionStatusreports the bound page, dirty state, successful mutation count, and content-generation count
Changed
- Committed object batches now invoke
FPDFPage_GenerateContentonce instead of once per insert, remove, transform, property, mark, annotation-object, or appearance mutation - Saving, page changes, page deletion, nested edit transactions, and failed native insert or annotation updates are rejected before deferred content can be lost
Version 3.62.0
Added
ReadPageObjectsSnapshotcaptures caller-owned page-object facts with object, path, clip, mark, text, string, and deadline budgetsPageObjectsSnapshotprovides revision-aware LRU reuse with configurable capacity and occupancy, hit, and miss telemetry
Changed
PageComplexitynow reuses the immutable page-object snapshot instead of repeating native object enumeration, transparency, path, and image queries
Version 3.61.0
Added
TPdfnow exposes a unified thumbnail LRU for embedded and rendered previews with configurable entry and byte ceilings plus hit, miss, eviction, occupancy, and revision telemetryRenderPageThumbnailaccepts rotation, render options, background colour, andTPdfColorSchemewhile preserving the caller-owned bitmap contract
Changed
- Repeated thumbnail extraction and rendering reuse native PDFium results through revision, page, source, size, rotation, flags, background, and colour-scheme keys, including cached absence of optional embedded thumbnails
TPdfThumbnailViewsynchronises its visible-page bitmap cache with document thumbnail revisions so edits cannot leave stale previews
Version 3.60.0
Added
ReadTextPageSnapshotcaptures Unicode, UTF-16 mappings, character geometry and style, and normalised text-object metadata in one pass with explicit character, object, font-name, and deadline budgetsTextPageSnapshotprovides deep caller-owned copies through a configurable revision-aware LRU with capacity, count, hit, and miss telemetry
Changed
GetStructuredTextand physical-layoutGetTextInReadingOrdernow reuse the same text snapshot and apply O(n log n) geometry sorting
Fixed
- Small text and structure snapshot caches now evict the oldest page while storing new data under the requested page index, preventing cross-page cache aliasing
Version 3.59.0
Added
LifecycleActionPolicyselects disabled, explicit-only, or compatible automatic execution of PDF document and page lifecycle actionsExecuteDocumentLifecycleActionexposes document JavaScript, open, close, save, and print actions, whileExecutePageLifecycleActionruns page open and close actions without changingPageNumber
Changed
- Headless page loads now receive the same automatic page open and close actions as viewer-driven loads, with temporary pages reused or released under the render lock
Version 3.58.0
Added
ReadStructureElementsandVisitStructureElementsprovide iterative tagged-structure traversal with explicit depth, element, attribute, and time budgets plus detailed completion statusStructureElementsForPageexposes one-based page snapshots without changingPageNumber, backed by a configurable revision-aware LRU cache with hit, miss, and count telemetry
Changed
- Accessibility, reflow, validation, and viewer consumers now reuse caller-owned structure snapshots until a relevant document or page edit invalidates them
Version 3.57.0
Added
- Complete native form-host callbacks now provide lifetime-safe lazy page handles, interaction-view cursor routing, value-change notification, selected-text rectangles, URI events, and GoTo destination events
FormHostCallbacksCompletereports callback readiness, whileFormSelectionRectsandClearFormSelectionRectsexpose bounded page-space selection geometry
Fixed
- XFA current-page callbacks now translate correctly between PDFium's zero-based page indexes and the component's one-based
PageNumber - AcroForm and XFA URI callbacks now preserve raw URI bytes and require explicit host approval before any external launch
Version 3.56.0
Added
- Indexed
PageMetricssnapshots expose a page's dimensions, rotation, label, transparency, and five standard page boxes without changing the active page
Changed
- Repeated page-metadata reads reuse an automatically invalidated native snapshot cache, reducing page opens in thumbnail, preflight, and document-analysis workloads
Version 3.55.0
Added
- Path inspection exposes exact cubic Bézier control points when the loaded PDFium build provides
FPDFPath_GetBezierControlPoints, with an optional capability probe for older DLLs FormFieldTypeAtPoint,TPdfView.FormFieldTypeAt, and indexedFontFlagsproperties expose native form and font facts without raw handlesTPdf.Signaturesreturns all native signature contents, ByteRanges, subfilters, reasons, times, and permissions in one caller-owned snapshot
Changed
- Form-field presence checks now use direct native point hit testing instead of opening and closing annotation handles
Fixed
- PDF/E-1 validation now permits ordinary AcroForm fields, embedded files, and FileAttachment annotations while precisely reporting top-level AcroForm
/XFAand/NeedAppearances true, including indirect and object-stream values
Version 3.54.0
Added
FPdfProductionadds measured multi-codec image selection, colour and font processing backends, SVG paths, styled replacement plans, transactional XFA packet updates, barcode vectors, Portfolio models, and safe RichMedia extractionFPdfStandardsExecutionadds measurement and GeoPDF conversion, transactional PDF/A repair, PDF/UA-2 plans, external multicolour profiles, historical DSS and VRI evidence, DPart queries, deep PDF/E facts, and fixed-memory PDF/R stripsTPdf.ImportImposedcomposes bounded N-up and booklet plans through native N-up or page-XObject paths with exact gutter, bleed, and creep geometry, whileTPdf.CompareWithreports semantic, geometric, and tolerant pixel differences- PAdES signing now supports pluggable path validators and HSM providers, signature-attached PDF MAC,
cms-algorithm-protection, and offline signature-policy documents
Changed
- The layout engine accepts bounded HTML and Markdown, flows across columns, and resolves fixed, auto, and fractional grid tracks
- XFDF round trips now retain multivalue and rich-text fields, popups, actions, destinations, appearance overlays, custom namespaces, and explicit presence state
Version 3.53.0
Added
ConfigurePdfLibraryprovides immutable native renderer, font, V8, Brotli, user-font-path, and sandbox configuration before the first PDFium load- Native structure attributes, annotation relationships, annotation file attachments, typed dictionary values, focus policies, link and form z-order queries, and default TTF mapping diagnostics are available through bounded high-level APIs
TPdfView.ReplaceFormTextAndKeepSelectionpreserves the active selection across repeated edits and right-button release events now reach the native form engine
Changed
- Deterministic document time now uses a stable UTC calendar conversion as well as the fixed epoch, producing the same metadata in every host time zone
- Attachment string writes validate the native result and encode dictionary keys as UTF-8
Version 3.52.0
Added
TPdf.GetImageObjectRenderedBitmapreturns an image object's rendered result with its current matrix, colour space, masks, and rendering state appliedTPdf.TextObjectGlyphWidth,TPdf.TextObjectFontSize, andTPdf.SetTextObjectFontSizeexpose native glyph measurement and exact text-object font-size editingTPdf.TransformPageObjectClipPath,TPdf.DetachFormObjectChild,TPdf.SharePageObjectMark, andTPdf.IsAnnotationObjectSubtypeSupportedadd precise content-object editing and capability inspection
Version 3.51.0
Fixed
- Eight
TPdfmembers that earlier release notes announced were declared in the private section and could not be called from outside thePDFiumunit; they are now public as documented:LinkAtPoint,GetTextRenderMode,GetTextObjectRenderedBitmap,IsAnnotationSubtypeSupported,ChooseRenderFlags,AttachmentHasKey,GetAttachmentStringValue, andSetAttachmentStringValue
Changed
- The English reference documentation now covers every public member of
TPdfandTPdfView: 88 members that had no reference page received one, and the class pages, the navigation index, and the API reference list them all - Reference pages that previously pointed at a shared page now link to the page of the member itself, so a search result opens the description of the API that was searched for
- The API reference documents the enumerations and records reachable from public signatures, including load and stream reporting, text, font and OCR types, layout builder types, PAdES validation types, batch and validation types, and parallel rendering types
Version 3.50.0
Added
- Every GUI demo now opens with ready-to-use content instead of an empty form: viewer and lab demos load a generated sample document, report demos produce a completed report at startup, and processor demos pre-generate sample inputs so the main action runs with one click
MultiPageViewer,SplitViewandFontPropertiesgenerate in-memory sample documents at startup (a six-page showcase, two side-by-side comparison documents, and a multi-font page for click-to-inspect)- Processor demos such as
MergePDF,BatchExport,SplitPDF,ExtractText,PDFtoJpg,PrintPDFandPrintPreferencespre-generate sample PDFs next to the executable and pre-fill their input controls, with idempotent regeneration that never overwrites existing files FormFillandExtractImagesauto-load the sample files shipped in their demo folders,ImageToPDFgenerates two sample bitmaps,WatermarkStamppre-builds its stamp samples, andXfdfLabopens on a generated document carrying text and highlight annotations
Changed
CreatePDFnow generatesSample.pdfnext to the executable at startup without showing a dialog, so the document exists the moment the demo opensTPdf.AboutInfoand installer metadata now report Version 3.50.0 consistently
Version 3.49.0
Added
FORM_GetTextDirectionandFORM_SetTextDirectionfrom the updated PDFium binaries are now bound, keeping the dynamic binding layer at full coverage of all 472 PDFium exportsTPdf.FocusedFormFieldTextDirectionandTPdf.SetFocusedFormFieldTextDirectionexpose the focused widget's in-memory text direction through the newTPdfFormTextDirectionenum (ftdUnknown,ftdAuto,ftdLTR,ftdRTL), withTPdfViewcounterparts that repaint the page scene after a direction change
Changed
FPDF_LIBRARY_CONFIGnow mirrors the PDFium version 6 layout with the experimentalm_BrotliEnabledfield for binaries built withPDF_ENABLE_BROTLITPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.49.0 consistently
Version 3.48.0
Added
- The
PDFViewerdemo now generates a six-page showcase document in memory at startup using the creation API, so the viewer opens with rendered content and no sample file on disk - A thumbnail panel built on
TPdfThumbnailViewprovides click-to-navigate page previews beside the bookmark tree in all three demo ports - The viewer search now highlights every match on the current page through
HighlightSearchTextinstead of a single result rectangle, with the match count reported in the status bar - One-click
Nightand2-Uptoolbar buttons toggle the night duotone rendering mode and the two-page spread display mode
Changed
- Text selection in the viewer now uses the built-in
TPdfViewselection engine with double-click word selection, drag selection, and clipboard shortcuts replacing the hand-rolled selection code - Pages render with a drop shadow and smooth scrolling for a modern reading experience
TPdf.AboutInfoand installer metadata now report Version 3.48.0 consistently
Version 3.47.0
Added
FPdfBenchmarkruns bounded PDF corpora with configurable warm-up and measured passes, page and pixel limits, cooperative cancellation, and per-case pass, fail, or skipped statusTPdfBenchmarkReportrecords input and saved byte sizes, load and first-page latency, render throughput, save and reopen timing, sampled peak working set, semantic and pixel SHA-256 hashes, repeated-run stability, expected hash gates, and independent reopen equivalence- Benchmark reports export formula-safe CSV and structured JSON for CI, release qualification, and longitudinal performance tracking
GetSkiaRenderCapabilities,RenderPageSkia, andRenderPageSkiaByIndexexpose optional native Skia page and form rendering with parsed-page cache reuse and no hard DLL export requirement- A versioned capability-gated print-output ABI exposes exact spot-plate enumeration, plate rendering, overprint detection, and overprint preview when supplied by the loaded PDFium module
Fixed
- PDFium builds without
PDF_USE_SKIAnow load normally instead of failing because experimental Skia exports are absent
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.47.0 consistently
Version 3.46.0
Added
ValidatePdfRnow checks raster-only page content, strip geometry, colour models, effective resolution, compression parameters, required metadata, and encrypted PDF 2.0 profiles through configurable validation optionsBuildPdfARepairPlanturns validation evidence into dependency-ordered remediation steps with safety classes, signature-impact guards, and JSON outputBuildPdfXProductionPreflightreports page boxes, embedded fonts, output intents, colourants, transparency, overprint, separations, image resolution, and production readiness without decoding image payloads- PDF/UA-2 structure validation now checks associated-file ownership, reading order, descriptions, relationships, and discoverability
Changed
TAssociateFile.Description,TPdf.ImageInfo, andTPdf.PageComplexityexpose the metadata needed by associated-file and production preflight workflowsTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.46.0 consistently
Version 3.45.0
Added
TPdfXmpPacketparses, edits, clones, and serializes namespace-aware XMP with unknown namespaces, typed RDF containers, URI and resource values, qualifiers, language alternatives, packet wrappers, and preserved paddingTPdf.ReadXmpPacketandSaveAsWithXmpPacketexpose high-level metadata reading and atomic output, with signed-document changes requiring explicit authorization
Security
- The bounded XML reader rejects DTDs and external entities and limits packet bytes, nesting, nodes, attributes, and numeric character references
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.45.0 consistently
Version 3.44.0
Added
TPdfValidationRuleRegistryregisters profile clauses with severity, dependencies, repair guidance, evidence, and built-in or custom predicatesTPdfValidationBudgetandTPdfValidationExecutionContextbound rules, failures, objects, recursion, UTF-8 evidence, reserved memory, elapsed time, fast fail, and cooperative cancellationValidatePdfFilesParallelvalidates files through isolated worker documents while preserving input order and aggregating issue distributions, timings, failures, cancellations, and load errors
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.44.0 consistently
Version 3.43.0
Added
TPdfStructureElementnow carries namespace, namespace role mapping, reference, associated-file, annotation, widget, label, and appearance facts for PDF/UA-2 semantic validationValidatePdfUa2StructureElementsand its focused validators check ISO/TS 32005 namespaces and containment, bounded table grids, annotations, forms, Formula/MathML associations, associated files, document roots, FENote, lists, TOC references, titles, and captions without loadingpdfium.dllClassifyPdfUaNamespaceidentifies the PDF 1.7, PDF 2.0, MathML, ARIA, DPUB, custom, and missing structure namespacesPdfUa2StructureHasIssueprovides a C++Builder-safe single-issue query without returning a Pascal set by value
Changed
ValidatePdfUaStructureElementsautomatically applies the new semantic rule set forpuc2while preserving the PDF/UA-1 rule pathTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.43.0 consistently
Version 3.42.0
Added
TPdfUaSaveOptions.PdfUa2creates PDF/UA-2 output withpdfuaid:part2,pdfuaid:rev2024, and an effective PDF 2.0 catalog versionValidatePdfUadetectspuc2and reports missing revision metadata, non-PDF-2.0 files, unnamed optional-content configurations, deprecated annotations, and generic H headings
Changed
- PDF/UA validation now selects profile-specific tab-order, XFA, and heading rules for PDF/UA-1 and PDF/UA-2
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.42.0 consistently
Version 3.41.0
Added
SetPageObjectMarkParamadds or replaces one integer, real, string, or blob parameter on an existing marked-content entry without replacing the markRemovePageObjectMarkParamremoves one selected property while preserving the mark name and every unrelated property
Changed
- Non-integral marked-content numbers now round-trip as
pmpFloatinstead of being truncated into integer snapshots - Failed parameter validation during
AddPageObjectMarkremoves the partially created native mark TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.41.0 consistently
Version 3.40.0
Added
ConfigureSystemFontProviderinstalls an application font mapper before PDFium starts and supplies validated TrueType or OpenType bytes for missing or substituted document fontsTPdfSystemFontPolicycontrols face substitution, native fallback, per-font byte limits, and bounded request cachingGetSystemFontProviderStatisticsreports mapping, cache, fallback, rejection, data-table, and live-handle activity
Changed
- Provider callbacks expose PDFium's requested face, weight, style, charset, and pitch while keeping callback failures inside the native boundary
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.40.0 consistently
Version 3.39.0
Added
AddCidType2Textembeds caller-supplied TrueType data with explicit per-glyph CID-to-GID geometry and CID-to-Unicode mappingsTPdfCidFontOptionsselects full embedding, preferred subsetting with fallback, or required subsetting and configures bounded font, glyph, and Unicode budgetsTPdfCidFontReportreports subset decisions, byte sizes, unique glyphs, embedding state, expected text, extracted text, and extraction integrity
Changed
- TrueType subsetting preserves requested glyph identifiers, rejects unsafe output, and rolls back every inserted page object if mapping or extraction verification fails
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.39.0 consistently
Version 3.38.0
Added
BuildReflowDocumentcreates a bounded reusable semantic node tree from Tagged PDF structure or physical-layout inference across a selected page rangeTPdfReflowDocument.ToHtmlemits escaped responsive headings, paragraphs, lists, figures, captions, page sections, and tables with header and span semanticsTPdfReflowOptionscontrols table detection, page sections, geometry, CSS, line breaks, page range, cancellation, and resource budgets
Changed
- Table content replaces overlapping paragraph blocks during reflow, and active-page state is restored after success, failure, or cancellation
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.38.0 consistently
Version 3.37.0
Added
ApplyOcrSearchLayerrenders selected pages through PDFium and sends bounded top-down BGRA pixels to a caller-suppliedIPdfOcrProviderTPdfOcrWordcarries Unicode text, confidence, and pixel-space quadrilaterals that are mapped through native page geometry into invisible searchable textTPdfOcrReportrecords per-page completion, existing-text skips, failures, cancellation, rendered pixels, and accepted or rejected words
Changed
- OCR insertion preserves original scan image streams, filters malformed or low-confidence results, commits once per page, and restores the active page
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.37.0 consistently
Version 3.36.0
Added
ExtractTablesdetects ruled and whitespace-aligned tables from native word geometry and transformed path rulingsTPdfTablereports rows, columns, merged spans, page bounds, header cells, detection mode, confidence, and direct CSV or JSON outputExtractDocumentTablesscans every page under shared budgets and marks matching tables that continue across page boundaries
Changed
- Table extraction enforces configurable word, ruling, cell, and table limits and restores the active page after document-level scans
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.36.0 consistently
Version 3.35.0
Added
GenerateTaggedLayoutcreates a new semantic layout document with native marked content, a Document structure tree, ParentTree and IDTree mappings, and document language metadataTPdfLayoutSemanticsmodels headings, sections, lists, figures, captions, tables, header associations, spans, alternate text, actual text, languages, and element IDsTPdfLayoutDocument.AddLinkemits URI Link annotations and associates each annotation with its Link structure element through OBJR and StructParent mappings
Changed
- Layout text defaults to paragraph semantics while headers, footers, rules, images, and reusable forms default to artifacts unless explicitly tagged
- Semantic plan validation rejects duplicate IDs, missing parents, cycles, invalid list or table containment, figures without replacement text, and unresolved table header IDs before document emission
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.35.0 consistently
Version 3.34.0
Added
TPdf.AddShapedTextwrites RTL, bidi, contextual, and ligature glyph runs through native system shaping and PDFium CID Type 2 font APIsShapePdfTextandTPdfUniscribeTextShaperexpose positioned glyph IDs, advances, offsets, source clusters, visual run positions, and bidi levels without modifying a document
Changed
- Generated ToUnicode maps cover every shaped glyph while
ActualTextstores the original logical Unicode string for conforming extraction and accessibility consumers - Marked-content strings with UTF-16 byte-order marks now decode correctly through
PageObjectMarks TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.34.0 consistently
Version 3.33.0
Added
TPdfLayoutCachedNodebuilds subclassed layout content on first use and supports repeated scaled placements throughAddCachedNodeTPdfLayoutPlanreports measurement cache hits, misses, cached-node placements, and reused native XObjects
Changed
BuildPlanreuses matching plans by complete page constraints, content, font, style, source, and measurer identities without repeating text measurementGenerateLayoutconverts each unique cached node to one destination-bound XObject and creates lightweight Form objects for every placementTPdf.AboutInfo, package metadata, and installer metadata now report Version 3.33.0 consistently
Version 3.32.0
Added
TPdfLayoutDocumentbuilds wrapped text, spacers, rules, images, reusable page XObjects, explicit page breaks, headers, and footers into a measured page planGenerateLayoutpaginates the complete layout before atomically appending native pages and page objects, with stable{page}and{pages}references
Changed
TPdf.AboutInfo, package metadata, and installer metadata now report Version 3.32.0 consistently
Version 3.31.0
Added
TPdfPagePlanbuilders describe delete, move, insert, split, and merge page operations without applying themValidatePagePlanreturns the exact old-to-new page map and inventories affected bookmarks, named destinations, page labels, form fields, tagged pages, imported features, and signatures
Security
- Plans that would leave dangling navigation targets or change signed content without explicit authorization are rejected before any native page operation runs
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.31.0 consistently
Version 3.30.0
Added
SaveRecoverySnapshotwrites a checksummed, size-bounded recovery package containing the source fingerprint and verified document edit journalRestoreRecoverySnapshotreplays a recovery package only when its checksum, journal chain, source fingerprint, and recovered fingerprint all matchEnableRecoveryAutosaveatomically refreshes an explicit recovery file after each changed commit, undo, or redo without rewriting the source PDF
Changed
InspectRecoverySnapshotreports recovery source, fingerprints, entry count, position, and bounded storage without applying the packageImportEditJournaland recovery restore now require explicitAllowSignedDocumentauthorization before applying edits to a signed PDF- Recovery package storage uses the configured bounded random-access store and same-directory write-through replacement for large journals and crash-safe autosave updates
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.30.0 consistently
Version 3.29.0
Added
BeginEditTransaction,CommitEditTransaction, andRollbackEditTransactiongroup arbitrary native document edits into atomic transactionsUndoEditandRedoEditapply SHA-256-verified inverse and forward deltas across page, object, annotation, attachment, and metadata changesExportEditJournalandImportEditJournalpersist bounded portable deltas with source-fingerprint and digest-chain validation for later replay
Changed
- Transaction snapshots use reproducible native output so unchanged commits remain empty even when ordinary PDFium saves contain non-deterministic identifiers or timestamps
- Failed commits and invalid journal replay restore the previous loadable document atomically, while entry count, stored bytes, and snapshot size stay under caller-configured limits
- Signed PDFs require explicit
AllowSignedDocumentauthorization before a document edit transaction begins TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.29.0 consistently
Version 3.28.0
Added
TPdf.InspectOptionalContentenumerates OCG layers, default and alternate configurations, View/Print/Export usage states, zoom and language metadata, locked layers, order arrays, radio groups, OCMD policies, visibility expressions, and effective rendering stateTPdf.SaveAsOptionalContentConfiguredwrites a strictly verified copy with caller-selected layer states for a chosen usage and configuration
Changed
- Layer-state output now updates both configuration
/ONand/OFFarrays and OCG Usage state dictionaries so PDFium applies the requested visibility through its native rendering context - Configuration writes reject unknown groups, locked-layer changes, radio-group conflicts, encrypted staged files, and signed files without explicit authorization, and remove automatic-state rules by default to keep the selected result deterministic
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.28.0 consistently
Version 3.27.0
Added
TPdf.RenderPageByIndexrenders any one-based page at an exact pixel size without changing the active editing page or firing page-change eventsPageSceneCacheCapacity,PageSceneCacheCount, andClearPageSceneCacheexpose bounded scene-cache control and diagnostics
Changed
- Indexed page renders, rendered thumbnails, and embedded-thumbnail extraction now reuse parsed PDFium page state through an eight-entry LRU cache by default
- Scene entries are invalidated on page activation, editing, page-tree changes, form-state callbacks, explicit clearing, and document teardown, with in-flight renders retained safely until release
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.27.0 consistently
Version 3.26.0
Added
TPadesSignatureAlgorithmInforeports each CMS signer digest, signature, public-key, and named-curve OID together with its independently evaluated algorithm policy stateInspectPadesSignatureAlgorithmandEvaluatePadesSignatureAlgorithmrecognise P-256, P-384, P-521, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, Ed25519, and Ed448 profiles
Security
- PAdES validation now rejects elliptic-curve and digest mismatches, ECDSA signature OIDs that disagree with the CMS digest, unnamed EC parameters, Ed25519 parameters, and Ed448 SHAKE256 output lengths other than 512 bits
- Native CMS verification remains the source of cryptographic validity, while unavailable algorithms and unrecognised curves are reported as
pcsUnsupportedinstead of being treated as invalid signatures TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.26.0 consistently
Version 3.25.0
Added
TPdf.ExportObjectGraphexports active classic, xref-stream, and object-stream objects as bounded typed JSON with explicit dictionaries, arrays, strings, names, scalar values, indirect references, stream byte counts, and optional SHA-256 stream digestsTPdf.SaveAsObjectGraphPatchedsets or removes schema-checked top-level dictionary values through typed null, Boolean, integer, real, name, text-string, and indirect-reference patch values
Security
- Object-graph export enforces object, recursion, string, and output-byte budgets, while patching validates every operation before delivery, rejects dangling references, duplicate operations, encrypted inputs, protected stream filter or length changes, and signed documents unless explicitly authorized
- Object-graph patches are staged as an incremental revision, materialized again for xref verification, strict-loaded through PDFium, and copied or atomically renamed only after all checks succeed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.25.0 consistently
Version 3.24.0
Added
TPdf.ValidatePadesTrustverifies every discoverable detached signature against the exact originalByteRange, evaluates signing-certificate-v2 binding and current Windows system trust, and reports independent signature, chain, revocation, and timestamp statesTPdf.ValidatePadesTrustAsyncsnapshots the original loaded source before dispatch, reports staged progress for parsing, cryptography, chain building, AIA, OCSP, CRL, and RFC 3161 timestamp work, and supports cooperative cancellationTPadesTrustValidationOptionsselects offline or online trust, optional revocation and timestamp verification, a bounded URL retrieval timeout, a cancellation token, and a progress callback
Security
- Signature timestamp and Document Time-stamp tokens now validate their SHA-256 message imprint, attached CMS signature, TSA chain, and optional revocation state independently from the ordinary document signature
- Trust validation never hashes a PDFium-resaved copy, defaults to offline cache-only certificate retrieval, and reports unsupported or indeterminate states instead of treating unavailable native trust or revocation evidence as valid
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.24.0 consistently
Version 3.23.0
Added
TPdf.RenewPadesArchiveTimestampandRenewPadesArchiveTimestampToStreamappend a new RFC 3161 Document Time-stamp to an existing PAdES signature chain without changing any historical bytesTPadesArchiveTimestampOptionscontrols TSA access, nonce, reserved token capacity, and an optional complete DSS refresh whileTPadesArchiveTimestampReportrecords the source and result levels, chain lengths, byte lengths, and returned timestamp identity
Fixed
- New and renewed PAdES B-LTA output declares ESIC ExtensionLevel 2, while B-LT validation no longer requires Level 2 unless a Document Time-stamp is present
Security
- Renewal hashes the exact original loaded bytes plus any requested DSS update, rejects encrypted or incomplete sources, validates the discoverable B-LTA result before writing output, and stages file output before replacement
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.23.0 consistently
Version 3.22.0
Added
TPdf.AnalyzeSignatureRevisionsreconstructs the original incremental revision chain and returns per-signature object changes classified against DocMDP and FieldMDP permissionsTPadesRevisionAnalysisReportdistinguishes allowed form, annotation, signature, and validation-material updates from disallowed page or document changes, unresolved cases, and suspicious shadow definitions
Security
- Revision analysis detects unreferenced object definitions, signature-object redefinitions, active content, malformed revision chains, and unresolved compressed objects while enforcing bounded revision, object, and change budgets
- Analysis always uses the original loaded file, memory buffer, custom stream, or completed progressive source rather than bytes rewritten by PDFium
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.22.0 consistently
Version 3.21.0
Added
TPdf.PreparePadesRemoteSignaturecreates a fixed-width detached-signature placeholder and returns a persistent request containing the SHA-256 document digest, exactByteRange, reservation coordinates, and prepared-PDF fingerprintTPdf.CompletePadesRemoteSignaturefinishes HSM, cloud, or interrupted signing sessions after validating the persisted request and returned CMSTPdf.SavePadesRemoteSigningRequestandTPdf.LoadPadesRemoteSigningRequestprovide a stable versioned binary session format for process and machine boundaries
Security
- Completion rejects modified prepared PDFs, altered
ByteRangecoordinates, reused non-empty placeholders, oversized CMS values, unsupported SignedData shapes, missing signing-certificate-v2 attributes, and CMS message digests that do not match the prepared document TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.21.0 consistently
Version 3.20.0
Added
TPadesDssOptions.Vriswrites one indirect/Type /VRIdictionary per signature, keyed by the uppercase SHA-1 of the complete decoded/Contentsvalue including paddingTPadesDssVriselects certificate, OCSP, and CRL material through validated indexes while PAdES B-LT and B-LTA signing now creates the new signature's VRI automatically
Changed
- DSS certificates, OCSP responses, and CRLs are content-hash deduplicated with stable first-occurrence ordering, exact-byte collision checks, and VRI reference remapping before any destination bytes are written
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.20.0 consistently
Version 3.19.0
Added
TPdf.GetStructuredTextconverts the current page into reusable block, line, and styled-span records while preserving source character indices, Unicode scalars, geometry, font names, sizes, weights, and text anglesTPdfStructuredTextOptionsselects content-stream or physical-layout order, optional font and semantic enrichment, and a fail-closed maximum character budget- Tagged PDF and heuristic readable-content fragments enrich blocks with structure kind, heading level, language, source, and structure-element identity while unmatched Figure alternate text remains represented
Changed
- Physical-layout extraction now uses O(n log n) character ordering, geometrically growing line and span buffers, line and column clustering, buffered Unicode construction, and adjacent non-null text-object font caching for predictable large-page performance
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.19.0 consistently
Version 3.18.0
Security
TPdf.SaveAsRedactedapplies every/Redactrectangle to an isolated document snapshot, removes each intersecting top-level page object, and paints an opaque replacement rectangle without changing the loaded document- Redacted output removes redaction annotations, optionally removes other intersecting annotations, deletes native embedded attachments, and strips catalog
/AF, active content, forms, metadata, and unreachable prior-revision objects TPdfRedactionOptionscontrols replacement colour, overlapping-annotation removal, and a fail-closed page-object scan budget whileTPdfRedactionReportrecords every removal and output metricTPdfSanitiseOptions.StripAssociatedFilesnow removes catalog-level associated-file references by default
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.18.0 consistently
Version 3.17.0
Added
TPdf.RenderPagesParallelrenders one-based page requests concurrently while every worker owns an independently loaded PDFium module, document, and page state sourced from one captured document snapshotTPdfParallelRenderOptionscontrols DPI, worker count, rotation, native render flags, background colour, per-page pixel limits, and aggregate retained-output limitsTPdfParallelRenderReportpreserves request order and returns caller-owned top-down BGRA or RGBA buffers with per-page success, cancellation, failure, dimensions, timing, and diagnostic details- Progressive worker rendering polls
IPdfCancellationTokenbetween native chunks while invalid requests and budget failures remain isolated to their corresponding results TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.17.0 consistently
Version 3.16.0
Added
TPdfEncryptionRevision.erR7adds ISO/TS 32003 AES-256-GCM output with/V 6,/R 7,/CFM /AESV4, and the required PDF 2.0 developer extension- Every encrypted string and stream receives a unique 96-bit IV, unchanged-length ciphertext, and a 128-bit authentication tag, while
EncryptMetadata = Falsepreserves metadata stream bytes DecryptAesGcmDocumentBytesvalidates user or owner passwords, encrypted permissions, optional standalone PDF MAC data, and every GCM tag before returning PDFium-compatible plaintext bytes- AESV4 output can be combined with
TPdfEncryptOptions.EnableIntegrityProtectionso per-object GCM authentication and whole-document ISO/TS 32004 PDF MAC protection coexist - Encryption now uses valid classic cross-reference entries instead of interpreting object-shaped text inside stream data as indirect objects
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.16.0 consistently
Version 3.15.0
Added
TPdfEncryptOptions.EnableIntegrityProtectionwrites ISO/TS 32004 standalone PDF MAC authentication codes for AES-256 Standard Security Handler revision 5 and 6 documentsTPdf.ValidatePdfMacverifies the exact original source bytes, strict EOF-covering/ByteRange, CMSAuthenticatedData, password-derived file key, authenticated attributes, wrapped MAC key, and HMAC valueFPdfHmacadds HMAC-SHA256 and HKDF-SHA256 whileFPdfAesadds RFC 3394 AES-256 Key Wrap and authenticated unwrap primitivesTPdfMacValidationResultdistinguishes valid, absent, invalid, and unsupported authentication codes with diagnostic textTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.15.0 consistently
Version 3.14.0
Added
TPdf.ValidatePadesnow verifies detached CMS signatures against the exact original/ByteRangesegments on Windows, including signed attributes and the signature valueTPadesValidationResultexposes aggregate integrity status and per-signature ByteRange, CMS,signing-certificate-v2, system trust, revocation, and timestamp states without conflating unsupported or unchecked evidence with an invalid signature- Signer certificate binding is checked with SHA-256, certificate chains use cache-only Windows system trust evaluation, and native error codes remain available for diagnostics
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.14.0 consistently
Version 3.13.1
Fixed
TPdf.ValidatePadesnow inspects the original file, buffered memory, or custom stream bytes instead of a PDFium-resaved copy that could invalidate offsets or discard signature dictionaries- PAdES
/ByteRangechecks now accept signatures that cover an earlier complete PDF revision followed by valid incremental updates, while also validating Document Time-stamp ranges TPadesValidationResult.SourceStatusdistinguishes original source validation from unavailable or incomplete progressive input, and compliance predicates reject results without original bytesTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.13.1 consistently
Version 3.13.0
Added
FPdfSha3provides dependency-free SHA3-256, SHA3-384, SHA3-512, and SHAKE256 primitives for ISO/TS 32001 and related PDF 2.x cryptographic work- Incremental contexts absorb arbitrarily split input while SHAKE256 supports repeated squeeze calls and output that crosses sponge rate boundaries
- One-shot byte-array and lowercase hexadecimal helpers complement the streaming API, with explicit lifecycle and size validation across Delphi, C++Builder, and Lazarus
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.13.0 consistently
Version 3.12.0
Added
TPdf.ImportFDFimports FDF form data from files or streams and applies parsed values through the existing widget field pathFdfImportFromStreamandFdfImportFromFileparse direct or indirect hierarchical fields, PDF literal and hexadecimal strings, PDFDocEncoding, Unicode text, name values, and explicit empty values under bounded resource budgets- FDF export now writes non-ASCII field names and values as standards-compliant UTF-16BE text strings and safely escapes source file names
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.12.0 consistently
Version 3.11.0
Added
TPdf.DetectPageSkewrenders the current page at low DPI and detects the skew angle by projecting dark pixels onto candidate rotation angles, returning the angle that maximises row-sum variance (text-line alignment) with ~0.1 degree accuracyTPdfSkewReportexposes the detected angle, confidence, and sample dimensionsTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.11.0 consistently
Version 3.10.0
Added
TPdf.GetTextInReadingOrderextracts the current page text in raw content-stream order or physical-layout order (top-to-bottom, left-to-right) throughFPDFText_GetCharBox+ position-sorted character extraction, so multi-column and visually reordered text reads naturallyTPdfReadingOrderenum selects betweenroContentOrderandroPhysicalLayoutTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.10.0 consistently
Version 3.09.0
Added
TPdfImageOptimizeOptions.PreserveBilevelskips 1-bit bilevel images (ImageMask / line-art scans) duringOptimizeImagesso nearest-neighbour downsampling does not destroy their crisp edgesTPdfImageOptimizeOptions.MinDimensionskips images smaller than the threshold (typically icons or decorative elements that do not benefit from further reduction)TPdfImageOptimizeOptions.Defaultprovides the recommended starting point (150 DPI target, 1.5 ratio, bilevel preserved, min dimension 8)TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.09.0 consistently
Version 3.08.0
Added
TPdfTileCacheprovides a bounded LRU cache of rendered page tiles keyed by document revision, page, zoom, rotation, render flags, and device rectangle, so unchanged tiles are not re-rendered on repaints and stale tiles from a prior save are evicted automaticallyTTileKeyexposes the composite cache key with a staticCreatefactory and anEqualscomparatorTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.08.0 consistently
Version 3.07.0
Added
TPdf.GetAnnotationFontColorandTPdf.SetAnnotationFontColorwrap the previously-bound-but-unusedFPDFAnnot_GetFontColorandFPDFAnnot_SetFontColor, exposing widget text-colour read and write for form-field editing without touching the annotation dictionary directlyTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.07.0 consistently
Version 3.06.0
Added
TPdf.RenderPageBandedrenders the current page in horizontal bands via a callback, so posters and engineering pages can be exported without ever allocating a full destination bitmap — each band renders into a freshly createdTBitmapof the requested band height and is freed after the callback returnsTPdfBandCallbackexposes the per-band contract (band index, top-y offset, bitmap) with a Boolean return that lets callers cancel the banded render earlyTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.06.0 consistently
Version 3.05.0
Added
TPdf.RenderPageProgressiveWithColorSchemedrives the native progressive render loop with a low-vision colour scheme throughFPDF_RenderPageBitmapWithColorScheme_Start, letting callers override path fill / stroke and text fill / stroke colours for accessibility while keeping the cancellation-aware Continue loopTPdfColorSchemeexposes the fourTColoroverride fields with aDefaultthat delegates to PDFium's built-in colours when all fields areclDefaultTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.05.0 consistently
Version 3.04.0
Added
TPdf.ExportFDFserialises form field values as an FDF (ISO 32000-1 §12.7.11) document beside the existing XFDF path, reusing the sameTXfdfFielddata model so callers collect fields once and emit either formatFdfExportToStreamandFdfExportToFileinFPdfXfdfexpose the low-level FDF serialiser for callers that build field collections independently of a loadedTPdfTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.04.0 consistently
Version 3.03.0
Added
TPdf.SaveAsSanitisedwrites a clean single-revision copy that strips active content from the catalog (/OpenAction, catalog/AA,/Names,/AcroForm,/Metadata) and then prunes unreachable objects so the orphaned JavaScript, action, and attachment bodies disappear from the file bodyTPdfSanitiseOptionsexposes independent per-vector strip controls plus an optional reachability prune pass;TPdfSanitiseReportrecords stripped entry count, pruned object count, byte counts, and any errorTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.03.0 consistently
Version 3.02.0
Added
TPdf.SaveAsPageLabelledwrites a full PDF copy whose catalog/PageLabelsnumber tree is replaced with the supplied ranges, applying decimal, upper/lowercase roman, and upper/lowercase letter numbering styles with optional prefix text strings and start numbers per ISO 32000-1 §12.4.2TPdfPageLabelRange,TPdfPageLabelRanges,TPdfPageLabelStyle, andTPdfPageLabelReportexpose the range model, style enum, and per-save byte/range counts- Existing catalog
/PageLabelsentries are detected and rejected unlessReplaceExisting=Trueis passed, in which case the old entry is stripped before the new ranges are injected TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.02.0 consistently
Version 3.01.0
Added
TPdf.FlattenPageRotationbakes the current/Rotateof every page into the content stream, page boxes, and annotation rectangles, then resets/Rotateto 0 — wrappingFPDFPageObj_TransformF+FPDFAnnot_GetRect/SetRect+FPDFPage_SetMediaBox/SetCropBox+FPDFPage_SetRotationso the visual layout is preserved without relying on the rotation display hintTPdfFlattenRotationOptionsexposes per-page annotation transform, page-box swap, and auto-update controls;TPdfFlattenRotationReportrecords processed, skipped, and failed pages plus total transformed objects and annotationsTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.01.0 consistently
Version 3.00.0
Added
TPdf.StampPagesFromPdfstamps a source page as a positioned, scaled, optionally rotated Form XObject overlay or underlay across one or more target pages, wrappingCreateXObjectFromPage+FPDFPageObj_SetMatrix+FPDFPageObj_SetBlendMode+FPDFPage_InsertObjectAtIndexwith explicit page-box, anchor, margin, scale, rotation, blend, and z-order policiesTPdfOverlayOptionsandTPdfOverlayReportexpose the placement, transform, blend, and z-order controls plus per-page stamped, failed, and skipped countsTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 3.00.0 consistently
Version 2.99.0
Added
TPdf.RefreshAppearanceselectively regenerates a single widget's appearance stream throughFPDFAnnot_SetAP, avoiding a full-pageNeedAppearancesrebuildTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.99.0 consistently
Version 2.98.0
Added
TPdfView.MouseDownnow routes right-button events to the native form fill engine throughFORM_OnRButtonDown, enabling context menus and widget interactions on right click- Route map items 78 (link-annotation mapping), 82 (widget presentation), and 83 (structure attribute model) confirmed as already complete through existing infrastructure
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.98.0 consistently
Version 2.97.0
Added
TPdf.SetDeterministicTimeandTPdf.RestoreActualTimelet tests and reproducible builds inject a fixed creation, modification, and current time through supported native callbacksTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.97.0 consistently
Version 2.96.0
Added
TPdf.GetWidgetAdditionalActionJavaScriptreads widget additional-action JavaScript for a given event trigger throughFPDFAnnot_GetFormAdditionalActionJavaScriptwithout executing any scriptTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.96.0 consistently
Version 2.95.0
Added
TPdf.GetObjectTextextracts the Unicode text of a text page object throughFPDFTextObj_GetTextfor precise content editing and encoding diagnosticsTPdf.GetObjectsByTypereturns the indices of all page objects matching a category (text, path, image, form, shading) for selective category outputTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.95.0 consistently
Version 2.94.0
Added
TPdf.AttachmentHasKey,GetAttachmentStringValue, andSetAttachmentStringValueread, write, and probe custom file-spec extension values on embedded attachmentsTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.94.0 consistently
Version 2.93.0
Added
TPdf.InsertObjectAtIndexinserts a page object at a requested stack position viaFPDFPage_InsertObjectAtIndexrather than always appendingTPdf.UpdateAnnotationObjectcommits an edited annotation appearance object throughFPDFAnnot_UpdateObjectso changes to annotation-owned page objects persist reliablyTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.93.0 consistently
Version 2.92.0
Added
TPdf.InsertClipPathcreates a rectangular clip path and inserts it into the current page through the nativeFPDF_CreateClipPathandFPDFPage_InsertClipPathpaths, complementing the existingPageObjectClipPathinspectorTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.92.0 consistently
Version 2.91.0
Added
TPdf.GetPageComplexityscans the current page and reports image, path, and text object counts plus total path segments, total image pixels, and transparency presence for rendering planningTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.91.0 consistently
Version 2.90.0
Added
TPdf.IsAnnotationSubtypeSupportedasks the loaded PDFium DLL which annotation subtypes it supports before editingTPdf.ChooseRenderFlagsselects native render flags (halftone, limited image cache) from final scale and destination size for adaptive image subsamplingTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.90.0 consistently
Version 2.89.0
Added
TPdf.GetTextRenderModeexposes the native text rendering mode (fill, stroke, clip) of a text page object for authoring diagnosticsTPdf.GetTextObjectRenderedBitmaprenders a single text object to an isolated bitmap through the nativeFPDFTextObj_GetRenderedBitmappathTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.89.0 consistently
Version 2.88.0
Added
TPdf.GetThumbnailnow falls back to rendering a replacement when the page has no embedded thumbnail, implementing the embedded-thumbnail-first preferenceTPdf.LinkAtPointreturns whether a native link exists at a page-space coordinate usingFPDFLink_GetLinkAtPointrather than rectangle-only scansTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.88.0 consistently
Version 2.87.0
Added
TPdf.AuditActiveContentreturns aTPdfActiveContentAuditsnapshot of JavaScript action count, embedded file count, signature count, XFA form type, and document permissions without executing any script or actionTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.87.0 consistently
Version 2.86.0
Added
TPdf.GetFeatureInventoryscans every page once and returns a unified record of text, path, image, form XObject, and shading object counts alongside attachment, signature, form type, permission, and PDF version factsTPdfFeatureInventoryaggregates document-wide facts that previously required separate property calls into a single snapshotTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.86.0 consistently
Version 2.85.0
Added
TPdf.SaveAsReproduciblerewrites the document so that two saves of the same in-memory state produce byte-identical output- Non-deterministic
/Infotimestamps (/CreationDate,/ModDate) are stripped and the source/ID(derived from wall-clock-dependent bytes) is omitted, while object order and generation stay stable TPdfReproducibleReportreports kept and pruned object counts plus the number of stripped timestamp entriesTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.85.0 consistently
Version 2.84.0
Added
TPdf.SaveAsInlineImagesExternalisedrewrites the document extracting everyBI/ID/EIinline image into a reusable image XObject and replacing the inline block with a/ImN Dooperator- Inline-image dictionary abbreviations (
/W,/H,/BPC,/CS,/F, colour-space values, and filter values) are expanded to their full image-XObject names so the extracted object is standards-compliant - The page
/Resources /XObjectdictionary is updated with the new XObject references, and the rewritten content stream is Flate-compressed TPdfInlineImageExternaliseReportreports externalised, skipped, and failed counts plus the created XObject countTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.84.0 consistently
Version 2.83.0
Added
TPdf.SaveAsFlateRecompressedrewrites the document and re-encodes eligibleFlateDecodestreams at maximum compression, replacing a stream only when the measured byte saving clears a caller thresholdTPdfFlateRecompressOptionsselects a minimum saving in bytes and a minimum saving ratio so already-optimal streams are left untouchedTPdfFlateRecompressReportreports recompressed, skipped, and failed stream counts together with the original and recompressed stream byte totals- Object numbers and generations stay stable; only the recompressed stream payloads and their direct
/Lengthvalues change, so every surviving cross-reference remains valid TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.83.0 consistently
Version 2.82.0
Added
TPdf.OptimizeImageswalks every page image object and downsamples those whose effective placement DPI exceeds a caller-selected target, then commits each touched page through the native content generatorTPdfImageOptimizeOptionsselects the target DPI and a minimum ratio so only images that are genuinely over-sampled are re-encodedTPdfImageOptimizeReportreports optimized, skipped, and failed image counts together with a structured failure message- Downsampling uses a nearest-neighbour pass over the native PDFium bitmap buffer, preserving the source format, stride, and alpha channel, and
FPDFImageObj_SetBitmapre-encodes the survivor TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.82.0 consistently
Version 2.81.0
Added
TPdf.SaveAsDeduplicatedrewrites the document as a single clean revision that collapses compatible fonts, images, and form XObjects onto one shared representative- A recursive content fingerprint combines each resource dictionary, its full reachable subgraph, and its raw stream payload, so duplicates merge only when their entire content is identical
- Every cross-reference to a merged-away duplicate is rewritten to the surviving representative while the rebuilt classic cross-reference table keeps object numbers stable
TPdfDedupReportreports kept and pruned object counts plus per-category merged font, image, and form XObject countsTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.81.0 consistently
Version 2.80.0
Added
TPdf.SaveAsReachablerewrites the document as a single clean revision that keeps only the indirect objects reachable from the catalog and the trailer /Info dictionaryTPdfPruneReportreports the kept and pruned indirect object counts together with the source and output byte sizes, and structured failure reasons for encrypted or malformed input- Unreachable orphan objects left behind by incremental updates, page merges, or repaired saves are swept, while the rebuilt classic cross-reference and trailer preserve
/Root,/Info, and/IDwithout renumbering TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.80.0 consistently
Version 2.79.0
Added
TPdf.CreateDocumentSearchcreates a forward or backward document-wide search that returns one match at a time without building a full-document text indexTPdfDocumentSearchResultreports the one-based page, character range, matched text, and page-space rectangles for every result- Search sessions accept
IPdfCancellationToken, retain only the current PDFium page and text handles, and become safely finished when the document closes TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.79.0 consistently
Version 2.78.0
Changed
TPdfRangeRequestSchedulernow preempts overlapping lower-priority transfers so page-critical PDFium hints do not wait behind background downloads- Externally available sparse bytes cancel redundant active transfers, while superseded or duplicate transport callbacks return False without publishing stale coverage
- Priority promotion preserves independent retry histories, and transport preemption no longer consumes the retry budget of unaffected range tails
TPdfRangeRequestStatistics.SupersededRequestCountreports transport work displaced by higher-priority hints or externally supplied coverageTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.78.0 consistently
Version 2.77.0
Added
TPdf.SaveAsNormalizedContentwrites syntax-normalized page content to a stream or atomically replaced file and reports normalized, skipped, and coalesced page countsNormalizePdfContentSequenceprovides bounded standalone token normalization for decoded content-stream sequences
Changed
- Page
/Contentsarrays can now be coalesced into one stream while preserving strings, names, inline-image payloads, unknown operators, and cross-stream graphics state - Malformed tokens, unbalanced state scopes, unsupported filters, encrypted input, and signed-document rewrites have explicit policies and structured status reporting
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.77.0 consistently
Version 2.76.0
Added
TPdfStreamInspectorinventories arbitrary physical PDF stream objects and reports object offsets, raw lengths, filter chains, DecodeParms, external-file markers, encryption state, and native image or attachment pathsCopyRawDatacopies complete encoded payloads or validated byte windows, whileDecodeDataapplies ASCIIHex, ASCII85, LZW, Flate, RunLength, TIFF 8-bit, and PNG predictors in declared orderTPdfStreamInspectOptionsbounds source, raw, decoded, dictionary, stream-count, and expansion-ratio resources, with structured reports for limits, malformed data, unsupported codecs, encryption, and write failures
Changed
- Stream length resolution now exposes exact spans for direct and indirect
/Lengthvalues, including zero-length streams and payloads containing the literalendstreamsequence TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.76.0 consistently
Version 2.75.0
Added
TPdfLoadOptionsadds compatible, strict, and recovery policies to file, memory, byte-range, and custom-stream loadingTPdfLoadReportreports the native recovery route, xref validity, damaged offsets, entry conflicts, revision counts, audit budgets, and structured issues for classic, hybrid, and xref-stream documentsTPdf.SaveAsRepairedcreates a full single-revision copy and independently strict-loads it before delivering the verified stream or atomically replacing a target file
Changed
- Existing load overloads retain compatible behavior and now publish native xref validity and recovery status through
LastLoadReport - Strict loading rejects documents that required native xref rebuilding or failed structural audit, while signed repair output requires explicit caller authorization
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.75.0 consistently
Version 2.74.0
Added
TPdf.MergeFilesmerges file-backed source lists with per-source page ranges and passwords while keeping at most one source document openTPdfBatchMergeOptionsadds stop or skip error handling, source-scoped or chunked imports, form and outline policies, insertion control, progress callbacks, cancellation, viewer-preference copying, and rollback controlTPdfBatchMergeReportreports committed and rolled-back pages, source outcomes, native import calls, largest batch, peak open sources, policy detections, issues, and the terminal status
Changed
- The default batch path performs one native page import per source so PDFium can reuse cloned objects across that source, then closes the source before opening the next file
- Chunked mode provides finer cancellation points and smaller native batches, while failed partial sources and stop or cancellation outcomes can remove all pages inserted by the operation
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.74.0 consistently
Version 2.73.0
Added
TPdfRandomAccessStoreprovides thread-safe sequential and positioned I/O, keeps small content in bounded memory, and spills once to private temporary storage at a caller-selected ceilingTPdf.SaveMemoryLimitandSaveTemporaryDirectoryconfigure save staging, whileLastSaveSpillCountandLastSaveLargestMemoryBufferexpose measurable per-save diagnostics
Changed
- Save, standards conversion, validation, encryption, DSS, and PAdES staging buffers now share bounded working storage with exclusive delete-on-close spill files and memory scrubbing
- Custom PDFium block callbacks serialize ordinary stream seeks and use cursor-independent positioned reads when backed by
TPdfRandomAccessStore - The file-based XFA capability scan now reads fixed-size overlapping blocks instead of copying the complete PDF into memory
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.73.0 consistently
Version 2.72.0
Added
TPdf.BeginIncrementalSave,CommitIncrementalSave, andEndIncrementalSaveprovide a revision session that appends only changed or newly created indirect objectsTPdfIncrementalCommitInforeports changed-object count, appended bytes, total output bytes, and successful revision count for each commit
Changed
- Every dirty commit preserves the complete previous output as an exact byte prefix, emits no revision when nothing changed, and continues the source's classic or xref-stream format
- Native xref-stream incremental output is repaired with its required type, self entry, length, index, and object terminator before further processing
- Encrypted documents are rejected before a session begins, while signed documents require explicit caller permission so signature policy cannot be bypassed accidentally
- The file overload completes a sibling temporary file before atomically replacing the destination and rolls session state back after any write or replace failure
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.72.0 consistently
Version 2.71.0
Added
TPdf.SaveAsObjectStreamwrites PDF 1.5+ files with bounded compressed object groups and a pure xref stream containing complete type-2 entriesPackPdfObjectStreamscan modernise classic, hybrid, xref-stream, and existing object-stream input after resolving the active revision
Changed
- Page-local object ordering, adaptive xref field widths, direct catalog access, and configurable member and decoded-byte ceilings balance file size with random-access performance
- The file overload completes a sibling temporary file before atomically replacing the destination, while invalid incremental, version, and grouping options are rejected before output begins
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.71.0 consistently
Version 2.70.0
Added
TPdf.SaveAsLinearizedwrites a true Fast Web View PDF to a stream or file using first-page object grouping, two cross-reference sections, and Annex F page-offset and shared-object hint tables- Active object-stream members are materialized automatically, allowing xref-stream and object-stream inputs to become range-friendly output without changing visible page content
Changed
- The file overload completes a sibling temporary file before atomically replacing the destination, while the stream overload retains the normal PDFium save options and explicit version checks
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.70.0 consistently
Version 2.69.0
Added
TPdfRangeRequestSchedulerconverts PDFium byte-range hints into prioritized, coalesced, size-bounded transport work without forcing a contiguous download- Full and partial completion, bounded retries, sparse availability deduplication, request statistics, and generation-safe cancellation support HTTP Range and custom transport pipelines
TPdfProgressiveDocument.RangeRequestsautomatically receives document, form, and page hints, promoting only the exact bytes that block an interactive page
Changed
CancelProgressiveLoadnow cancels active range work before native availability and stream teardown, and stale transport completions are ignored safelyTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.69.0 consistently
Version 2.68.0
Added
TPdfProgressiveDocumentkeeps PDFium's availability session alive while a remote or growing random-access stream receives the byte ranges PDFium requestsCheckDocumentAvailability,CheckFormAvailability, andLoadAvailablePagereturn mergedTPdfDownloadRangehints so a host can fetch only the data needed to open and display a linearized pageAvailableByteCountsupports monotonic contiguous downloads, whileOnDataAvailablesupports sparse and out-of-order range caches
Changed
- Linearized files use PDFium's native progressive document, form, and page gates; non-linearized files automatically switch to the native custom-stream loader after the complete file is present
TPdfStreamAdaptercan expose a logical final size that differs from the bytes currently stored, while preserving the explicit 4 GiBFPDF_FILEACCESSlimitTPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.68.0 consistently
Version 2.67.0
Added
TPdfView.AllowFormEventsswitches off the mouse, keyboard and focus events the viewer forwards to the form-fill layer, for a read-only viewer or one that drives form interaction itself- Form fields still render normally with it off: page load and close are deliberately left ungated, since those initialise the form layer rather than react to input
- The switch joins the existing
AllowUserPageChangeandAllowUserTextSelectiontoggles and defaults to True, so existing behaviour is unchanged
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.67.0 consistently
Version 2.66.0
Added
- Named actions a document raises (ISO 32000-1 §12.6.4.11) now reach the host through the new
OnNamedActionevent; previously every one of them was discarded - Left unhandled, the four standard navigation names —
NextPage,PrevPage,FirstPage,LastPage— move the page, clamping at the first and last rather than wrapping TPdf.PerformNamedActionlets an application trigger the same behaviour directly, returning False for a name that has no library-supplied meaning
Fixed
- An encryption test measured a stream body by scanning backwards from
endstream, which occasionally mistook a ciphertext byte for a line terminator and reported an intermittent failure; the library was correct throughout
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.66.0 consistently
Version 2.65.0
Added
BuildToUnicodeCMapgenerates the ToUnicode CMap (ISO 32000-1 §9.10.3) a CID font needs so its text can be copied, searched and read by assistive technology — without one the text renders correctly but extracts as nothing- Entries are chunked at the 100-per-block limit the specification sets, duplicate glyphs are written once, and
.notdefis skipped - The CMap follows the CID = GID convention, so no
CIDToGIDMapstream is needed beside it
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.65.0 consistently
Version 2.64.0
Added
- Ink and stamp annotations draw themselves from their own page objects rather than from the page content stream, and those objects are now reachable:
AnnotationObjectCountandAnnotationObjectInforead them,AddPathToAnnotationhands the annotation a path built withCreatePath, andRemoveAnnotationObjectdeletes one - Building a stamp’s appearance no longer requires an external tool: create the path as usual, then give it to the annotation instead of to the page
- PDFium accepts page objects on ink and stamp subtypes only, so any other subtype is refused with a message naming the restriction rather than failing obscurely
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.64.0 consistently
Version 2.63.0
Added
TPdf.AddStandardFontTextdraws text with one of the 14 fonts every PDF reader is required to provide, embedding no font program at all — the resulting file is measurably smaller than the same text drawn withAddText, which embeds the system face it finds- The new
TPdfStandardFontenum names all 14 faces, so a caller cannot mistype a base font name; PDFium matches those names exactly and a typo would silently yield no font - PDF/A and PDF/X both require every font embedded, so output aimed at those profiles should keep using
AddText
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.63.0 consistently
Version 2.62.0
Added
TPdf.TextObjectGlyphOutlinereturns the outline of one glyph of a text object’s font as path segments, for converting text to vector art or inspecting a glyph a font substitution may have altered- The result reuses the existing
TPdfPathSegmentstype, so it reads exactly like the outline of a drawn path object - Coordinates are in the font’s own design space, normalized so one em is 1.0; the requested font size does not scale them, so a caller wanting device units multiplies by the point size itself
- An empty result means the font exposes no outline for that glyph, which is not an error; asking for a glyph of a non-text object raises
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.62.0 consistently
Version 2.61.0
Added
TPdf.InspectAvailabilityreports what PDFium can tell about a PDF without loading it as a document: whether the file is linearized (“web optimized”), whether a full parse would succeed, whether it carries form data, and which page a viewer would show first- The new
TPdfAvailability,TPdfLinearizationandTPdfFormAvailabilitytypes carry the answers; the stream is read but not retained, and its position is restored on return - This closes the last gap in the
FPDFAvail_*family, which was bound and loaded but had no caller anywhere in the library - Delphi, Lazarus, and C++Builder each cover the reported facts, the stream-position guarantee, and the nil-stream rejection
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.61.0 consistently
Version 2.60.0
Added
- Marked content (ISO 32000-1 §14.6) is now reachable from the high-level API:
PageObjectMarksreads every BDC tag and its property list off a page object,AddPageObjectMarkwrites one,RemovePageObjectMarkdeletes one, andPageObjectMarkedContentIDreports the MCID - New
TPdfContentMark,TPdfContentMarkParamandTPdfMarkParamKindtypes carry the tag name and its typed parameters (integer, float, string, blob), with the value kind resolved from PDFium rather than guessed from the getter that succeeds - Adding a mark rebuilds the page content stream, so the tag survives a save; this had to be explicit because
SaveAsdoes not regenerate content on its own - Delphi, Lazarus, and C++Builder each carry six cases, including one that inflates the saved content stream to confirm the BDC operator and its property list really landed
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.60.0 consistently
Version 2.59.0
Added
TPdfAnnotationgainsHasLinkUriandLinkUri, soCreateAnnotationcan now produce a working web link: the annotation is saved with a/URIaction pointing at the given address- Setting a link URI on any subtype other than
anLinkraises, since only a Link annotation carries an action dictionary - The field is write-only for now; reading a link target back goes through the
FPDFLink_*family, which needs the document handle - Delphi, Lazarus, and C++Builder all verify the saved bytes carry the
/URIaction and the target address
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.59.0 consistently
Version 2.58.12
Added
- PDF/X validation reports
pvxiTrimBoxWithArtBoxwhen a page carries/TrimBoxand/ArtBoxtogether; both state the finished page, so a RIP has no way to know which one is authoritative (ISO 15930) - PDF/X validation reports
pvxiPageBoxOutsideMediaBoxwhen/TrimBoxor/BleedBoxreaches outside/MediaBox, including a box with a negative origin; a box past the medium cannot be imaged - Rectangles are normalized before comparison, so either corner order is accepted, and a box touching the media edge exactly still validates
- Preflight reports classify both issues under structure and name the concrete remedy
- Delphi, Lazarus, and C++Builder all cover the two rejected cases and the conforming one
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.12 consistently
Version 2.58.11
Added
- PDF/UA validation reports
pvuaiTociWithoutTocwhen a document tags TOCI entries but never tags the TOC container they belong to, which leaves assistive technology announcing table of contents items with no table of contents (ISO 14289-1 §7.7) - Preflight reports classify the issue under structure and recommend wrapping the entries in a TOC element
- C++Builder gains its first PDF/UA test coverage alongside the Delphi and Lazarus cases
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.11 consistently
Version 2.58.10
Added
- PDF/A validation reports
pvaiSymbolicTrueTypeEncodingwhen a symbolic TrueType font carries an/Encodingentry; ISO 19005-1 §6.3.7 admits only the font’s built-in cmap, so an/Encodingwould contradict it - The symbolic flag is read from the
/FontDescriptor, whether it is written inline in the font dictionary or referenced indirectly; a non-symbolic font keeps its required/WinAnsiEncodingor/MacRomanEncodingwithout being flagged - Preflight reports classify the issue under content and recommend removing the entry
- Delphi and Lazarus cover the flagged case plus both accepted cases; C++Builder covers the flagged and the non-symbolic case
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.10 consistently
Version 2.58.9
Added
- PDF/A validation reports the container implementation limits of ISO 19005-1 Annex C:
pvaiNameOverLimitfor names longer than 127 bytes,pvaiArrayOverLimitbeyond 8191 elements,pvaiDictOverLimitbeyond 4095 entries, andpvaiNestingOverLimitbeyond 28 levels of nesting - The limits are inclusive, so a container sitting exactly on one still validates; tests pin both the rejected and the accepted side of each boundary
- Preflight reports classify the four issues under structure and name the concrete limit in each recommendation
- Delphi and Lazarus cover all four limits plus the boundary cases; C++Builder covers the array limit and the boundary
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.9 consistently
Version 2.58.8
Added
- PDF/R validation reports
pvriPageImageMismatchwhen the image count does not match the page count; ISO 23504-1 §6.5.1 makes every page exactly one strip image, so a page with none or with several is not conforming - Delphi, Lazarus, and C++Builder tests cover a page without an image, a page with two, and the conforming one-image case
Changed
- The PDF/R marker-injection tests now start from a source page that already carries a strip image, since marker injection adds metadata and cannot supply page content
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.8 consistently
Version 2.58.7
Added
- PDF/R validation reports
pvriFontForbiddenwhen a page names a font resource; a PDF/raster page carries the scanned image and nothing else (ISO 23504-1 §6.5.2) - PDF/R validation reports
pvriForbiddenImageFilterfor strip encodings outside the white list, so/LZWDecode,/RunLengthDecode,/ASCII85Decode,/ASCIIHexDecode,/JBIG2Decode, and/Cryptare rejected while/CCITTFaxDecode,/DCTDecode,/JPXDecode, and/FlateDecodepass (ISO 23504-1 §6.6) - Preflight reports classify both issues under content and recommend the concrete remedy
- Delphi, Lazarus, and C++Builder tests cover a font resource, a rejected filter, and a page using only white-listed encodings
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.7 consistently
Version 2.58.6
Added
- PDF/E validation reports
pveiFontNotEmbeddedwhen a document shows font usage but carries no embedded font program, so the requirement is checked on the DLL-free path as well as through PDFium - An engineering drawing has to render identically decades later, so ISO 24517-1 exempts none of the standard 14 fonts; the check applies to
/Type1,/TrueType,/Type0, and/MMType1alike - Preflight reports classify the new issue under content and recommend embedding every font program
- Delphi, Lazarus, and C++Builder tests cover a descriptor without a program, an embedded
/FontFile2, and a document that uses no font at all
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.6 consistently
Version 2.58.5
Added
InjectPdfEMarkersnow writes the output intent ISO 24517-1 §6.2 requires: an embedded sRGB ICC destination profile, a/GTS_PDFE1output intent naming it, and the catalog/OutputIntentsarray, all as part of the same incremental update- The profile stream derives its
/Nfrom the ICC header rather than assuming three components, so a CMYK profile would be described correctly - PDF/E validation reports
pveiMissingOutputIntentandpveiMissingIccProfile, so a candidate without a stated colour condition is no longer accepted - Delphi, Lazarus, and C++Builder tests cover an accepted output intent, one without a destination profile, and a catalog with no output intent at all
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.5 consistently
Version 2.58.4
Added
- PDF/X validation now reports
pvxiFontNotEmbeddedfrom a byte scan, so an unembedded font is caught on the DLL-free path instead of only through the PDFium-backed check - Unlike PDF/A, the standard 14 fonts are not exempt in PDF/X, so any font usage without an embedded font program is reported
- The check stays conservative: it fires only when the file shows font usage yet carries no
/FontFile,/FontFile2or/FontFile3at all, because counting descriptors against programs produces false positives on shared descriptors - Delphi, Lazarus, and C++Builder tests cover a descriptor without a program, an embedded program, and a document that uses no font
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.4 consistently
Version 2.58.3
Added
- PDF/X validation now reports
pvxiColorSpaceForbiddenwhen a PDF/X-1a candidate carries/DeviceRGB,/CalRGBor/Lab, which ISO 15930-1 §6.2 excludes from its CMYK exchange - The check is gated on PDF/X-1a alone, so PDF/X-3 and later keep permitting RGB and the device-independent spaces they pair with the output intent
- Only unambiguous colour space name tokens are tested; an
ICCBasedstream needs its/Nresolved and stays with the object-model layer - Delphi, Lazarus, and C++Builder tests cover a flagged RGB space, a flagged Lab space, an accepted CMYK and grayscale pair, and the permitted case on PDF/X-3
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.3 consistently
Version 2.58.2
Added
- PDF/X validation now reports
pvxiTransparencyForbiddenfor a transparency group or an active soft mask, which ISO 15930-1 §6.2 (PDF/X-1a) and ISO 15930-3 §6.3 (PDF/X-3) forbid - The check is gated on the detected conformance, so PDF/X-4 and PDF/X-6 keep permitting transparency and a file whose level could not be identified is never flagged for a rule that may not apply to it
- A soft mask explicitly switched off with
/SMask /Noneis not treated as transparency PdfHasActiveSMaskmoved fromFPdfPdfainto theFPdfPdfCommoninterface so every validator can share one soft-mask rule- Delphi, Lazarus, and C++Builder tests cover a flagged group on X-1a, a flagged soft mask on X-3, a disabled soft mask, and the permitted case on X-4
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.2 consistently
Version 2.58.1
Added
- PDF/X validation now checks the shape of the output intent required by ISO 15930-7 §6.2.4:
pvxiOutputIntentSchemereports a subtype that is present but is not/GTS_PDFX, andpvxiOutputIntentMissingIdentifierreports a missing/OutputConditionIdentifier - The subtype is matched as a whole name token, so a longer name such as
/GTS_PDFXVersionno longer passes, while a#xxescaped spelling of the same name still does - An output intent that carries no subtype at all is left alone, because its absence is already reported by the marker-level issues
- Preflight reports file both issues under the output intent category and suggest the fix
- Delphi, Lazarus, and C++Builder tests cover the accepted subtype, a PDF/A subtype, a longer name token, an absent subtype, and a missing condition identifier
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.58.1 consistently
Version 2.58.0
Changed
- All 35 callbacks PDFium invokes from its own C++ frames (form fill, XFA, JavaScript platform, progressive render pause, and stream read and write) now contain any Pascal exception and return the documented failure value instead of unwinding across the language boundary
- An event handler that raises, a failing allocation, or an unexpected error inside a callback can therefore no longer take the process down or leave PDFium in an undefined state
Fixed
- Registering a form timer leaked its entry when the underlying timer could not be created
Added
- Delphi, Lazarus, and C++Builder tests now cover saving into a destination stream that refuses writes and assert the document stays usable and savable afterwards
Version 2.57.8
Fixed
- Older Delphi releases (XE5 and earlier) stopped compiling the trial library with
E2003 Undeclared identifier: 'GetTickCount64'inFPdfPades.pas, because the Windows unit shipped with those compilers does not export the symbol - The same compilers also failed on
GetUserDefaultLocaleNameinPDFium.pasand on theTBytestoarray of Byteassignment inGetXfaFormPackets, so the XFA locale callback and packet snapshot now build on those compilers as well
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.8 consistently
Version 2.57.7
Changed
- Every save-side rewrite now truncates the destination stream before writing instead of only rewinding it, so a caller-supplied buffer that already held a longer document cannot keep a stale tail past the new
%%EOF - Delphi, Lazarus, and C++Builder tests now cover saving into a pre-filled stream
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.7 consistently
Version 2.57.6
Fixed
- The object scan that precedes encryption accepted digit runs of any length, so a long number anywhere in the file could wrap into a negative or bogus object number and add a phantom entry to the rebuilt cross-reference table
- Object numbers above the ISO 32000-1 Annex C limit and generations above 65535 are now rejected as object headers instead of being truncated
Added
- Delphi, Lazarus, and C++Builder tests now assert the exact in-use entry count of the rebuilt table
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.6 consistently
Version 2.57.5
Fixed
- Encrypting with
EncryptMetadata = Falsewrote/EncryptMetadata falseinto the Encrypt dictionary but still ciphered the document metadata stream, so a reader following that declaration found unreadable XMP - A
/Type /Metadatastream is now copied unchanged when metadata encryption is switched off, while every other stream is still encrypted
Added
AnsiNameTokenMatchesKeyis now part of theFPdfPdfCommoninterface for delimiter-aware name comparisons- Delphi, Lazarus, and C++Builder tests now cover both metadata encryption modes
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.5 consistently
Version 2.57.4
Fixed
- The cross-reference table rebuilt while encrypting omitted the mandatory object 0 free-list head required by ISO 32000-1 §7.5.4, so its first subsection started one object late
- Every rebuilt entry claimed generation 0; objects written with a higher generation now keep it, so the table agrees with the object headers it points at
Added
- Delphi, Lazarus, and C++Builder tests now cover the free-list head entry and generation preservation in the rebuilt table
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.4 consistently
Version 2.57.3
Fixed
- Encrypted output dropped the
streamkeyword of every stream object, so the saved file was no longer valid PDF syntax and strict readers reported the page content as neither a stream nor an array of streams - The
/Lengthrewrite matched/Lengthas a plain substring, so a stream dictionary carrying/Length1(any embedded font) had its key name corrupted while the real length stayed stale - A stream stating its length indirectly as
/Length N 0 Rhad the object number overwritten with the new length; the entry is now replaced by the direct encrypted length - A stream dictionary with no
/Lengthat all now receives one instead of leaving the reader without a length
Added
AnsiFindDictKeyTokenis now part of theFPdfPdfCommoninterface for top-level, delimiter-aware dictionary key lookups- Delphi, Lazarus, and C++Builder tests now cover
/Length1preservation, indirect length replacement, and stream-body size agreement
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.3 consistently
Version 2.57.2
Fixed
SaveAsEncryptedandSaveAsEncryptedToStreamwithRevision = erR6produced documents that rejected their own correct password in roughly one file out of four, because the ISO 32000-2 §7.6.4.3 algorithm 2.B round counter started one round too low and the extra round changed the/U,/O,/UE, and/OEvalues- R6 encrypted documents now reopen with the user or owner password in any conforming reader, and still reject a wrong password
Added
- Lazarus and C++Builder test suites gained encryption coverage that was previously Delphi-only: R6 key lengths, Encrypt dictionary fields, a repeated encrypt and reopen round trip, and wrong-password rejection
Changed
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.2 consistently
Version 2.57.1
Changed
- Typing in a form field, moving the caret, and toggling checkboxes now repaint only the area PDFium reports as damaged instead of the whole viewer
- Damage boxes are normalized for the upward page Y axis, widened by one pixel so anti-aliased widget borders stay clean, and clipped to the visible client area
- A damage box that is scrolled completely out of the viewport no longer schedules a repaint, while an inactive view or an unmapped page still falls back to a full repaint
- Delphi, Lazarus, and C++Builder tests now cover bounded form invalidation, flipped page boxes, off-screen boxes, and inactive-view safety
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.1 consistently
Version 2.57.0
Added
TPdfThumbnailView.Orientationsupports vertical and horizontal thumbnail layouts while preserving the existing vertical defaultFirstVisiblePageIndex,LastVisiblePageIndex, andEnsureCurrentPageVisibleexpose and control the thumbnail viewport with one-based page indexes
Changed
- Changing
CurrentPageIndexnow scrolls the selected thumbnail into view in either orientation - Delphi, Lazarus, and C++Builder tests now cover orientation defaults, switching, visible ranges, and selected-page visibility
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.57.0 consistently
Version 2.56.2
Changed
HighlightSearchText,AddSearchTextHighlight, andClearHighlightnow invalidate only the device rectangles for search ranges that were added or removed instead of repainting the full viewer- Replacing highlights with the same matches or appending duplicate matches no longer schedules an unnecessary repaint
- Delphi, Lazarus, and C++Builder tests now cover bounded invalidation, idempotent updates, clearing, and inactive-view safety
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.56.2 consistently
Version 2.56.1
Changed
TPdfThumbnailViewnow reuses rendered bitmaps for pages that remain visible across repaints and adjacent scroll positions- The cache retains only the current visible page range and releases entries precisely when pages leave that range, the assigned document changes, or thumbnail dimensions change
- Delphi, Lazarus, and C++Builder tests now cover cache reuse, viewport pruning, size invalidation, document replacement, and component destruction
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.56.1 consistently
Version 2.56.0
Added
TPdfView.CutSelectedFormTextToClipboardandTPdfView.PasteFormTextFromClipboardprovide Unicode clipboard editing for the focused editable form widget
Changed
- Focused form editors now handle the standard copy, cut, paste, and select-all keyboard shortcuts before forwarding text input to PDFium
- Cut and paste reject read-only fields and sessions without form-fill or modify permission, while cut copies successfully before removing selected text
- Delphi, Lazarus, and C++Builder tests now cover no-focus, round-trip shortcut, and read-only rejection behaviour
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.56.0 consistently
Version 2.55.0
Added
TPdfView.AddSearchTextHighlightappends unique matches for another search term to the current page overlay, allowing several queries to remain highlighted together
Changed
HighlightSearchTextremains the replacement entry point and now shares the additive scanner, while duplicate character ranges are ignored andClearHighlightremoves the complete accumulated set- Delphi, Lazarus, and C++Builder tests now cover distinct-query accumulation and duplicate-range suppression
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.55.0 consistently
Version 2.54.0
Added
TPdfnow exposes complete page-object snapshots, batched style updates, affine object transforms, path segments, clip paths, and Form XObject children- Character inspection now includes fill and stroke colours, font name and flags, loose glyph bounds, effective matrices, text-object handles, and character-to-text index conversion
- Annotations now round-trip border geometry and normal, rollover, and down appearance streams
- New raw and decoded thumbnail accessors, page-content and annotation transforms, and
RenderPageWithMatrixprovide direct advanced rendering and editing paths
Changed
- Page-object style changes can be committed as one batch so PDFium regenerates page content only once
- Matrix rendering uses the existing zero-copy bitmap path when the destination bitmap layout is compatible
Version 2.53.1
Fixed
- The built-in Chinese Copy menu caption now uses encoding-independent Unicode code points and displays correctly in Lazarus builds
- Older Delphi toolchains can compile
FPdfAsyncwhen theirWinapi.Windowsunit omits theGetTickCount64declaration
Version 2.53.0
Added
- New
Tests.ApiCoveragetest fixture covering public TPdf APIs that previously had zero end-to-end test coverage:GetPageBox/SetPageBox(MediaBox/CropBox read/write, missing-box errors, and save round-trip),FlattenPage/FlattenAllPages(return value and page-count preservation),GenerateFormAppearances(no-op on non-form documents),SaveAsEncrypted/SaveAsEncryptedToStream(AES-256 with password round-trip — verifies that the encrypted file refuses to open without the password and opens with it),DeletePageboundary validation (page 0 and out-of-range raiseEPdfError), and theHasContents/HasAuthorannotation sentinels introduced in v2.38.0 (verifyingDefault(TPdfAnnotation)leaves themFalse)
Version 2.52.0
Added
TPdfView.CopySelectedFormTextToClipboardcopies the text selection inside the focused AcroForm widget to the Windows clipboard asCF_UNICODETEXT
Changed
- Page-text and focused-form copy operations now share the same defensive Unicode clipboard writer and leave the clipboard unchanged when their selection is empty
- Delphi, Lazarus, and C++Builder tests now cover inactive or unfocused form-copy calls and a focused form selection round trip through the Windows clipboard
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.52.0 consistently
Version 2.51.0
Added
TPdfView.SelectLineAtselects the visual text line containing a one-based page and zero-based character index without requiring mouse input
Changed
- Programmatic line selection, triple-click selection, and
Shift+HomeorShift+Endnow share one character-box line-boundary model - Delphi, Lazarus, and C++Builder tests now cover stable line selection and invalid page or character indexes
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.51.0 consistently
Version 2.50.0
Added
TPdf.LoadDocumentnow accepts a zero-basedIndexandCountwindow into aTBytesbuffer, allowing embedded PDFs to load without allocating a temporary byte-array slice
Changed
- Byte-range loading rejects negative or out-of-bounds windows before changing document state and preserves the existing buffered and borrowed-buffer lifetime options
- Delphi, Lazarus, and C++Builder tests now cover embedded PDF windows and invalid byte-range arguments
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.50.0 consistently
Version 2.49.1
Added
TPdfView.FitModenow supportspfmFitHeightfor fitting the current page to the visible viewport height while allowing horizontal scrolling when needed
Fixed
- Fit modes now converge after scrollbar visibility changes the client area, keeping fit-page, fit-width, and fit-height results consistent across VCL and LCL
- Delphi, Lazarus, and C++Builder viewer tests now cover
pfmFitHeightselection and enum round trips TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.49.1 consistently
Version 2.49.0
Added
- The public PDFium binding surface now covers all 470 exported functions in the reviewed headers, including attachment description access through
FPDFAttachment_SetDescriptionandFPDFAttachment_GetDescription TPdfnow exposes attachment descriptions, cross-reference validity, trailer end offsets, security-handler revision, 64-bit memory loading, signature byte ranges, web-link text ranges, and expanded image data, filter, metadata, and ICC profile snapshots- Form helpers now support native field focus, focused choice-option queries and updates, mouse-wheel forwarding, writable ink strokes, and form overlays after progressive rendering
Changed
FormFieldCount, form-field indexes, and tab order now describe only widget annotations instead of including unrelated page annotations- Headless
TPdfpages now enter and leave the form-fill page lifecycle so native focus and focused-field APIs work without aTPdfView - Attachment description exports are capability-gated so applications using an older PDFium build can still load the library and detect the unavailable feature
Fixed
- Progressive page rendering now paints form controls when form filling is enabled
- Delphi, Lazarus, and C++Builder tests now cover the new document diagnostics, attachment descriptions, ink paths, form behavior, signature byte ranges, web-link ranges, and image metadata
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.49.0 consistently
Version 2.48.0
Added
TPdfMatrixnow exposes factories, cloning and assignment, finite-state and invertibility diagnostics, tolerance-based comparison, translation access, determinant reporting, and affine decomposition- Prepend composition, pivot-aware rotation, scaling, skewing and flips, plus stretch, contain and cover rectangle mapping support local-space and fitted-layout workflows without manual coefficient arithmetic
- Non-mutating inverse access, inverse point mapping, vector and quadrilateral transforms, dynamic point and rectangle batches, in-place variants, and one-pass transformed bounds expand the reusable geometry surface
Changed
- Translation, scaling and axis flips now update only the affected coefficients instead of routing through general affine multiplication
- Rectangle transformation normalizes its input once, uses a specialized exact axis-aligned path where possible, and computes general rotated bounds without temporary point records
- Point and rectangle batch transforms allocate one result array or reuse caller storage, while transformed point bounds are accumulated in one pass without an intermediate array
Fixed
- Rectangle mapping rejects zero-sized, non-finite, and
Single-overflowing results before publishing an unusable matrix - Delphi, Lazarus, and C++Builder tests now verify composition order, pivot invariants, inverse round trips, fitted rectangles, decomposition, and bulk geometry behavior
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.48.0 consistently
Version 2.47.0
Added
FPdfAsyncnow provides structured cancellation reasons and messages, removable callback registrations, timeout-backed sources, cancellation waiting, and atomic try-cancel operations through extended interfaces that preserve the original APITPdfFuture<T>.RunExadds configurable reply dispatch and worker priority while result envelopes expose operation IDs, value validity, exception class names, completion timing, and reusable completion helpersTPdfAsyncExecutoradds a reusable fixed worker pool with four FIFO priority lanes, optional bounded-queue backpressure, cancelable task handles, timeout-aware waiting, task snapshots, aggregate statistics, and graceful shutdown
Changed
- Repeated asynchronous jobs can reuse worker threads and O(1) queue operations instead of creating a thread for every task, while synchronized completion remains available for UI hosts
- Executor and future failures preserve exception class and message diagnostics, cancellation keeps its original reason, and callback exceptions remain isolated from worker lifecycle and shutdown
- Delphi, Lazarus, and C++Builder tests now cover the extended cancellation, future metadata, task control, backpressure, priority ordering, statistics, failure, and shutdown surface
Fixed
- Concurrent cancellation owners now receive a deterministic first-writer result instead of relying on a separate observation and cancel sequence
- Main-thread idle waiting processes synchronized task replies, preventing a completed worker from leaving the executor permanently non-idle during coordinated shutdown
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.47.0 consistently
Version 2.46.0
Added
FPdfAsn1now exposes identifier classes, 64-bit high-tag-number encoding and decoding, parsed TLV records, zero-copy child reader windows, typed primitive decoders, and content or encoded-value slices- DER writers now support the full unsigned 64-bit INTEGER range, validated arbitrary INTEGER content, ENUMERATED, automatic UTCTime or GeneralizedTime selection, application and private tags, multi-value SEQUENCE, and canonically sorted SET OF output
ValidateDerreturns offset-aware validation errors while enforcing configurable nesting, node-count, content-length, error-count, root, and optional SET ordering limits
Changed
- DER concatenation and multi-value composition use one output allocation, writer buffers expose reserve, count, capacity, and ownership-transfer operations, and SET OF sorting now uses
O(n log n)merge sorting - BOOLEAN, INTEGER, BIT STRING, OBJECT IDENTIFIER, NULL, UTF8String, PrintableString, IA5String, UTCTime, and GeneralizedTime values receive canonical form checks during encoding, typed decoding, or validation
- The Lazarus runtime package now exports
FPdfAsn1, and Delphi, Lazarus, and C++Builder test suites exercise the same public DER surface
Fixed
- Context-specific tag numbers greater than 30 are no longer truncated into the low five identifier bits
- Malformed high-tag identifiers, non-minimal definite lengths, invalid UTF-8, non-zero BIT STRING padding, invalid time fields, trailing roots, and resource-limit violations are rejected deterministically
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.46.0 consistently
Version 2.45.0
Added
FPdfPreflightReportnow assigns Info, Warning, or Error severity to every issue and exposes per-standard and report-level severity, status, category, issue-code, lookup, search, flattening, and filtering APIs- Preflight reports now export SARIF 2.1.0, JUnit XML, NDJSON, and native XML through matching
To*andSave*ToFilemethods for CI, automation, and streaming pipelines - Stable SHA-256 report fingerprints identify equivalent validation results independently of source paths and generation timestamps
Changed
- JSON, CSV, text, Markdown, and HTML reports now include severity and expanded status summaries; HTML adds accessible table captions and a status summary
- Issue and standard collection construction uses geometric capacity growth, query results are pre-sized, JSON escaping writes into one bounded output buffer, and all report files use one direct UTF-8 writer
- Issue-category summaries use deterministic ordering, timestamps include milliseconds, JSON carries
formatVersion: 2, and CSV cells neutralize spreadsheet formulas
Fixed
- JSON export now preserves valid supplementary Unicode pairs and replaces isolated UTF-16 surrogate code units instead of emitting malformed scalar data
- HTML export now escapes apostrophes, and filtered report views own independent issue arrays instead of sharing mutable result storage
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.45.0 consistently
Version 2.44.0
Added
- Bookmarks and destinations expose open state, descendant counts, action targets, destination view modes, and up to four view parameters
Metadata,GrantedPermissions,UserGrantedPermissions,HasPermission, andUserHasPermissionprovide typed document-inspection snapshots and permission queriesExtractThumbnail(PageNumber)renders a requested page without changing the active page, and RFC 3161 timestamp results expose policy, generation time, and nonce details
Changed
- Bookmark, JavaScript, metadata, destination, and thumbnail paths use validated two-pass buffers, geometric collection growth, and cycle-safe traversal
- Save post-processing resolves the active catalog, page tree, and open action through the current xref revision, caches decoded object streams, and scans PDF dictionaries with lexical boundaries
- Shared PDF parsing now enforces exact object headers, generations, dictionary keys, stream lengths, predictor geometry, integer ranges, and comment, literal-string, and hexadecimal-string boundaries
- RFC 3161 response validation now binds both nonce and SHA-256
messageImprint, requires a structurally valid signer, and applies strict DER length, OID, INTEGER, and GeneralizedTime rules
Fixed
- Incremental documents no longer select inactive duplicate catalogs or malformed reference suffixes when adding a default open action
- Timestamp tokens with long-form DER lengths retain the complete encoded token, while malformed CMS optional-field ordering and empty signer sets are rejected
- Clean Delphi builds now write PAdES nonce seed fields through aligned-safe byte copies and pass XFA response bytes with the exact native pointer type
TPdf.AboutInfo, Lazarus package metadata, and installer metadata now report Version 2.44.0 consistently
Version 2.43.0
Added
- XFDF field and annotation records now expose presence flags that distinguish an omitted XML value from an explicitly empty value
Changed
- XFDF import accepts namespace-prefixed elements and attributes, mixed text and CDATA content, entity references, and whitespace-significant values while rejecting invalid Unicode scalar references
- XFDF import and export use indexed field matching and bounded geometric buffers, improving throughput and peak allocation behaviour for deeply nested forms, large annotation collections, ink lists, vertices, and markup quadrilaterals
- PDF/A and PDF/UA validation use bounded growth for large page, stream, structure-name, and RoleMap collections; PDF/UA RoleMap resolution now follows direct arrays and exact-generation indirect name or array objects
Fixed
- XFDF round-trips now preserve deeply nested field paths, explicit empty field values, explicit empty annotation contents, and the distinction between absent and empty contents
- Invalid memory-buffer loads and out-of-range page assignments are rejected without leaving partial document or page state, and a failed native page reload preserves the previously active page
- Large marked-content identifiers and signature metadata buffers are bounded and validated before allocation or native access
Version 2.42.0
Added
TPdfMatrixnow providesInvert,TryInvert,TransformPoint, andTransformRectfor coordinate mapping, hit testing, normalized bounds, and explicit singular-matrix handlingTPdf.WrapTextgained aBreakLongWordsoverload that splits CJK and other text without spaces while keeping valid UTF-16 surrogate pairs togetherTPdfAnnotation.AttachmentPointSetsexposes every quadrilateral in multi-line markup annotations while the existingAttachmentPointsfield remains an alias for the first set
Changed
- Text extraction, readable-content construction, word lookup, and spoken-text offset mapping now use bounded allocation and binary lookup paths, reducing repeated allocations and linear scans on large pages
- ASN.1 serialization and encrypted PDF generation now use geometric output buffers; encrypted-object ordering uses
O(n log n)sorting and xref rows are written directly to the final buffer WrapTextpreserves CR, LF, and CRLF line boundaries and reuses one native measurement object for the whole operation- XFDF import and export preserve every markup quadrilateral; import also applies RGB/interior colors and parses decimal coordinates independently of the process locale
Fixed
- Legacy callers can again update annotation content and author by assigning non-empty strings without setting the newer
HasContentsandHasAuthorsentinels - Explicitly empty annotation strings now use a valid zero-terminated native buffer, so clearing
/Contents,/T, and other optional text keys no longer passes a nil pointer to PDFium
Version 2.41.0
Changed
- Preflight report
SaveJsonToFile,SaveMarkdownToFileandSaveTextToFilenow write UTF-8 on Delphi (matching the existingSaveHtmlToFile), instead of the system ANSI code page. Non-ASCII characters in file paths, recommendations and scope notes were garbled on Delphi when saved through these methods SaveCsvToFilenow writes UTF-8 with a BOM prefix, so Excel for Windows auto-detects the encoding. Without the BOM, Excel treats a UTF-8 CSV as code-page 1252 and mangles any non-ASCII characters
Fixed
- The
ExtractImagesdemo leaked the cachedTBitmapobjects inFExtractedImageswhen the form was closed without explicitly clearing them first. The form now overridesDestroyto callClearExtractedImages, releasing every cached bitmap
Version 2.40.0
Changed
TPdf.RenderPage(HDC, ...)now masks FPU/SSE exceptions around theFPDF_RenderPagecall, matchingTPdfView.RenderPage(HDC)(fixed in v2.25.0) and every bitmap-returning rendering entry point. TheTPdf-level direct-to-DC overload previously left FPU exceptions unmasked on pre-D12 compilers
Fixed
ColorToARGBnow returns a fully transparent pixel (alpha 0) forclNoneandclDefaultinstead of treating the sentinel value as a literal RGB colour. The previous behaviour produced a dark, nearly opaque fill when a caller passedclNoneexpecting “no colour”
Version 2.39.1
Fixed
- Explicit PDF 1.3 saves now remove
/SMask /None,/AIS false, and/TK trueentries that only repeat the initial graphics state while continuing to reject non-default transparency state
Version 2.39.0
Changed
CreatePDFandImageToPDFnow use confirmed save destinations and report success only whenSaveAscompletes successfullyBatchExport,PDFtoJpg, andSplitPDFnow allocate unique output directories so repeated runs and same-named inputs preserve earlier resultsSplitViewnow wraps search once without leaving hidden page state behind after cancellation or no match, and aborts incomplete print jobs instead of submitting partial output
Fixed
MergePDFnow rejects malformed page-range tokens and source-overwriting output paths, counts the pages actually imported, and refuses to save an empty result- The Delphi and C++Builder
Attachmentdemos now commit same-path saves through rollback-safe file replacement so a failed rename cannot remove the original PDF
Version 2.38.0
Changed
SetAnnotationDatanow guards the/Contentsand/Authorwrites behindHasContents/HasAuthorsentinels onTPdfAnnotation, matching the existingHasName/HasSubject/HasIconpattern. Previously these two fields were written unconditionally, so assigning aDefault(TPdfAnnotation)record to update only colour or flags silently overwrote the annotation's existing content and author with empty strings.GetPageAnnotationnow sets the sentinels so a read-modify-write cycle preserves the original values
Fixed
GenerateFormAppearancesnow reads the checkbox/radio button value viaFPDFAnnot_GetFormFieldValue(which walks to the parent field dictionary per ISO 32000-1 §12.7.5) instead ofFPDFAnnot_GetStringValue(Annot, 'V', ...)(which reads the widget dictionary). The widget usually carries no/V, so/ASwas never synced to the checked state and a flattened checkbox/radio rendered as unchecked
Version 2.37.0
Changed
ParseTsaUrlnow clamps the port to1..65535after parsing; an oversized port value would otherwise wrap viaDWORDtruncation and could land on a valid port- XFDF
ParseFieldnow accepts a depth parameter (default 0, capped at 64) and returns an empty field at the limit, so a maliciously nested 100 000-deep<field>chain can no longer overflow the stack
Fixed
- TSA HTTP request now guards against an empty request body before passing
@ReqDer[0]toWinHttpSendRequest. A zero-length dynamic array dereference would access an ungrounded pointer;BuildTimeStampReqalways returns a non-empty SEQUENCE, but the call site now defends the contract
Notes
- The
FPdfTsaWinheader comment about HTTPS revocation checking has been corrected: WinHttp validates the server certificate chain by default but does not perform CRL/OCSP revocation checking unless explicitly enabled viaWinHttpSetOption. The previous wording claimed revocation checking “comes for free”, which was misleading
Version 2.36.0
Changed
- TSA HTTP requests now send an explicit
Content-Lengthheader in addition to theContent-TypeandAcceptheaders. WinHttp synthesises it from the total length, but some RFC 3161 proxies require an explicit header and reject the request with411 Length Requiredwithout it - XFDF export now drops C0 control characters (other than TAB/LF/CR which are already escaped) instead of emitting an invalid backslash-hex sequence. The previous
\-01Fescape is not valid XML (backslash has no special meaning in XML), so any conforming reader would have rejected the document as malformed InjectAssociatedFilesnow writes/Subtypeon the EmbeddedFile stream dictionary when the caller suppliesTAssociateFile.MIMEType. The field was declared and documented but the injector previously hard-coded/Type /EmbeddedFileand ignored it (ISO 32000-2 §7.11.4 allows/Subtypeon the stream)
Fixed
- XFDF import skipped the first content byte after a UTF-8 BOM and the first byte when no BOM was present:
BytesToAnsi(Bytes, 4, ...)(BOM) andBytesToAnsi(Bytes, 1, ...)(no BOM) used off-by-one start offsets becauseBytesToAnsitakes a 0-based array index. The calls now use3and0 ExtractSignatureValuehad two dangling-ifindentation bugs whereR.Position:= CNran unconditionally for the optionalcertificates [0]andsignedAttrs [0]branches. The branches are now wrapped inbegin/endso the position is advanced only when the optional TLV was actually read (same class of bug fixed inAddSignatureTimestampToCmsin v2.22.0)
Version 2.35.0
Changed
TFPDFAvail_IsDocAvail,TFPDFAvail_IsPageAvailandTFPDFAvail_IsFormAvailnow takehints: PFX_DOWNLOADHINTSinstead ofvar hints: FX_DOWNLOADHINTS, so the documentednullptrquery-only mode (check current availability without requesting more data) is reachable from Delphi. The PDFium header explicitly allowshintsto be null; the previousvarbinding made that impossibleTFPDF_SetSystemFontInfonow takespFontInfo: PFPDF_SYSFONTINFOinstead ofvar pFontInfo: FPDF_SYSFONTINFO, so callers can passnilto tell PDFium to stop using a previously registered system font interface (the documented disable path)TPdfThumbnailView.Paintnow computesVisibleRowswith the same formula asUpdateScrollBarRange(ClientHeight div RowHeight), so the number of rows painted matches the scrollbar page size. The previous paint-only formula ((ClientHeight - FMarginY) div RowHeight + 1) could differ by one row at edge heights, wasting a render on an off-page row or missing the last visible row
Version 2.34.0
Added
TPdf.SaveAsEncrypted/SaveAsEncryptedToStream— high-level API that saves the document then encrypts it with PDF 2.0 AES-256-CBC (V=5/R=5/R=6). Takes aTPdfEncryptOptionswith user/owner password, permissions and revision; delegates toEncryptDocumentBytes- StrF literal-string encryption:
EncryptDocumentBytesnow encrypts(...)literal strings in non-stream objects (Info dictionary, etc.) to AES-256-CBC hex strings, matching the stream encryption format (16-byte IV + PKCS7 ciphertext). Hex strings<...>are left untouched
Version 2.33.0
Added
- Full-document AES-256-CBC encryption injector in
FPdfEncrypt.pas.EncryptDocumentBytestakes a plaintext PDF and a password, encrypts every indirect stream object (16-byte IV + AES-256-CBC PKCS7 under the file key), patches/Length, appends the/Encryptdictionary object, and rebuilds a complete classic cross-reference table + trailer with/Encryptand/ID. Completes the PDF 2.0 encryption stack (AES block + GCM + SHA-512/384 + R6 key derivation + dictionary + document sweep) EncryptStreamPayloadhelper — the PDF 2.0 AES-256 stream format (IV prepended to AES-CBC-PKCS7 ciphertext), reusable by callers that manage their own object layout
Version 2.32.0
Added
- SHA-512 / SHA-384 hash (FIPS 180-4) in the new
FPdfSha512.pasunit, implemented in pure Pascal. Required by the PDF 2.0 R6 password-hash iteration, which branches on a 128-bit mod-3 value to pick SHA-256/384/512 each round. FIPS-180-4 B.1 known-answer verified - PDF 2.0 encryption key derivation and Encrypt dictionary builder in the new
FPdfEncrypt.pasunit. Implements ISO 32000-2 §7.6.4.3 algorithm 2.B (R6 hash dance: AES-128-CBC + iterative SHA-256/384/512 selection), derives the 32-byte file encryption key plus the/O,/U,/OE,/UE,/Permsentries, and builds the V=5/R=5/R=6 Encrypt dictionary with/CFM /AESV3. Uses TBytes-style byte buffers
Version 2.31.0
Added
- AES block cipher primitives (FIPS 197) in the new
FPdfAes.pasunit. Pure-Pascal AES-128 and AES-256 block ciphers plus CBC mode helpers and a CSPRNG backend. FIPS-197 Appendix C.2 / C.3 known-answer tests verify correctness. This is the cryptographic foundation for the PDF 2.0 encryption stack - AES-GCM authenticated encryption (NIST SP 800-38D) in the new
FPdfAesGcm.pasunit. Implements GHASH (GF(2^128) multiplication), GCTR and the GCM AEAD construction on top of the AES block primitives. NIST GCM test cases 1 and 3 (AES-128) match the authoritative ciphertext and tag exactly; test case 13 (AES-256) round-trips. GCM is the ISO/TS 32003 mode for PDF 2.0 - PDF/A Level A ParentTree and ClassMap integrity validation (ISO 19005-1 §6.8.3).
pvaiParentTreeMissingflags a StructTreeRoot without the /ParentTree number tree;pvaiClassMapUnresolvedflags a /C class reference without a /ClassMap
Version 2.30.0
Added
- Associate Files injection (
InjectAssociateFiles/TPdf.SaveAsWithAssociateFiles, ISO 32000-2 §7.11.4). The newFPdfAssocFilesunit attaches/AFarrays of filespec references to the catalog or any page dictionary, covering all eight ISO 32000-2 Table 45/AFRelationshipvalues. Reuses the incremental-update pattern proven byInjectPadesDssMarkers - PDF/X-6 (ISO 15930-9:2020) support.
TPdfXConformanceaddspxc6; the injector and validator thread it throughpdfxid:GTS_PDFXVersionidentification. PDF/X-6 is the PDF 2.0-based successor to PDF/X-4 for complete exchange - PDF/A forbids the
/Threadaction (ISO 19005-1 §6.6.1 whitelist gap). The forbidden-action list now covers Thread alongside Launch, ResetForm, ImportData, SetOCGState, SetState, GoTo3DView, Rendition and Hide
Fixed
- PDF/A-4e validation path now honours the same tagged-structure, MarkInfo and word-break checks as Level A. The v2.29.0 save-side downgrade covered
PdfAIsLevelE, but threeValidatePdfACompliancegates checkedPdfAIsLevelAalone, so a PDF/A-4e document lacking tagged structure passed silently - OCG
/BaseStatetest drift: the v2.28.0 PostProcess pass correctly widened acceptance to/ONor/OFF(ISO 32000-1 Table 8.70), but the Delphi and C++ tests still expected/OFFto be rejected. Tests now use a truly invalid value (/Undefined) and a new positive test locks the/OFFacceptance - Geospatial
/Subtype /GEOover-matching:ContainsDictionarySubtype('GEO')matched any dictionary carrying the token, including unrelated ones like a stray/ViewerPreferences << /Subtype /GEO >>. The newContainsMeasureDictionarySubtypeadditionally requires/Type /Measureor a Measure-exclusive sibling key, so non-Measure dictionaries no longer trip the ADBE ExtensionLevel 3 requirement
Version 2.29.0
Added
- PDF/A-4 (ISO 19005-4:2020) support across the validator, XMP injector and Pdfium object-model layer.
TPdfAConformanceaddspac4base,pac4fandpac4e; the base level is PDF 2.0 (ISO 32000-2) and replaces the legacy A/B/U levels with base + F (form) + E (accessibility).ValidatePdfAreads apdfaid:part=4XMP packet (base omits the conformance element),SaveAsPdfAemits it, andSignPadesWithPdfAacceptspac4baseas a long-term archive container FPDFBookmark_GetColorbinding — the last unbound PDFium public export (469/469).TBookmarkgainsHasColorandColorfields populated from the bookmark/Carray (ISO 32000-1 §12.3.3). The binding uses tolerant loading so older DLLs that predate the export keep working- PDF/E-1 (ISO 24517-1 §5) header version check
pveiBadPdfVersion— PDF/E-1 is based on PDF 1.6 and a non-1.6 header is now flagged - PDF/R-1 (ISO 23504-1)
pvriEncryptVersionMismatch— encryption is permitted only on a%PDF-2.0header; a 1.x body carrying/Encryptis now flagged (previously a no-op statement) - PDF/R-1
pvriBadMediaBox— each pageMediaBoxshall be[0 0 w h];PdfRHasNonZeroMediaBoxOriginis a locale-independent ASCII scanner that skips indirect-reference MediaBoxes - PDF/A Level A
pvaiRoleMapUnresolved(ISO 19005-1 §6.8.3.4) — a present-but-incomplete RoleMap that leaves custom/Sstructure types unmapped is now flagged, closing the gap left by the existing presence-onlypvaiRoleMapMissingcheck
Fixed
PdfVersionToName(20)returned"1.0"instead of"2.0", corrupting the catalog/Versionentry and validator messages for every PDF 2.0 save. The formatter now splits major.minor explicitly for version codes>= 20FPdfAsn1.pasnegative-INTEGER encoder failed to compile under Delphi 12 (E2015onInteger(-(V<0))), blocking the whole test project. Fixed by usingInt64(-Ord(V<0))for the sign-extension mask- PDF/A forbidden-annotation list now includes
/RichMediaacross all parts (previously missed; ISO 32000-1 §12.5.6.35 forbids it in PDF/A)
Version 2.28.0
Added
TPdfVersionnow includespv20for PDF 2.0 (ISO 32000-2).DecodePdfVersion(20)returnspv20instead ofpvUnknown, andEncodePdfVersion(pv20)emits 20 so a PDF 2.0 document's version is no longer lost on read-back and can be written explicitly
Changed
DecodeDatenow parses PDF date strings with optional trailing fields per PDF Reference 3.8.3, instead of requiring the full 23-characterD:YYYYMMDDHHmmSSOHH'mm'form. Conformant truncated dates such asD:20260712,D:20260712153000, andD:20260712153000Zare now accepted; previously they were rejected by a hardLength=23gate. Timezone hour offset is now validated against the real-world UTC-12..UTC+14 range instead of> 23FPdfMeasure.MeasureTextnow encodes the font name as FPCAnsiString/ DelphiUTF8Encode, matching the library's other FPDF_BYTESTRING call sites, instead of a bareAnsiStringcast that garbled non-ASCII family names through the current code page
Fixed
TDerWriter.Integernegative-value path crashed or produced malformed DER: the loopwhile V <> -1 do V := V shr 8leftInnerempty forValue = -1(range error on the subsequentInner[Length(Inner)-1]) and over-produced bytes for other negatives. The encoder now extracts two's-complement bytes with sign-extending shifts and stops correctly when the remainder is pure sign extension. CMS/PAdES INTEGER fields are positive, so this only affects callers passing negative values, but the path is now correctTPdf.GetCharacterOriginandTPdfView.GetCharacterOriginignored theFPDFText_GetCharOriginreturn value and returned an uninitialised point on failure. The result is now zero-initialised and a failed read returns the origin (matchingGetCharacterRectangle's contract)
Version 2.27.0
Changed
- The Delphi, C++Builder, and Lazarus
PDFViewerandMultiPageViewerdemos now wrap document searches once, acceptEnterandF3for the next result, reset the search context when match options change, and reserveEscfor cancelling an active search or print job - Viewer printing now follows the current viewer rotation and selects portrait or landscape output accordingly, so toolbar rotation is reflected in printed pages
- All three
ViewerInteractionLabdemos now supportCtrl+A,Ctrl+C,Enter,F3, andEscshortcuts without intercepting native edit-control selection and copy commands
Fixed
- C++Builder and Lazarus viewer print cancellation now aborts the printer job instead of submitting the pages rendered before cancellation, and Lazarus explicitly exits every nested copy, page, and collation loop
- The Delphi
MultiPageViewerCancel button is now connected to its handler, and C++Builder/LazarusMultiPageViewersearch fields retain native arrow, Home, and End key editing
Version 2.26.0
Changed
TPdf.GetObjectBitmap,TPdf.GetBitmap,TPdf.GetThumbnailand theirTPdfViewcounterparts now acquire the render lock around theFPDFImageObj_GetBitmap/FPDFPage_GetThumbnailAsBitmapcall, matchingRenderPage/RenderTile. These are PDFium rendering-side calls that previously ran without the lock and could race with a concurrentUnloadPage/ReloadPageon the same documentTPdf.RenderPageThumbnailnow honours the page/Rotateentry: the fit is recomputed from the rotated dimensions for/Rotate 90or270pages so the thumbnail aspect ratio matches what the viewer shows, instead of using the intrinsic (unrotated) dimensions returned byFPDF_GetPageSizeByIndex
Fixed
TPdfView.GetCharacterRectangleignored the return value ofFPDFText_GetCharBoxand passed an uninitialisedTPdfRectangletoPageToDevicewhen PDFium reported failure. The rectangle is now zero-initialised and a failedGetCharBoxreturnsRect(0,0,0,0)GetLinkAnnotationsURI path and file path buffer length was off by one: the secondFPDFAction_GetURIPath/GetFilePathcall passedsize(which includes the trailing NUL) as the buffer length to a buffer allocated assize-1. The call now passessize-1so it cannot write past the allocation on a PDFium build that does not self-clamp
Version 2.25.0
Changed
TPdf.AddText,SetText,AddPathandInsertFormObjectFromXObjectnow invalidate the cached text page and link annotations before regenerating page content, matchingSetTextPositionsandRemoveObject. Previously aGetText/GetWebLinks/FindFirstcall after editing the page returned stale text and link data captured before the edit, and the retainedFPDF_TEXTPAGEhandle was used after content regeneration with undefined behaviourTPdfView.RenderPage(HDC, ...)now acquires the render lock and masks FPU/SSE exceptions around theFPDF_RenderPagecall, matching every other rendering entry point. The previous direct-to-DC overload could race with a concurrentUnloadPage/ReloadPageon the same document and left FPU exceptions unmasked on pre-D12 compilers- The Delphi
PrintPDFdemo now callsPrinter.Aborton cancellation instead of letting thefinallyblock reachPrinter.EndDoc, which submitted the pages rendered before the cancel. The Lazarus demo already handled this correctly
Fixed
TPdf.GetCharacter,TPdf.GetCharcodeand theirTPdfViewcounterparts truncated astral-plane code points (emoji, CJK Extension B) returned byFPDFText_GetUnicodeto the low 16 bits viaWideChar(), producing a lone surrogate that corrupted downstream text processing. Characters above U+FFFF now return U+FFFD (replacement character); useGetTextto retrieve the full UTF-16 encoding of astral charactersGetWebLinkscalledSetLength(Rectangles, FPDFLink_CountRects(...))without guarding against a-1return, which raised anEOutOfMemoryon a malformed page. A negative count is now clamped to zeroTPdf.Destroynow scrubs thePasswordstring from memory (viaUniqueString+FillChar) before the reference-counted buffer is released, so the password is not left readable on the heap after the component is destroyed
Version 2.24.0
Added
TPdf.DeletePage,GetAttachment,GetAttachmentName,GetAttachmentType,SetAttachmentandDeleteAttachmentnow validate the page/attachment index and raiseEPdfErroron an out-of-range value, matching the existing behaviour of the annotation accessors. Previously an out-of-range index was passed straight to PDFium and produced a silent no-op or undefined behaviour
Fixed
- Page-object handle leaks on failure in
TPdf.AddText,AddBitmapandAddJpegImage: whenFPDFText_SetText,FPDFImageObj_SetBitmap,FPDFImageObj_SetMatrixorFPDFImageObj_LoadJpegFileInlineraised after the object was created but beforeFPDFPage_InsertObjecthanded it to the page, the nativeFPDF_PAGEOBJECThandle was leaked. Each path now destroys the object on the exception before re-raising TPdf.UnloadPagediscarded an in-progressFPathhandle (set byCreatePathbut not yet consumed byAddPath) by setting it tonilwithout callingFPDFPageObj_Destroy. The handle is now destroyed so a path created then abandoned (or interrupted by a page switch) no longer leaksTPdf.InsertFormObjectFromXObjectomitted theUpdatePage(FPDFPage_GenerateContent) call that every sibling insertion (AddText/AddPath/AddBitmap/AddJpegImage/SetText/RemoveObject) performs, so a Form XObject inserted this way vanished on the next reload or save.UpdatePageis now called after the insertion
Version 2.23.0
Fixed
- Optional-content
/BaseStatevalidation now accepts/OFFin addition to/ON(ISO 32000-1 Table 8.70 permits both). The previous check rejected legitimate/OCProperties /D /BaseState /OFFconfigurations with a “malformed optional content” error even though the file was conformant - Optional-content
/Intentvalidation now accepts/Designand name arrays such as[/View /Design], not only the literal/View. ISO 32000-1 Table 8.70 defines/Intentas a name or array of names drawn from/Viewand/Design; the previous single-value check over-rejected standard authoring output - Geospatial Measure dictionary detection for the PDF 1.7
/Extensions /ADBEExtensionLevel 3 gate no longer requires/Type /Measure, which ISO 32000-1 Table 254 marks optional. GeoPDF producers that omit/Type(PDFBox, QGIS, FME) previously bypassed the gate and silently produced non-conformant PDF 1.7 output; the detector now matches/Subtype /GEOalone
Version 2.22.0
Changed
TPdfViewfit-zoom calculations (GetPageZoom,GetPageWidthZoom,GetPageHeightZoom) now useClientWidth/ClientHeightinstead of the windowWidth/Height, sopfmFitPage/pfmFitWidth/pfmFitHeightsize the page to the visible viewport rather than the outer frame including scrollbars and borders, eliminating the redundant scrollbar that appeared when the fitted page was slightly larger than the client areaAddSignatureTimestampToCmsnow raises an explicitExceptionidentifying the unreadable CMS SignerInfo field (version / sid / digestAlgorithm / signedAttrs / signatureAlgorithm) instead of silentlyExit-ing and letting a partial parse flow on as though it were a complete signed CMS; a missingbegin/endblock around the optionalsignedAttrs [0]branch that leftR.Positionun-advanced is also corrected
Fixed
- CNG private-key handle leak in
ResolveWinSigner: whenCryptAcquireCertificatePrivateKeysucceeded but the subsequent issuer/serial extraction orTWinCmsSigner.Createraised, theNCryptKeyHandlewas never freed because its ownership only transfers to the signer on a successful constructor. The post-acquire setup is now wrapped so the handle is released viaNCryptFreeObjecton any failure first EcDsaP1363ToDernow rejects an all-zerororshalf instead of emitting anINTEGER 0; ECDSA signatures withr = 0ors = 0are invalid (RFC 4754 §6 / FIPS 186-4 §6 require1 ≤ r, s ≤ n-1) and would otherwise be accepted as genuine by a lenient verifier
Version 2.21.12
Fixed
- Explicit PDF 1.5 through PDF 1.7 saves now reject malformed catalog
/OCPropertiesstructures, including missing required/OCGsor/Dentries, invalid default configuration values, and non-array state entries
Version 2.21.11
Fixed
- Explicit PDF-version saves now reject direct or indirect Page
/Annotsentries whose annotation dictionaries omit the required/Subtypeor/Rectentry
Version 2.21.10
Fixed
- Explicit PDF 1.7 saves now require geospatial
/Type /Measure /Subtype /GEOdictionaries and Projection annotations to declare/Extensions /ADBEwith/BaseVersion /1.7and/ExtensionLevel 3or newer
Version 2.21.9
Fixed
- Explicit PDF 1.7 saves now require RichMedia annotations and
RichMediaExecuteactions to declare/Extensions /ADBEwith/BaseVersion /1.7and/ExtensionLevel 3or newer
Version 2.21.8
Fixed
- Explicit PDF 1.7 saves now require PRC 3D streams to declare
/Extensions /ADBEwith/BaseVersion /1.7and/ExtensionLevel 1or newer, instead of treating PRC as a core PDF 1.7 feature
Version 2.21.7
Fixed
- Explicit PDF 1.4 and older saves now reject image XObject
/SMaskInDataentries, including an explicit value of0, because embedded JPEG 2000 soft-mask channels require PDF 1.5 or newer
Version 2.21.6
Fixed
- Explicit PDF 1.4 and older saves now reject 16-bit image XObjects, which require PDF 1.5 or newer, while PDF 1.5 through PDF 1.7 targets preserve their
/BitsPerComponent 16image data
Version 2.21.5
Fixed
- Explicit PDF 1.4 and older saves now reject document catalog
/PageLayout /TwoPageLeftand/TwoPageRightvalues, which require PDF 1.5 or newer, while PDF 1.5 through PDF 1.7 targets preserve the requested two-page layout
Version 2.21.4
Fixed
- Explicit PDF 1.3 saves now reject document catalog
/Langentries, which require PDF 1.4 or newer, while PDF 1.4 through PDF 1.7 targets preserve the language identifier
Version 2.21.3
Fixed
- Explicit PDF 1.3 saves now reject document
/EmbeddedFilesname trees, which require PDF 1.4 or newer, without rejecting embedded-file streams referenced through older file specifications
Version 2.21.2
Fixed
- Explicit PDF 1.3 saves now reject active metadata streams, which require PDF 1.4 or newer, while preserving them for PDF 1.4 through PDF 1.7 targets
Version 2.21.1
Fixed
- Hybrid-reference validation now applies supplemental
/XRefStmentries before same-revision classic xref placeholders, so compressed annotations and other version-gated objects are no longer missed when the compatibility table marks them free
Version 2.21.0
Changed
- All Delphi, C++Builder and Lazarus viewer examples can open a PDF passed as the first command-line argument, and the C++Builder and Lazarus
MultiPageViewerexamples provide explicit select-all and copy shortcuts
Fixed
- Viewer examples now reject invalid bookmark and link page targets, preserve load errors, validate manual zoom input consistently, print the requested form-filled page instead of repeating the visible page, and abort cancelled Delphi print jobs instead of submitting partial output
Version 2.20.0
Changed
- All Delphi, C++Builder and Lazarus viewer examples now provide consistent shortcuts for opening, searching, saving, printing, zooming and page navigation, while every
ViewerInteractionLabvariant also supports page jumps, validated 10–600% manual zoom, persistent interaction logs and click-coordinate round-trip checks
Version 2.19.1
Fixed
- Explicit PDF-version validation now follows the active classic, hybrid or xref-stream revision chain, including compressed-object entries, so superseded, freed and unreferenced objects no longer cause false feature-version failures
Version 2.19.0
Changed
- The C++Builder and Lazarus attachment, image extraction, text extraction, page conversion and split examples now use dedicated output folders or safely finalised files, stable zero-padded names, responsive progress updates, and completion summaries with per-item error counts
Fixed
- The C++Builder
CJKTextLabnow measures text through the exported PDFium editing functions, andMergePDFavoids an ambiguous VCL message overload, restoring clean RAD Studio 37 builds
Version 2.18.3
Fixed
- The PAdES B-LTA Document Time-stamp is now registered as a discoverable signature field — an invisible Widget reachable through the first-page
/Annotsand the AcroForm/Fields(ETSI EN 319 142-1 §5.4.3) — instead of an unreachable orphan object that signature-field-enumerating validators could not find; existing annotations and fields are preserved
Version 2.18.2
Fixed
- PAdES signing and classic cross-reference writing now raise a clear error when a byte offset exceeds the fixed 10-digit field width (~9.3 GB) instead of silently leaving the
/ByteRangeplaceholder unwritten (producing an invalid signature) or overrunning the 20-byte xref line (ISO 32000-1 §7.5.4); cross-reference-stream output uses 8-byte binary fields and is unaffected
Version 2.18.1
Fixed
- PAdES signing now resolves indirect first-page
/Annots,/AcroFormand/Fieldsreferences by whole object header (ISO 32000-1 §7.5.3) and by the reference's actual generation number; a bare substring search previously matched an object number inside a longer one (resolving5 0 Rto15 0 obj) and a hard-coded generation missedgen>0objects, corrupting the signature field arrays or rejecting valid documents - When the catalog, first page,
/Annots,/AcroFormor/Fieldslives inside an object stream, signing now retries on an expanded copy before failing instead of rejecting the document outright
Version 2.18.0
Added
ReadPdfVersionInforeports the header version, effective core version, catalog override and Adobe developer extension level from a PDF stream
Changed
- Explicit PDF 1.3-1.7 saves now validate catalog, page-resource, XFA, redaction and developer-extension structures in their owning object context; encrypted explicit-version output and PDF 1.3 incremental normalization are rejected to preserve document integrity
- File-path saves now write to a sibling temporary file and replace the destination only after all compression, normalization and version checks succeed
Fixed
- PDF 1.3 output now carries the required full
/ProcSetresource and removes PDF 1.4 transparency keys when they only repeat the PDF 1.3 initial graphics-state values - Hybrid-reference, xref-stream and object-stream files are no longer rewritten by the classic-xref compressor, preventing compressed-object entries from being dropped
- Names that resemble transparency or catalog feature keys inside strings, comments or unrelated resource maps no longer cause false target-version failures
Version 2.17.0
Added
- PAdES signatures are now registered as invisible Widget annotations in the first page
/Annotsarray and in the AcroForm/Fieldsarray, preserving existing annotations and form fields
Changed
- Incremental PDF/A, PDF/X, PDF/E, PDF/R, PDF/UA, PDF/VT and PAdES updates now preserve the source cross-reference representation: xref-stream documents receive an xref-stream update as required by ISO 32000-1 §7.5.8.1, while classic documents continue to receive an xref table
- Cross-reference offsets,
startxref,/Prev, PAdES ByteRange values and SHA-256 range processing now use 64-bit positions with chunked hashing, enabling files larger than 2 GB in 64-bit builds - Generated writable XMP packets now reserve 2048 bytes of padding before the closing packet instruction
Version 2.16.10
Fixed
- Object-stream expansion no longer resurrects stale copies of objects that an incremental update migrated out of the object stream into a plain definition (ISO 32000-1 §7.5.7); conformance checks and marker injection previously resolved the outdated catalog or metadata dictionary on such files
Version 2.16.9
Fixed
- On Free Pascal, text strings whose input is not valid UTF-8 are widened byte-by-byte as Latin-1 and written as UTF-16BE hex strings; the raw high bytes previously leaked into a literal string, which is not a legal PDF 1.7 text-string encoding
- Stream decoding now recognises raw deflate data without the RFC 1950 zlib wrapper (a common defect of broken writers) and decompresses it in raw mode, so conformance scans no longer go silently blind on such streams
Version 2.16.8
Fixed
- Incremental updates written by the save post-processing path now refresh the second (changing) trailer
/IDelement as required by ISO 32000-1 §14.4; both elements were previously copied verbatim, so caching and synchronisation tools saw an unchanged identifier after every update
Version 2.16.7
Fixed
- The stream-body blanking used by conformance scans now requires the
streamkeyword to be followed by an end-of-line (ISO 32000-1 §7.3.8.1); the word inside a literal string such as(downstream)previously blanked all following structure up to the nextendstream, hiding real violations from the byte-level checks - The PDF/X and PDF/E forbidden-feature scans additionally blank literal strings and comments (§7.2.2), so a value such as
/Title (see /JavaScript docs)or a commented token no longer produces a falseJavaScript,AcroFormorLZWDecodefinding
Version 2.16.6
Fixed
- PDF/VT DPM entries are now validated at write time as documented: key names violating the ISO 16612-2 §6.6 NMTOKEN rule or the Annex E registrant-prefix rule, and duplicate names, are rejected instead of being written into the DPart dictionary — a name containing a space previously split into a bogus key/value pair and corrupted the dictionary
Version 2.16.5
Fixed
- Removing a dictionary entry whose value is a hex string (such as
/Check <...>) now removes the whole entry; the injectors previously left an orphan hex value behind, producing a syntactically broken dictionary - Removing an entry whose indirect reference uses newlines between the tokens (ISO 32000-1 §7.3.10 allows any whitespace) no longer leaves the generation number and
Rkeyword behind
Version 2.16.4
Fixed
- The maximum-object-number scan no longer requires object headers to start a line (ISO 32000-1 §7.5.3 allows any whitespace or delimiter before them), so injectors can no longer allocate an object number that collides with an inline
N G objheader and silently corrupt the file; object numbers are bounded by the Annex C ceiling - Streams whose
/Lengthis an indirect reference now resolve the referenced integer object and use its value when it lines up with the closingendstream; previously such streams were bounded by a pattern search, which truncated bodies legally containing theendstreambyte sequence — typical for embedded PDF attachments
Version 2.16.3
Fixed
- Stream compression passes cross-reference-stream documents (PDF 1.5+ files without a classic
trailerkeyword) through unchanged; the rebuild path previously misparsedstartxrefas the table location and synthesised a guessed trailer, which could produce an unopenable file - The compressor skips XMP metadata streams so a PDF/A document keeps its mandatory unfiltered metadata stream (ISO 19005-1 §6.7.2), and leaves external file streams (
/Fwith/FFilter) untouched - The rebuilt cross-reference table scans a stream-stripped copy of the document, so binary stream content can no longer fake object headers or inflate the table; the rebuilt trailer's
/Sizenow reflects the actual table and object numbers are capped at the Annex C ceiling - Locating the original cross-reference table accepts CR-only line endings (ISO 32000-1 §7.5.1) and can no longer match the
xrefletters insidestartxref; stream keyword scanning gained the sameendstream-tail guard used elsewhere and now advances past skipped stream bodies
Version 2.16.2
Fixed
- Integer parsing across the byte-level PDF readers now accepts the explicit
+sign allowed by ISO 32000-1 §7.3.3 and rejects digit runs that would overflow, so hostile or corrupt documents can no longer wrap parsed lengths and offsets into misleading values
Version 2.16.1
Fixed
- The PDF/UA injector writes the catalog
/Langvalue as a proper PDF text string; it previously ran the value through the XML escaper, so a language tag containing&or parentheses produced a corrupted entry, and non-ASCII input was written as raw UTF-8 - The PDF/E
/ISO_PDFEVersionInfo entry uses the shared text-string encoder, keeping non-ASCII values legal in PDF 1.7 - XML escaping for XMP packets drops control characters that are illegal in XML 1.0, so metadata copied from a damaged source document can no longer render the whole metadata stream non-well-formed
- PDF-to-XMP date conversion validates that date fields are numeric and pads a missing minute field, preventing malformed ISO 8601 dates in generated XMP; on non-Windows platforms the fallback timestamp now includes the time of day instead of the bare date
Version 2.16.0
Added
- Stream decoding now reconstructs
/DecodeParmspredictors (PNG predictors 10-15 and TIFF predictor 2, ISO 32000-1 §7.4.4.4) after FlateDecode, honouring/Colors,/BitsPerComponentand/Columns; object streams compressed with a predictor — a common PDF 1.5+ writer choice — previously surfaced differenced bytes, so the objects they carry were silently invisible to conformance scans and marker injection
Fixed
- The FlateDecode detection now parses the
/Filtervalue as a name or array instead of a substring match, so cascaded filter chains and occurrences of the word inside unrelated values no longer trigger a bogus inflate; unsupported chains fall back to the raw bytes as before
Version 2.15.1
Fixed
- The dictionary scanner now skips literal strings, hex strings and comments while balancing
<</>>(ISO 32000-1 §7.2.2), so dictionaries containing values such as(A >> B)or a hex string abutting the closing delimiter are no longer truncated during trailer, catalog and conformance-scan parsing - Literal string extraction now decodes the full §7.3.4.2 Table 3 escape set —
\n \r \t \b \f, octal\ddd, line continuations and unescaped EOL normalisation — instead of copying the escape letter verbatim, restoring correct/Producer,/GTS_PDFXVersionand/ISO_PDFEVersioncomparisons for writers that use octal escapes - Literal strings written by the marker injectors now escape CR, LF and other control characters so values survive the reader-side end-of-line normalisation byte-for-byte
Version 2.15.0
Fixed
- Incremental updates written by the PDF/A, PDF/X, PDF/E, PDF/R, PDF/UA and PDF/VT marker injectors and by the PAdES signing and DSS paths now preserve the source document's permanent file identifier: the first trailer
/IDelement is carried over verbatim as required by ISO 32000-1 §14.4 and only the second (changing) element is refreshed; previously both elements were regenerated, so external references and long-term-validation workflows saw a different document identity after every save - PAdES signatures, DSS injection and B-LTA Document Time-stamps now carry the source trailer's
/Inforeference forward (ISO 32000-1 §7.5.6), so document properties no longer disappear from reader panels after signing; the Document Time-stamp trailer also gains the/IDarray - The trailer
/Infofallback for cross-reference-stream documents now locates the XRef stream dictionary correctly and preserves the reference's generation number; it previously never matched on conforming PDF 1.5+ files, silently dropping/Info
Version 2.14.4
Fixed
- The signature dictionary
/Mdate written byTPdf.SignPadesandSignPadesBytesnow carries the mandatoryD:prefix and theZUTC offset marker required by ISO 32000-1 §7.9.4; strict validators previously rejected the signing time as a malformed date string
Version 2.14.3
Fixed
- Dictionary key lookups in the shared PDF reader now match whole name tokens (ISO 32000-1 §7.3.5); previously a stream whose dictionary listed
/Length1before/Length(typical for FontFile streams) was truncated to the wrong byte count, silently blinding PDF/A, PDF/UA and other conformance scans that read font, CMap or metadata streams /Encrypt,/Root,/Sizeand/Infotrailer lookups no longer match longer keys sharing the same prefix (such as/EncryptMetadata)- Object-stream expansion no longer trusts a corrupt or hostile
/Nvalue: non-integer values now yield 0 instead of an uninitialized number, and an upper bound derived from/Firstprevents oversized allocations while scanning malformed documents
Version 2.14.2
Fixed
- The PDF/X, PDF/VT, PDF/UA, PDF/E and PDF/R marker injectors now copy encrypted source documents through unchanged instead of appending plaintext update sections; the previous behaviour produced files whose latest trailer lost the
/Encryptentry (ISO 32000-1 §7.5.6), so conforming readers misread the encrypted body as plaintext TPdf.SignPades,SignPadesBytesandInjectPadesDssMarkersnow raiseEPadesCryptowhen the source document is encrypted, instead of silently emitting a corrupted or unverifiable file; remove encryption before signing or embedding DSS material
Version 2.14.1
Fixed
TPdf.SignPadesandSignPadesBytesnow back-fill all four/ByteRangefields of the signature dictionary; previously the last three fields stayed at their zero placeholders, so produced signatures declared an empty byte range and failed verification in conforming validators- PAdES B-LTA Document Time-stamp dictionaries receive the same
/ByteRangeback-fill correction ValidatePadesCompliancenow accepts the standard signature layout where the byte range gap holds the hex/Contentsvalue, and checks that the second range segment ends exactly at end of file; previously only gapless ranges passed the coverage check
Version 2.14.0
Added
TPdf.ExportXFDFserializes every form field value and annotation across all pages to an XFDF document (ISO 19444-1), emitting<fields>for hierarchical form values and<annots>for all supported annotation subtypes (text, highlight, underline, strikeout, squiggly, line, circle, square, caret, polygon, polyline, stamp, ink, freetext, fileattachment, sound, link, redact)TPdf.ImportXFDFreads an XFDF document back into the loaded PDF, re-creating annotations on the matching pages and applying field values to their widget annotations- The
TPdfAnnotationrecord gainedName(NM),Subject,ModificationDate(M),CreationDate,Icon,Opacity(CA), line endpoints, polygon/polyline vertices and ink-list gesture fields so XFDF round-trips preserve the full annotation metadata - New
XfdfLabsample in the Delphi, C++Builder and Lazarus demo sets demonstrates the export/import round-trip
Version 2.13.6
Fixed
ValidatePdfAnow treats catalog/Metadatastreams without/Type /Metadataor/Subtype /XMLas missing XMP metadata throughpvaiMissingXmpMetadata- PDF/A preflight reports now classify
pvaiMissingXmpMetadataas Metadata and recommend a catalog/Metadatastream with/Type /Metadata,/Subtype /XML, unfiltered XMP, andpdfaidmarkers
Version 2.13.5
Fixed
ValidatePdfAnow reports Widget annotations without an appearance dictionary and PDF/A-2 / PDF/A-3 annotations that require but lack/APthroughpvaiAnnotationApDictViolation- PDF/A preflight reports now categorize
pvaiAnnotationApDictViolationas content that marker injection cannot repair
Version 2.13.4
Fixed
ValidatePdfAnow reports PDF/A-2 and PDF/A-3 inline images whose/Ior/Interpolatevalue istruethroughpvaiImageDictionaryViolation, matching the existing Image XObject dictionary coverage- PDF/A preflight reports now categorize
pvaiImageDictionaryViolationas content that marker injection cannot repair
Version 2.13.3
Fixed
ValidatePdfAnow reports PDF/A-1 inline images that use/LZWDecodeor abbreviated/LZWfilters inside content streams throughpvaiInlineImageLzwForbidden, matching the existing PDF/A-2 and PDF/A-3 inline-image coverage- The inline-image filter scanner now advances past leading resource names such as
/GS1, avoiding stalls while scanning broader PDF/A-1 content streams
Version 2.13.2
Added
TPdf.SetFocusedFormFieldTextwrites text into the currently focused form field's edit buffer viaFORM_ReplaceSelection, symmetric toFocusedFormFieldText. For AcroForm text/combo fields the value commits to/Von focus loss and persists; for XFA text fields the write lands in the in-memory buffer only (PDFium exposes no public API to reconcile XFA values back to the datasets packet, so it does not persist across save)- The JavaScript host platform is now attached whenever the V8 engine is available, regardless of whether the document is XFA — so embedded AcroForm JavaScript (doc-level scripts, field calculations,
app.alert) can execute too. Previouslym_pJsPlatformwas only wired for XFA documents, leaving AcroForm JS silently disabled
Changed
- JavaScript platform attachment is now independent of the XFA decision in
InitializeFormFill— them_pJsPlatformtable is built wheneverV8FeaturesAvailableis true, applied after the XFA version/callback wiring rather than nested inside it
Version 2.13.1
Added
- New host events surface information the v2.13.0 form-fill callbacks previously swallowed:
OnXfaUriAction,OnXfaPageCountChanged,OnXfaFocusChange,OnXfaEmail,OnXfaHttpRequest,OnXfaOpenFile,OnJavaScriptBeep,OnJavaScriptPrint,OnJavaScriptMail,OnJavaScriptSubmitForm. Every event defaults to the existing no-op behavior when unassigned, so existing hosts are unaffected TPdf.XfaFormPacketsread-only property returns a one-shot snapshot of all XFA packets (TXfaPacketList), fulfilling theTXfaPacket/TXfaPacketListtypes previously declared but unused- XFA-specific PDFium error codes
FPDF_ERR_XFALOAD/FPDF_ERR_XFALAYOUTare now bound and surfaced throughLastPdfError, replacing the generic "Unknown error" for XFA load/layout failures
Changed
FFI_DoURIActionWithKeyboardModifiernow consultsOnXfaUriActionbefore shell-executing a URI from an XFA field, giving the host a veto (security: a malicious XFA field could previously launch arbitrary URLs unconditionally). Unassigned handlers preserve the priorShellExecuteWdefaultDecodeFormFieldTypenow routes XFA field types throughIsXfaFormFieldrather than an explicit 8-branch case, keeping the enum aligned withFPDF_FORMFIELD_XFA_*by ordinal offset
Fixed
ValidatePdfAnow reports PDF/A-1 claims that use PDF 1.5 cross-reference streams or object streams with the newpvaiPdfA1Pdf15Structureissue, while continuing to allow object streams for PDF/A-2 and PDF/A-3
Version 2.13.0
Added
- Full XFA (XML Forms Architecture) runtime support:
TPdf.InitializeFormFillnow wires all 14 version-2FPDF_FORMFILLINFOcallbacks (FFI_DisplayCaret,FFI_GotoURL,FFI_PageEvent,FFI_PopupMenu,FFI_OpenFile,FFI_EmailTo,FFI_UploadTo,FFI_GetPlatform,FFI_GetLanguage,FFI_DownloadFromURL,FFI_PostRequestURL,FFI_PutRequestURL,FFI_OnFocusChange,FFI_DoURIActionWithKeyboardModifier) and attaches anIPDF_JsPlatformso an XFA-enabledpdfium.dllcan render and script dynamic XFA forms - New
Lib\FPdfXfa.pasunit declaring the XFA constants (FXFA_PAGEVIEWEVENT_*,FXFA_MENU_*,FXFA_SAVEAS_*,FPDF_FORMFIELD_XFA_*) andTXfaPacket/TXfaSaveFormattypes that were previously only referenced in comments - XFA static packet reader on
TPdf:GetXfaPacketCount/GetXfaPacketName/GetXfaPacketContent/GetXfaPacketByNameplusGetXfaTemplate/GetXfaDatasets/GetXfaConfigextract the XFAtemplate,datasetsandconfigpackets as raw XML without needing an XFA-enabled runtime — useful for compliance auditing and data migration - Capability probes: global
XfaFeaturesAvailable, and per-documentTPdf.XfaRuntimeAvailable(whetherFPDF_LoadXFAactually succeeded) andTPdf.XfaStaticReadable(whether the packet reader exports resolve) TPdfFormFieldTypeextended withfiXfa,fiXfaCheckBox,fiXfaComboBox,fiXfaImageField,fiXfaListBox,fiXfaPushButton,fiXfaSignature,fiXfaTextField, withDecodeFormFieldTypemapping the newFPDF_FORMFIELD_XFA_*values- JavaScript host events on
TPdf:OnJavaScriptAlert,OnJavaScriptResponse,OnXfaGotoUrlandOnXfaRuntimeMissinglet the host customize JS dialogs and XFA navigation, or react when an XFA document cannot run the engine - New
XfaLabDelphi sample demonstrating XFA detection, packet extraction, capability probing and the runtime-missing fallback path
Changed
TPdf.LoadDocumentnow pre-scans the input for XFA markers (/XFAin the AcroForm dictionary, or catalog/NeedsRendering) and, when found, auto-selectspdfium.v8.dllby settingEnableV8Engine := Truebefore the singleton library is first loaded; once a plainpdfium.dllis loaded the process cannot switch, soOnXfaRuntimeMissingsignals that caseTPdf.GetPageCountnow reflects the page count the XFA engine reports viaFFI_PageEventafter dynamic repagination, rather than only the static PDF page tree- When an XFA document is opened but the runtime is unavailable,
InitializeFormFillnow pinsversion=1andxfa_disabled=1instead of requesting version 2 with unassigned callbacks, which previously risked a bad callback pointer dereference
Version 2.12.2
Fixed
ValidatePdfACompliancenow reports used custom XMP namespaces withoutpdfaExtension:schemaswhile still accepting standardpdfaidmetadata without extension declarations- PDF/A-3 embedded file validation now requires both top-level
/Fand/UFentries on filespec dictionaries and ignores nested/EFstream keys when checking those names
Version 2.12.1
Fixed
ValidatePdfACompliancenow decodes escaped PDF name tokens before matching JavaScript, LZWDecode, Type1, and related forbidden names, so obfuscated but semantically identical names are reported correctly- PDF/A inline-image checks now reject
/Filterand/Fvalues that use/LZWDecode, abbreviated/LZW, or/Crypt, including array and escaped-name forms - PDF/A validation now reports metadata streams with forbidden stream filters, OutputIntent ICC profiles whose
/Ncomponent count is missing or inconsistent, and PDF/A-3 embedded file specs with missing or invalid/AFRelationship
Version 2.12.0
Added
- TSA HTTP requests now set explicit 30 s timeouts for each phase (resolve/connect/send/receive) via
WinHttpSetTimeouts, so a slow or unreachable timestamp authority cannot hang the signing thread indefinitely instead of relying on WinHttp's implicit defaults - Per-request nonce derivation for PAdES B-T / B-LTA timestamp requests when the caller omits
TPadesSignOptions.Nonce: a SHA-256 fold of monotonic counter + wall clock +GetTickCount64+ process id replaces the previous fixed$100000000fallback, so two requests issued in the same millisecond no longer reuse the same anti-replay nonce PdfInflatenow caps decompressed output at 256 MiB to stop a zlib-compressed stream from exhausting memory on a hostile or corrupt input (a “zlib bomb”); the cap is generous for any real PDF stream
Changed
TPdfViewoverlay blending (search highlight, text selection, reading word, spread selection) no longer uses per-pixelGetPixel/SetPixelV; the rectangle is now blended through a 32-bpp off-screenTBitmapandScanLinein a single pass, eliminating thousands of GDI kernel crossings per paint and making large selections responsiveFPdfAsn1.TDerReader.ReadIntegernow rejects INTEGER fields longer than 8 bytes (and 8-byte negatives whose sign bit would requireshl >= 64), returning 0 instead of computing a wrong value through undefined-shift behaviour on CMS/PAdES ASN.1 inputParseTimeStampRespno longer echoes the request nonce back asTPadesTimestamp.Nonce; until the TSTInfo walker that verifies the returned nonce lands, the field stays 0 to signal “not verified” rather than giving callers false confidence that the timestamp response is fresh
Fixed
PointsToPixelsreturned its input unchanged for every DPI: the divisor wasPointsPerInch(the 72 constant) instead of the literal 72, collapsing the formula toResult := Points. Any external caller doing points→device-pixel sizing through this helper now gets the correctPoints × PixelsPerInch / 72PdfMaxObjNumundercounted on documents that use object streams (PDF 1.5+ ObjStm): objects compressed inside an/ObjStmcarry noN 0 objmarker, so the raw-byte scan missed them, and injectors that allocateMaxObj+1for new objects would collide with hidden ObjStm members and silently corrupt the file. The scan now expands object streams first so every object number is visibleInjectPdfAMarkersno longer forges a PDF/A conformance claim on an encrypted document: PDF/A (ISO 19005-1 §7.1) forbids encryption, and the injector previously copied the source through with the markers even though the very next validation would reject it. WhenHasEncryptis set the source is now passed through unchanged. The normalTPdf.SaveAsPdfApath already strips encryption (saRemoveSecurity) before injection, so this only affects direct callersPdfReadStreamBytesnow refuses a/Lengthlarger than the entire file before allocating the result buffer, closing an early-allocation path on a corrupt or hostile indirect length
Version 2.11.0
Added
- The PDFium
FPDF_FILEHANDLERrecord now declares its six callbacks (Release,GetSize,ReadBlock,WriteBlock,Flush,Truncate) as real fields instead of comments, matching the C header layout. The XFA FFI file-transfer callbacks (FFI_OpenFile/FFI_EmailTo/FFI_UploadTo/FFI_DownloadFromURL) that return or consumePFPDF_FILEHANDLERare still left unimplemented in the Pascal form-fill layer, but the type is now structurally correct for any future XFA submit/upload path - PDFium library load and unload (
LoadLibrary/UnloadLibrary) are now serialised by a process-global critical section, so twoTPdfFuture<T>worker threads (or a worker racing the main thread) cannot both observePDFiumLibrary=0and double-bind, or free the DLL while another thread is mid-bind - An
initialization/finalizationsection now callsUnloadLibraryon unit unload, ensuringFPDF_DestroyLibraryruns (worker-thread join, V8 isolate disposal, font/cache teardown) instead of relying on the OS to reclaim the DLL
Changed
TPdf.SetActivenow swallows any exception during load (previously onlyEPdfError), so a stream error or access violation during form/page setup leavesActive=Falseinstead of a partially-loaded component with indeterminate state- Consistent character encoding for PDFium metadata key arguments:
TPdf.GetMetaTextnow uses the same FPCAnsiString/ DelphiUTF8Encodesplit asGetViewerPreferenceand the load paths, instead of a bareAnsiString(Tag)cast - Deduplicated the
BytesToAnsi,AnsiToBytes,WriteBytesandWriteStrhelpers:FPdfCompressnow imports them fromFPdfPdfCommon(itsWriteBytesToStream/WriteAnsiToStreamaliases are retired) and the redundant three-argumentBytesToAnsioverload inFPdfPdfais removed.FPdfAsn1keeps its local copy by design to keep the cryptography layer free of the conformance-layer unit
Fixed
- Resource leak in
TPdf.LoadDocument(file, memory,TBytes,TMemoryStream, custom stream) andTPdf.CreateDocument: ifInitializeFormFillorReloadPageraised afterFPDF_LoadDocument/FPDF_CreateNewDocumentsucceeded, the nativeFPDF_DOCUMENThandle was leaked becauseFActivewas still False at that point. Each path now wraps the post-load setup intry/exceptand closes the document on failure, leaving the component cleanly inactive - Friendlier PDFium DLL load diagnostics:
CheckLoadLibrarydetectsERROR_BAD_EXE_FORMAT(193) and reports a 32/64-bit architecture mismatch pointing at the matchingDLLs/Win32orDLLs/Win64build, instead of relaying only the generic OS error.CheckGetProcAddressnow states the deployedpdfium.dllis older than the binding when a required export is missing, rather than the bare OS "procedure not found" text
Version 2.10.1
Fixed
- PAdES SignerInfo sid standardisation: the signer identifier now uses the RFC 5652 §5.3
issuerAndSerialNumberform (issuer Name + serialNumber, both extracted verbatim from the signer certificate DER), replacing the previous non-standardsubjectKeyIdentifier+ full-cert SHA-256 placeholder that Adobe Acrobat and other conforming validators rejected. A new TbsCertificate DER walker (ExtractIssuerAndSerial) reads the issuer SEQUENCE and the serial INTEGER as raw TLV bytes — serials commonly exceedInt64range, so the raw TLV is mandatory. ThesubjectKeyIdentifierform remains as a fallback only when cert DER parsing fails
Changed
TCmsSignerId.SerialNumber: Int64replaced withSerialDer: TBytes(the raw serialNumber TLV). The CMS builder embeds the sliced TLV verbatim inIssuerAndSerialNumber, avoidingInt64overflow on 20-byte CA serials (RFC 5280 §4.1.2.2 upper bound)
Version 2.10.0
Added
- PAdES B-LT long-term validation: when
TPadesSignOptions.Level >= plB_LT,SignPadesBytesappends an incremental update carrying a/DSSdictionary with the signer certificate and the full intermediate chain (the self-signed root is excluded per RFC 5652 §10.2.3), plus the/Extensions /ESICLevel 1 marker (EN 319 142-1 §5.4.2) - PAdES B-LTA archive timestamp: when
Level >= plB_LTAandTsaUrlis set, a Document Time-stamp signature dictionary (/SubFilter /ETSI.RFC3161) is appended whose/ByteRangecovers the entire file; the ESIC marker is promoted to Level 2. This completes the four PAdES baseline levels (B-B, B-T, B-LT, B-LTA) - Certificate chain collection:
ResolveWinSignernow callsCertGetCertificateChainand populatesTPadesResolvedSigner.ChainCertDerwith the intermediate CA certificates, so B-LT/DSS /Certscarries every cert needed to validate the signature without external lookups.CertFreeCertificateContextis now bound, closing the one-context-per-sign leak noted in v2.8.0 - PDF/A integration workflow:
TPdf.SignPadesWithPdfAconverts the document to PDF/A first (highest level the library emits today) then applies the requested PAdES signature — the long-term-archival container pattern EN 319 142-1 Annex A.7 recommends
Version 2.9.0
Added
- PAdES B-T trusted timestamp:
TPadesSignOptionsgainsLevel,TsaUrlandNoncefields. WhenLevel >= plB_TandTsaUrlis set,SignPadesBytesextracts the signature value from the built CMS, requests an RFC 3161 timestamp over it, and embeds the returned TimeStampToken as the SignerInfo unsigned attributesignature-time-stamp— the B-T trusted-time step (EN 319 142-1 §6.3 req o) FPdfTsa: cross-platform RFC 3161 client —BuildTimeStampReq(version 1, SHA-256 messageImprint over the signature value, nonce, certReq=true),ParseTimeStampResp(accepts PKIStatus 0/1, rejects 2+, extracts the TimeStampToken ContentInfo verbatim), andRequestTimestamp(one-shot build+POST+parse).PadesTsaAvailablegates the feature on platforms without an HTTP backendFPdfTsaWin: Windows WinHttp backend, dynamically bound from winhttp.dll (zero new compile-time dependency; HTTPS negotiated by the Windows certificate store). Mirrors theFPdfCryptoWindynamic-binding patternFPdfCms:ExtractSignatureValuewalks a built CMS to recover the raw signature octets (the TSA hash input), andAddSignatureTimestampToCmsrebuilds the ContentInfo with a newunsignedAttrs [1](0xA1) carrying the timestamp attribute. The stage-1 validator recognises the result as a B-T signature
Version 2.8.0
Added
- PAdES B-B signing stack: four new pure-Pascal/cross-platform building blocks (
FPdfSha256,FPdfAsn1,FPdfCms,FPdfCrypto) plus a Windows CNG backend (FPdfCryptoWin) letTPdf.SignPades/SignPadesToStreamproduce a PAdES B-B signature end-to-end. The signer certificate is resolved by SHA-1 thumbprint from the Current User “MY” store; RSA-PSS (recommended), RSA PKCS#1 v1.5 and ECDSA are all supported viaNCryptSignHash FPdfSha256: self-contained FIPS 180-4 SHA-256 (Init/Update/Final + one-shot helpers). FPC 3.2.2 ships no SHA-2 unit, so the library owns one to keep every CMS code path on a singleTSHA256Digesttype with no RTL branchingFPdfAsn1: DER encoder (TDerWriter) and reader (TDerReader) covering SEQUENCE/SET/OID/INTEGER/OCTET STRING/UTCTime/GeneralizedTime/context-specific tags, with the definite-length encoding and IMPLICIT-tag handling CMS requiresFPdfCms: CAdES SignedData builder (BuildSignedData) emitting the content-type, message-digest and signing-certificate-v2 signed attributes PAdES baseline mandates, with optional signing-time and commitment-type-indication. The signedAttrs digest is computed over the SET-tagged (0x31) form and re-emitted with the IMPLICIT [0] (0xA0) tag per RFC 5652 §5.4FPdfCrypto+FPdfCryptoWin: cryptographic-backend abstraction withPadesCryptoAvailable/ResolvePadesSigner, and the Windows implementation binding crypt32.dll / ncrypt.dll dynamically (no new compile-time DLL dependency). ECDSA signatures are re-encoded from the Windows IEEE P1363 r¦s form into the DERECDSA-Sig-ValueCMS requiresSignPadesBytes: byte-level signature injection — reserves a fixed-width/Contentshex slot, computes the covering/ByteRange, digests the document, builds and embeds the CMS, and appends the incremental update. The validator (v2.7.0) recognises the output as a PAdES B-B signature
Version 2.7.0
Added
- PAdES structural validator (ETSI EN 319 142-1 V1.2.1): the new
FPdfPadesunit andTPdf.ValidatePadesmethod inspect signature value dictionaries reachable from/ByteRange, walk the CMSSignedDatainside/Contentsfar enough to confirm the CAdES detached shape, and detect the four baseline levels (B-B, B-T, B-LT, B-LTA) plus Document Time-stamp dictionaries (/SubFilter /ETSI.RFC3161) - PAdES clause-level issue set: 26
ppei*enums cover/SubFilteracceptability (adbe.pkcs7.sha1andadbe.x509.rsa_sha1flagged as forbidden),/ByteRangefile coverage,/Certprohibition, CMSSignedDatashape (single signer, detached eContent, version range), the required signed attributes (content-type,message-digest,signing-certificate/v2), forbidden digests (MD5, SHA-1),/Reasonvscommitment-type-indicationmutual exclusion (req d), the B-T trusted-time requirement, the B-LT/DSS+/Certs+ ESIC Level 1 marker, and the B-LTA Document Time-stamp + ESIC Level 2 marker - DSS injector:
TPdf.SaveAsPadesDss/SaveAsPadesDssToStreamappend an incremental update carrying a/DSSdictionary (with/Certs,/OCSPs,/CRLsstream arrays) and the/Extensions /ESICmarker (Level 1 or 2) onto a copy of the document, preserving the original bytes — the B-LT/B-LTA validation-material embedding step (clause 5.4.2) - Cross-platform, zero-dependency stage: the validator and injector are pure-Pascal and work on every supported IDE (Delphi, Lazarus, FPC, C++Builder); no cryptographic backend is required for this release, and no new DLL dependency is introduced
Version 2.6.0
Changed
- Cross-standard deduplication: seven more duplicated helper functions (PdfEnclosingObjNum, PdfDictRefNum, PdfExpandObjectStreams, PdfTextStr, ExtractLiteralString, ExtractXmpAttr) have been removed from the individual standard units and consolidated into
FPdfPdfCommon, reducing ~300 lines of copy-paste maintenance burden - PreflightReport quality: PDF/X and PDF/E content-class issues that previously fell through to the generic “missing marker” category now carry accurate Content/Metadata/Security categories and clause-specific recommendations (~15 enums across both standards)
- PDF/E and PDF/R test coverage: six more zero-coverage enums gained positive tests (
pveiLzwForbidden,pveiJavaScriptForbidden,pveiFormFieldsForbidden,pveiEmbeddedFilesForbidden,pvriBadHeader,pvriProhibitedInfoEntry) - Lazarus build fix:
Tests.PdfVT(a Delphi-only DUnitX unit added in v2.5.x) is now excluded from the Lazarus project to restore compilation
Version 2.5.3
Added
- OutputIntent completeness (PDF/X-4 §6.2.4):
pvviOutputIntentSchemeflags an OutputIntent whose/Sis not/GTS_PDFX;pvviOutputIntentMissingIdentifierflags a missing/OutputConditionIdentifier - PDF/VT-2 Reference XObject exemption (§6.2.2):
pvviReferenceXObjectForbiddenno longer fires for aPDF/VT-2file, which may legally use Reference XObjects on an X-5g/5pg base - MIME boundary character validation (RFC 2046 §5.1.1):
vtmviBoundaryInvalidCharflags a boundary whose characters fall outside the bchars set or whose length exceeds 70
Fixed
InjectPdfVTMarkersnow writes Info/CreationDateand/ModDatefrom the save options, so the produced file round-tripsValidatePdfVTCompliancewithout a falsepvviInfoModDateMismatch(the injector previously rewrote the XMP dates but left the Info dictionary dates stale)
Version 2.5.2
Added
- Info
/ModDateconsistency (§6.3 NOTE 2, PDF/X-4 base):pvviInfoModDateMismatchflags an Info dictionary/ModDatethat, after PDF-date to XMP-date normalisation, does not equalxmp:ModifyDate - PDF/VT-2s inline chunk conformance (Annex A.2): the MIME validator now runs
ValidatePdfVTComplianceon every inlineapplication/pdfpart and flags a non-PDF/VT body viavtmviInlinePdfNotPdfVT
Version 2.5.1
Added
- DParts chunking validation (ISO 16612-2 §6.5 Table 4):
pvviDPartsBadChunkingflags a/DPartsarray whose non-final sub-arrays do not have exactly 8192 entries or whose last sub-array falls outside 1..8192 - RecordLevel cross-stream consistency (Annex A.2): the PDF/VT-2s MIME validator now extracts each inline PDF's
/RecordLeveland flags disagreement viavtmviRecordLevelMismatch, complementing the existing NodeNameList check - Recurring graphical object hints (§6.7):
pvviGtsScopeInvalidValueflags a/GTS_Scopeoutside {SingleUse, Record, File, Stream, Global, Unknown};pvviGtsScopeRecordWithoutRecordLevelflags/Recordwithout a/RecordLevel;pvviGtsXidNotUuidflags a/GTS_XIDthat is not an RFC 4122 uuid: URI;pvviGtsEnvMissingflags a missing/GTS_Envwhen/GTS_Scopeis Stream or Global (§6.7.4) - MIME forward-reference detection (Annex A.2):
vtmviForwardReferenceflags an inline PDF that cites a filename (via/EF /F) not introduced by an earlier attachment part in the stream
Fixed
ExtractNodeNameListFromPdfandExtractRecordLevelFromPdfinFPdfPdfvtMimeresolved a recurring off-by-one where the 1-based offset returned byAnsiFindKeywas treated as an absolute byte offset into the expanded PDF
Version 2.5.0
Added
- PDF/VT Document Part Metadata (DPM, ISO 16612-2 §6.6):
TPdfVTSaveOptionsgainedDpmEntriesandDpmTargetso a writer can attach a/DPMdictionary to the synthesized DPart node, with key-name validation against the Annex E second-class-prefix rule and the §6.6 NMTOKEN / uniqueness /GTS_Managed-shape rules on the validator side - PDF/VT-2s streaming exchange (Annex A): the new
FPdfPdfvtMimeunit providesBuildPdfVT2sStreamandValidatePdfVT2sStreamfor themultipart/mixedMIME envelope carrying inline PDF/VT chunks plus attachment ICC profiles, with theX-PDFVT-Stream-version: 1header ordering rule and cross-streamNodeNameListconsistency check TPdf.ValidatePdfVTnow performs an authoritative JavaScript-action count viaFPDFDoc_GetJavaScriptActionCount, complementing the byte-level/JavaScriptname scan
Fixed
- PDF/VT
Trappedcorrectness on the PDF/X-4 base: theptvUnknownenum value is removed (PDF/X-4 forbids/Unknown),ptvUnspecifiedis normalized to/Falseat write time (a missing/Trappedis also forbidden), and a newpvviTrappedInvalidissue flags an absent orUnknownvalue ValidatePdfVTCompliancenow expands object streams (PdfExpandObjectStreams) before scanning, so a catalog, OutputIntent or Metadata dictionary stored inside a compressed ObjStm (PDF 1.5+, typical of PDF/X-4 producers) is reachable by the byte-level lookups
Changed
- PDF/VT-1 now inherits the full PDF/X-4 content prohibitions:
pvviAcroFormForbidden(/AcroFormor/XFA),pvviAdditionalActionsForbidden(catalog/AA),pvviMissingTrimBoxandpvviReferenceXObjectForbidden(Reference XObject, X-5g/5pg only) - Cross-standard deduplication:
BuildDictObj,IccComponentCount, the built-in sRGB ICC profile (GetSrgbIccProfile),PdfTextStr,PdfEnclosingObjNum,PdfDictRefNumandPdfExpandObjectStreamswere promoted from triplicated local copies inFPdfPdfa/FPdfPdfx/FPdfPdfvtto a single canonical home inFPdfPdfCommon; the 3144-byte ICC literal now exists exactly once in the codebase
Version 2.4.0
Fixed
InjectPdfUaMarkersno longer drops the trailer/Inforeference on a cross-reference-stream base: the localSourceTrailerInfoRef(which lacked the xref-stream fallback) has been replaced by the sharedPdfSourceTrailerInfoRef(promoted from the PDF/A copy which had the fallback since v2.0.0)- The shared
PdfReadStreamBytesnow handles indirect/Length N G Rreferences (ported from the PDF/A local copy), so the PDF/VT, PDF/R and PDF/E validators no longer mis-read or skip XMP metadata streams produced by tools that use indirect Length (Acrobat, Ghostscript)
Changed
- Cross-standard deduplication: the local
PdfReadTrailercopies inFPdfPdfaandFPdfPdfx, the localSourceTrailerInfoRefcopies inFPdfPdfaandFPdfPdfua, and the localPdfReadStreamBytesinFPdfPdfahave all been deleted — the sharedFPdfPdfCommonversions now apply everywhere. This removes ~330 lines of duplicated code and eliminates the maintenance burden of keeping copies in sync - PDF/X test-debt closure: seven previously zero-coverage content-class enums gained positive tests (
pvxiLzwForbidden,pvxiJavaScriptForbidden,pvxiFormFieldsForbidden,pvxiAdditionalActions,pvxiEmbeddedFilesForbidden,pvxiMissingTrimBox,pvxiTrappedNotSet)
Version 2.3.0
Changed
- PDF/A test-debt closure continues: three more zero-coverage enums gained positive tests.
pvaiForbiddenRenderingIntent(§6.2.9) flags a non-standard rendering-intent name in a content stream.pvaiJpeg2000Violation(§6.2.2) flags a JPXDecode image with/NumComponentsoutside {1,3,4} at Part 2.pvaiInlineImageLzwForbidden(§6.1.10) flags an inline image using the LZW filter at Part 2
Version 2.2.0
Changed
- Cross-reference-stream regression tests: the existing
Validate_XrefStreamTrailer_DetectsConformancenow also verifies that the catalog/Metadatareference is resolved and the XMPpdfaid:partis read on an xref-stream base (not just/Root+/ID). A newInjectPdfA_XrefStreamBase_RoundTripstest guards the injector's xref-stream path added in v2.0.0. Two cross-standard tests (PdfE_XrefStreamBase_NotRejectedAsUnparsable,PdfR_XrefStreamBase_NotRejectedAsUnparsable) verify the PDF/E and PDF/R validators no longer reject xref-stream PDFs as unparsable - PDF/A test-debt closure:
Validate_MinimalPdf_FlagsRequiredMarkersasserts that a bare minimal PDF triggerspvaiMissingPdfAIdentifier,pvaiMissingOutputIntent,pvaiMissingIccProfile,pvaiMissingXmpMetadataandpvaiMissingXmpDates— closing the symmetry gap with the PDF/E and PDF/X validators which already had equivalent tests. Two more zero-coverage enums gained positive tests:pvaiUnembeddedFontandpvaiSubsetMissingCidSet
Version 2.1.0
Fixed
- PDF/E was inadvertently left out of the v2.0.0 cross-reference-stream fix: both
InjectPdfEMarkersandValidatePdfECompliancestill calledPdfReadTrailerwithoutAcceptXrefStream, so the PDF/E injector silently failed on PDF 1.5+ output (pdfium’sSaveAsCopydefault). Both call sites now passTrue - The shared
PdfReadTrailercross-reference-stream fallback now carries the/Type /XRefguard that the PDF/A and PDF/X local copies already had, so a corruptstartxrefoffset pointing at an unrelated dictionary fails cleanly instead of being mis-parsed as the trailer - The indirect-reference
/Langresolver inValidatePdfUaCompliance(v2.0.0) was unreachable:PdfFindObjDictonly finds<<dictionaries, but a/Langstring object is(...)or<...>with no dictionary. Replaced with a direct object-body scan that locates the string token
Changed
- Seven dead-shadow helper duplicates (PdfStructureBytes, PdfHasName, PdfCountName, BuildStreamObj) that were byte-identical copies of the shared
FPdfPdfCommonversions have been removed fromFPdfPdfaandFPdfPdfua— the shared versions now apply everywhere viauses
Version 2.0.0
Fixed
- Cross-standard silent failure: the shared
PdfReadTrailerhelper (used by the PDF/UA, PDF/X, PDF/VT and PDF/R marker injectors and validators) now accepts anAcceptXrefStreamparameter and falls back to the cross-reference-stream object dictionary when notrailerkeyword is present (PDF 1.5+). Previously, pdfium’sSaveAsCopyoutput (which uses a cross-reference stream) caused every marker injector to silently fail — the source bytes were copied through unchanged and the call still returned success. The PDF/R-1.0 validator (whose PDF 2.0 base is always a cross-reference stream) was effectively a no-op. The PDF/A validator’s mature implementation was ported to the shared helper so every standard benefits - Trailer dictionary scanning in
InjectPdfUaMarkersandInjectPdfAMarkersnow uses the depth-awarePdfDictEndinstead of a bare>>search, so a trailer containing a nested dictionary (e.g./Encrypt << ... >>) is no longer cut short before a trailing/Infoentry
Changed
TPdf.ValidatePdfUanow suppresses the coarse byte-levelpvuaiFontNotEmbeddedwhen the precise Pdfium object-modelpvuaiPdfiumFontNotEmbeddedhas already fired, so the preflight report no longer carries two near-duplicate “embed your fonts” rows for the same defectpvuaiLangInvalidFormat(§7.2) now resolves an indirect-reference/Lang(N 0 R) to its string object and validates the content, so an indirectly-referenced language tag is no longer a blind spot
Version 1.99.0
Fixed
pvuaiLangInvalidFormat(§7.2) no longer gives hex-encoded/Langstrings a free pass: UTF-16BE pairs (with aFE FFBOM) and bare ASCII hex strings are now decoded and run through the same BCP 47 grammar check as literal(...)strings, so a malformed hex/Langis caught while a conformant one (e.g. a UTF-16BEen-US) is no longer at risk of being flagged
Changed
pvuaiFontMissingToUnicode(§7.21.7) now exempts/MacExpertEncodingalongside/WinAnsiEncodingand/MacRomanEncoding, matching the four exemption conditions the clause lists
Version 1.98.0
Added
pvuaiNeedAppearancesTrue(§7.18.4) flags an AcroForm whose/NeedAppearancesflag is true, so widget appearances are not reliably locked and assistive technology cannot associate them with the structure tree. Ported from the PDF/A validator and gated on/AcroFormpresence to narrow the scan surface
Changed
- veraPDF corpus regression: wired the §7.20 Reference-XObject pass+fail pair and the §7.21.4.2 subset CharSet/CIDSet pass+fail pairs into
Live_Corpus_ValidatePdfUaMatchesConformance. The §7.21.7 ToUnicode-forbidden-value and §7.18.6.2 media-clip pass samples were also wired as false-positive guards (their fail samples use dictionary layouts the byte-level scan does not catch, so only the pass side is wired) - The corpus pass-path assertion list gained 15 new zero-false-positive guards so every active
pvuai*byte-level and structure check is now exercised against conformant samples (previously only ~30 of the 60 active issues were guarded). ThepvuaiLangInvalidFormatguard was deliberately omitted because the byte-level checker conservatively flags hex-encoded/Langstrings it cannot decode
Version 1.97.0
Fixed
ValidatePdfUaStructureElementshardening: theEnclosingTableparent-chain walk now carries a hop counter (bounded by the element count), so a malformedParentIndexcycle on a synthetic structure-element array can no longer hang the caller. TheValidatePdfUaPageContentTaggingmarked-content-ID array allocation is now capped at one million entries, preventing a multi-GB allocation on a malformed/maliciousMarkedContentID
Changed
- The
pvuaiOrderedListMissingListNumberingenum doc comment now accurately describes what the check does: it flags anLelement whoseListNumberingvalue is outside the ISO 32000-1 Table 347 set (an absent attribute is not flagged). The earlier comment implied it also detected ordered lists missing the attribute, which the implementation does not do - The two
7.21.3.3-t02WMode-mismatch corpus fail samples are now wired intoLive_Corpus_ValidatePdfUaMatchesConformance— since v1.95.0 the CMap stream is FlateDecode-inflated, so the dictionary-vs-content comparison now runs on a readable side. The stale “not wired” comment was removed
Version 1.96.0
Added
- Cross-standard consistency:
TPdf.ValidatePdfUagains two checks ported from the PDF/A validator.pvuaiAnnotationFlagsViolation(§7.18.1) flags a non-exempt annotation carrying the Hidden / Invisible / NoView flag, which breaks the assistive-technology reading flow.pvuaiActionTargetMissing(§7.18.5) flags a GoToR / URI / SubmitForm action that lacks its required target key (/F+/D, /URI, /F), leaving the link unusable by AT
Fixed
- Cross-page structure-tree merge: the
AllElemsaccumulation loop inTPdf.ValidatePdfUanow rebases each element'sParentIndexfrom the page-local array to the merged array. Without this, page 2's child elements kept a page-local index that pointed into page 1's slice, silently corrupting every ParentIndex-dependent check (table/list structure, §7.4.4 H-child count, EnclosingTable) - RoleMap parsing:
PdfReadRoleMapPairsno longer terminates the whole key/value scan when a value is an indirect reference (N 0 R) or an array ([...]) — both valid RoleMap forms per ISO 32000-1 14.8.5.1. It now skips just that entry (Continue) instead ofBreak-ing, eliminatingpvuaiRoleMapUnresolvedfalse positives on types mapped after an indirect/array entry
Changed
FPdfPreflightReport: 18 activeTPdfUaValidationIssuevalues that previously fell through to the catch-all “missing marker” category and recommendation now carry accurate categories (Structure / Content / Metadata / Security) and clause-specific recommendations. Also fixed thepuaNone / pua1→pucNone / puc1typo inPDFSpecComplianceMatrix.md
Version 1.95.0
Changed
TPdf.ValidatePdfUarecall and soundness pass: the §7.21.3.3pvuaiCMapWModeMismatchcheck and the §7.21.7pvuaiToUnicodeForbiddenValuecheck now inflateFlateDecode-compressed CMap / ToUnicode streams before scanning (previously only uncompressed streams were judged, a known false negative). The sharedPdfInflate/PdfReadAndDecodeStreamhelpers were promoted fromFPdfPdfa/FPdfPdfxtoFPdfPdfCommonso every conformance unit shares one copy
Added
pvuaiSubsetCharSetEmpty(§7.21.4.2) flags a Type 1 subsetFontDescriptorthat carries a/CharSetkey whose string value is empty — the existingpvuaiSubsetMissingCharSetonly caught a missing key. An empty/CIDSetis not flagged, since a font with no CIDs may legitimately carry an empty bitmap
Version 1.94.0
Added
- Second-pass
TPdf.ValidatePdfUaaudit closed six ISO 14289-1 gaps surfaced by a clause-by-clause review and a re-scan of Pdfium native APIs already wrapped but unused by the PDF/UA path.pvuaiHeadingFormatInvalid(§7.4.3) flags user-defined heading tags that start with H but carry separators, spaces or Roman numerals instead of pure Arabic digits.pvuaiMissingDocumentOutline(§7.17, should) flags a multi-page document that carries no bookmark outline (single-page documents are exempt).pvuaiStructElementLangInvalid(§7.2) flags a structure element/Langvalue that is not a valid BCP 47 tag.pvuaiWidgetMissingPrintField(§7.14 / §7.18.4) flags a Widget structure element missing the PrintField attribute owner.pvuaiLinkNotInStructureTree(§7.18.5) flags a document whose/Subtype /Linkannotations are not exposed as Link structure elements.pvuaiPdfiumAnnotationMissingContentsandpvuaiPdfiumLinkMissingContents(§7.18.1 / §7.18.5) add a precise Pdfium object-model annotation scan that exempts hidden, off-crop-box, Popup and Widget annotations — eliminating the false positives of the byte-level heuristic, which cannot read the/Fflags or/Rect
Version 1.93.0
Added
TPdf.ValidatePdfUanow layers a Pdfium object-model pass on top of the byte-level inspector, mirroring the PDF/A round-7 architecture: it walks every page’s text objects viaFPDFTextObj_GetFont→FPDFFont_GetIsEmbedded(pvuaiPdfiumFontNotEmbedded, §7.21.4) and scans every character viaFPDFText_HasUnicodeMapError(pvuaiPdfiumUnicodeMapError, §7.21.7) andFPDFText_GetUnicode(pvuaiPdfiumNotDefGlyph, §7.21.8) — more precise than the byte-level heuristics, which only fire when zero font programs are present or no/ToUnicodeappears at all. The walk short-circuits at three levels: the page loop exits when all three Pdfium-layer issues are already set, the per-object loop exits on the first non-embedded font, and the character scan skips the.notdefpass whenUnicodeMapErroralready hit. PDF/UA was the last PDF-standard validator without a Pdfium object-model layer
Version 1.92.0
Added
- Created
Tests.PdfR— the first test file for the PDF/R-1 validator (FPdfPdfr), covering header validation, ObjStm prohibition, raster-marker detection, and a clean-file no-false-positive guard. All six PDF-standard test suites now have dedicated test files: PdfA(80), PdfUa(101), PdfX(7), PdfE(5), PdfVT(15), PdfR(4) = 212 tests total
Version 1.91.0
Added
ValidatePdfEandValidatePdfVTgained content-level checks previously available only in the PDF/A, PDF/UA and PDF/X validators:pveiLzwForbidden,pveiJavaScriptForbidden,pveiFormFieldsForbidden(PDF/E only),pveiEmbeddedFilesForbidden(PDF/E only),pveiOpiForbidden,pvviLzwForbidden,pvviJavaScriptForbidden,pvviEmbeddedFilesForbidden,pvviOpiForbidden.TPdf.ValidatePdfEandTPdf.ValidatePdfVTalso gain a Pdfium object-model layer (pveiPdfiumFontNotEmbedded/pvviPdfiumFontNotEmbedded) that walks page text objects viaFPDFFont_GetIsEmbedded, short-circuiting on the first non-embedded font
Version 1.90.0
Added
TPdf.ValidatePdfXnow layers a Pdfium object-model pass on top of the byte-level inspector: it walks every page’s text objects viaFPDFTextObj_GetFont→FPDFFont_GetIsEmbeddedand reports a non-embedded font aspvxiPdfiumFontNotEmbedded— more precise than the byte-level heuristic which only fires when zero font programs are present. The walk short-circuits on the first non-embedded font found
Changed
TPdf.ValidatePdfUastructure-tree walk: the per-pageValidatePdfUaPageContentTaggingcall (which builds a marked-content-ID claim map and cross-checks every text/image object) is now skipped on subsequent pages oncepvuaiUntaggedContentis already found — structure elements are still collected for the cross-page checks (Note unique ID, heading sequence), but the expensive per-page content-tagging pass stops early
Version 1.89.0
Changed
TPdf.ValidatePdfAPdfium object-model layer performance: the page/object walk now short-circuits at three levels — the page loop exits when all applicable Pdfium-layer issues are already found, the per-object loop exits when both per-object issues (font embed + transparency) are set, and the text-page character scan skips the.notdefpass whenUnicodeMapErroralready hit.Assigned()API-availability checks and conformance flags are cached to local booleans once before the loop instead of being re-evaluated on every page/object/character. On a large non-conformant document the walk can now stop after the first page instead of scanning all pages; on a conformant document the overhead per page is lower (no repeatedAssignedcalls)
Version 1.88.0
Added
ValidatePdfXgained eight new content-levelTPdfXValidationIssuevalues covering the print-exchange restrictions that PDF/X imposes beyond the file-format markers:pvxiLzwForbidden(/LZWDecode),pvxiJavaScriptForbidden(/JavaScript),pvxiFormFieldsForbidden(/AcroForm//XFA),pvxiAdditionalActions(/AA),pvxiEmbeddedFilesForbidden(/EmbeddedFiles//FileAttachment),pvxiOpiForbidden(/OPI//Alternates),pvxiMissingTrimBox(no/TrimBoxon any page), andpvxiTrappedNotSet(/Trappedabsent or/Unknown). The PDF/X validator previously checked only XMP/OutputIntent markers; this is its first content-level pass. SharedPdfStructureBytes/PdfHasName/PdfCountNamehelpers were added toFPdfPdfCommonso all conformance units can use them
Version 1.87.0
Added
- PDF/UA validation now covers the ISO 14289-1 §7.21.3 composite-font rules:
pvuaiCidSystemInfoMismatchflags Type0 fonts whose embedded CMap and descendant CIDFont disagree onRegistry/Orderingor whose CIDFontSupplementexceeds the CMap’s,pvuaiCMapNotEmbeddedflags CMaps referenced by name (asEncodingorUseCMap) that are not ISO 32000-1 Table 118 predefined CMaps, andpvuaiCMapWModeMismatchflags embedded CMaps whose dictionaryWModediffers from the WMode in their stream content
Fixed
- The §7.21.3.2
pvuaiCidFontMissingCidToGidMapcheck missed CIDFontType2 dictionaries whoseSubtypekey/value pair is separated by a newline, and now also flags aCIDToGIDMapname value other thanIdentity
Version 1.86.0
Added
- PDF/UA validation now covers the ISO 14289-1 §7.21.6 TrueType encoding rules:
pvuaiTrueTypeEncodingInvalidflags non-symbolic TrueType fonts whoseEncodingis missing or is neitherMacRomanEncodingnorWinAnsiEncoding(directly or viaBaseEncoding), andpvuaiSymbolicTrueTypeEncodingflags symbolic TrueType fonts carrying a non-standardEncodingname
Version 1.85.1
Changed
- The ISO 14289-1 §7.18.3 tab-order check
pvuaiMissingTabsOrdernow runs per page: every page carrying annotations must declare/Tabs /Sin its own page dictionary, so a conformant sibling page no longer masks a page without one
Version 1.85.0
Added
- PDF/UA validation now distinguishes dynamic from static XFA forms per ISO 14289-1 §7.15:
pvuaiXfaDynamicflags forms whose XFA configuration setsdynamicRendertorequired
Changed
- The former any-XFA candidate flag
pvuaiXfaPresentis retired and no longer raised (static XFA conforms to §7.15); the enum value remains for API compatibility
Version 1.84.0
Added
- PDF/UA validation now detects untagged real content required by ISO 14289-1 §7.1:
pvuaiUntaggedContentflags rendered text and image objects that are neither claimed by the page’s structure tree (via their marked-content IDs) nor marked as an Artifact - New page-level helpers
GetPageContentMarkInfosandValidatePdfUaPageContentTaggingwith theTPdfPageContentMarkInforecord for direct use
Version 1.83.0
Added
- PDF/UA validation now enforces the ISO 14289-1 §7.4.4 heading model:
pvuaiHeadingModelMixedflags documents that mix the genericHtag with numberedH1..Hnheadings, andpvuaiHeadingMultipleInNodeflags structure nodes carrying more than one childHheading
Version 1.82.0
Added
- PDF/UA validation now resolves the RoleMap required by ISO 14289-1 §7.1:
pvuaiRoleMapRemapsStandardflags RoleMap entries that redefine a standard structure type, andpvuaiRoleMapUnresolvedflags used non-standard structure types whose RoleMap chain is missing, dangling or cyclic — indirect chains that reach a standard type are accepted, and unused RoleMap entries are never judged - New helpers
PdfUaIsStandardStructType,PdfReadRoleMapPairs(with PDF name#hhescape decoding) andValidatePdfUaRoleMapUsagefor direct use
Version 1.81.0
Added
- PDF/UA validation now covers the ISO 32000-1 list tagging required by ISO 14289-1 §7.6:
pvuaiListStructureInvalidflags LI items outside an L container and Lbl/LBody parts outside an LI item, while accepting nested lists and the legitimate Lbl usage inside Note and BibEntry elements
Version 1.80.0
Added
- PDF/UA validation now covers the ISO 32000-1 table tagging required by ISO 14289-1 §7.5:
pvuaiTableStructureInvalidflags TH/TD cells outside a TR row and rows or row groups outside their Table container,pvuaiTableHeaderMissingScopeflags header cells whose relationship is determinable neither via a Scope attribute nor a Headers/ID association, andpvuaiTableHeadersUndefinedIdflags Headers references in documents that define no structure element IDs TPdfStructureElementexposes the table attributesScope,HasHeaders,HeadersIds,ColSpanandRowSpan, resolved during the structure-tree walk
Changed
- The structure-tree walk now reads all layout and table attributes in a single pass over each element’s attribute dictionaries instead of one scan per attribute
Version 1.79.1
Added
- Ported the
AnnotationsLabsample to Lazarus and C++Builder, joining the existing Delphi console sample
Fixed
TPdf.CreateAnnotationcould raise “Cannot set attachment points” for markup annotations that use quad points (Highlight, Underline, StrikeOut, Squiggly) because the new annotation had no quad slot yet to replace; it now appends the first quad instead
Version 1.79.0
Added
- New
AnnotationsLabDelphi console sample: creates Text, Highlight, Square and Circle annotations, writes them to a PDF, then reloads the file and enumerates the page annotation list
Version 1.78.0
Added
- New
TPdf.MeasureTextandTPdf.MeasureTextWidth: measure the rendered width and height of a string for a given font and size (PDF user units, 1 unit = 1/72 inch) without adding content to a page, making layout and word-wrap logic possible on top ofAddText; provided by the standaloneFPdfMeasureunit as a class helper - New
TPdf.WrapText: greedy word wrap built onMeasureTextWidththat splits text on spaces and packs words into lines no wider than a given width (PDF user units); an overlong single word gets its own line (no intra-word breaking), returning the wrapped lines as an array
Version 1.77.0
Added
ValidatePdfAgained three newTPdfAValidationIssuevalues covering the clauses previously rated “NO” or “reader behaviour” by the earlier gap audit (appended ordinals, existing values unchanged):pvaiPdfiumNotDefGlyph(PDF/A-2 6.2.11.8 — a character that resolves to Unicode 0 without a mapping error, the runtime symptom of a.notdefglyph reference; detected via the Pdfium object-model layer),pvaiWordBreakMissing(Level A 6.8.3.2 — a content-stream show string longer than 20 characters with no space, a likely merged-words violation; coarse heuristic that avoids CJK false positives), andpvaiLinkActionMissingTarget(6.6.3 — a GoToR/URI/SubmitForm action missing its display target key so a reader cannot present it)
Version 1.76.0
Added
ValidatePdfAgained three newTPdfAValidationIssuevalues (appended ordinals, existing values unchanged):pvaiNameNotValidUtf8(PDF/A-2/3 6.1.8 — a/BaseFontor/FontNametoken containing bytes ≥ 0x80 that do not form valid UTF-8),pvaiInlineImageLzwForbidden(PDF/A-2/3 6.1.10 — an inline image in a page content stream uses the LZW or Crypt filter), andpvaiTrueTypeDifferencesForbidden(6.3.7 Cor.2 — a non-symbolic TrueType font whose Encoding dictionary carries/Differences)
Version 1.75.0
Added
ValidatePdfAgained three newTPdfAValidationIssuevalues (appended ordinals, existing values unchanged):pvaiIntegerImplementationLimit(PDF/A-2/3 6.1.13 — a numeric token exceeding the 32-bit signed integer limit 2,147,483,647),pvaiBlendModeNotWhitelisted(PDF/A-2/3 6.2.10 — a/BMvalue outside the ISO 32000-1 §11.3.5 standard blend-mode set; complements the PDF/A-1pvaiTransparentColorSpacewhich only allows Normal/Compatible), andpvaiHexStringOddDigits(6.1.6 — a<...>hex string with an odd number of hex digits)
Version 1.74.0
Added
ValidatePdfAgained three newTPdfAValidationIssuevalues (appended ordinals, existing values unchanged):pvaiPermissionsViolation(6.1.12 — a/Permsdictionary carrying/DigestLocation,/DigestMethodor/DigestValuealongside/DocMDP),pvaiTransActionForbidden(PDF/A-2 6.5.1 — a Trans transition action, detected via the/S /Transaction-dict pattern to avoid false-matching/Transparency), andpvaiPdfiumObjectTransparency(PDF/A-1 6.4 — a page object carries real transparency perFPDFPageObj_HasTransparency, extending the Pdfium object-model layer introduced in v1.73.0 to catch blend-mode/soft-mask effects the byte-level name scan can miss)
Version 1.73.0
Added
TPdf.ValidatePdfAnow layers a Pdfium object-model pass on top of the byte-level inspector: it walks every page’s text objects viaFPDFPage_GetObject→FPDFTextObj_GetFont→FPDFFont_GetIsEmbeddedand reports a non-embedded rendered font aspvaiPdfiumFontNotEmbedded(ISO 19005 6.3.4), and loads each text page to scanFPDFText_HasUnicodeMapErrorand reports a broken Unicode mapping aspvaiPdfiumUnicodeMapError(6.3.8). These are checks the byte-level inspector cannot do — it only sees name tokens, not resolved font handles or per-character mapping state — and are merged into the byte-level result. The standaloneValidatePdfACompliancebyte-level function is unchanged
Version 1.72.0
Added
ValidatePdfAgained five newTPdfAValidationIssuevalues (appended ordinals, existing values unchanged):pvaiNeedsRenderingPresent(PDF/A-2 6.4.2 — the catalog shall not carry/NeedsRendering),pvaiDestOutputProfileRef(PDF/A-3 6.2.3 — an OutputIntent shall not carry/DestOutputProfileRef),pvaiEmbeddedFileMissingUF(PDF/A-3 6.8 — a file spec with/EFshall also carry/UF),pvaiXmpPacketBytesAttr(6.7.5 — the XMP packet header shall not carry the deprecatedbytes=orencoding=attribute), andpvaiAnnotationToggleNoView(PDF/A-2 6.3.2 — the annotation/FToggleNoView bit, value 512, is forbidden)
Version 1.71.0
Changed
ValidatePdfUanow raisespvuaiOrderedListMissingListNumbering(ISO 14289-1 7.6): the structure-tree walker resolves theListNumberinglayout attribute on everyLelement via the Pdfium attribute API and flags any value outside the ISO 32000-1 Table 347 set (Decimal,UpperRoman,LowerRoman,UpperAlpha,LowerAlpha,None,Circle,Disc,Square). An absent attribute is not flagged, since the list may be unordered; this closes the last residual ISO 14289-1 gap recorded at the end of round 5
Version 1.70.0
Added
ValidatePdfUagained four newTPdfUaValidationIssuevalues (appended ordinals, existing values unchanged):pvuaiSubsetMissingCidSet(ISO 14289-1 7.21.4.2 — a CID subsetFontDescriptorshall declare/CIDSet),pvuaiToUnicodeForbiddenValue(7.21.7 — a ToUnicode CMap shall not map any code toU+FEFForU+FFFE; uncompressed streams are scanned for the<FEFF>/<FFFE>output forms),pvuaiLangInvalidFormat(7.2 —/Langshall be a valid RFC 1766 / BCP 47 tag; a permissive grammar acceptsen,en-US,zh-Hans,es-419and flags clearly non-conforming values), andpvuaiOrderedListMissingListNumbering(7.6 — retained for API completeness; not yet raised by the validator because reliably distinguishing ordered from unordered lists needs theListNumberingattribute value, which the structure-tree walker does not expose)
Version 1.69.0
Added
ValidatePdfUagained two newTPdfUaValidationIssuevalues (appended ordinals, existing values unchanged):pvuaiWidgetOutsideForm(ISO 14289-1 7.18.4 — a Widget structure element shall be nested within aFormelement; the structure-tree walker now verifies each Widget’s direct parent type) andpvuaiSubsetMissingCharSet(7.21.4.2 — a Type 1 subsetFontDescriptorshall declare/CharSet, identified by the six-letter+subset-name prefix on/FontName)
Version 1.68.0
Added
ValidatePdfUagained two newTPdfUaValidationIssuevalues (appended ordinals, existing values unchanged):pvuaiUriActionIsMap(ISO 14289-1 7.18.5 — a URI action dictionary shall not carry/IsMapwith valuetrue, since it disables the accessible link target) andpvuaiHeadingSequenceViolation(7.4.2 — numbered headings shall start atH1and a descending sequence shall not skip an intervening level, e.g.H1→H3is a violation). The heading check is the first structure-tree-level PDF/UA rule in the validator:ValidatePdfUaStructureElementsnow walks the typed element list and verifies theH1…H6(andH7+per 7.4.3) sequence in document order
Version 1.67.0
Added
ValidatePdfUagained five newTPdfUaValidationIssuevalues (appended ordinals, existing values unchanged):pvuaiLinkMissingContents(ISO 14289-1 7.18.5 — a Link annotation shall carry an alternate description via/Contents),pvuaiAnnotationMissingContents(7.18.1 — any non-exempt annotation without/Contentsshall have an alternative description; Popup and Widget are exempt),pvuaiEmbeddedFileMissingName(7.11 — a file specification dictionary shall contain/Fand/UF),pvuaiMediaClipMissingAlt(7.18.6.2 — a media clip data dictionary shall contain/CTand/Alt), andpvuaiCidFontMissingCidToGidMap(7.21.3.2 — an embedded Type 2 CIDFont shall contain/CIDToGIDMap)
Version 1.66.0
Added
ValidatePdfUagained five newTPdfUaValidationIssuevalues (appended ordinals, existing values unchanged):pvuaiRoleMapMissing(ISO 14289-1 7.1 — a tagged document with non-standard structure types shall carry a/RoleMap),pvuaiOptionalContentAsKey(7.10 — an optional-content configuration dictionary shall not carry the/ASauto-state key),pvuaiXfaPresent(7.15 — an AcroForm/XFApresence is flagged since dynamic XFA is forbidden),pvuaiTrapNetAnnotation(7.18.2 —/TrapNetannotations are forbidden), andpvuaiReferenceXObject(7.20 — Reference XObjects, keyed off the/Refmarker, are forbidden)
Fixed
ValidatePdfUano longer false-positivespvuaiEncryptionPresenton every encrypted file: PDF/UA permits encryption as long as the encryption dictionary/Pkey has bit position 10 (value 1024) set, which grants assistive-technology access (7.16). The precise violation is now reported via the newpvuaiEncryptionPBitMissing;pvuaiEncryptionPresentis retained in the enum for API compatibility but is no longer raised by the byte-level validator
Version 1.65.0
Added
ValidatePdfAgained five newTPdfAValidationIssuevalues (appended ordinals, existing values unchanged):pvaiCidFontMissingCidToGidMap(ISO 19005-1 6.3.3.2 Cor.2 — an embedded Type 2 CIDFont shall carry/CIDToGIDMap),pvaiSubsetMissingCharSet(6.3.5 — a Type 1 subsetFontDescriptorshall carry/CharSet),pvaiSubsetMissingCidSet(6.3.5 — a CID subsetFontDescriptorshall carry/CIDSet),pvaiWidgetActionForbidden(6.6.1 — a Widget annotation shall not carry/Aor/AA), andpvaiOptionalContentAsKey(ISO 19005-2 6.9 — an optional-content configuration dictionary shall not carry the/ASauto-state key, newly relevant because PDF/A-2 permits optional content)
Version 1.64.0
Added
ValidatePdfAgained eight newTPdfAValidationIssuevalues (appended ordinals, existing values unchanged):pvaiHeaderBinaryMarkerMissing(ISO 19005-1 6.1.2 — the%PDF-x.yheader must be followed by a%comment with at least four bytes greater than 127),pvaiExternalStreamRef(6.1.7 — a stream dictionary shall not carry/F,/FFilteror/FDecodeParms),pvaiOutputIntentScheme(6.2.2 — the OutputIntent/Sshall be/GTS_PDFA1),pvaiInfoXmpDateMismatch(6.7.3 — InfoCreationDate/ModDateshall also appear asxmp:CreateDate/xmp:ModifyDate),pvaiMarkInfoMissing(6.8.2.2 — Level A requires/MarkInfowith/Marked true),pvaiAnnotationApDictViolation(6.5.3 Cor.2 — the annotation/APdictionary shall contain only/N),pvaiEmbeddedFileMissingAFRelationship(ISO 19005-3 Annex E.2 — each associated filespec shall carry/AFRelationship), andpvaiJpeg2000Violation(ISO 19005-2 6.2.8.3 — a JPEG2000 image shall declare 1, 3 or 4 components)
Fixed
ValidatePdfAno longer false-positivespvaiAnnotationFlagsViolationon documents that use a single-letter font resource name such as/Font << /F 5 0 R >>; the/Fflag scan is now gated on an annotation context (/Subtypeof an annotation type), matching the documented behaviour (6.5.3)ValidatePdfAnow reports the PDF/A-3 associated-file requirement per file: a document is flagged only when an embedded/Type /Filespecthat references an embedded stream via/EFlacks/AFRelationship, instead of the previous whole-document any-or-none check (ISO 19005-3 Annex E.2)- Added the deprecated
/SetStateaction to the forbidden-action set alongside/SetOCGState, so the PDF Reference action name is caught directly (6.6.1)
Version 1.63.0
Added
- Added
TPdf.MeasureTextandTPdf.MeasureTextWidth: measure the rendered width and height of text in a given font and size without adding content to a page (in PDF user units, 1 unit = 1/72 inch), enabling layout calculations and automatic line wrapping on top ofAddText; provided by the standalone unitFPdfMeasureas a class helper
Changed
Demo\Delphi\MergePDF,Demo\CBuilder\MergePDF, andDemo\Lazarus\MergePDFenhanced across all three IDEs: added per-file page range selection, optional output path, deduplication, a run log, a cancel button, and a merge completion summary, with bookmarks and metadata carried over from the first source on importCreatePDFdemos across all three IDEs now include a “European Text” option to write accented text in Czech, French, German, Spanish, Portuguese, Polish, and Turkish, for verifying font selection and Unicode handling (the formerEuropeanTextsample has been merged in)- Removed the
ExtractTextPagesandEuropeanTextsamples: the per-page text output capability ofExtractTextPagesis now covered by the page-range and page-separator options inExtractText; the multilingual text rendering ofEuropeanTexthas been merged intoCreatePDF
Version 1.62.2
Fixed
- Regenerated the C++Builder headers (
.hpp) for every RAD Studio version and platform (Win32/Win64/Win64x); they had drifted from the Pascal sources, leaving stale function signatures and missing units that reached C++Builder users through the source distribution
Version 1.62.1
Fixed
- Restored source compilation on RAD Studio 12 Athens and earlier: a
TArray<Byte>assignment in the PDF/UA validation path used a Delphi 13-only implicit array conversion that failed to compile on older IDEs
Version 1.62.0
Added
TPdf.RenderPageThumbnailrenders any page by index into an aspect-fitted bitmap without changing the document's current page, loaded page or firingOnPageChange
Fixed
TPdfThumbnailViewno longer drives the host document'sPageNumberwhile painting; earlier each repaint reloaded pages, firedOnPageChangeand discarded the text page, which could disrupt a linkedTPdfViewand trigger repaint loops. Thumbnails now render throughRenderPageThumbnailwith no such side effects- PDF/X conformance validation now inspects cross-reference-stream documents (PDF 1.6, typical of PDF/X-4) and objects stored in compressed object streams, instead of reporting such files wholesale as non-conformant; the
GTS_PDFXVersionmarker is read from both element-form and RDF attribute-form XMP - PDF/R validation now reports
pvriInfoXmpMismatchwhen the Info dictionary and XMP disagree on Producer or Creator; the issue was previously declared but never raised - Form-fill timers are tracked per request, so a document that runs several timers at once (for example a JavaScript interval alongside the field caret blink) keeps them all instead of losing every timer but the most recent
TPdfViewpainting and its publicRenderPage/RenderTilemethods now hold the document render lock, serializing against worker-thread rendering of the sameTPdf(PDFium is not thread-safe)- Non-ASCII text written into PDF/X, PDF/R and PDF/VT metadata (OutputIntent condition names, Creator, Producer) is now encoded as a UTF-16BE string per ISO 32000-1 §7.9.2.2 instead of raw UTF-8, which conforming readers would misread
- Conformance helpers read embedded metadata streams whose
/Lengthis an indirect reference correctly, load source bytes withReadBuffer(so a short read fails cleanly), and reject a negativestartxrefoffset instead of risking an out-of-range read
Version 1.61.0
Changed
- FFI/ABI declaration corrections that may require recompiling code which implemented the affected callbacks: the
FFI_OpenFileform-fill callback now carriescdecl(Win32 stack convention), and thevalueparameter ofFPDFAnnot_SetStringValueandFPDFAttachment_SetStringValueis nowFPDF_WIDESTRING(UTF-16LE) to match the PDFium headers - Progressive-load callbacks
FX_FILEAVAIL.IsDataAvailandFX_DOWNLOADHINTS.AddSegmentnow takesize_toffsets, andsize_tis pointer-width on Free Pascal / Lazarus Win64 (previously truncated to 32-bit), fixing data-availability andoutsize_tAPI calls on FPC Win64
Fixed
- Memory safety: a use-after-free of the form-fill timer when destroying a
TPdfwith an active AcroForm caret; a doubleFPDF_CloseDocumenton the error path ofImportNPagesToOne; Pascal exceptions escaping theFPDF_FILEWRITE/FPDF_FILEACCESScallbacks across the C boundary during save and JPEG insert; and an integer overflow in text extraction when reading from a start index to the end of the page TPdfFuture<T>now reliably delivers its result callback; the reply was previously almost always dropped (and could touch a freed thread) because the worker freed itself before the queued reply ran- PDF/A, PDF/X, PDF/E, PDF/R, PDF/VT and PDF/UA output now write cross-reference entries that are exactly 20 bytes as required by ISO 32000-1 §7.5.4
- Standards marker injection no longer destroys a dictionary when the removed key (for example
/Trapped) was the last entry, which previously swallowed the closing>>and produced a malformed object - OutputIntent ICC profile streams now declare the required
/Ncomponent count for PDF/X and PDF/VT (already present for PDF/A); encrypted source documents are decrypted before PDF/X, PDF/E, PDF/R, PDF/VT and PDF/UA markers are injected, so the output is valid rather than silently corrupted - The UTF-8 xpacket BOM in generated XMP is emitted as exact bytes, fixing corruption on Delphi installations whose ANSI code page is not Latin-1; incremental-update trailers now retain the document
/Inforeference SaveAswith compression no longer truncates streams whose/Lengthis an indirect reference, and rebuilt cross-reference tables now use 20-byte entries, real generation numbers, and drop the stale/Prevpointer- Conformance validation reads attribute-form XMP version markers for PDF/E and PDF/X (so attribute-serialised PDF/X-4 files are recognised), requires the exact
PDF/E-1identifier, reads indirect-/Lengthmetadata streams correctly, and no longer false-matches a structure element's/IDor/StructTreeRootkey when checking the PDF/UA trailer; a malformedstartxrefoffset no longer raises a range error TPdfThumbnailView: the final page is now reachable with the scroll bar, the host document's current page is restored after thumbnails are painted, and the standard mouse-leave handling is dispatched again- Grayscale page and image bitmaps are no longer rendered with a wrong palette;
TPdfViewis no longer left with a dangling reference when itsTPdfis freed first - Preflight reports: HTML is saved as UTF-8 to match its declared charset, and JSON string escaping produces correct
\usequences for non-ASCII characters on Free Pascal - Trial builds: the trial reminder dialog now appears instead of being suppressed before it could show
TPdfStreamAdapternow rejects streams larger than 4 GiB with a clear error instead of silently truncating the length passed to PDFium
Version 1.60.1
Changed
- The AccessibilityReader demos for Delphi, Lazarus and C++Builder now run read-aloud on
TPdfReadingSession: each page is assembled into one spoken chunk withBuildSpokenTextFromWords, SAPI word positions feedFeedSpokenPosition, and the session advances pages and drives the view's word cursor, replacing the hand-written orchestration each demo carried before - Word-level karaoke tracking in the demos now also works when NVDA is the speech engine:
EstimatePacingpaces the reading cursor by elapsed speaking time, where NVDA previously read aloud with no word tracking at all - Pause and Resume in the demos now work with NVDA too:
ResumeRestartsChunkre-speaks the current page from its start on Resume, while SAPI keeps its native in-place pause and resume
Version 1.60.0
Added
- Live low-vision rendering on
TPdfView: the newreInvertandreNightDuotonerender options recolour every rendered page tile (full colour inversion, or a night duotone palette) before the search, selection, reading and word-cursor overlays are painted, bringing the existing bitmap colour transforms into the interactive viewer for both single-page and facing-pages layouts; toggling the options repaints immediately NightDuotoneInkandNightDuotonePaperconfigure the night palette, defaulting to amber text on a black page;reInvertwins when both options are set
Version 1.59.0
Added
TPdfReadingSession: a speech-engine-neutral read-aloud orchestration component. It keeps the chunk cursor, the word cursor and the playback state (Play/PlayFrom/Pause/Resume/Stop), advances through the loadedTPdfSpokenTextchunks as the host reports the engine idle viaTick, translates spoken-text offsets back to page characters, and drives an attachedTPdfViewword cursor automatically; the host connects any speech engine throughOnSpeakand the cancel / pause / resume request events, so the library links no speech API itselfFeedSpokenPositionconsumes engine word positions (such as SAPIStatus.InputWordPosition);EstimatePacingwithEstimatedWordsPerMinutepaces engines without a position signal;ResumeRestartsChunkre-speaks the current chunk for engines without a native pauseOnChunkChange,OnWordChangeandOnFinishedfire only on real changes, and a freed attached view detaches itself automatically, so host code stays flicker-free and crash-safe
Version 1.58.0
Added
EstimateSpokenWordIndexestimates which word a speech engine is voicing from the elapsed time and a words-per-minute rate, giving longer words proportionally more time, so engines that report no word position (such as the NVDA controller client) can still drive the word-level reading cursor; the caller supplies the elapsed time, so the routine stays clock-free and unit-testable
Version 1.57.0
Added
- Spoken-text assembly with two-domain mapping for read-aloud tracking:
BuildSpokenTextFromWordsandSpokenTextAppendbuild the string handed to a text-to-speech engine from page word boxes while recording a span table, andSpokenToPageChartranslates an engine-reported spoken offset (such as SAPIStatus.InputWordPosition) back to the page character index, so word-level highlight tracking stays correct when the spoken text is not the whole page text (skipped regions, per-unit reading, pronunciation overrides) TPdfSpokenTextandTPdfSpokenSpantypes carry the spoken string plus the source page ranges it was built from; offsets on inserted separators resolve to the next mapped word and offsets past the mapped runs report no match
Version 1.56.9
Added
Demo\Delphi\PreflightReportadds an Action Plan preview that condenses non-passing standards, priorities, next actions, issue codes, and recommendations into a remediation checklistDemo\Delphi\PreflightReportCliacceptsplan/actionplanas an output format for single-file and batch runs, writing the same remediation checklist to a text file
Changed
- Both Delphi PreflightReport demos now display pass / action / review status counts alongside total standards and issues
Version 1.56.8
Changed
ViewerInteractionLabnow includes page-jump controls, manual zoom controls, click-basedDeviceToPage/PageToDevicecoordinate logging, and a clearer interaction log for selection, search, rotation, and navigation checksViewerInteractionLabreadme pages now document the added interaction workflow across the localized demo readme set
Version 1.56.7
Added
AccessibilityWorkbenchClimaps every triggered finding to its WCAG 2.1 Success Criteria and ISO 14289-1 (PDF/UA-1) clause area and shows a standards-coverage section in the reportsAccessibilityWorkbenchClicomputes a documented 0-100 accessibility score with a published penalty rubric and an excellent / good / needs work / poor band, surfaced per file and as a batch averageAccessibilityWorkbenchCliacceptsfailscore=Nto fail the run (exit code 2) when any file scores below NAccessibilityWorkbenchCliwrites a SARIF 2.1.0 log when the batch summary name ends in.sarif, with one rule per finding kind carrying its WCAG 2.1 and PDF/UA tags for CI and code-scanning ingestionAccessibilityWorkbenchCliadds aversioncommand that prints the linked PDFium Delphi Component version
Version 1.56.6
Added
IntakeWorkbenchClicomputes a SHA-256 forensic hash of each input file (degrading tounavailableon compilers withoutSystem.Hash) and reports it in every formatIntakeWorkbenchCliacceptspasswords=file.txtto trial-unlock password-required documents from a candidate list, recording the matching candidate index without ever logging the password textIntakeWorkbenchCliacceptscopyto=dirto route each audited file into a per-risk-level subfolder, turning the auditor into an intake sorterIntakeWorkbenchCliwrites a SARIF 2.1.0 log when the batch summary name ends in.sarif, with one rule per risk flag and one result per flagged file for CI and code-scanning ingestionIntakeWorkbenchCliadds aversioncommand that prints the linked PDFium Delphi Component version
Version 1.56.5
Added
IntakeWorkbenchClinow derives recommended post-intake actions such as accept, request-password, manual-review, quarantine, and deduplicate, and exposes action counts in batch summariesAccessibilityWorkbenchClinow derives recommended remediation actions such as pass-through, remediate-tags, run-ocr, remediate-semantics, and manual-review, with matching batch action counts
Changed
- Both tool-grade CLI demos surface the recommended action in console, text, HTML, JSON, and CSV output so batch operators can route files without post-processing risk or status fields
Version 1.56.4
Fixed
- Reading annotations, bookmarks, or link annotations in a loop no longer leaks the previous item's text strings: the
TPdfAnnotation,TBookmark, andTLinkAnnotationresult records are now cleared with managed-type-aware initialization instead of raw memory zeroing, so documents carrying very large numbers of text-bearing annotations no longer inflate process memory for the lifetime of the application - Destroying a
TPdfthat had registered anOnUnsupportedFeaturehandler now detaches it from the process-global PDFium callback, so a later document load from anotherTPdfinstance without its own handler can no longer dispatch into the freed component (use-after-free)
Version 1.56.3
Fixed
AccessibilityWorkbenchClino longer counts blank pages as heuristic reading-order pages, so tagged documents with empty separator pages keep their correct accessibility status; pages without readable content are now reported separatelyAccessibilityWorkbenchClitable-header detection no longer credits an outer table forTHcells that belong to a nested table, and form-field and font names are matched case-sensitively so distinct fields are not mergedIntakeWorkbenchCliURL host inventories now strip userinfo, query, and fragment parts, so a crafted link such as[email protected]is attributed to the real host, andmailto:targets contribute their domain instead of being invisibleIntakeWorkbenchCliMarkdown reports escape backticks in attacker-controlled paths, hosts, and attachment names so report formatting cannot be broken from inside a document
Changed
AccessibilityWorkbenchClireports font-scan and form-field-scan failures as separate counters, marks non-embedded fonts that also have embedded instances, and caps long font lists with an explicit truncation markerIntakeWorkbenchClibatch summaries add an attachment-annotation count column, and the per-page annotation census is capped at 20000 annotations per page with the cap reported in every format
Version 1.56.2
Added
AccessibilityWorkbenchClinow audits font embedding, form-field tooltips, reading-order source, document outlines, table and list structure, suspicious alternate text, and richer per-page review details so accessibility batch reports identify more remediation targetsIntakeWorkbenchClinow reports page scan limits, launch and remote-go-to actions, URI host inventories, annotation counts, unsupported PDFium features, duplicate document identifiers, and expanded risk flags for automated intake review
Changed
IntakeWorkbenchCliacceptsmaxpages=Nin single-file and batch modes to cap per-document page scans while still completing metadata, attachment, script, XFA, signature, and risk reporting
Version 1.56.1
Fixed
- Loading an older
pdfium.dllthat is missing a newer export now fails cleanly: the failure path resets every bound API entry point, soAssigned()checks (for example onFPDF_GetLastErrororFPDF_GetSecurityHandlerRevision) report the library as not loaded instead of calling into the already-unloaded module and crashing with an access violation UnloadLibrarynow clears all PDFium API bindings rather than only the optional V8 helpers, so no stale function pointers survive after the DLL is released
Version 1.56.0
Added
- Word-level karaoke reading cursor on
TPdfView:TrackReadingWordAtmaps a text-to-speech engine's current-word character offset (such as SAPIStatus.InputWordPosition) onto the page word boxes, highlights the word that contains it as a distinct overlay above the reading block, scrolls it into view, and returns the word index, so the spoken word lights up as the voice advances SetReadingWordandClearReadingWordset or clear the highlighted word from aTPdfWordBoxdirectly; re-setting the same word is a no-op, so per-word tracking never flickers the viewReadingWordColorandReadingWordFollowcontrol the word cursor colour and whether the view auto-scrolls the spoken word into view
Version 1.55.2
Fixed
- ViewerInteractionLab now gives the toolbar rows more vertical space so Open PDF, Create Sample, navigation, search, and selection controls no longer overlap under scaled fonts
Version 1.55.1
Fixed
- ViewerInteractionLab now places Prev, Next, and Rotate on the second toolbar row, avoiding the startup overlap with Open PDF and Create Sample
Version 1.55.0
Added
- Word-to-selection bridge for "read it, select it" reading:
TPdfView.SelectWordBoxandSelectWordSpanselect a single word box or a same-page span of word boxes (fromPageWordBoxes) by their character ranges, so the word or line currently being read can also be selected and copied WordBoxIndexAtCharIndexmaps a character index back to the word box that contains it, driving word-by-word highlight as a TTS read cursor advances
Version 1.54.0
Added
- Voice form-filling accessors that read the focused field straight from the logical cursor:
FocusedFormFieldValue,FocusedFormFieldNameandFocusedFormFieldDetailsonTPdfandTPdfViewreport the current field's value, human-readable name (/TUtooltip, falling back to/T) and fullTPdfFormFieldInfo(type, flags, options) — everything a voice UI needs to announce as it steps through a form
Fixed
FocusedFormFieldValuereads the field byFocusedFormFieldIndexrather than pdfium interactive focus, so a voice-driven form filler gets the right value even with no on-screen caret (the existingFocusedFormFieldTextstill reflects pdfium focus and is unchanged)
Version 1.53.0
Added
- Word-level highlighting support:
TPdf.PageWordBoxesandTPdfView.PageWordBoxessplit a page intoTPdfWordBoxrecords, each carrying the word text, its character range and a page-space bounding rectangle, so an accessibility reader can highlight each spoken word in turn ("karaoke" reading) by passing the rectangle toSetReadingHighlight BuildWordBoxesexposes the tokenizer step on its own, turning page text into word boxes with character ranges
Version 1.52.0
Added
- Low-vision rendering helpers
InvertPdfBitmap,GrayscalePdfBitmapandDuotonePdfBitmapapply in-place colour transforms to a rendered 32-bit bitmap, so an accessibility reader can present pages inverted / dark-mode, grayscale, or in a custom two-colour scheme (for example a dark background with light text) for low-vision users - The transforms run per pixel and behave identically on VCL and Lazarus/LCL, leaving bitmap dimensions untouched
Version 1.51.0
Added
- Sentence-level reading units for assistive listen-reading:
TPdf.ReadingUnits,TPdf.DocumentReadingUnitsandTPdfView.ReadingUnitslinearize the readable content stream into ordered, sentence-sizedTPdfReadingUnitrecords — each carries the text to speak plus its semantic kind, page, highlight rectangles and language tag, so a screen-reader app can step through a page or the whole document one spoken unit at a time - Semantic navigation with
NextReadingUnitOfKind, letting a voice UI jump to the next or previous heading, figure, list item or table cell without scanning the stream by hand BuildReadingUnitsconverts anyTPdfContentFragmentsinto reading units directly: headings and figure/alt descriptions stay whole while paragraphs split on sentence boundaries, decimal points are preserved, and the reading cursor is a plain caller-owned index
Version 1.50.0
Added
ValidatePdfAcan now inspect PDF 1.5+ documents that store the catalog, OutputIntent or other dictionaries inside compressed object streams (/Type /ObjStm). The object streams are inflated and the objects they carry are resolved, so such documents are validated on their merits instead of being reported as missing their PDF/A markers
Version 1.49.5
Fixed
ValidatePdfAno longer reports a missingpdfaExtension:schemasdescription as a problem. The PDF/A identifier schema (pdfaid) is well-known, so neither veraPDF nor PDF/A-2/-3 require an extension-schema description for it, and flagging its absence mis-reported every conformant third-party PDF/A. Documents the library itself produces still include the description
Version 1.49.4
Fixed
ValidatePdfAnow detects the conformance level when the PDF/A identifier is written as XML attributes (pdfaid:part="2") rather than child elements, so attribute-form documents are no longer reported with an unknown level. This also corrects a cascade in which an undetected level made the part-specific checks fall back to the strict PDF/A-1 rules and wrongly flag embedded files and transparency that PDF/A-2 and PDF/A-3 permit
Version 1.49.3
Fixed
ValidatePdfAnow inspects PDF 1.5+ documents whose cross-reference data is a cross-reference stream (files that have notrailerkeyword). The conformance level, trailer/IDand the other markers are read from the cross-reference stream dictionary, so such documents are validated on their merits instead of being reported as entirely non-conformant
Version 1.49.2
Fixed
ValidatePdfAno longer reports a spurious non-embedded-font issue on documents that embed all of their fonts. The previous heuristic compared the number of/FontDescriptortokens against embedded font programs, but each embedded font contributes two/FontDescriptortokens (the font dictionary reference plus the descriptor object), so every embedded-font file was wrongly flagged. The check now reports only a document that references fonts yet embeds no font program at all, matching the correspondingValidatePdfUacorrection
Version 1.49.1
Fixed
- PDF/A output now validates as conformant PDF/A-1b and PDF/A-1a with veraPDF: the embedded sRGB OutputIntent ICC profile stream (referenced by
/DestOutputProfile) now declares the required/Ncomponent count (3 for the built-in RGB profile), as mandated by ISO 19005-1 6.2.3.2. Documents produced bySaveAsPdfApreviously failed strict PDF/A-1 validation because the destination profile stream omitted/N; the value is derived from the ICC profile header, so a caller-supplied CMYK or Gray profile receives the correct count as well
Version 1.49.0
Fixed
ValidatePdfUano longer reports spurious missing XMP identification on conformant tagged PDFs — the PDF/UA identifier (pdfuaid:part),dc:title, the XMP dates and the trailer/IDare now read from the original document bytes instead of the re-saved copy, which omits the/MetadataXMP stream and, for cross-reference-stream files, the trailer/IDValidatePdfUafont-embedding check corrected so a document that embeds all of its fonts is no longer reported as having non-embedded fonts; it now flags only a document that references fonts yet embeds no font program at allValidatePdfUanow accepts aFormulastructure element whose alternative text is supplied throughActualTextrather than anAltentry (ISO 14289-1 §7.7), consistent with the existingFigurerule
Version 1.48.0
Added
- Programmatic text selection on
TPdfView:SelectTextRange(by page and character range) andSetSelection(by explicit per-page ranges) select text from code — for example to read and highlight a passage; both repaint and raiseOnSelectionChangewhen the selection changes.SelectionRangesreads the current selection as per-page character ranges, andSelectionRectanglesreturns its rectangles in page coordinates for custom highlighting or scroll-to
Version 1.47.0
Added
- Form field navigation for voice-driven form filling, on both
TPdfandTPdfView:FormFieldTabOrder,FocusedFormFieldIndex,FocusFormField,FocusNextFormField,FocusPreviousFormField,ClearFormFieldFocusandFocusedFormFieldText. These move a logical field cursor over the page's widget fields in tab order (wrapping at the ends), so an assistive reader can walk the form, announce each field viaFormFieldInfo[Index].AlternateName(the /TU tooltip), and fill it viaFormField[Index] TPdfView.OnFormFieldFocusChangeevent, raised when the field cursor moves (carrying the new field index, or -1 when cleared)
Version 1.46.0
Added
- Assistive listen-reading content stream:
TPdf.ReadableContent,TPdf.ReadablePageContent,TPdf.DocumentReadableContentandTPdfView.ReadableContentreturn an ordered list of semanticTPdfContentFragmentitems, each carrying the spoken text (real glyphs, orActualText/Alt for figures), a fragment kind (heading with level, paragraph, figure, list item, table cell, link, plain), language, 1-based page, and block plus per-line highlight rectangles. Tagged PDFs are linearised in logical reading order from the structure tree; untagged pages fall back to render order so any document can be read aloud - Synced reading highlight on
TPdfView:SetReadingHighlight,ClearReadingHighlightand the publishedReadingHighlightColorhighlight the block currently being read, on top of the search and selection overlays - New public types
TPdfContentFragment,TPdfContentFragments,TPdfReadableContent,TPdfContentFragmentKindandTPdfReadingOrderSource, and the new helperClassifyStructType
Version 1.45.0
Added
ValidatePdfUanow also walks the live tagged structure tree and reports three high-confidence content violations that byte-level scanning cannot detect: aFigureelement with neither an Alt entry nor ActualText (ISO 14289-1, 7.3), aFormulaelement without an Alt attribute (7.7), and aNoteelement that lacks a unique ID (7.9). Three newTPdfUaValidationIssuevalues surface these:pvuaiFigureMissingAlt,pvuaiFormulaMissingAltandpvuaiNoteMissingId. The tree walk is skipped for untagged documents- New public helper
ValidatePdfUaStructureElementsapplies those structure-tree rules to a flat element list (as returned byTPdf.StructureElements), so the checks can be run or unit-tested without loading a full document
Version 1.44.5
Fixed
- The
ValidatePdfAfont-embedding check (pvaiFontNotEmbedded, ISO 19005-1, 6.3.4) now also detects non-embedded simple fonts that carry no/FontDescriptor, most importantly the 14 standard Type 1 fonts (Helvetica, Times, Courier, and so on) which PDF/A requires to be embedded with no exemption. Previously such a font went unnoticed; the check now also counts simple-font dictionaries (/Type1,/TrueType,/MMType1) against the embedded font programs, mirroring the PDF/UA fix in 1.44.3
Version 1.44.4
Fixed
ValidatePdfVTnow rejects malformed ISO 16612-2 §6.5 DPart trees where/DPartsis a flat reference array instead of the required array of arrays, or where a leaf DPart repeats its/Startpage as/Endeven though the range contains only one pageValidatePdfVTnow validates/NodeNameListnames as XML NMTOKEN values after PDF name#xxescape expansion, so invalid hierarchy level names are reported throughpvviMissingDPartRootinstead of being accepted as usable DPart structure
Version 1.44.3
Fixed
- The
ValidatePdfUafont-embedding check (pvuaiFontNotEmbedded, ISO 14289-1, 7.21.4) now also detects non-embedded simple fonts that carry no/FontDescriptor, most importantly the 14 standard Type 1 fonts (Helvetica, Times, Courier, and so on) for which PDF/UA grants no embedding exemption. Previously such a font went unnoticed and a document that used it could be reported as compliant; the check now also counts simple-font dictionaries (/Type1,/TrueType,/MMType1) against the embedded font programs
Version 1.44.2
Fixed
ValidatePdfVTnow leaves a present but unrecognizedpdfvtid:GTS_PDFVTVersionmarker aspvcUnknowninstead of downgrading it topvcNone. This keeps invalid file-level strings such asPDF/VT-2sdistinguishable from documents that carry no PDF/VT marker; PDF/VT-2s is identified by the MIME stream header in ISO 16612-2 Annex A, not by a PDF file's XMP marker- The
/DPartRootcheck now validates the ISO 16612-2 §6.5 tree semantics more tightly:/DPartRootNodeand/NodeNameListmust describe the actual DPart depth, DPart parent links must form a tree,/Startand/DPartsare mutually exclusive, and each page/DPartmust point to the covering leaf DPart in the same depth-first order as the page tree
Version 1.44.1
Fixed
SaveAsPdfVTnow writes a minimal ISO 16612-2 §6.5 Document Part Hierarchy when the source PDF lacks a usable/DPartRoot. The generated tree links every page through/DPart, preserves an existing valid hierarchy, and leaves richer recipient/DPM metadata to the calling workflowValidatePdfVTnow validates the usable DPart structure, reads PDF/VT XMP values from both RDF attributes and element text, and enforces the exact PDF/VT-to-PDF/X base pairing: PDF/VT-1 requires PDF/X-4, while PDF/VT-2 requires PDF/X-4p, PDF/X-5g, or PDF/X-5pgTPdfVTSaveOptions.Conformance = pvc2no longer writes invalid single-file PDF/VT-2 markers. The single-file writer normalizes output to PDF/VT-1 because PDF/VT-2 requires file-set semantics
Version 1.44.0
Added
ValidatePdfUanow also reports byte-checkable content-level PDF/UA violations in addition to the file-format markers: a font program that is not embedded (ISO 14289-1, 7.21.4), a font that lacks a/ToUnicodeCMap when no exempt simple-font encoding is present (7.21.7), and a document that carries annotations but declares no page/Tabs /Stab order (7.18.3)- Three new
TPdfUaValidationIssuevalues —pvuaiFontNotEmbedded,pvuaiFontMissingToUnicodeandpvuaiMissingTabsOrder— are surfaced byValidatePdfUaand in the preflight report. They are coarse heuristics intended as preflight hints rather than a full ISO 14289-1 verification
Version 1.43.1
Fixed
SaveAsPdfUanow enforces the ISO 14289-1, 7.1 mandatory/ViewerPreferences/DisplayDocTitle trueand/MarkInfo/Marked true/Suspects falsecatalog entries even when the source document already provides those dictionaries with missing or contradicting values. Previously the markers were injected only when the dictionaries were entirely absent, so a source that carried, for example, a/ViewerPreferenceswithoutDisplayDocTitleor a/MarkInfowith/Marked falseround-tripped to a non-conforming file- Existing keys in a pre-existing
/ViewerPreferencesor/MarkInfodictionary are preserved, and a dictionary supplied as an indirect reference is resolved before the mandatory keys are applied
Version 1.43.0
Added
ValidatePdfAnow applies the PDF/A-2 / PDF/A-3 rules for embedded and associated files and for Level U text. Embedded files are still rejected for PDF/A-1; for PDF/A-3 an embedded file that lacks the required/AFRelationshipkey (ISO 19005-3 Annex E) is flagged, while PDF/A-2 attachments are permitted (their own conformance is not verified recursively). A newpvaiUnicodeMappingMissingissue reports a PDF/A-2u or PDF/A-3u document whose fonts carry no/ToUnicodemapping (ISO 19005-2 6.2.11.7). Transparency and optional content remain flagged only for PDF/A-1
Version 1.42.0
Added
- PDF/A-2 (ISO 19005-2) and PDF/A-3 (ISO 19005-3) are now supported at all three conformance levels — a, b and u — by
SaveAsPdfA,ValidatePdfAand thePdfAConformanceproperty. TheTPdfAConformanceenumeration gainspac2a,pac2u,pac3aandpac3u(PDF/A-1 has no Level u). Saving writes the matchingpdfaid:part(2 or 3) andpdfaid:conformance(A, B or U), keeping theGTS_PDFA1OutputIntent subtype that ISO 19005-2 retains for compatibility. A Level A request still downgrades to the matching Level B (for any part) when the document lacks the tagged structure that level requires
Version 1.41.0
Added
ValidatePdfAnow detects content-level PDF/A violations that marker injection cannot repair, on top of the structural markers it already reported: JavaScript and other forbidden actions, additional-actions (/AA), embedded files,LZWDecode, transparency (soft masks and transparency groups), optional content (/OCProperties), forbidden annotation subtypes (FileAttachment, Sound, Movie, 3D, Screen), AcroForm/NeedAppearances trueand/XFA, fonts whose descriptors lack an embedded font program, and a Level A claim made without the tagged structure required by ISO 19005-1 6.8. The transparency, optional-content and embedded-file checks apply only to PDF/A-1 (these features are permitted in PDF/A-2 and PDF/A-3). NewTPdfAValidationIssuevalues surface each case; the existing values are unchanged
Version 1.40.3
Fixed
SaveAsPdfAnow strips any source-document encryption before producing PDF/A output. ISO 19005-1 6.1.3 forbids the trailer/Encryptkey, but the save path previously preserved the source's security handler, so saving an encrypted document as PDF/A produced an encrypted, non-conformant file. The PDF/A save now decrypts the document first. Unencrypted documents are unaffected
Version 1.40.2
Fixed
- Stopped
SaveAsPdfAfrom emitting a false PDF/A Level A conformance claim. When Level A (pac1a) is requested but the source document lacks the tagged-structure markers required by ISO 19005-1 6.8 — a/StructTreeRootin the catalog and a/MarkInfodictionary with/Marked true— the saved file is now identified as the matching Level B (pdfaid:conformance=B) instead of asserting Level A. Purely visual PDF/A-1b output is unaffected
Version 1.40.1
Fixed
- Tightened PDF version-compliance validation so that the
SetOCGState(set-optional-content-group-state) action is recognized as a PDF 1.5 feature. Saving to a PDF 1.2, 1.3, or 1.4 target that contains aSetOCGStateaction is now rejected to match ISO 32000-1 (Table 198); previously such an action could pass through into lower-version output. The distinct, obsolete PDF 1.2SetStateaction is still accepted from PDF 1.2 onward
Version 1.40.0
Added
- Bound the PDFium
FPDFPageObj_AddExistingMark()API, which attaches an existing content mark to a page object. When consecutive page objects share the same mark, the saved PDF collapses them into a single mark that spans all of them; non-consecutive objects receive separate copies - Bound the PDFium
FPDFTextObj_SetFontSize()API for changing the point size of an existing text object, complementing the existingFPDFTextObj_GetFontSize()binding
Changed
- Refreshed the bundled PDFium runtime DLLs (Win32 and Win64, standard and V8 builds) to the 2026-06-02 PDFium snapshot
Version 1.39.53
Changed
- Changed the Delphi
PDFViewer,SplitView, andMultiPageViewerdemos to open documents inZoom to Pagemode by default - The initial render now fits the whole page into the viewer surface before the user chooses a manual zoom level
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.53
Version 1.39.52
Changed
- Enhanced
Demo\Lazarus\CreatePDFso the introductory sample now generates a two-page PDF with vector paths, table content, an embedded image, a text annotation, rotated text, and a clearer document-building walkthrough - Added polished
README.htmlpages for every Delphi, C++Builder, and Lazarus demo folder, replacing the remaining text-only demo README with a browser-readable guide - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.52
Version 1.39.51
- Enhanced
Demo\Delphi\PreflightReportClibatch summaries with standard status totals for Pass, Action required, and Review results across the selected standards - Per-file rows now include action-required and review counts in TXT / HTML / JSON / CSV summaries, making CI artifacts easier to inspect without opening each generated report
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.51
Version 1.39.50
- Enhanced
Demo\Delphi\PreflightReportClidirectory batch mode sobatchdir=foldercollects discovered PDF paths, sorts them, and then generates reports in a stable order - Recursive directory scans now produce reproducible report order and summary rows, while explicit
batch=list.txtprocessing continues to preserve the list file order - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.50
Version 1.39.49
- Enhanced
Demo\Delphi\PreflightReportClibatch summaries to record run settings: source kind, source path, recursive state, output directory, report format, selected standards, andfailon=mode - JSON summaries now include a
runobject, TXT and HTML summaries show a run settings section, and CSV rows repeat the same audit columns for spreadsheet and CI pipelines - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.49
Version 1.39.48
- Enhanced
Demo\Delphi\PreflightReportClibatch output naming so duplicate input file names that share oneoutdir=no longer overwrite each other's generated reports - Batch runs now append
-2,-3, and later suffixes when a generated report path has already been assigned in the same run, and summaries record the final collision-safe report path - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.48
Version 1.39.47
- Enhanced
Demo\Delphi\PreflightReportClibatch summaries so TXT and JSON outputs now include aggregate totals for total files, processed files, failed files, issues, andfailon=matches - CSV summaries remain a pure row table for existing consumers, while HTML summaries continue to show the same aggregate metrics in the dashboard header
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.47
Version 1.39.46
- Enhanced
Demo\Delphi\PreflightReportCliwithsummary=batch.html/.htmso batch runs can emit a browser-readable dashboard alongside TXT / CSV / JSON manifests - HTML summaries show total, processed, failed, issue, and
failon=match metrics, then list each input with report links, status, counts, and error text - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.46
Version 1.39.45
- Enhanced
Demo\Delphi\PreflightReportCliwithbatchdir=folderandrecursiveso scripts can scan PDF folders directly without first writing a list file - Directory batch mode reuses
outdir=,summary=,standards=, andfailon=behavior from list-based batch mode, while non-recursive scans only the selected folder andrecursiveincludes subfolders - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.45
Version 1.39.44
- Enhanced
Demo\Delphi\PreflightReportCliwithsummary=batch.csv|json|txtso batch runs can emit a machine-readable manifest beside the per-file reports - Batch summaries include each input path, report path, status, standard count, passed count, issue count,
failon=match state, and error text for CI jobs and external scripts - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.44
Version 1.39.43
- Enhanced
Demo\Delphi\PreflightReportCliwithbatch=list.txtandoutdir=reportsso scripts can generate preflight reports for a list of PDF files in one run - Batch mode skips blank and
#comment lines, derives each.preflight.<ext>report name from the input PDF, continues after per-file errors, and summarizes processed and failed files before returning - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.43
Version 1.39.42
- Enhanced
Demo\Delphi\PreflightReportCliwithfailon=none|issues|action|reviewso CI jobs can turn generated preflight results into deterministic exit codes - The CLI now returns exit code 2 when a selected
failon=rule matches after the report file and optional attached-report PDF have been generated, while runtime errors still return exit code 1 - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.42
Version 1.39.41
- Enhanced
Demo\Delphi\PreflightReportCliwithattach=output.pdfso a generated preflight report can be embedded as a document-level attachment in a new PDF copy - The CLI keeps the generated TXT / HTML / Markdown / JSON / CSV report file on disk and refuses to attach back into the original input PDF path, reducing accidental overwrite risk
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.41
Version 1.39.40
- Added
Demo\Delphi\PreflightReportCli, a Delphi console companion for scriptableFPdfPreflightReportgeneration without opening a viewer - The CLI supports no-argument sample creation plus input / output arguments, optional password,
text/html/md/json/csvoutput formats, andstandards=filtering for PDF/A, PDF/UA, PDF/E, PDF/X, PDF/R, and PDF/VT - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.40
Version 1.39.39
- Enhanced
FPdfPreflightReportwithTPdfPreflightReport.ToMarkdownandSaveMarkdownToFileso preflight reports can be exported as issue-tracker-friendly Markdown - Updated the Delphi, C++Builder, and Lazarus
PreflightReportsamples with Markdown preview switching and Save MD actions alongside the existing TXT / HTML / JSON / CSV workflow - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.39
Version 1.39.38
- Enhanced the Delphi, C++Builder, and Lazarus
SecurityAuditsamples with JSON audit report export alongside the existing TXT save / copy workflow - The JSON report contains
format,generatedAt,summary,findingCount, and structuredfindingsrows with severity, area, and detail fields - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.38
Version 1.39.37
- Enhanced
FPdfPreflightReportwithTPdfPreflightReport.ToCsvandSaveCsvToFileso preflight reports can be exported as spreadsheet-friendly CSV - Updated the Delphi, C++Builder, and Lazarus
PreflightReportsamples with CSV preview switching and Save CSV actions alongside the existing TXT / HTML / JSON workflow - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.37
Version 1.39.36
- Enhanced
FPdfPreflightReportwithTPdfPreflightReport.IssueCategoryCountsplus reusableTPdfPreflightIssueCategoryCountandTPdfPreflightIssueCategoryCountstypes for aggregating marker-level issues by category - Updated
TPdfPreflightReport.ToText,ToHtml, andToJsonso generated PreflightReport output includes issue-category count summaries alongside per-standard rows and detailed issue recommendations - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.36
Version 1.39.35
- Renamed the expanded
PrintDialogsample toPrintPreferencesacross Delphi, C++Builder, and Lazarus so the demo name now matches its PDF author print preferences, N-up printing, odd / even filtering, grayscale, cell border, and duplex mapping workflow - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.35
Version 1.39.34
- Enhanced
Demo\Delphi\PrintPDFwith drag-and-drop PDF loading and documented the existingDemo\CBuilder\PrintPDFworkflow alongside the Delphi and Lazarus PrintPDF samples - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.34
Version 1.39.33
- Added
Demo\CBuilder\SplitView, completing the SplitView sample matrix across Delphi, C++Builder, and Lazarus - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.33
Version 1.39.32
- Added
Demo\Lazarus\SplitView, bringing side-by-side PDF comparison to Lazarus with two- or three-pane layouts, active-view navigation, synchronized commands, zoom presets, and rotation - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.32
Version 1.39.31
- Added
Demo\Lazarus\PrintPDF, bringing the standard PDF print workflow to Lazarus with preview navigation, page ranges, copies, collate mode, progress, and cancellation - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.31
Version 1.39.30
- Added
Demo\Lazarus\FontProperties, completing the FontProperties sample matrix across Delphi, C++Builder, and Lazarus - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.30
Version 1.39.29
- Added
Demo\CBuilder\FontProperties, bringing indexed character and font metadata inspection to C++Builder alongside the Delphi sample - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.29
Version 1.39.28
- Added
Demo\Delphi\ExtractTextPages, completing the per-page text extraction sample matrix across Delphi, C++Builder, and Lazarus - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.28
Version 1.39.27
- Added
Demo\Lazarus\PrintDialog, completing the PrintDialog sample matrix across Delphi, C++Builder, and Lazarus - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.27
Version 1.39.26
- Added
Demo\CBuilder\PrintDialog, bringing the N-up printing and PDF author print preferences workflow to C++Builder alongside the Delphi sample - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.26
Version 1.39.25
- Added
Demo\CBuilder\ViewerInteractionLab, completing the ViewerInteractionLab sample matrix across Delphi, C++Builder, and Lazarus - Updated the library build workflow and Win64 C++Builder package outputs so
TPdfViewviewer interaction methods link correctly in Win64 demos - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.25
Version 1.39.24
- Added
Demo\Lazarus\ViewerInteractionLab, bringing the focused viewer interaction workflow to Lazarus alongside the Delphi sample - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.24
Version 1.39.23
- Added
Demo\Lazarus\SearchAndSelect, completing the SearchAndSelect sample matrix across Delphi, C++Builder, and Lazarus - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.23
Version 1.39.22
- Added
Demo\CBuilder\ContentExtractionLabandDemo\Lazarus\ContentExtractionLab, bringing the multi-category content extraction workflow to all supported demo IDEs - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.22
Version 1.39.21
- Enhanced
Demo\Delphi\PreflightReport,Demo\Lazarus\PreflightReport, andDemo\CBuilder\PreflightReportwith a preview format selector so users can inspect text or JSON output before saving reports - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.21
Version 1.39.20
- Added JSON export to
FPdfPreflightReportthroughTPdfPreflightReport.ToJsonandSaveJsonToFile, producing machine-readable summaries, per-standard status / priority, next actions, and issue details - Updated
Demo\Delphi\PreflightReport,Demo\Lazarus\PreflightReport, andDemo\CBuilder\PreflightReportwith Save JSON actions alongside TXT / HTML export - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.20
Version 1.39.19
- Enhanced
FPdfPreflightReportwithTPdfPreflightStatus, issue categories, per-standard priority, and next-action guidance in TXT / HTML reports - Updated
Demo\Delphi\PreflightReport,Demo\Lazarus\PreflightReport, andDemo\CBuilder\PreflightReportto show status, priority, issue count, and next action in the summary grid - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.19
Version 1.39.18
- Added
Demo\Lazarus\SecurityAudit, completing the Delphi, C++Builder, and Lazarus demo matrix for the read-only PDF risk-surface audit workflow - The Lazarus sample enumerates permissions, attachments, JavaScript actions, URI / Launch link annotations, web links, signatures, XFA state, V8 / XFA helper availability, and unsupported-feature callbacks, then saves or copies the finding list as a TXT report
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.18
Version 1.39.17
- Added
Demo\CBuilder\SecurityAudit, bringing the read-only PDF risk-surface audit workflow to C++Builder alongside the existing Delphi sample - The C++Builder sample enumerates permissions, attachments, JavaScript actions, URI / Launch link annotations, web links, signatures, XFA state, V8 / XFA helper availability, and unsupported-feature callbacks, then saves or copies the finding list as a TXT report
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.17
Version 1.39.16
- Added
Demo\CBuilder\SearchAndSelect, bringing the standalone SearchAndSelect viewer workflow to C++Builder alongside the existing Delphi sample - The C++Builder sample creates or opens PDFs, lists all-page matches with page / character-index previews, supports Previous / Next and double-click navigation, and highlights current-page matches with
HighlightSearchText - It also exposes
AllowUserTextSelection,SelectedText,SelectAll,CopySelectionToClipboard,ClearSelection,OnSelectionChange, and spreadDisplayModeoptions; version metadata now reports 1.39.16
Version 1.39.15
- Added
Demo\CBuilder\WatermarkStamp, completing the Delphi, Lazarus, and C++Builder demo matrix for reusable Form XObject watermark and stamp workflows - The C++Builder sample creates target and stamp PDFs, reuses the stamp page through
CreateXObjectFromPage, appliesTPdfMatrixtransforms, and saves centered watermarks, corner stamps, and page number labels - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.15
Version 1.39.14
- Added
Demo\Lazarus\WatermarkStamp, bringing the reusable Form XObject watermark and stamp workflow to Lazarus - The Lazarus sample creates target and stamp PDFs, reuses the stamp page through
CreateXObjectFromPage, appliesTPdfMatrixtransforms, and saves centered watermarks, corner stamps, and page number labels - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.14
Version 1.39.13
- Added
Demo\CBuilder\PreflightReport, completing the Delphi, Lazarus, and C++Builder demo matrix for the reusableFPdfPreflightReportworkflow - The C++Builder sample uses
FPdfPreflightReport.hppto generate standard summaries, TXT report previews, TXT / HTML report files, and Open Last Report behavior - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.13
Version 1.39.12
- Added
Demo\Lazarus\PreflightReport, bringing the PDF/A, PDF/UA, PDF/E, PDF/X, PDF/R, and PDF/VT preflight report workflow to Lazarus - The Lazarus sample can open or create a PDF, select target standards, preview summary rows and TXT report output, save TXT / HTML reports, and open the most recently saved report
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.12
Version 1.39.11
- Enhanced
Demo\Delphi\SearchAndSelectwith an all-page search results list that records page number, character index, and preview text - Added Previous / Next match navigation and double-click result jumping while preserving current-page
HighlightSearchTextbehavior - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.11
Version 1.39.10
- Enhanced
Demo\Delphi\SecurityAuditwith Save Report and Copy Report actions that export the current summary and finding rows as a TXT audit report - The demo now clears report export state when the audit panel is reset, keeping copied or saved reports aligned with the visible findings
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.10
Version 1.39.9
- Enhanced
Demo\Delphi\ContentExtractionLabwith source-PDF save, report copy-to-clipboard, and all / none category selection actions - The demo now invalidates the current report when category selections change, so TXT / JSON exports reflect the visible extraction scope
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.9
Version 1.39.8
- Added
Demo\Delphi\ContentExtractionLab, a unified content extraction workflow sample for document metadata, page text, page objects, images, attachments, links, annotations, bookmarks, and font / character metrics - The sample can open an existing PDF or create a synthetic PDF with text, image, attachment, and annotation content, then generate summary rows and detailed TXT / JSON reports
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.8
Version 1.39.7
- Added
Lib\FPdfPreflightReport.pas, a reusable report helper that wrapsValidatePdfA,ValidatePdfUa,ValidatePdfE,ValidatePdfX,ValidatePdfR, andValidatePdfVTinto oneTPdfPreflightReportobject - Added
Demo\Delphi\PreflightReport, a workflow sample that opens or creates a PDF, selects target standards, previews summary rows and issue recommendations, and saves TXT or HTML reports - The generated reports explicitly describe the built-in marker-level validation boundary so applications can pair them with dedicated content-level preflight tools when required
- Updated
TPdf.AboutInfo, Lazarus package metadata, package project lists, and installer version metadata to report 1.39.7
Version 1.39.6
- Added
Demo\Delphi\SearchAndSelect, a focused viewer workflow sample for search highlighting, text selection, selected-text preview, copy, clear, and spread display modes - The sample demonstrates
HighlightSearchText, match-case / whole-word search options,AllowUserTextSelection,SelectedText,SelectAll,CopySelectionToClipboard, andClearSelectionwithout adding new library API - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.6
Version 1.39.5
- Expanded
Demo\Delphi\ViewerInteractionLabinto a SearchAndSelect-style viewer UX sample withHighlightSearchText, match-case / whole-word options, selected-text preview, and existing selection / clipboard controls - Extended
Demo\Delphi\PrintDialogto inspect PDF author print preferences:PrintCopies,PrintPageRanges,PrintScaling,PrintPaperHandling, and visibleSetPdfPrintPaperHandlingDevModeduplex mapping - Added
Demo\Delphi\SecurityAudit, a read-only risk-surface sample that lists permissions, attachments, document JavaScript, URI / Launch links, web links, signatures, XFA state, and V8 / XFA helper availability - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.5
Version 1.39.4
- Added
Demo\CBuilder\ImageToPDFandDemo\Lazarus\ImageToPDF, completing the ImageToPDF sample matrix across Delphi, C++Builder, and Lazarus - The new samples demonstrate multi-image selection, selected-image preview, one PDF page per image, A4 portrait / landscape page sizing, centered image scaling, per-image progress, and opening the generated PDF after saving
- Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.4
Version 1.39.3
- Added
Demo\CBuilder\BatchExport, bringing the multi-file PDF to JPG export workflow to C++Builder alongside the existing Delphi and Lazarus samples - The sample demonstrates
LoadCustomDocument,IPdfCancellationTokenSource, streamingTFileStreaminput, per-file and per-page progress, cancel handling, DPI / quality / password inputs, and output-folder opening after completion - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.3
Version 1.39.2
- Added
Demo\Delphi\WatermarkStamp, a runnable Form XObject workflow sample that creates a target PDF and reusable stamp PDF, then applies centered watermarks, top-right stamps, and page-number labels across every page - The sample demonstrates
CreateXObjectFromPage,InsertFormObjectFromXObject,TPdfMatrix, andFPDFPageObj_SetMatrixwithout adding new library API - Updated
Docs\en-us\Examples.htmlto use the currentTPdfMatrix.Handlepattern when passing matrices toFPDFPageObj_SetMatrix - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.2
Version 1.39.1
- Added
Demo\Delphi\ViewerInteractionLab, a focusedTPdfViewsample for display modes, fit modes, page colors, rotation, user text selection, clipboard actions, andDeviceToPagecoordinate feedback - Added
Demo\CBuilder\StandardsLab/Demo\Lazarus\StandardsLabso Lazarus users can run the PDF/A, PDF/UA, PDF/E, PDF/X, PDF/R, and PDF/VT validation and marker-output workflow - Listed the standards units in
Lib\37.0\PDFiumPas.dprojandLib\FPC\PDFiumLaz.lpkand fixed the DelphiSplitViewdemo build by removing a duplicateWinapi.ShellAPIimport - Fixed Delphi demo batch-build blockers in
BatchExport,PDFViewer,MultiPageViewer, andSplitViewwithout changing their runtime behavior - Fixed C++Builder demo batch-build compatibility in
PDFViewerandMultiPageViewerby replacingnullptrwithNULLfor the current project mode - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.1
Version 1.39.0
- Added
Demo\Delphi\StandardsLab, a runnable standards workflow sample that loads or creates a PDF, runsValidatePdfA,ValidatePdfUa,ValidatePdfE,ValidatePdfX,ValidatePdfR, andValidatePdfVT, and displays detected conformance, pass/fail status, and issue counts in one grid - The StandardsLab save buttons call
SaveAsPdfA,SaveAsPdfUa,SaveAsPdfE,SaveAsPdfX,SaveAsPdfR, andSaveAsPdfVT, making PDF standards marker output visible without writing a custom harness - Updated
TPdf.AboutInfo, Lazarus package metadata, and installer version metadata to report 1.39.0
Version 1.38.0
TPdfViewsearch and text-selection overlays now use real alpha blending instead of logical mask painting, preserving page content under highlights- Added
SetPdfPrintPaperHandlingDevModeto mapTPrintPaperHandlinginto WindowsDEVMODE.dmDuplexvalues:DMDUP_SIMPLEX,DMDUP_HORIZONTAL, andDMDUP_VERTICAL TPdfView.SmoothScrollnow animates line/page scrollbar commands in timer-driven segments; thumb tracking remains immediate- Updated
TPdf.AboutInfoand installer version metadata to report 1.38.0
Version 1.37.0
TPdfnow owns a per-instance render lock that serializesRenderPage,RenderTile,RenderPageProgressive, page reload, and document unload paths. Worker-driven rendering through a shared component is now practical, while applications still coordinate document mutation and lifetime- Fixed the zero-copy bitmap wrapper to reject bottom-up
TBitmapDIB layouts and fall back to a PDFium-owned buffer before copying out, eliminating stride-corruption / access-violation failures in VCL render tests - Tightened
TPdfViewselection behavior:AllowUserTextSelectiongates user input only, code-level selection APIs still paint, andSelectAllfollows the actual visible spread so the cover page no longer selects page 2. Delphi, Lazarus, and C++Builder tests were expanded accordingly - Updated
TPdf.AboutInfoand installer version metadata to report 1.37.0
Version 1.36.0
- Activated end-user text selection in
TPdfView— theAllowUserTextSelectionproperty reserved in v1.17.0 now drives a complete drag-select pipeline. Left-click on a text character enters select mode (hit-test auto); left-click on a blank area continues to pan as before. The form-fill widget keeps priority, so clicking on a form field still focuses the field rather than starting a selection - Double-click selects the word, triple-click selects the line,
Ctrl+Aselects the current page (both pages in spread display modes), andCtrl+Ccopies the selection to the Windows clipboard asCF_UNICODETEXT Shift+Left/Shift+Rightextends the selection one character at a time (spilling to the adjacent page in spread mode);Shift+Home/Shift+Endextends to the visual line edge using the seed character's box height as the line-cluster tolerance, so mixed-font-size lines stay clustered correctly- Hovering over text changes the cursor to
crIBeam; hovering off text restores the default cursor. While a text-selection drag is in progress, dragging into a 20-pixel dead zone at any viewer edge auto-scrolls the page (50 ms tick, 16 px / tick, clamped to the same bounds the pan path uses) so the selection can extend past the current viewport without first releasing the mouse - Cross-page selection works in spread display modes (
dmTwoPageContinuous,dmTwoPageContinuousWithCover): a drag started on the left page and ending on the right page selects the contiguous range spanning both.SelectedTextjoins the per-page slices with CR/LF so the round-tripped text reads like normal multi-line content - New published property
SelectionColor(defaultclHighlight, the Windows system selection color) — independent fromHighlightColorwhich colors search results in yellow. Search highlights and a live drag-selection can be shown on screen simultaneously without color conflict - New published event
OnSelectionChangefires whenever the selection's materialised ranges actually mutate — never on identical re-application, so host applications can wire it directly to status-bar text or button enabled state without debouncing - New public API on
TPdfView:HasSelection,SelectionCharCount,SelectedText,ClearSelection,SelectAll,CopySelectionToClipboard. These are code-level entry points and always work regardless ofAllowUserTextSelection— the flag only gates user input (mouse, Ctrl+C, Ctrl+A, Shift+arrows), so kiosk hosts can disable user-driven selection while still building "Select All / Copy" toolbar buttons that drive the same API - A default right-click
Copy/复制popup menu is auto-attached when the host has not assigned its ownPopupMenu— standard "select text, right-click, copy" works out of the box. The caption is picked between English and Chinese bySysLocale.PriLangID; hosts that need full localization (or a richer menu) just assign their ownPopupMenuand the default is suppressed - Selection is automatically cleared on
SetPdf,SetPageNumber,SetActive(False), andDisplayModetransitions, withOnSelectionChangefiring exactly once when the previous selection was non-empty. The form-fill subsystem keeps priority — while a form field is being edited, all selection keyboard shortcuts defer so the field receivesCtrl+C/Ctrl+A/Shift+arrowsfor its own selection - Expanded the Delphi and Lazarus regression suites to 202 cases each, and the C++Builder suite to 159 cases, covering default values, round-trip, public API behavior, state-change clears, mouse drag (hit-text / hit-blank), click vs drag, IBeam cursor switching, double-click word, triple-click line, keyboard shortcuts, default popup attach / defer / caption, and spread cross-page selection — including a clipboard CR/LF round-trip check
Version 1.35.0
- Added PDF/VT (ISO 16612-2:2010) marker injection support: TPdf.SaveAsPdfVT promotes the current document to a PDF/VT-1 or PDF/VT-2 conformant file (the variable and transactional printing PDF subset). PDF/VT is built on top of PDF/X-4 — ISO 16612-2 §6.2.1 requires every PDF/VT-1 file to also conform to PDF/X-4 — so the injector writes the full PDF/X-4 marker set (XMP
pdfxid:GTS_PDFXVersion = "PDF/X-4", Info/GTS_PDFXVersion (PDF/X-4)and/Trapped, catalog/OutputIntentsreferencing an OutputIntent dictionary with embedded ICC profile) alongside the PDF/VT-specific properties - The PDF/VT-specific injection covers XMP
pdfvtid:GTS_PDFVTVersion(= "PDF/VT-1" or "PDF/VT-2" per §6.3 Table 2) andpdfvtid:GTS_PDFVTModDate(kept in sync withxmp:ModifyDateper §6.3 NOTE 1), plus a pdfaExtension:schemas description that declares both the pdfxid and pdfvtid namespaces (NPES URIshttp://www.npes.org/pdfx/ns/id/andhttp://www.npes.org/pdfvt/ns/id/). The trailer carries an/IDarray - Added TPdf.SaveAsPdfVTToStream for in-memory PDF/VT output, and a default-options shorthand
TPdf.SaveAsPdfVT(FileName)that produces PDF/VT-1 with the bundled sRGB IEC61966-2.1 OutputIntent (3144 bytes, same profile as SaveAsPdfA / SaveAsPdfX) and/Trapped /False - Added TPdf.ValidatePdfVT: checks an open PDF for PDF/VT compliance markers (XMP
pdfvtid:GTS_PDFVTVersionandGTS_PDFVTModDatepresence, equality betweenpdfvtid:GTS_PDFVTModDateandxmp:ModifyDate, presence of the underlyingpdfxid:GTS_PDFXVersionidentifier, catalog/DPartRootpresence per §6.5,/OutputIntentswith/DestOutputProfile, trailer /ID, encryption status,xmp:CreateDate/ModifyDatepresence) and returns TPdfVTValidationResult with the detected conformance level and the set of issues found - Added TPdf.PdfVTConformance property: returns the conformance level of the currently open document (pvc1, pvc2, pvcNone, or pvcUnknown) without needing to call ValidatePdfVT explicitly
- New types exported in the new unit FPdfPdfvt: TPdfVTConformance (pvcUnknown/None/1/2), TPdfVTTrappedState (ptvUnspecified/True/False/Unknown), TPdfVTValidationResult, TPdfVTValidationIssue, TPdfVTSaveOptions
- Document Part Hierarchy (
DPartRoot/DParttree per §6.5) is application-level structure that depends on the variable-data print workflow's recipient / page-range mapping. SaveAsPdfVT does NOT synthesise a DPart tree — ValidatePdfVT surfaces a missing/DPartRootaspvviMissingDPartRootso callers can route PDF/VT files through a separate DPart-building step. Content-level PDF/X-4 requirements (font embedding, transparency, ICC managed color, OPI / JavaScript / Reference XObject prohibitions, etc.) remain the responsibility of the document author and PDFium's rendering pipeline - Updated TPdf.AboutInfo string to report the current product version
Version 1.34.0
- Added PDF/R-1 (ISO 23504-1:2020) marker injection support: TPdf.SaveAsPdfR promotes the current document to a PDF/R-1 conformant file (the raster-image transport subset of PDF used for scanned documents). The injection covers the file-format level requirements that can be attached by post-processing — the unique
%PDF-raster-1.0version-identification comment written between the trailer dictionary and the startxref keyword (§5), the catalog dictionary stripped down to the §6.3 white list (only Version / ViewerPreferences / PageLayout / PageMode / AcroForm / Metadata survive), the Document Information Dictionary stripped to the §6.4.3 white list (only Creator / Producer / CreationDate / ModDate), a catalog /Metadata XMP stream carrying the four §6.4.4 Table 1 entries (xmp:CreatorTool / pdf:Producer / xmp:CreateDate / xmp:ModifyDate), and a trailer /ID array - Added TPdf.SaveAsPdfRToStream for in-memory PDF/R output, and a default-options shorthand
TPdf.SaveAsPdfR(FileName)for the common case - Added TPdf.ValidatePdfR: checks an open PDF for PDF/R-1 compliance markers (the
%PDF-raster-x.yfooter comment, header version, /Type /ObjStm absence, catalog white-list compliance, Info dictionary white-list compliance, XMP metadata stream presence, trailer /ID) and returns TPdfRValidationResult with the detected conformance level and the set of issues found - Added TPdf.PdfRConformance property: returns the conformance level of the currently open document (prc1, prcNone, or prcUnknown) without needing to call ValidatePdfR explicitly
- New types exported in the new unit FPdfPdfr: TPdfRConformance, TPdfRValidationResult, TPdfRValidationIssue, TPdfRSaveOptions.
TPdfRSaveOptions.Defaultsets StripInfoOptionalEntries and StripCatalogOptionalEntries to True, so the injector defaults to producing a §6.3 / §6.4.3 compliant catalog and Info dictionary; callers may set these to False to preserve source entries (the output then won't satisfy those PDF/R clauses, but other markers stay attached) - Content-level requirements remain the responsibility of the source PDF: per-page Contents structure (§6.5.1), MediaBox
[0 0 w h]form (§6.5.3), filter restrictions (§6.2.2 — only FlateDecode, CCITTFaxDecode bitonal, DCTDecode 8-bit gray/RGB), absence of object streams (§6.2.4), and strip layout per §6.6. These cannot be enforced by post-processing — PDF/R is structurally a much stricter subset than the other PDF/x standards and requires generating the source bytes correctly. ValidatePdfR surfaces the file-format issues this unit can detect; pair with a TWAIN Working Group PDF/R validator for full content-level checks - Updated TPdf.AboutInfo string to report the current product version
Version 1.33.0
- Added PDF/X (ISO 15930 family) marker injection support: TPdf.SaveAsPdfX promotes the current document to a PDF/X-1a:2001, PDF/X-3:2002, or PDF/X-4 conformant file by post-processing the base PDF with an incremental update. The injection covers the file-format level requirements that can be attached by post-processing — XMP metadata stream carrying
pdfxid:GTS_PDFXVersion(andpdfxid:GTS_PDFXConformancefor PDF/X-1a / PDF/X-3) plus the matching pdfaExtension:schemas description, a rewritten Document Information Dictionary with/GTS_PDFXVersion,/GTS_PDFXConformance, and/Trappedentries, an updated catalog with/OutputIntents [N 0 R]referencing an OutputIntent dictionary with/S /GTS_PDFXand an embedded ICC profile, and a trailer/IDarray - Added TPdf.SaveAsPdfXToStream for in-memory PDF/X output, and a default-options shorthand
TPdf.SaveAsPdfX(FileName)that produces PDF/X-4 with the built-in sRGB IEC61966-2.1 OutputIntent (3144 bytes, identical to the profile used by SaveAsPdfA) - Added TPdf.ValidatePdfX: checks an open PDF for PDF/X compliance markers (XMP pdfxid identifier and equality with the Info-dictionary value, pdfxid extension schema description, /OutputIntents array with /DestOutputProfile, Title presence, trailer /ID, encryption status, xmp:CreateDate / xmp:ModifyDate presence) and returns TPdfXValidationResult with the detected level and the set of issues found
- Added TPdf.PdfXConformance property: returns the conformance level of the currently open document (pxc1a, pxc3, pxc4, pxcNone, or pxcUnknown) without needing to call ValidatePdfX explicitly. The XMP version string is parsed to disambiguate among the three conformance levels
- New types exported in the new unit FPdfPdfx: TPdfXConformance (pxcUnknown/None/1a/3/4), TPdfXTrappedState (ptUnspecified/True/False/Unknown), TPdfXValidationResult, TPdfXValidationIssue, TPdfXSaveOptions.
TPdfXSaveOptions.Defaulttargets PDF/X-4 with sRGB OutputIntent and/Trapped /False; callers may overrideConformance, supply a CMYKIccProfileDatablob for commercial print workflows, or changeOutputCondition/OutputConditionIdentifier/RegistryNameto point at a specific ICC characterisation registry entry (e.g. FOGRA39, GRACoL2006_Coated1v2) - Content-level requirements (all fonts embedded, no JavaScript, no visible annotations, OPI prohibition, transparency rules for PDF/X-1a / PDF/X-3, etc.) remain the responsibility of the document author and PDFium's rendering pipeline. Pair ValidatePdfX with a preflight tool such as callas pdfaPilot or the Ghent PDF Workgroup Output Suite for complete conformance verification
- Updated TPdf.AboutInfo string to report the current product version
Version 1.32.0
- Added PDF/E-1 (ISO 24517-1:2008) marker injection support: TPdf.SaveAsPdfE promotes the current document to a PDF/E-1 conformant file by post-processing the base PDF with an incremental update. The injection covers the file-format level requirements that can be attached by post-processing — an XMP metadata stream carrying
pdfe:ISO_PDFEVersion = "PDF/E-1"plus the matching pdfaExtension:schemas description, a rewritten Document Information Dictionary with the mandatory/ISO_PDFEVersion (PDF/E-1)entry required by §5, the Info-XMP bridging blocks inherited from ISO 19005-1 §6.7 via §13.1 (dc:title / dc:creator / dc:description / pdf:Producer / pdf:Keywords / xmp:CreateDate / xmp:ModifyDate / xmp:MetadataDate / xmp:CreatorTool), and a trailer/IDarray required by §6.2 - Added TPdf.SaveAsPdfEToStream for in-memory PDF/E output and a default-options shorthand
TPdf.SaveAsPdfE(FileName)for the common case - Added TPdf.ValidatePdfE: checks an open PDF for PDF/E-1 compliance markers (XMP pdfe:ISO_PDFEVersion presence and equality with the Info-dictionary value, pdfe extension schema description, Info-dictionary /ISO_PDFEVersion entry, trailer /ID, xmp:CreateDate / xmp:ModifyDate presence) and returns a structured result with the detected conformance level and the set of issues found
- Added TPdf.PdfEConformance property: returns the conformance level of the currently open document (pec1, pecNone, or pecUnknown) without needing to call ValidatePdfE explicitly
- New types exported in the new unit FPdfPdfe: TPdfEConformance, TPdfEValidationResult, TPdfEValidationIssue, TPdfESaveOptions
- The Info-dictionary rewrite is a first for PDFium Delphi Component's PDF/x post-processing path — it rewrites the existing Info object with the same object number (so xref subsection / trailer /Info reference stay valid) and synthesises a fresh Info dictionary when the source trailer has no /Info entry. PDFium itself emits an Info dictionary in every SaveAs output, so the common case is the rewrite path
- Content-level requirements (font embedding, ToUnicode CMaps, prohibited XObjects / ExtGState keys / XFA forms, etc.) remain the responsibility of the document author — SaveAsPdfE attaches the file-format markers but does not alter page content or remove prohibited features
- Updated TPdf.AboutInfo string to report the current product version
Version 1.31.0
- Added PDF/UA-1 (ISO 14289-1:2014) marker injection support: TPdf.SaveAsPdfUa promotes the current document to a PDF/UA-1 conformant file by post-processing the base PDF with an incremental update. The injection covers the file-format level requirements that can be enforced by post-processing — an XMP metadata stream carrying
pdfuaid:part = 1plus the matching pdfaExtension:schemas description, mandatorydc:title, catalog/MarkInfo << /Marked true /Suspects false >>and/ViewerPreferences << /DisplayDocTitle true >>(only when the source has none), catalog/Lang(when caller supplies a BCP 47 tag), and a trailer/IDarray - Added TPdf.SaveAsPdfUaToStream for in-memory PDF/UA output, and a default-options shorthand
TPdf.SaveAsPdfUa(FileName)for the common case - Added TPdf.ValidatePdfUa: checks an open PDF for PDF/UA-1 compliance markers (StructTreeRoot existence, /Lang, /MarkInfo /Marked true with /Suspects = false, /ViewerPreferences /DisplayDocTitle true, XMP pdfuaid:part identifier, dc:title presence, trailer /ID, encryption status) and returns a structured result with the detected conformance level and the set of issues found
- Added TPdf.PdfUaConformance property: returns the conformance level of the currently open document (puc1, pucNone, or pucUnknown) without needing to call ValidatePdfUa explicitly
- New types exported in the new unit FPdfPdfua: TPdfUaConformance, TPdfUaValidationResult, TPdfUaValidationIssue, TPdfUaSaveOptions
- Title / Author / Subject / Keywords / Creator / Producer / CreationDate / ModDate / DocumentId / InstanceId / Language fields left empty in TPdfUaSaveOptions are auto-populated from FPDF_GetMetaText / FPDF_GetFileIdentifier / FPDFCatalog_GetLanguage, so existing callers can save with a single line
- Content-level requirements (StructTreeRoot tagging completeness, Figure Alt text, ToUnicode CMaps, font embedding, etc.) remain the responsibility of the document author — SaveAsPdfUa attaches the file-format markers but does not alter page content or invent tags. ValidatePdfUa surfaces the absence of StructTreeRoot as
pvuaiMissingStructTreeRootso callers can route untagged documents through a separate tagging pipeline - Updated TPdf.AboutInfo string to report the current product version
Version 1.30.0
- PDF/A-1b output now satisfies the ISO 19005-1 (with Cor.1:2007) requirements for Document Information Dictionary / XMP equivalence: every Info dictionary entry PDFium writes into the base PDF is mirrored into the XMP packet, including Title (dc:title), Author (dc:creator), Subject (dc:description per Cor.1), Keywords (pdf:Keywords), Creator (xmp:CreatorTool), Producer (pdf:Producer), CreationDate (xmp:CreateDate), and ModDate (xmp:ModifyDate). xmp:MetadataDate is also emitted
- The trailer of a PDF/A document now always contains an /ID array (ISO 19005-1 6.1.3 hard requirement). When TPdf.SaveAsPdfA processes a document whose source already has a file identifier, the existing 16-byte permanent and changing IDs are reused; otherwise a deterministic 16-byte fallback ID is derived from the source bytes
- The injected XMP now embeds the pdfaid extension schema description required by ISO 19005-1 6.7.8 (replaced by Cor.1) — pdfaid is treated as an extension schema relative to XMP Specification 2004, so all conforming files must declare its property names, value types, and categories in the pdfaExtension:schemas container
- TPdfASaveOptions gained five new optional fields: Producer, CreationDate, ModDate (PDF date strings in “D:YYYYMMDDHHmmSSOHH'mm'” form), DocumentId, and InstanceId (16-byte byte strings for the trailer /ID array). TPdf.SaveAsPdfA / SaveAsPdfAToStream auto-populate the missing fields from FPDF_GetMetaText and FPDF_GetFileIdentifier, so existing callers continue to work without changes
- TPdf.ValidatePdfA / TPdf.PdfAConformance now report three additional issues: pvaiMissingTrailerId (no /ID in the trailer), pvaiMissingXmpDates (xmp:CreateDate or xmp:ModifyDate missing), and pvaiMissingExtensionSchema (pdfaid extension schema description absent)
- Non-ASCII characters in Title, Author, Subject, Keywords, Creator, and Producer are now encoded as UTF-8 in the XMP packet (XMP Specification requires UTF-8), preserving multilingual metadata round-trip through SaveAsPdfA
- Updated TPdf.AboutInfo string to report the current product version
Version 1.29.0
- Refreshed the bundled PDFium DLLs (Win32 and Win64, both standard and V8 builds) to the 2026-05-22 PDFium snapshot, picking up fixes to FPDFText_SetText / FPDFText_SetCharcodes crash paths and assorted internal hardening from the PDFium project
- Exposed PDFium’s new FPDF_SUBSET_NEW_FONTS save flag in FPdfPageOps.pas, allowing FPDF_SaveAsCopy callers to request automatic subsetting of embedded font files for newly added text objects. The existing FPDF_INCREMENTAL, FPDF_NO_INCREMENTAL, and FPDF_REMOVE_SECURITY constants are now defined using the PDFium bit-shift form (the legacy numeric value 3 is preserved as FPDF_REMOVE_SECURITY_DEPRECATED for binary compatibility)
- Added the FPDF_FONT_BACKEND_TYPE enum (FREETYPE / FONTATIONS) and the matching m_FontLibraryType field on FPDF_LIBRARY_CONFIG in FPdfView.pas, so applications that initialize PDFium with the Skia renderer can now pick the font backend at startup
- Updated the TFPDFPage_InsertObject signature to match the PDFium C export: the function now returns FPDF_BOOL (TRUE on success, FALSE if page_object is NULL or ownership transfer fails) instead of void. Existing PDFium Delphi Component callers continue to compile unchanged since Delphi / FPC allow ignoring a function’s return value
- Corrected the TPdf.AboutInfo string to report the current product version (was stale at v1.27.0 since the v1.28.0 documentation-only release)
Version 1.28.0
- Substantially expanded the in-page documentation across the entire API reference: every property, method, event, and global function entry now carries a 3-paragraph Description, a Remarks list, a multi-line Delphi Example, and a richer See Also block — covering 200+ previously thin pages including all TPdf counters, metadata getters, font and character accessors, page-level properties, indexed records, document-level methods, and the full TPdfView state / display / event surface
- Fine-tuned the help layout to match the losLab visual baseline: matched h1/h2 sizes, consolidated the API navigation grid styles into the shared StyleSheet, and removed the per-page inline CSS overrides on Navigation.html
- Documentation now ships with a helper script (Docs\Build-Expand-Entries.ps1) that regenerates the entry-page enrichment from a single data table for repeatable maintenance
Version 1.27.0
- Added PDF/A-1b creation support: TPdf.SaveAsPdfA saves any open document as a PDF/A-1b conformant file by post-processing the base PDF with an incremental update that injects an XMP metadata stream, an sRGB ICC OutputIntent, and an updated document catalog — all without requiring extra DLL APIs. Works on any platform supported by PDFium Delphi Component
- Added TPdf.SaveAsPdfAToStream for in-memory PDF/A output
- Added TPdf.ValidatePdfA: checks an open PDF for PDF/A compliance (XMP pdfaid markers, OutputIntent with embedded ICC profile, encryption) and returns a structured result with the detected conformance level and a set of specific issues found
- Added TPdf.PdfAConformance property: returns the conformance level of the currently open document (pac1b, pac1a, pac2b, pac3b, pacNone, or pacUnknown) without needing to call ValidatePdfA explicitly
- New types exported: TPdfAConformance, TPdfAValidationResult, TPdfAValidationIssue, TPdfASaveOptions (in new unit FPdfPdfa.pas)
- SaveAsPdfA supports a custom ICC profile via TPdfASaveOptions.IccProfileData; when left empty the built-in sRGB IEC61966-2.1 (HP/Microsoft, 3144 bytes) profile is used automatically
- Replaced the monolithic HTML reference with a restructured web help system: 302 individual API entry pages (one per property, method, event, and global function) covering TPdf and TPdfView, each with a full description, parameter table, Delphi code example, and See Also links
- Added Navigation.html: a comprehensive one-page API navigation index organised into six sections (TPdf properties/methods/events, TPdfView properties/methods/events, global functions) with a 5-column flex grid for fast scanning
- Rebuilt TPdf.html and TPdfView.html as compact component overview pages retaining the type-reference sections (Types, Constants, Global Variables) and linking out to the individual entry pages for all members
- Added full-text search powered by Search.js with incremental client-side matching across all 312 indexed pages
- Updated all navigation bars site-wide to point to Navigation.html
Version 1.26.0
- Added Demo/Lazarus/BatchExport, the LCL port of the v1.14.0 Delphi BatchExport demo. Same feature set: multi-file PDF -> JPG export with per-file overall progress, per-page current progress, DPI / quality / password inputs, and a cooperatively-cancellable batch backed by IPdfCancellationToken. The output folder is opened in the platform file manager when extraction finishes successfully
Version 1.25.0
- Added Form XObject page reuse to TPdf, enabling watermark, template overlay, and “stamp one page onto many” workflows: CreateXObjectFromPage manufactures a reusable handle from any page of another document; InsertFormObjectFromXObject inserts ONE copy of the wrapped page into the current page. Returns the inserted FPDF_PAGEOBJECT so the caller can position / scale / rotate it with FPDFPageObj_SetMatrix and the v1.9.0 TPdfMatrix helpers
- The new TPdfXObject Pascal class wraps PDFium’s FPDF_XOBJECT handle and closes it automatically in its destructor, eliminating the manual FPDF_CloseXObject ceremony
- Expanded the Delphi and Lazarus regression suites to 147 cases each, and the C++Builder suite to 123 cases, covering handle creation and page-object insertion contracts
Version 1.24.0
- Added TPdf.RenderPageProgressive — a cancellable variant of RenderPage that drives PDFium’s progressive rendering loop and polls a v1.7.0 IPdfCancellationToken between iterations, so long high-DPI renders can abort mid-page instead of blocking the caller until completion
- Returns a TPdfProgressiveStatus value: prsDone, prsCancelled, or prsFailed. Pass AToken = nil to render to completion without ever pausing (no possibility of prsCancelled)
- Uses the same zero-copy fast path introduced in v1.21.0 — PDFium renders directly into the destination TBitmap’s DIB. The same legacy fallback applies when the DIB can’t be wrapped
- Expanded the Delphi and Lazarus regression suites to 145 cases each, and the C++Builder suite to 121 cases, covering nil-token (completes), pre-cancelled token (prsCancelled), and pixel-equivalence with sync RenderPage on a live token
Version 1.23.0
- Added six new TPdfView methods that expose PDFium’s form-widget text selection and Undo/Redo to applications: GetSelectedFormText returns the currently selected text inside the focused form widget; SelectAllFormText selects every character; FormUndo / FormRedo / FormCanUndo / FormCanRedo drive the focused widget’s edit history. The underlying PDFium APIs were already bound but had no high-level entry point. All six short-circuit safely when the view is inactive or the document has no AcroForm widget focused
- Expanded the Delphi and Lazarus regression suites to 142 cases each, and the C++Builder suite to 119 cases, covering the no-form-no-focus contract for every new method
Version 1.22.0
- Added page composition wrappers to TPdf: ImportPagesByIndex takes a zero-based index array to copy specific pages from a source document; ImportNPagesToOne returns a brand-new TPdf whose pages are N-up composites of this document; MovePages reorders pages in place. The underlying PDFium APIs were already bound but had no Pascal-friendly entry point
- ImportPagesByIndex accepts an empty array to import every source page (equivalent to passing nil at the C ABI level)
- Expanded the Delphi and Lazarus regression suites to 136 cases each, and the C++Builder suite to 115 cases, covering subset import, whole-document import, page reorder, and N-up composite
Version 1.21.0
- Improved rendering performance by switching TPdf.RenderPage / TPdf.RenderTile (and the corresponding TPdfView helpers) to a zero-copy output path. PDFium now writes directly into the destination TBitmap’s DIB buffer instead of into an internal buffer that was then copied row by row, saving one width x height x 4 bytes memory copy per render. The improvement is most noticeable at high DPI (thumbnail panels, print-quality export, batch export)
- The legacy per-scanline path is kept as a safety fallback for the unlikely case where the destination DIB cannot be wrapped (extreme dimensions, unusual stride, OOM). Behavior is byte-identical between the two paths, just slower in the fallback
- Expanded the Delphi and Lazarus regression suites to 132 cases each, and the C++Builder suite to 112 cases, covering caller-bitmap pf32bit upgrade, dimensions round-trip, and a large-bitmap stride sanity test
Version 1.20.0
- Added search-result highlighting to TPdfView: HighlightSearchText(Text, MatchCase, MatchWholeWord) scans the current view page and returns the number of matches found, painting a HighlightColor mask over each match on every redraw. ClearHighlight removes the highlights; switching the view to a different page clears them automatically since matches are page-specific
- HighlightColor defaults to clYellow and is published so applications can theme the highlight to match their UI palette
- Expanded the Delphi and Lazarus regression suites to 129 cases each, and the C++Builder suite to 109 cases, covering default color, color round-trip, “real fixture word matches” against the sample.pdf string, and the “missing word returns zero matches” contract
Version 1.19.0
- Added FitMode property to TPdfView with four values: pfmNone (manual zoom), pfmActualSize (100%), pfmFitPage (whole page fits in the viewport), and pfmFitWidth (page width matches viewport width). The active fit mode is re-applied automatically on Resize and when the current page changes, so long documents with mixed page sizes stay perfectly framed
- Setting Zoom directly cancels the active fit mode (FitMode reverts to pfmNone), matching the standard PDF viewer convention where typing a zoom value drops out of Fit Page / Fit Width
- Default is pfmNone so existing applications keep their explicit-zoom behavior
- Expanded the Delphi and Lazarus regression suites to 124 cases each, and the C++Builder suite to 106 cases, covering default value, mode round-trip, fit-page producing a real zoom on a loaded document, and manual-zoom-cancels-fit-mode
Version 1.18.0
- Added PageColor property to TPdfView, decoupling the rendered PDF page background from the surrounding control’s Color. Default is clWhite, so PDF pages now render as paper-white regardless of the host application’s theme. Dark-mode viewers can now keep the scroll area dark while leaving the actual PDF page white (or any color the application picks)
- Behavior change: applications that used to set TPdfView.Color in order to recolor the PDF page should set PageColor instead. The default experience improves for the common case (white pages on themed control backgrounds) without any code change
- Expanded the Delphi and Lazarus regression suites to 120 cases each, and the C++Builder suite to 103 cases, covering default value and color round-trip
Version 1.17.0
- Added user-input lock-down toggles to TPdfView so applications embedding the viewer in kiosks, preview panes, or read-only contexts can disable navigation gestures without subclassing: AllowUserPageChange controls the new PgUp / PgDn / Ctrl+Home / Ctrl+End keyboard shortcuts; ChangePageOnMouseScrolling controls the new wheel-up / wheel-down page jumps; AllowUserTextSelection is reserved for the future mouse-drag text-selection path. All three default to True so existing applications upgrade with no behavioral change
- Mouse wheel page navigation skips Ctrl+wheel so applications can keep Ctrl+wheel reserved for zoom
- Expanded the Delphi and Lazarus regression suites to 118 cases each, and the C++Builder suite to 101 cases, covering default values and toggle round-trip
Version 1.16.2
- Expanded TPdfView regression coverage for annotation link clicks when the viewer page differs from the associated TPdf page, using a real headless mouse click path across Delphi, Lazarus, and C++Builder
- The Delphi and Lazarus suites now run 114 cases each, and C++Builder now runs 99 cases
Version 1.16.1
- Fixed TPdfView link-click handling so automatic annotation and web-link actions use the page currently displayed by the viewer, even when the associated TPdf component is parked on a different page
- Hardened TPdfThumbnailView against dangling Pdf references when the linked TPdf component is destroyed
- Added thumbnail-reference lifetime regression coverage; the Delphi and Lazarus suites now run 113 cases each, and C++Builder now runs 98 cases
- Synchronized README, test documentation, HTML Help search/index content, and generated C++ package outputs with the v1.7.0 through v1.16.0 integration updates
Version 1.16.0
- Added a new Delphi PrintDialog demo (Demo/Delphi/PrintDialog) that focuses on N-up printing (1 / 2 / 4 / 9 pages per sheet) with odd / even page filtering, grayscale rendering, and optional 1-pixel cell borders. It is a deliberate small companion to the existing PrintPDF demo, which already covers preview, recent files, zoom, and scaling
Version 1.15.0
- Added a new TPdfThumbnailView component (FPdfThumbnail unit) that renders one page thumbnail per row in a scrollable side panel with hover and selection highlighting plus click-to-go navigation. Designed to sit next to a TPdfView so end users can browse a long document by page
- The component is registered on the losLab palette tab alongside TPdf and TPdfView; key properties: Pdf, CurrentPageIndex, ThumbnailWidth, ThumbnailHeight, TextColor, HoverColor, SelectionColor, BorderColor, and the OnPageClick event
- Expanded the Delphi and Lazarus regression suites to 112 cases each, and the C++Builder suite to 97 cases, covering defaults, thumbnail-size round-trip, extreme-value clamping, color round-trip, and event handler assignment
Version 1.14.0
- Added a new Delphi BatchExport demo (Demo/Delphi/BatchExport) showing how to convert many PDF files to JPG in one pass using TPdf.LoadCustomDocument for streaming load, IPdfCancellationToken for cooperative cancellation, and per-file overall + per-page progress bars. The demo uses one TPdf instance per file (PDFium itself is not thread safe) and opens the output folder in Explorer when extraction finishes successfully
Version 1.13.0
- Added an async-rendering UI overlay to TPdfView through three new properties: AsyncRendering, LoadingText, and LoadingColor. When AsyncRendering is True the single-page paint path draws a small “Loading...” indicator over the rendered page so applications using their own worker for long renders share a consistent visual affordance
- Defaults preserve the existing behavior: AsyncRendering is False, so applications that do not opt in see no visual change
- Documentation clarifies that PDFium itself is not thread safe — actually offloading the render to a worker requires the caller to keep one TPdf per worker; the upcoming batch-export demo shows that pattern
- Expanded the Delphi and Lazarus regression suites to 106 cases each, and the C++Builder suite to 93 cases, covering default values and the three-property round-trip
Version 1.12.0
- Added click-driven link handling to TPdfView. The new LinkOptions property controls automatic behavior for the four PDF link action types: goto (page jump), URI (ShellExecute), launch (ShellExecute), and embedded GotoR (reserved). Defaults enable loAutoGoto and loAutoOpenURI; loAutoLaunch and loAutoEmbeddedGoto stay off so a stray click cannot run an arbitrary program
- Added OnAnnotationLinkClick and OnWebLinkClick events that fire before any automatic action and let applications inspect the link, mark it Handled, or redirect it (for example, to a security prompt)
- Link click detection runs only when the gesture is a click rather than a drag, using a fresh MouseDown anchor so panning gestures still flow through the existing scroll path unchanged
- Expanded the Delphi and Lazarus regression suites to 102 cases each, and the C++Builder suite to 91 cases, covering default LinkOptions, set round-trip, and event-handler assignment
Version 1.11.0
- Added visual polish to TPdfView: PageShadowSize, PageShadowColor, and PageBorderColor properties paint an optional drop shadow under the page rectangle and a one-pixel border around it. Defaults preserve the previous flat look (PageShadowSize = 0; border is drawn in the default clBlack but blends into the default white background until callers change the colors)
- Added a SmoothScroll property as an opt-in flag for future incremental scroll animation; the property round-trips today and is wired up so applications can persist the preference, while the rendering side still uses the existing immediate scroll behavior
- Expanded the Delphi and Lazarus regression suites to 98 cases each, and the C++Builder suite to 89 cases, covering default values, property round-trip, and the negative-shadow-size clamp
Version 1.10.0
- Added direct image insertion through new TPdf.AddImage and TPdfView.AddImage overloads that take either a file path or a TBitmap, in addition to the existing TPicture-based AddPicture. AddImage(FileName) recognizes any format registered with the VCL or LCL graphics units (BMP, PNG via the PngImage unit, JPG, etc.) and goes through the same pipeline as AddPicture so behavior is identical
- AddImage(TBitmap) skips the TPicture intermediary, which simplifies callers that already hold a TBitmap from rendering or batch generation work
- Expanded the Delphi and Lazarus regression suites to 92 cases each, and the C++Builder suite to 84 cases, covering bitmap insertion, page-object bounds, nil bitmap rejection, and BMP file loading
Version 1.9.0
- Added high-level transformation matrix support through the new TPdfMatrix class in the FPdfMatrix unit. TPdfMatrix wraps PDFium’s FS_MATRIX with an OO API for Translate, Scale, Rotate, HorizontalFlip, VerticalFlip, CentralFlip, Skew, and Multiply, suitable for composing transforms before handing them to FPDFPageObj_SetMatrix and similar PDFium APIs
- TPdfMatrix.Multiply correctly snapshots the six matrix elements before computing the new row values, fixing a latent issue where the alternative Pascal implementations overwrite earlier elements during the same call and produce incorrect results for any composition beyond pure translation
- Expanded the Delphi and Lazarus regression suites to 88 cases each, and the C++Builder suite to 81 cases, covering identity, reset, translate / scale / flip, post-multiplicative composition order, and the Multiply regression case
Version 1.8.0
- Added on-demand stream loading through the new TPdf.LoadCustomDocument(AStream, AOwnsStream) method and TPdfStreamAdapter helper class, backed by PDFium’s FPDF_LoadCustomDocument. PDFium now reads blocks from the supplied TStream only when needed, so very large or remote PDFs no longer require an up-front in-memory copy
- Added optional stream ownership: passing AOwnsStream = True hands the TStream’s lifetime to TPdf, which frees it when UnloadDocument runs
- Expanded the Delphi and Lazarus regression suites to 79 cases each, and the C++Builder suite to 75 cases, covering streaming load via TFileStream, owned-stream cleanup, and the externally-owned-stream survives-unload contract
Version 1.7.0
- Added cooperative async cancellation primitives in the new FPdfAsync unit, exposing IPdfCancellationToken / IPdfCancellationTokenSource and a reusable PdfNoCancellationToken singleton so long-running rendering and export workflows can support clean cancel-from-UI semantics
- Added a lightweight TPdfFuture<T> helper that runs a worker on a background thread and posts the TPdfFutureResult<T> envelope back to the main thread, distinguishing success, cancellation, and failure cases
- Expanded the Delphi and Lazarus regression suites to 76 cases each, and the C++Builder suite to 73 cases, with shared coverage of cancellation state, idempotent cancel, callback fan-out, and post-cancel registration
Version 1.6.10
- Added high-level TPdf.PrintPageRanges access to the PDF viewer preference print page range, returning one-based page ranges for application code
- Added TPdf.SetFormFieldFlags / SetFormFieldFlagsAt and matching TPdfView helpers so applications can update AcroForm field flags through the public API, including password and multi-select flag coverage
- Hardened PDFium binding ABI coverage for Windows-sized FPDF_DWORD, FPDF_FILEACCESS callbacks, and V8 embedder slot fields
Version 1.6.9
- Added low-level Skia rendering bindings for the newly exported FPDF_RenderPageSkia and FPDF_FFLDrawSkia APIs in the bundled standard and V8 PDFium DLLs
- Expanded the public binding coverage checks so standard and V8 DLL loading now verifies the Skia render entry points alongside the existing V8/XFA capability probes
Version 1.6.8
- Added TPdf.SetTextPositions and TPdfSingleArray to set per-character positions on existing text objects through the newly exported FPDFText_SetPositions API
- Promoted FPDFText_SetPositions to a required binding for the current bundled PDFium DLLs, while confirming the Skia render entry points remain unavailable because the DLLs still do not export them
- Expanded the Delphi, C++Builder, and Lazarus regression suites to 65 cases each with text-position coverage
Version 1.6.7
- Added high-level TPdf access to document JavaScript name-tree actions, returning action names and scripts through JavaScriptAction and JavaScriptActions
- Added TPdf.FileIdentifier to read permanent and changing trailer IDs as binary TBytes without the PDFium terminator byte
- Added TPdf.PageBox, GetPageBox, and SetPageBox for MediaBox, CropBox, BleedBox, TrimBox, and ArtBox on the current page
- Confirmed the current bundled PDFium DLLs leave only the Skia render entry points unavailable at runtime because those exports are not present
- Expanded the Delphi, C++Builder, and Lazarus regression suites to 64 cases each with document JavaScript, trailer ID, and page-box coverage
Version 1.6.6
- Added runtime support for the bundled V8-enabled PDFium DLL. Setting EnableV8Engine before loading now selects pdfium.v8.dll from the DLLs\Win32 or DLLs\Win64 tree and exposes V8/XFA-only bindings when the loaded DLL provides them
- Added V8FeaturesAvailable, XfaBStrHelpersAvailable, GetRecommendedV8Flags, and low-level optional bindings for FPDF_BStr_*, FPDF_GetRecommendedV8Flags, and FPDF_GetArrayBufferAllocatorSharedInstance
- Made FPDFText_SetPositions optional so PDFium Delphi Component keeps loading with PDFium DLLs that do not export that experimental text-position setter
- Expanded the Delphi, C++Builder, and Lazarus regression suites to 61 cases each with standard-DLL and V8-DLL capability coverage