ChangeLog
Release history
Version history of the PDFlibPas library. Entries are listed newest first; each release follows semantic versioning per the project release policy.
v3.43.0 2026-05-20
- SetStructElemSpaceBefore and SetStructElemSpaceAfter set the /SpaceBefore and /SpaceAfter attributes (Layout owner) on the currently open structure element, expressing spacing before and after block-level elements in points. Defined in ISO 32000-1 §14.8.5.4.2 Table 340. Available in the Delphi library, ActiveX (Dispids 73008051/73008052), and DLL interfaces.
- SetStructElemStartIndent and SetStructElemEndIndent set the /StartIndent and /EndIndent attributes (Layout owner), expressing indentation from the writing-mode-aware start and end edges of the content rectangle in points. Defined in ISO 32000-1 §14.8.5.4.2 Table 340. Available in the Delphi library, ActiveX (Dispids 73008053/73008054), and DLL interfaces.
- SetStructElemColor sets the /Color attribute (Layout owner) as an RGB triplet (each component 0.0-1.0), describing the foreground colour of the element for re-flow engines and downstream colour-contrast checkers. Defined in ISO 32000-1 §14.8.5.4.2 Table 340. Available in the Delphi library, ActiveX (Dispid 73008055), and DLL interfaces.
- Fixed a serialization bug in BuildStructElemDictRef: single-token numeric attribute values (such as SpaceBefore, SpaceAfter, StartIndent, EndIndent) were being written as PDF names instead of PDF numbers. The fix applies to both single-owner and multi-owner attribute branches.
v3.42.0 2026-05-20
- CheckCompliancePDFA now correctly validates all six PDF/A modes (1a, 1b, 2a, 2b, 3a, 3b). The PDFAID check (code 00005) accepts any of the six valid XMP markers instead of only '1B'. The version ceiling check (00002) applies 1.4 for PDF/A-1 and 1.7 for PDF/A-2 and PDF/A-3.
- The OCProperties check (code 00003) is now conditional: it applies only to PDF/A-1 documents, where optional content (layers) is forbidden. PDF/A-2 and PDF/A-3 permit layers and are no longer flagged.
- Three new compliance checks added: code 00006 flags encrypted documents (encryption is forbidden in all PDF/A versions); code 00007 flags documents missing an OutputIntents entry in the catalog (required by all PDF/A versions); codes 00011 and 00012 flag documents missing MarkInfo or StructTreeRoot when the conformance level is -a (accessibility).
v3.41.0 2026-05-20
- PDF/A mode now enforces prohibited operations at the API level. When a PDF/A mode is active (any of modes 1-6), calling SetEncryption, AddSeparationColor, SetFillColorCMYK, SetTextColorCMYK, or any other CMYK/Separation/Shader API returns 0 and has no effect, consistent with PDF/A's requirement for a single sRGB output intent.
- Transparency is prohibited in PDF/A-1 (modes 1 and 2): SetTransparency, SetBlendMode, and SetPageTransparencyGroup return 0 and are no-ops when the active mode is 1 or 2. PDF/A-2 and PDF/A-3 (modes 3-6) allow limited transparency and are not restricted.
- JavaScript actions are prohibited in all PDF/A modes (1-6): SetOpenActionJavaScript, PageJavaScriptAction, DocJavaScriptAction, AddGlobalJavaScript, and AddLinkToJavaScript all return 0 and are no-ops when any PDF/A mode is active. ISO 19005-1 §6.6.1 explicitly bans JavaScript from PDF/A documents.
- File attachment APIs (EmbedFile, AddFileAttachment) are blocked in PDF/A-1 and PDF/A-2 modes (1-4). They remain functional in PDF/A-3 (modes 5 and 6), which explicitly permits arbitrary embedded files.
v3.40.0 2026-05-20
- SetPDFAMode now supports PDF/A-2 and PDF/A-3 conformance levels. Pass NewMode=3 for PDF/A-2b, 4 for PDF/A-2a, 5 for PDF/A-3b, or 6 for PDF/A-3a. PDF/A-2 targets PDF 1.7 and permits layers, interactive forms, JPEG2000 images, and limited transparency. PDF/A-3 extends PDF/A-2 by allowing arbitrary embedded files (any MIME type). All -a variants automatically write /MarkInfo and the tagged-PDF structure markers required by the accessibility conformance level.
- Fixed: SetPDFAMode(1) (PDF/A-1a) was previously a no-op due to an internal routing bug introduced in v3.20.0. It now correctly writes /MarkInfo and /OutputIntents and sets XMP pdfaid:part=1/conformance=A.
- GetInformation(201) returns '1' through '6' matching the active PDF/A mode, consistent with the new mode numbering.
v3.39.0 2026-05-20
- SetStructElemWritingMode sets the /WritingMode attribute (Layout owner) on the currently open structure element. Valid values are LrTb (left-to-right, the default for Latin scripts), RlTb (right-to-left, for Arabic and Hebrew), and TbRl (top-to-bottom right-to-left, for traditional CJK vertical text). Defined in ISO 32000-1 §14.8.5.4.2 Table 340. Available in the Delphi library, ActiveX (Dispid 73008049), and DLL interfaces.
- SetStructElemListNumbering sets the /ListNumbering attribute (List owner) on the currently open structure element. Supported values include None, Disc, Circle, Square (unordered markers) and Decimal, UpperRoman, LowerRoman, UpperAlpha, LowerAlpha (ordered numbering). The attribute is set on the L (list) element and enables assistive technology to announce the list type correctly. Defined in ISO 32000-1 §14.8.5.3.2 Table 336. Available in the Delphi library, ActiveX (Dispid 73008050), and DLL interfaces.
v3.38.0 2026-05-20
- SetStructElemColSpan sets the /ColSpan attribute (Table owner) on the currently open structure element, indicating how many columns the cell spans. Defined in ISO 32000-1 §14.8.5.7.2 Table 337. Available in the Delphi library, ActiveX (Dispid 73008047), and DLL interfaces.
- SetStructElemRowSpan sets the /RowSpan attribute (Table owner) on the currently open structure element, indicating how many rows the cell spans. Defined in ISO 32000-1 §14.8.5.7.2 Table 337. Available in the Delphi library, ActiveX (Dispid 73008048), and DLL interfaces.
- Both functions are convenience wrappers equivalent to calling AddTagAttribute with Owner='Table' and the respective attribute name. They complement SetStructElemScope for fully described table cells in complex or spanning-header tables.
v3.37.2 2026-05-20
- GetPDFUADiagnostics now reports FORM-NO-TOOLTIP:N when N interactive form fields (Widget annotations) are missing a TU (tooltip / accessible name) entry. ISO 14289-1 §7.18.4 requires all interactive form fields to carry a TU entry so assistive technology can announce the field's purpose to the user when the field receives focus. /TU is the accessible name that screen readers speak aloud; it is distinct from /T, which is the partial field name used for programmatic access and form submission.
v3.37.1 2026-05-20
- GetPDFUADiagnostics now reports LIST-STRUCT:N when N LI or LBody structure elements appear outside their required parent element. ISO 32000-1 §14.8.4.4 requires LI to be a direct child of L (list) and LBody to be a direct child of LI (list item). Malformed list nesting prevents assistive technology from correctly traversing and announcing list content, and can cause document structure validation failures in PDF/UA-1 validators.
v3.37.0 2026-05-20
- BeginTagEx2 is a new API that opens a structure element and sets all main element properties in a single call. In addition to the TagType, AltText, ActualText, and Lang parameters of BeginTagEx, BeginTagEx2 accepts Title (/T, for the Tags navigation panel), ElemID (/ID, unique element identifier), and Expansion (/E, full text of an abbreviation or acronym). Passing an empty string for any of these three additional parameters is equivalent to omitting the corresponding setter. BeginTagEx2 reduces boilerplate for well-described elements — rather than calling BeginTagEx followed by SetStructElemTitle, SetStructElemID, and SetStructElemExpansion separately, all seven properties can be set in one call. The function is available in the Delphi library, ActiveX (Dispid 73008046), and DLL interfaces.
v3.36.1 2026-05-20
- GetPDFUADiagnostics now reports TABLE-TH-NO-SCOPE:N when N TH (table header cell) structure elements are missing a Scope attribute. ISO 32000-1 §14.8.4.3.4 Table 337 defines Scope (Row, Column, or Both) as the attribute that describes which data cells a header cell applies to. Without it, screen readers and other assistive technology cannot reliably associate header cells with data cells in complex or multi-header tables, which is required by ISO 14289-1 §7.5. Call SetStructElemAttr('Table','Scope', 'Column') (or 'Row' / 'Both') immediately after tagging each TH element.
v3.36.0 2026-05-20
- SetStructElemExpansion is a new API that sets the /E (expansion text) entry on the currently open structure element (ISO 32000-1 §14.9.5). The expansion text is the fully spelled-out form of an abbreviation or acronym contained in the element — e.g. "World Wide Web" for a Span whose text is "WWW". Screen readers speak the expansion instead of attempting to pronounce the abbreviated characters, which is critical for accessibility of technical and scientific content. PDF/UA-1 (ISO 14289-1 §7.2) requires that natural language be unambiguously determinable; /E is the standard mechanism for abbreviations and acronyms. The function is available in the Delphi library, ActiveX, and DLL interfaces.
v3.35.1 2026-05-20
- GetPDFUADiagnostics now reports DOCINFO-TITLE-MISSING when the document information dictionary /Title entry is absent or empty. PDF/UA-1 (ISO 14289-1) requires a document title so screen readers can announce it when the document is opened. The existing DISPLAYDOCTITLE-FALSE check confirms that the title is shown in the viewer title bar; DOCINFO-TITLE-MISSING is complementary — it confirms the title value itself is set. Call SetDocumentInfo('Title', ...) to supply the value.
v3.35.0 2026-05-20
- SetStructElemTitle is a new API that sets the /T (title) entry on the currently open structure element (ISO 32000-1 §14.7.2 Table 324). The title is a human-readable label that identifies the specific element instance — for example "Chapter 1", "Summary Table", or "Figure 3: Quarterly Sales" — and is shown in the Tags navigation panel of PDF viewers and used by accessibility remediation tools. /T is distinct from /Alt (alternative text for rendering-impaired users) and /ActualText (glyph-level text correction); it is most useful on non-text container elements such as Table, Figure, Form, Sect, and Div. Pass an empty string to clear a previously set value. The function is available in the Delphi library, ActiveX, and DLL interfaces.
v3.34.0 2026-05-20
- SetStructElemAltText is a new API that sets the /Alt entry on the currently open structure element (ISO 32000-1 §14.9.3). It is equivalent to passing AltText to BeginTag but allows the alternative text description to be set or updated after the element has been opened — useful when the description is computed separately from the element type. PDF/UA-1 (ISO 14289-1 §7.5) requires Alt text on Figure and Formula elements; GetPDFUADiagnostics already reports FIGURE-NO-ALT:N for missing values. The function is available in the Delphi library, ActiveX, and DLL interfaces.
v3.33.1 2026-05-20
- GetPDFUADiagnostics now includes a ROLEMAP-UNMAPPED:N check that detects custom structure element type names used in the document that have no entry in the /RoleMap dictionary. ISO 14289-1 §7.1 and ISO 32000-1 §14.7.3 require every non-standard structure type to be mapped to a standard PDF type (such as P, Span, or Figure) so assistive technology can determine how to handle the element. When N unmapped types are found the issue description includes the list of type names so callers know which AddRoleMap entries are needed. All 49 standard structure types defined in ISO 32000-1 Table 333 (PDF 1.7) are recognised and excluded from the report.
v3.33.0 2026-05-20
- SetStructElemLang is a new API that sets the /Lang entry on the currently open structure element (ISO 32000-1 §14.9.2). The language tag overrides the document-level language declared by SetDocumentLanguage or SetPDFUAMode for the element and all its descendants, enabling mixed-language documents to mark each span with its correct BCP 47 language tag (e.g. 'en-US', 'fr', 'zh-Hant-TW'). Screen readers use the element-level /Lang to select the appropriate text-to-speech engine or voice when reading the document aloud. The function is available in the Delphi library, ActiveX, and DLL interfaces.
v3.32.0 2026-05-20
- SetStructElemActualText is a new API that sets the /ActualText entry on the currently open structure element (ISO 32000-1 §14.9.4). Use it to specify the exact Unicode text that a glyph sequence represents when content-stream extraction would yield incorrect results — the most common cases are OpenType ligature glyphs (U+FB00 ff, U+FB01 fi, U+FB02 fl) and abbreviations with non-obvious expansions. ActualText supplements, rather than replaces, the rendered content; it overrides what assistive technology and text extractors read out for that element without suppressing visual rendering. The function is available in the Delphi library, ActiveX, and DLL interfaces.
v3.31.1 2026-05-20
- GetPDFUADiagnostics now checks Formula structure elements in addition to Figure elements when reporting missing Alt text (FIGURE-NO-ALT:N). ISO 32000-1 §14.9.3 requires alternative descriptions for both graphical figures and mathematical formulas; previously only Figure elements were scanned.
- GetPDFUADiagnostics now reports PDF-VERSION-LOW when the document's PDF version is below 1.7. PDF/UA-1 (ISO 14289-1) is defined against PDF 1.7 (ISO 32000-1:2008); documents at PDF 1.5 or 1.6 would not satisfy the base specification requirements. Call SetPDFUAMode to automatically raise the version to 1.7.
v3.31.0 2026-05-19
- Structure element IDs and table header association are now supported. SetStructElemID assigns a unique string identifier (/ID) to the currently open structure element; IDs are collected into an /IDTree name tree on the structure tree root when the document is saved, enabling accessibility tools and cross-references to locate elements by ID (ISO 32000-1 §14.7.4). SetStructElemHeaders associates the current table cell (TD or TH) with one or more header cells via a comma-separated list of previously assigned IDs, writing the /Headers array in the Table attribute owner dictionary (ISO 32000-1 §14.8.5.7.2). Together these two functions support complex table markup for PDF/UA-1 (ISO 14289-1 §7.10) and WCAG 2.x SC 1.3.1. Both functions are available in the Delphi library, ActiveX, and DLL interfaces. AddTagAttribute also now correctly handles the /Headers attribute with comma-delimited values written as PDF text string arrays.
v3.30.1 2026-05-19
- GetPDFUADiagnostics now includes a HEADING-LEVEL-SKIP:N check that detects heading level jumps in document order (e.g. an H1 immediately followed by an H3 without an H2 in between). The check performs a pre-order traversal of the entire structure element tree and counts each occurrence where the next heading level exceeds the previous by more than one. Generic H elements are treated as H1. Going back to a higher-level heading (H3 → H1) is not counted as a skip. WCAG 2.x Success Criterion 1.3.1 and ISO 14289-1 §7.1 require headings to nest without gaps.
v3.30.0 2026-05-19
- Structure element attributes are now supported for tagged PDF and PDF/UA documents. Three new API functions allow attributes to be attached to the structure element currently being built on the tag stack: AddTagAttribute (general-purpose, any owner/name/value), SetStructElemScope (convenience wrapper that sets the /Scope attribute under the Table owner, for TH header cells — ISO 32000-1 §14.8.5.7.2), and SetStructElemBBox (convenience wrapper that sets the /BBox attribute under the Layout owner, for figures and other visually-positioned elements — ISO 32000-1 §14.8.5.4). When the document is saved, attributes are written as /A attribute dictionaries in each structure element; multiple attributes from the same owner are grouped into one dict, and attributes from different owners are written as an array of dicts. All three functions are available in the Delphi library, ActiveX, and DLL interfaces.
v3.29.1 2026-05-19
- GetPDFUADiagnostics now includes two additional checks: whether any Figure structure elements in the document are missing an Alt text value (reported as FIGURE-NO-ALT:N, per ISO 14289-1 §7.5 and ISO 32000-1 §14.9.3), and whether any structure elements are still open because EndTag was not called (reported as STRUCT-UNCLOSED:N). The figure check performs a full recursive walk of the structure element tree, covering elements at all nesting depths.
v3.29.0 2026-05-19
- GetPDFUADiagnostics is a new diagnostic API that checks a document for potential PDF/UA-1 (ISO 14289-1) compliance issues and returns a newline-separated list of findings. Six checks are performed: whether MarkInfo/Marked is set (tagged PDF), whether the document catalog has a /Lang entry, whether ViewerPreferences/DisplayDocTitle is true, whether the XMP metadata contains a pdfuaid:part identifier, the count of non-exempt annotations lacking a Contents entry, and the count of embedded files lacking an AFRelationship entry. Each finding is identified by a short code (e.g. LANG-MISSING, ANNOT-NO-CONTENTS:3) followed by a human-readable description. Returns an empty string when no issues are found. Available in the Delphi library, ActiveX, and DLL interfaces.
v3.28.5 2026-05-19
- PDF/UA-1 annotation accessibility improvement: when a FileAttachment annotation has no Contents entry and no /T field, the filename from the annotation's embedded file specification (/FS /UF or /F) is now used as the fallback accessible description. This completes the annotation Contents fallback chain: /T → Link URI → Stamp name → FileAttachment filename. Screen readers receive the name of the attached file rather than silence, satisfying ISO 14289-1 §7.18.1 for the most common annotation types.
v3.28.4 2026-05-19
- PDF/UA-1 annotation accessibility improvement: when a Stamp annotation has no Contents entry (or an empty one) and no /T field, the stamp type name from the annotation's /Name entry is now used as the fallback accessible description (e.g. "Approved", "Draft", "Confidential", "Final"). This extends the annotation Contents fallback chain introduced in v3.28.3 to cover stamp annotations, which are common in workflows involving reviewed or approved documents and frequently lack an explicit Contents value.
v3.28.3 2026-05-19
- PDF/UA-1 annotation accessibility improvement: when a Link annotation has no Contents entry (or an empty one) and no /T field, the URI from the annotation's URI action is now used as the fallback accessible description. This applies only during SetPDFUAMode processing and only to Link annotations that carry a /URI action. Screen readers receive the URL as a last-resort label, satisfying ISO 14289-1 §7.18.1 in the common case where authors create hyperlinks without providing a human-readable description.
v3.28.2 2026-05-19
- SetEmbeddedFileAFRelationship is a new API for explicitly setting the AFRelationship value on an embedded file's file specification dictionary. Required by ISO 14289-1 (PDF/UA-1) §7.11, this allows callers to specify the semantic relationship of an embedded file to the document content by choosing from the five valid values: Source, Data, Alternative, Supplement, or Unspecified. When SetPDFUAMode is active, any embedded file without an AFRelationship key is automatically assigned Unspecified; use this function to override that default before saving. Available in the Delphi library, ActiveX, and DLL interfaces.
v3.28.1 2026-05-19
- When SetPDFUAMode is called on a document whose XMP metadata carries the generic library-default title rather than a document-specific one, the title is now automatically replaced with the value from the document's /Info Title entry (if one is present). This ensures that the pdfuaid:part-1 XMP packet reflects the actual document title rather than a placeholder, satisfying PDF/UA-1 verifier expectations.
- The XMP parser (LoadFromString) now reads the dc:title value from existing XMP metadata when a document is loaded, so round-tripping a PDF that already has dc:title correctly preserves that title instead of reverting to the default placeholder.
v3.28.0 2026-05-19
- BeginArtifactEx(ArtifactType, ArtifactSubtype) is a new tagged-PDF API that extends BeginArtifact to express both the artifact /Type and the Pagination /Subtype in a single call. When both parameters are non-empty the operator written is /Artifact << /Type /T /Subtype /S >> BMC, enabling fully specified Pagination artifacts such as headers and footers per ISO 32000-1 §14.8.2.2.1. If only one parameter is non-empty the corresponding single-key form is used. DLL entry points DLBeginArtifactEx and DLBeginArtifactExA are also exported.
v3.27.2 2026-05-19
- BeginArtifact now correctly distinguishes artifact types from pagination subtypes. When the argument is Pagination, Layout, or Page (artifact types per ISO 32000-1 §14.8.2.2.1 Table 330), the marked-content operator writes /Type rather than /Subtype. Other values such as Header, Footer, and Watermark continue to be written as /Subtype. This corrects the previously incorrect output that would write /Subtype /Pagination when the caller intended to mark a pagination artifact.
v3.27.1 2026-05-19
- When PDF/UA mode is active and the document contains embedded files, each file specification dictionary that lacks an AFRelationship entry now receives one automatically at save time. The value written is /Unspecified, satisfying the ISO 14289-1 §7.11 requirement that every embedded file carry an AFRelationship key. This applies both to files added via EmbedFile and to embedded files already present in a loaded document.
v3.27.0 2026-05-19
- AddRoleMap(CustomType, StandardType) is a new tagged-PDF API that registers a mapping from a custom (non-standard) structure element type name to a standard PDF structure type. When saved, the mappings are written to the RoleMap dictionary in the structure tree root, satisfying the ISO 14289-1 §7.1 requirement for documents that use application-specific tag names. Multiple mappings may be registered; duplicate keys are overwritten by the last call. DLL entry points DLAddRoleMap and DLAddRoleMapA are also exported.
v3.26.0 2026-05-19
- BeginTagEx(TagType, AltText, ActualText, Lang) is a new tagged-PDF API that extends BeginTag with an explicit natural-language attribute. When Lang is non-empty it is written to the structure element's /Lang attribute, enabling per-element language annotation required by ISO 14289-1 §7.2 for multilingual documents. Pass an empty Lang string to behave identically to BeginTag. DLL entry points DLBeginTagEx and DLBeginTagExA are also exported.
v3.25.1 2026-05-19
- Non-subsetted TrueType fonts loaded with the default Windows code page (WinAnsiEncoding) now receive a ToUnicode CMap stream, enabling reliable Unicode text extraction and copy/paste for these fonts. Previously a ToUnicode stream was only written when an explicit code-page override or Differences array was present; the common default-encoding path was missing it.
- The same fix applies to TrueType fonts loaded with an explicit non-default code page but no Differences array, and to fonts loaded via the packaged-font format.
v3.25.0 2026-05-19
- When PDF/UA mode is active, non-exempt annotations (all types except Widget, PrinterMark, and TrapNet) that lack a non-empty Contents entry now receive one automatically at save time. The annotation's /T (title / author) value is used as the fallback, satisfying ISO 14289-1 §7.18.1 for annotations that carry a title but no explicit accessible description.
v3.24.0 2026-05-19
- When PDF/UA mode is active, interactive form fields that lack a TU (tooltip / alternate description) entry now receive one automatically at save time. The field's partial name (/T entry) is used as the fallback value, ensuring screen readers can identify every field. Push buttons are correctly excluded from this requirement per ISO 14289-1 §7.18.4.
v3.23.1 2026-05-19
- GetInformation(200) returns '1' when PDF/UA-1 mode is active on the selected document, enabling callers to query conformance mode status at runtime.
- GetInformation(201) returns '1' for PDF/A-1a, '2' for PDF/A-1b, or an empty string when PDF/A mode is off.
- GetInformation(311) and GetInformation(312) now correctly return the version requirement string and feature name from the most recent version-lock conflict (previously advertised in the v3.20.3 entry but not yet implemented).
- GetInformation(313) returns the PDF version string at which the save target is currently locked, or an empty string for freely-versioning documents.
v3.23.0 2026-05-19
- SetMarkInfo(Marked) is now a public API, allowing the MarkInfo.Marked flag to be set independently of the full PDF/UA-1 setup performed by SetPDFUAMode. When Marked is 1, MarkInfo.Suspects is also set to false as required by ISO 14289-1 §7.18.6.
- When PDF/UA mode is active, all pages automatically receive a /Tabs /S entry at save time, satisfying the structure-based tab-order requirement of ISO 14289-1 §7.18.4.
- HTML reference documentation added for SetPDFUAMode, SetDocumentLanguage, SetMarkInfo, BeginTag, EndTag, BeginArtifact, and EndArtifact, with full syntax tables and usage examples.
v3.22.0 2026-05-19
- BeginTag(TagType, AltText, ActualText) opens a tagged-PDF structure element in the current content stream, writing a BDC operator with an auto-assigned MCID and registering the element in the document structure tree. TagType is any PDF standard structure type (P, H1, Figure, Table, etc.). AltText and ActualText are optional accessibility strings encoded as PDF text strings (UTF-16BE).
- EndTag closes the most recently opened structure element, writing the matching EMC operator to the content stream.
- BeginArtifact(SubType) marks a content region as a PDF artifact (pagination artefact, background, etc.), writing a BMC operator. SubType is optional; when provided it is written as /Artifact << /Subtype /SubType >>.
- EndArtifact closes the artifact region with an EMC operator.
- At save time, when any tagged structure elements have been registered, the library automatically builds the complete StructTreeRoot, assigns StructParents keys to affected pages, and writes the ParentTree number tree, satisfying ISO 32000-1 §14.7 requirements for tagged PDF.
- Standard Type 1 fonts (Helvetica, Times, Courier family, Symbol) and embedded Type 1 fonts with WinAnsi encoding now receive a ToUnicode CMap stream, enabling reliable Unicode text extraction and copy/paste for these font types.
v3.21.0 2026-05-19
- SetPDFUAMode(Language) activates PDF/UA-1 (ISO 14289-1) conformance mode: auto-bumps the document to PDF 1.7, writes MarkInfo.Marked and MarkInfo.Suspects, enables DisplayDocTitle in ViewerPreferences, sets Catalog.Lang when Language is non-empty, and writes the pdfuaid:part = 1 XMP namespace entry required by ISO 14289-1 Section 6.7.11.
- SetDocumentLanguage(Language) writes the Catalog /Lang entry directly, allowing the document language to be declared independently of PDF/UA mode.
- MarkInfo.Suspects is now set to false whenever MarkInfo.Marked is set to true, satisfying the ISO 14289-1 tagged-PDF structure requirement (Section 7.18.6).
- Encrypt now forces the CanCopyAccess (content copying for accessibility) permission flag when the document is in PDF/UA mode, as required by ISO 14289-1 Section 7.17.
- Choice (dropdown) form fields no longer carry a meaningless hardcoded tooltip value; TU is left unset so the caller can assign a meaningful label via the form field property API.
v3.20.3 2026-05-19
- Encrypt and AddSWFAnnotationFromFile now return 0 immediately with LastErrorCode 602 when the save version is locked below the minimum required by the selected encryption strength or annotation type, instead of silently proceeding and failing only at save time.
- GetInformation(311) and GetInformation(312) now reflect the conflicting version requirement at write time when a locked version blocks extension-level features such as AES-256 or RichMedia annotations.
v3.20.2 2026-05-19
- AddU3DAnnotationFromFile now auto-bumps the document version to PDF 1.6 when a 3D annotation is added to a lower-version document, consistent with the version auto-bump behaviour of all other PDF 1.6+ API entry points.
v3.20.1 2026-05-17
- PDF 1.2 save targets are now enforced as strict PDF 1.2 contracts. Saving PDF 1.3+ objects such as page TrimBox data under a PDF 1.2 target fails before output is written instead of emitting a mixed-version file.
- PDF 1.7 Adobe extension-level compliance is now part of save preflight. AESV3, AES-256, RichMedia, Projection, geospatial dictionaries, and ETSI signature subfilters are checked against the required ExtensionLevel.
- AES-256 encryption, RichMedia annotations, geospatial dictionaries, and ETSI signature subfilters now declare the matching Adobe Extensions entry when PDFlib auto-bumps a document to PDF 1.7 extension content.
- Append saves now use the same version-compliance gate as full saves.
- Bundled optional PDFium runtime DLLs were refreshed for Win32 and Win64. GDI+ remains the default renderer; PDFium stays opt-in via SetPDFiumFileName and SelectRenderer(3).
- Validation: Delphi Win32 and Win64 DUnitX suites passed 207/207 each, and C++Builder Win64x GoogleTest passed 61 tests with 2 existing sample-dependent tests skipped.
v3.20.0 2026-05-17
- Eight more PDFlib writer entry points now route through Phase 3 EnsureMinVersion so the document version auto-bumps to the minimum required by the feature being emitted: SetDocumentMetadata (PDF 1.4 - /Metadata XMP stream) SetPDFAMode(1 or 2) (PDF 1.4 - /MarkInfo + /OutputIntents) PageJavaScriptAction (PDF 1.5 - Page /AA + JavaScript) DocJavaScriptAction (PDF 1.4 - Catalog /AA + JavaScript) SetTabOrderMode (PDF 1.5 - Page /Tabs) NewOptionalContentGroup (PDF 1.5 - /Type /OCG) SetNeedAppearances (PDF 1.5 - AcroForm /NeedAppearances) NewFormField(ftSignature) (PDF 1.5 - AcroForm /SigFlags AppendOnly)
- Combined with the v3.15.0 set (SetTransparency, SetPageUserUnit, Encrypt, SetPageLayout) and the v3.17.0 set (eight JavaScript / embedded-file / XFA / SWF entries), PDFlib now auto-bumps FVersion across twenty-one writer entry points.
- NewOptionalContentGroup previously bumped FVersion directly; it now goes through EnsureMinVersion so LockSaveVersion is honoured and the bump is recorded in AutoBumpedFeatures.
v3.19.0 2026-05-17
- Save-time and load-time PDF version compliance now also recognises four previously deferred features: Btn /Ff bit 15 NoToggleToOff (radio-button-only) -> PDF 1.4 DeviceN /Subtype /NChannel (color-space refinement) -> PDF 1.6 FontFile3 /Subtype /OpenType (font program type) -> PDF 1.6 Sig /SubFilter ETSI.CAdES.detached or ETSI.RFC3161 -> PDF 1.7
- The NChannel rule matches the DeviceN color-space array form [/DeviceN names alternateSpace tintTransform attributes] when the attributes dictionary at index 4 carries /Subtype /NChannel.
- The FontFile3 OpenType rule fires only when the stream is reached through a parent key named 'FontFile3', so unrelated streams that happen to carry /Subtype /OpenType are not flagged.
- The PDFFeatureRules table now carries 103 rules (99 + 4 new).
v3.18.6 2026-05-17
- Save-time and load-time PDF version compliance now recognises /AA (additional actions) with container-type awareness: Catalog /AA (document-level triggers) -> PDF 1.4 Annot /AA (annotation triggers) -> PDF 1.4 Page /AA (page triggers) -> PDF 1.5
- Form-field /AA (PDF 1.2) remains covered by the existing PDF 1.3 save contract; no rule needed.
- The PDFFeatureRules table now carries 99 rules (96 + 3 new).
v3.18.5 2026-05-17
- Save-time and load-time PDF version compliance now correctly classify Page /Tabs as a PDF 1.5 feature; it was previously misclassified as PDF 1.4. PDF 1.4 spec changes document (Adobe TN #5409) does not list /Tabs, and PDF 1.5 Table 8.10 introduces "Tabs (Optional; PDF 1.5)".
- New rule: AcroForm /NeedAppearances is recognised as a PDF 1.5 feature per PDF 1.5 Table 218.
- The PDFFeatureRules table now carries 96 rules (95 + 1 new).
v3.18.4 2026-05-13
- PDFlibZLib now always uses the bundled static zlib-ng object backend on normal library builds, removing the remaining System.ZLib fallback path.
- The zlib-ng regression coverage now includes boundary-sized payloads, PNG-like scanline data, stored multi-block streams, and known zlib streams across Delphi and C++Builder test runners.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 194/194 each, and C++Builder Win64x GoogleTest passed 58 tests with 2 existing sample-dependent tests skipped.
v3.18.3 2026-05-12
- Delphi and C++Builder demos that generate PDF or text output now open the generated document automatically after a successful save.
- Installer packaging now keeps build artifacts out of demo folders and makes C++Builder samples plus DLL and ActiveX/OCX modules opt-in components; their matching files are installed only when the component is selected.
v3.18.2 2026-05-12
- The Delphi and C++Builder EditFormField demos now clear /NeedAppearances before updating field values, so every edited text field gets a refreshed normal appearance stream in the saved PDF.
- This keeps the saved /AP stream in sync with the stored /V value and avoids viewer-dependent differences where focusing the field reveals text that was missing from the static field appearance.
v3.18.1 2026-05-10
- Save-time and load-time PDF version compliance now also recognises bit-level form-field /Ff flags and the AcroForm /SigFlags AppendOnly bit: /Ff bit 21 (FileSelect, mask 1048576) -> PDF 1.4 /Ff bit 22 (MultiSelect, mask 2097152) -> PDF 1.4 /Ff bit 23 (DoNotSpellCheck, mask 4194304) -> PDF 1.4 /Ff bit 24 (DoNotScroll, mask 8388608) -> PDF 1.4 /Ff bit 25 (Comb, mask 16777216) -> PDF 1.5 /Ff bit 26 (RichText / RadiosInUnison, 33554432) -> PDF 1.5 /Ff bit 27 (CommitOnSelChange, mask 67108864) -> PDF 1.5 /SigFlags bit 2 (AppendOnly, mask 2) -> PDF 1.5
- /Parent inheritance is not followed: only dictionaries that explicitly carry /Ff or /SigFlags trigger the rules.
- The PDFFeatureRules table now carries 95 rules (87 + 8 new bit-level).
- Validation: Delphi Win32 and Win64 DUnitX suites passed 191/191 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.18.0 2026-05-10
- Save-time and load-time PDF version compliance now also recognises nine more sub-key and bit-level features: bit-level annotation flags (/F mask): Locked (128) -> PDF 1.4 ToggleNoView (256) -> PDF 1.5 LockedContents (512) -> PDF 1.7 distinctive catalog and page sub-keys: /BoxColorInfo (page) -> PDF 1.4 /Permissions, /Legal, /PresSteps -> PDF 1.5 /VP (page geospatial viewport) -> PDF 1.6 /Collection (catalog portable collection) -> PDF 1.7
- The PDFFeatureRules table now carries 87 rules (78 chapter-level + 9 sub-key / bit-level).
- Validation: Delphi Win32 and Win64 DUnitX suites passed 189/189 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.17.0 2026-05-10
- Eight more PDFlib writer entry points now route through Phase 3 EnsureMinVersion so the document version auto-bumps to the minimum required by the feature being emitted: AddLinkToJavaScript, SetOpenActionJavaScript, AddGlobalJavaScript, FormFieldJavaScriptAction (PDF 1.3 - JavaScript actions) AddEmbeddedFile, AddFileAttachment (PDF 1.3 - file attachments) SetXFAFromString (PDF 1.5 - XFA forms) AddSWFAnnotationFromFile (PDF 1.7 - RichMedia annotation)
- Combined with the v3.15.0 set (SetTransparency, SetPageUserUnit, Encrypt, SetPageLayout) PDFlib now covers thirteen high-version writer entry points end-to-end.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 187/187 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.16.3 2026-05-10
- New PDFlib API: LockSaveVersion(Version) pins the document at Version and stops Phase 3 writer-side EnsureMinVersion from auto-bumping above it. UnlockSaveVersion clears the lock.
- The save-time gate is unchanged: writer-emitted features above the locked version still produce LastErrorCode 602 at save time, instead of silently bumping the header.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 184/184 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.16.2 2026-05-10
- Loaded PDFs now expose a contributor-only view of the load-time feature detection through GetInformation(103) ("ContributorFeatures"). The list contains only features whose minimum required version is strictly greater than HeaderVersion (key 100), so it directly answers "why is the effective version higher than the file header?".
- GetInformation(101) ("DetectedFeatures") is unchanged and still lists every matched feature regardless of contribution.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 181/181 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.16.1 2026-05-10
- Expanded loader-side detection test coverage with six additional synthetic fixtures: in-page transparency ExtGState (no version bump), Catalog /MarkInfo (PDF 1.3 -> PDF 1.4), /OCProperties + OCG content (PDF 1.4 -> PDF 1.5), /Type /3DStream (PDF 1.5 -> PDF 1.6), a multi-feature combination fixture, and a snapshot-stability check.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 179/179 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.16.0 2026-05-10
- Loaded PDF documents now go through a content-driven version detection pass: every indirect object is walked through the feature-to-minimum- version table used by the save-time gate, and FVersion is bumped above the literal %PDF-X.Y header value when content actually requires a higher version. For example a /UserUnit page entry bumps the effective version to PDF 1.6 even when the file header says PDF 1.4.
- New GetInformation keys: 100 returns HeaderVersion (literal %PDF-X.Y), 101 returns DetectedFeatures (CRLF-delimited features matched on load), 102 returns AutoBumpedFeatures (CRLF-delimited features that triggered writer-side EnsureMinVersion).
- The save-time gate is unaffected: documents whose effective version was bumped on load, then explicitly downgraded with SetInformation(0, ...), still produce LastErrorCode 602 at save time.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 173/173 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.15.0 2026-05-10
- Writer entry points that produce features requiring a particular minimum PDF version now auto-bump the document's PDF version automatically. Calling SetTransparency on a document marked as PDF 1.3 now promotes the header to PDF 1.4 instead of failing the save with LastErrorCode 602.
- Wired the same auto-bump into SetPageUserUnit (>=1.6), Encrypt with Strength 1/2/3/4 (>=1.4/1.6/1.7/1.7 respectively), and the two-page variants of SetPageLayout (>=1.5).
- Behaviour change versus 3.14.x: applications that previously relied on the v3.12.6 "save target rejects writer-emitted features" gate now succeed at the bumped version. Loaded PDFs that already contain higher- version features still go through the existing save-time gate, so loading a tagged PDF and selecting PDF 1.3 still fails with LastErrorCode 602.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 170/170 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.14.3 2026-05-10
- Save-time PDF version compliance now also recognises the remaining PDF 1.6 3D dictionary types (/Type /3DStream /3DRef /3DBackground /3DRenderMode /3DLightingScheme /3DCrossSection /3DNode) and the PDF 1.7 Redact, RichMedia, and Projection annotation subtypes plus the /Type /Requirement and /ReqHandler companion dictionaries.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 168/168 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.14.2 2026-05-10
- Save-time PDF version compliance now also recognises PDF 1.5 features: /XFA forms, /AlternatePresentations, /Renditions name tree, the /Type /Rendition /MediaCriteria /MediaPermissions /MediaPlayers multimedia dictionaries, and the Screen annotation subtype.
- Saving as PDF 1.4 now rejects documents that carry these features with LastErrorCode 602.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 166/166 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.14.1 2026-05-10
- Save-time PDF version compliance now also recognises PDF 1.4 features: tagged-PDF /StructTreeRoot /MarkInfo and StructElem dictionaries, the document /Lang and page /Tabs entries, /OutputIntents and /OutputIntent dictionaries, the /UR3 usage-rights signature, and the PDF 1.4 annotation subtypes Polygon, PolyLine, Caret, Ink, Popup, and Watermark.
- Saving as PDF 1.3 now rejects documents that carry these features with LastErrorCode 602.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 165/165 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.14.0 2026-05-10
- Save-time PDF version compliance now also recognizes PDF 1.3 features such as smooth shading, function objects, ICCBased and DeviceN color spaces, /TrimBox /BleedBox /ArtBox page entries, /ToUnicode CMaps, file attachment and /Sound and /Movie annotations, /Type /Filespec and /Type /EmbeddedFile dicts, the /Group /EF /Alternates /Mask keys, and JavaScript actions.
- PDF 1.2 callers now save under the PDF 1.3 contract: the literal %PDF-1.2 header is preserved, but the gate accepts PDF 1.3 features. PDF 1.4 and later features are still rejected with LastErrorCode 602.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 162/162 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.13.0 2026-05-10
- Refactored the PDF version-compliance gate that rejects later-version features at save time into a dedicated module so the rule set can grow without churning the document core.
- No user-visible behavior change versus v3.12.7: the same out-of-version features are still rejected with LastErrorCode 602.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 155/155 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.12.7 2026-05-09
- Expanded automated test coverage for the PdfToImage direct-access rendering workflow in both Delphi DUnitX and C++Builder GoogleTest suites.
- The Delphi VCL GUI test runner now registers the Syntax and XRef fixtures, matching the console runner coverage.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 147/147 each, and C++Builder Win64x GoogleTest passed 57/57.
v3.12.6 2026-05-09
- Saving as PDF 1.3, 1.4, 1.5, 1.6, or 1.7 now enforces the selected version as the full-save output contract.
- Full saves remove catalog /Version overrides, remove unsupported catalog extension and metadata entries for lower targets, and suppress PDF 1.4 XMP metadata streams when saving as PDF 1.3.
- SaveToFile, SaveToString, and SaveToStream now fail with LastErrorCode 602 when the selected PDF target version is lower than features still present in the document, such as transparency, optional content, JPX, UserUnit, 3D, or AES crypt-filter features.
v3.12.5 2026-05-09
- Improved PDF 1.7 literal string parsing so unknown escape sequences ignore the backslash as required by the standard.
- Literal string octal escapes now consume only octal digits and preserve a following non-octal digit as regular string data.
- Added regression coverage for unknown literal-string escapes and mixed octal/non-octal escape sequences.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 141/141 each.
v3.12.4 2026-05-09
- Improved PDF 1.7 lexical parsing so name objects now stop correctly at the right-brace delimiter.
- Fixed SmartAccess loading of xref stream compressed-object entries whose object stream number is larger than the PDF byte length.
- Added regression coverage for right-brace name delimiters and sparse compressed-object xref stream entries.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 139/139 each.
v3.12.3 2026-05-08
- Improved PDF 1.7 encrypted-document compatibility for standard security handler files that use StrF, StmF, EFF, Identity, None, or named StdCF-style crypt filters.
- Metadata streams now honor EncryptMetadata=false during decrypt, encrypt, and copy/save workflows instead of being processed like ordinary streams.
- Embedded file streams now carry /Type /EmbeddedFile and use the embedded-file crypt-filter decision path when encrypted documents are loaded or saved.
- External embedded file streams now promote FDecodeParms to DecodeParms when FFilter is promoted to Filter, preserving stream decode parameters.
- New AES encrypted PDFs now write crypt-filter Length values as bit lengths, matching the PDF 1.7 crypt filter dictionary contract.
- XRef stream Prev/XRefStm values and large numeric offsets now keep 64-bit precision through parser and SmartAccess paths.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 137/137 each.
v3.12.2 2026-05-08
- Improved PDF 1.7 stream decoding compatibility. Generic stream decoding now honors /DP as a DecodeParms alias, resolves indirect decode-parameter array entries, and accepts the /AHx and /LZW standard filter abbreviations.
- Large-file PDF output now writes xref, startxref, linearization, and digital signature ByteRange offsets through 64-bit formatting paths instead of narrowing those values through 32-bit integer helpers.
- Loaded documents now treat a catalog /Version entry as the effective PDF version when it is newer than the file header version.
- Rewritten xref-stream trailers no longer retain stream-only DecodeParms keys when PDFlibPas saves them as classic trailer dictionaries.
- Validation: Delphi Win32 and Win64 DUnitX suites passed 134/134 each.
v3.12.1 2026-05-06
- Generated PDFs now open with the first page sized to the viewer window's available height, so the entire first page is visible top-to-bottom at the largest zoom that fits the window. Configure a custom OpenAction (SetOpenActionDestination, SetOpenActionMenu, SetOpenActionJavaScript) on the document to override this default.
v3.12.0 2026-05-06
- The Windows static backends now include libjpeg-turbo NASM SIMD objects for Win32 and Win64, plus zlib-ng x86 SIMD dispatch objects for the Win64x zlib-ng set.
- Reworked the zlib-ng rebuild scripts so Win64x bcc64x and diagnostic MSVC builds compile the generic, SSE2, SSSE3, SSE4.1/SSE4.2, PCLMULQDQ, and AVX2 source files with per-file feature flags instead of relying on one global compiler switch.
- Added 32-byte aligned malloc/calloc/realloc/free CRT stubs for the static C libraries and fixed TPDFJPEGImage.Compress to release jpeg_mem_dest buffers through the same C free path that allocated them.
- Expanded the public validation notes to call out the strict automated coverage behind this release: library builds, compression round trips, HelloWorld /FlateDecode output, JPEG rendering, image workflows, fonts, forms, security, signing, printing, and C++Builder demo-derived workflows.
v3.11.0 2026-05-05
- Switched Windows Flate compression and decompression to zlib-ng in zlib-compatible mode. Win32, Delphi Win64, and C++Builder Win64x now link ABI-matched zlib-ng static object sets from Lib\thirdparty\Win32, Lib\thirdparty\Win64, and Lib\thirdparty\Win64x.
- The Win64 path no longer routes through Delphi's System.ZLib unit, so PDF stream compression/decompression can benefit from the zlib-ng backend just like the 32-bit build.
- Added a small zlib-ng bridge object for Win64 builds so Pascal code keeps stable zlib-compatible entry points while Delphi and C++Builder consume their own linker-compatible object sets.
- Updated all C++Builder demo projects to define PDFLIB_CPPBUILDER, matching the GoogleTest runner and preventing Win64x demos from linking the Delphi Win64 zlib-ng objects.
v3.10.3 2026-05-01
- Extended the C++Builder GoogleTest suite to cover every demo under Demo\C++Builder. The 7-fixture phase-1 layout grew to 15 fixtures / 52 GoogleTest cases, all passing on Win64x. Newly covered demos: AddFormattedTitle, AddTextImage, AddTrueTypeSubsettedFont, AddWebLink, CanvasText, CaptureToNewSize, CopyPageRanges, CreateWithImage, CreateWithImageToStream, DoInTheStream, DrawWrappedText, EditFormField, EmbeddedFonts, ExtractAnnotAttach, ExtractEmbeddedFonts, ExtractImage, ImageToPdf, ImportEMF, MultiFunction (renderer switch), PageOperations, PdfDecrypt, PdfPermission, PrintPDF, TextMeasure, TextPaging.
v3.10.2 2026-05-01
- Added a C++Builder GoogleTest runner under Tests\C++Builder that exercises Lib\PDFlibrary.pas through the same {$JPHNE}-emitted HPP headers used by the C++Builder demos. The first phase mirrors seven core Delphi scenarios (HelloWorld, DrawShapes, CreateTable, PdfEncrypt, ExtractText, PdfSigning, PdfToImage rendering) as 17 GoogleTest cases, all passing on Win64x.
- Extended the Delphi DUnitX suite with Tests.Print covering the PrintPDF and ShowPrinterBins demos (default-printer enumeration, custom-printer setup, print options, redirect-to-file print job) and a renderer-switch test in Tests.Render exercising the MultiFunction demo's GDI+ / PDFium / Cairo engine selection on the same source PDF.
v3.10.1 2026-05-01
- Added 57 named page sizes to SetPageSize so the same canonical names used by the sister HotPDF library work here too: SIZE8X11, QUADA0, DOUBA0, B0PLUS, ENVB4/B5/C6/DL/MONARCH, ENV9/10/11, ANSIA/B/C/D/E, ARCHA/B/C/D/E1/E, SHIROKU, G1K, USBC/EUBC/ASBC, ID1/ID2/ID3, ONEINCH/TWOINCH/L2INCH/USVISA, P2R..P24R / S8R / P4D photo prints, plus the Chinese / Taiwanese octavo and sextodecimo sheet formats LARGE/STANDARD/CROWN/ROC 8K and the matching 16K halves.
v3.10.0 2026-04-30
- Added native C++Builder versions for every Delphi sample under Demo. The PDF-creation, page-manipulation, font, image, security, signing, rendering and printing demos can now be built and run from C++Builder without any Delphi-side wrapper.
- Each new demo lives in Demo\C++Builder\<Name>\ as a console project that consumes Lib\PDFlibrary.pas directly and ships the input files needed to run.
- Added a brief English Readme.txt to every Delphi demo folder describing what the demo shows, the API it focuses on, and how to run it; an HTML overview at Demo\Delphi\index.html links to all of them grouped by topic.
- Mirrored the same Readme.txt for every C++Builder demo with a Run section rewritten for the console workflow (argv arguments instead of Open/SaveDialogs); a matching Demo\C++Builder\index.html lists every C++Builder demo with the same topic groups.
- Fixed a memory leak in the ImportEMF demo (the TPDFlib instance was created but never freed).
v3.9.14 2026-04-30
- Fixed the page-range copy demo so it actually copies pages instead of always reporting failure.
- Tidied up the wrapped-text and HTML pagination demos so each one focuses on its own API and runs from a single button.
- Renamed two demo projects (EmbeddedFonts and PdfPermission) so the compiled executables match the folder names instead of older prototype names.
v3.9.13 2026-04-30
- Fixed a stream-position bug in the internal buffer reader: two-byte word reads were advancing the read cursor by four bytes instead of two. In buffers longer than two bytes, subsequent reads landed at the wrong offset and silently returned incorrect data. The effect was most visible when parsing binary data structures that interleave byte and word reads.
- Introduced an automated DUnitX test suite (console and VCL GUI runners) covering utility units — buffer, AES, ZLib, Unicode, and digest hashing — and library-level workflows including document creation, save-to-file and save-to-stream, load round-trips, and AES-128/AES-256 encryption.
v3.9.12 2026-04-30
- GDI+ image rendering now defaults to smooth, high-quality bicubic interpolation when scaling raster images to screen or export resolution. Previously the default was nearest-neighbour, which produced visible staircase artefacts on small images (logos, thumbnails) enlarged for screen preview or high-DPI export. Callers that prefer the sharper nearest-neighbour mode can restore the old behavior via SetGDIPlusOptions.
v3.9.11 2026-04-30
- Fixed Cairo rendering of PDF images that use color-key transparency (a /Mask color-range array in the image dictionary). Previously, when a page contained an image with this form of transparency, the Cairo renderer omitted the image entirely rather than compositing it against the page background. The fix derives a per-pixel alpha channel from the declared color-key ranges and renders the result as a transparent image, producing output visually consistent with the GDI+ renderer.
v3.9.10 2026-04-30
- Fixed a Cairo rendering regression where all page content following a clipped-image sequence was incorrectly confined to the image's clipping rectangle. PDF pages that save the graphics state, apply a clip path, paint an image, then restore the state — a common layout technique for framed or bordered images — would render all subsequent text, shapes, and graphics inside the clipped region only. Cairo state save and restore now map correctly to the PDF q/Q operators, so the clipping region is discarded after the image is drawn.
v3.9.9 2026-04-29
- Added a Cairo-based PDF rendering engine as a third rendering option alongside GDI+ and PDFium. Call SelectRenderer(2) before rendering to activate it; the engine requires cairo.dll from the bundled DLL\Cairo folder. Cairo rendering supports the same output modes as GDI+: bitmap file and stream export (BMP, JPEG, PNG, GIF, TIFF, G4 TIFF), device-context rendering, and direct printer output.
- The MultiFunction View/Print demo now exposes a three-way renderer selector so users can compare GDI+, PDFium, and Cairo output side-by-side on the same document without any code changes.
v3.9.8 2026-04-29
- Suppressed two spurious compiler diagnostics in the Win32 C-runtime shim that appeared on RAD Studio 13.1 and later. A deprecation warning (W1000) was raised because a compiler-version capability guard was not propagated to compilers newer than Delphi 2009, causing them to compile against a deprecated memory-manager API. An unused-variable hint (H2164) was raised for an internal compatibility variable only needed for Delphi 7 builds; it is now scoped to that version's conditional block. Both issues were diagnostic-only with no runtime impact.
v3.9.7 2026-04-29
- Added optional PDFium-based page rendering on Windows, including BMP stream rendering, device-context rendering, memory rendering, and printer output.
- Updated the Delphi MultiFunction View/Print demo with a renderer selector so users can switch between the existing GDI+ renderer and PDFium.
v3.9.6 2026-04-29
- Added separate Inno Setup scripts for the full PDFlibPas package and the trial package, with release-focused exclusions for source-control metadata, build outputs, IDE caches, local agent files, and bundled third-party source trees that are not part of the shipped package.
- The trial installer now builds and packages trial binary libraries for RAD Studio 11.3, 12.3, and 13.1, plus the trial Delphi demos, before the setup executable is generated.
v3.9.5 2026-04-29
- Fixed Win32 library builds under RAD Studio 9.0 / Delphi XE2. The build script was passing a DCU output-directory flag that only exists from Delphi 2010 onward; XE2's compiler interpreted the flag differently, producing a garbled output path and a fatal error before any source file was processed. The script now selects the appropriate flag automatically based on the target compiler version.
- Corrected a related compiler-version guard in the library source that was calling a name-qualified runtime function introduced in XE4 under an XE2+ condition. Builds targeting XE2 and XE3 now resolve the correct compatibility import instead.
v3.9.4 2026-04-29
- Fixed printer setup for network and server-shared printers by applying paper tray, media, duplex, quality, and other print settings through the printer DEVMODE handle instead of the printer device context handle.
v3.9.3 2026-04-29
- Refreshed the bundled AES backend to Brian Gladman's 2018 AES sources on both Win32 and Win64. Reproducible build scripts now allow the static AES objects to be rebuilt from source at any time. An ABI defect in the Pascal bindings was discovered and fixed in the process: the AES-CBC encrypt and decrypt functions were missing their C calling-convention declaration, so Win32 builds silently passed arguments in the wrong register order, potentially producing incorrect encrypted output. Win64 builds were unaffected because the platform enforces a uniform calling convention.
- Hardened the third-party rebuild scripts so the MSVC-based zlib, JPEG, and CRT-stub scripts can be launched from the repository root as well as from the thirdparty directory; previously they required the working directory to be set to the thirdparty folder.
v3.9.2 2026-04-29
- Upgraded the JPEG 2000 backend from the legacy OpenJPEG 1.5 to OpenJPEG 2.5.4 on both Win32 and Win64. Both platforms now use static object linking, so JPEG 2000 encoding and decoding work without an additional runtime DLL. The modern codec brings current JP2/J2K header handling, a callback-driven stream API, and accumulated bug and security fixes from the upstream project. The public TJpeg2000Bitmap API is unchanged.
v3.9.1 2026-04-29
- Fixed JPEG page rendering and image export after the libjpeg-turbo upgrade, restoring PdfToImage JPG conversion and TPDFJPEGImage.SaveToStream output on Win32 and Win64.
- Corrected Win32 libjpeg-turbo ABI bindings so callbacks, structure alignment, boolean fields, and memory-backed JPEG destinations match libjpeg-turbo 3.1.90.
- Fixed Win32 FlateDecode stream decompression with the bundled zlib 1.3.2 backend, restoring PDF xref stream loading for files such as the PdfToImage sample document.
v3.9.0 2026-04-29
- Upgraded the bundled JPEG 2000 backend from legacy OpenJPEG 1.5 to OpenJPEG 2.5.4. JPEG 2000 loading and saving now use the modern codec, callback-driven stream API, and current JP2/J2K header handling while preserving the public TJpeg2000Bitmap API.
- JPEG 2000 output now selects a valid OpenJPEG resolution count for small images automatically, and the Win32 static backend no longer depends on missing MSVCRT helper exports.
v3.8.1 2026-04-29
- Eliminated all 16 cosmetic linker W1028 "Bad global symbol definition" warnings on Win32 and Win64. Source-level renames remove the redundant Pascal-side duplicates (jpeg_std_error and the jmemnobs allocator stubs now resolve solely from the obj layer); the three remaining bcc32 / vc64 obj symbols (jpeg_natural_order, jpeg_aritab, jpeg_nbits_table) that must stay link-resolved against Pascal-side data are now stripped of their COFF symbol names via an ObjConv post-processing pass during thirdparty\build-jpeg-vc64.bat. No public API change; clean linker output for both Delphi Win32 and Win64 builds.
v3.8.0 2026-04-29
- Win64 JPEG codec upgraded from IJG-style libjpeg to libjpeg-turbo 3.1.90, completing the JPEG migration started in v3.7.0 (Win32). Both Win32 and Win64 paths now share the same modern JPEG codec, with the same SIMD- optimized inner loops and 30+ accumulated CVE / fuzz fixes from upstream. Public PDFlibPas API unchanged.
v3.7.0 2026-04-28
- Win32 JPEG codec upgraded from IJG libjpeg-6b to libjpeg-turbo 3.1.90. Significantly faster JPEG encode/decode through SIMD-optimized inner loops, plus the 30+ CVE / fuzz fixes accumulated in libjpeg-turbo upstream. Public PDFlibPas API (TPDFJPEGImage class, DumpJPEG functions) is unchanged; existing PDF/JPEG code paths run faster with no source changes required.
v3.6.0 2026-04-28
- Win32 zlib upgraded from 1.2.x to 1.3.2. Includes the standard 25+ CVE / fuzz fixes accumulated upstream since 1.2.8, plus the new inflateBack9 / inflateTree9 entry points used by 64-bit-window streams. Public PDFlibPas API (DeflateStr / InflateStr / InflateStrParms) is unchanged.
- Win64 zlib path is unchanged in this release - it continues to use the Delphi-bundled System.ZLib unit.
- Activated the Win64 link-time CRT shim PDFlibCLibs.pas (introduced in v3.5.0) for the Win32 zlib path, providing memcpy / memset / malloc / free symbols that the new zlib 1.3.2 obj files reference.
v3.5.0 2026-04-28
- Vendored fresh build infrastructure for the bundled C image / compression libraries: zlib 1.3.2, libjpeg-turbo 3.1.90, libtiff 4.7.1. Build scripts for both Embarcadero bcc32 (Win32) and MSVC cl.exe (Win64) live in Lib/thirdparty/ alongside the source trees, so anyone with RAD Studio + VS2022 can rebuild the static obj files from clean source.
- Added build infrastructure for OpenJPEG 2.5.4. The OpenJPEG source tree itself is fetched independently by the user (git clone uclouvain/openjpeg into Lib/thirdparty/OpenJPEG/) so it can be upgraded without touching PDFlibPas's build configuration.
- Added Lib/PDFlibCLibs.pas, a Win64 link-time CRT shim shared with the sister project HotPDF. It bridges the gap between the MSVC-compiled C obj files and Delphi's Win64 linkers (dcc64 / Win64x ld.lld / BCB ilink64), which do not pull in msvcrt.dll automatically.
v3.4.0 2026-04-28
- Hardened encryption key, AES initialization vector and Perms permission block generation against predictable random number sources. Encrypted PDFs produced on systems started near the same wall-clock time are no longer trivially correlatable; AES-256 documents now keep their full key strength.
- Hardened image dictionary parsing against malformed or hostile PDFs that declare unreasonable Width, Height, BitsPerComponent or DeviceN component counts. Out-of-range values are clamped before any pixel-buffer arithmetic, preventing crashes when opening such files.
- Hardened cross-reference and page-tree traversal against documents whose /Prev xref chains or /Parent page links form a cycle or are excessively deep. The reader now rejects malformed structures cleanly instead of recursing until it runs out of stack.
v3.3.1 2026-04-27
- Streamlined the per-component Windows build scripts. The DLL/, OCX/ and Dylib/ folders no longer carry separate build12-* / build13-* variants: each platform now has a single build-Win32 / build-Win64 script that pins to the latest RAD Studio and accepts an optional "debug" argument.
- Added inline rationale comments around the PDFlibRenderer.pas render fixes that were already present in the initial Git baseline. The comments document why SetPen scales stroke widths by the active canvas transform, and why Type 3 font CharProc d0/d1 operators must consume their operands. No runtime behavior changed.
v3.3.0 2026-04-26
- Fixed transformed stroke rendering in PDFlibRenderer.pas. SetPen now applies the current canvas-transform scale to PDF line widths before calling Picasso, preventing oversized or undersized strokes on paths whose coordinates have already been transformed. This fixes Type 3 glyph outlines that could render as thick, irregular blocks.
- Fixed Type 3 font CharProc d0/d1 handling in the content stream parser. d0 now consumes its two width operands, and d1 consumes its six width/bounding box operands before later drawing commands run, preventing stale operands from corrupting glyph or path geometry.