HotPDF Notes de version

Version history for HotPDF user-visible features, fixes, compatibility updates, and documentation changes

Note: Only the latest 500 change records are kept

Last release

  • Latest version: 2.415.0; Release date: 2026-07-12

Version 2.415.0

Added

  • HPDFParsePDFDate now honours the timezone suffix (+HH’mm, -HH’mm, or Z) and returns a UTC TDateTime; HPDFFormatPDFDate is the inverse formatter producing D:YYYYMMDDHHmmSS+00’00
  • GetLoadedExtGStateInfo reads LW / LC / LJ / ca / CA off a named ExtGState entry on a loaded page; GetLoadedShadingCount / GetLoadedShadingName and GetLoadedPatternCount / GetLoadedPatternName enumerate the /Shading and /Pattern resource sub-dictionaries
  • ReplaceLoadedPage swaps a page’s contents from a source document, SwitchLoadedPages exchanges two pages, ReverseLoadedPages flips page order in a range, ExtractLoadedPagesToPDF saves a page range as a standalone PDF, and GetLoadedPageInheritedBox resolves inherited page boxes through the page-tree parent chain
  • GetLoadedFileSpecInfo reads embedded-file metadata (name / description / MIME / size), GetLoadedEmbeddedFileMIME returns the /Subtype, GetLoadedEmbeddedFileChecksum returns the /Checksum digest, and THPDFNameTreeType + GetLoadedNameTreeRootCount provide a typed enumeration of all nine name-tree categories
  • HPDFEnablePerMonitorDPI dynamically enables per-monitor DPI awareness; THPDFBackgroundRenderer renders pages on a background thread with a request queue and cancellation; GetLoadedPageContentStreamCount reports whether /Contents is a single stream or an array; GetLoadedXMPValue extracts a namespace-qualified XMP property; and GetLoadedDocumentReport aggregates all diagnostic info into a JSON string

Version 2.414.0

Added

  • THPDFActionBuilder.URIWithIsMap creates a URI action with /IsMap true for server-side image-map tracking, where the previous URI builder only set the bare /URI string
  • AddLoadedCaretAnnotationEx adds an optional paragraph symbol (/Sy P) to caret annotations, the visual marker editors use for insert-tracking
  • GetLoadedAnnotationDA parses a FreeText annotation’s /DA string into font name, font size and RGB colour components, so a caller can inspect or clone the appearance without re-parsing the raw operator string

Version 2.413.2

Fixed

  • The C++Builder package now links without requiring crypt32.lib: HPDFWinCertSigner loads the CryptoAPI entry points (CertOpenStore, CertEnumCertificatesInStore, CryptAcquireCertificatePrivateKey, and the Crypt hash helpers) dynamically via LoadLibrary/GetProcAddress, matching the pattern already used by HPDFDoc.EnumerateSystemCertificates

Version 2.413.1

Fixed

  • Type1 and CFF font handling now preserves parser ownership across repeated stream checks and multi-font FontSets, returns stable glyph names and bounding boxes, keeps fractional font sizes and DPI scaling, and avoids composite-glyph and private-dictionary memory errors
  • The C++Builder AddDelPages, HugeFileBenchmark, and Security demos now compile for Win64, while page-operation and preflight examples release partially constructed objects safely

Version 2.413.0

Changed

  • The Delphi E-Invoice demo now validates required invoice fields, amount and VAT ranges, currency syntax, and embedded XML profile compatibility before writing output
  • The attach workflow now rejects identical source and output paths, reports the detected XML guideline, and combines container, PDF/A, XML profile, signature, visual consistency, Schematron, and external-report checks into one verdict

Fixed

  • E-Invoice generation and manual validation no longer report a successful result when an enabled validation layer finds issues
  • Loaded electronic-invoice summaries now read the invoice number, seller, and buyer from their correct XML aggregates, preventing false visible-text consistency findings

Version 2.412.0

Changed

  • All Delphi demos now resolve no-argument relative assets and outputs from their executable directory while preserving the caller working directory for command-line paths
  • Delphi command-line demos now provide stricter argument validation, failure exit codes, deterministic comparison inputs, and generated-document verification across page copying, text extraction, preflight, optimisation, inspection, and in-memory workflows

Fixed

  • Delphi demos no longer risk page-list overflow above 100 selected pages, create an extra blank page in the add-page workflow, close unrelated PDF viewer windows, or report failed preflight checks as successful
  • The E-Invoice attach workflow now rebuilds its current page correctly when a single-page source is converted, signed, and stripped of the temporary initial blank page

Version 2.411.0

Added

  • E-Invoice demo: new "Attach to existing PDF" mode converts an existing PDF to PDF/A-3, embeds a Factur-X/ZUGFeRD invoice XML as a document-level attachment, and optionally signs the result with a PFX certificate

Version 2.410.0

Added

  • Loaded AcroForm fields can now update flags, maximum length, text justification, per-widget rectangles, rotation, border colour, and visible or printable state, with widget enumeration for radio groups and other multi-widget fields

Fixed

  • Loaded field tooltip, border-width, and background-colour edits now mark the correct field or widget dictionaries dirty, apply visual properties to every widget, and invalidate only the affected page render cache

Version 2.409.0

Added

  • ActivateLoadedLinks turns bare HTTP, HTTPS, FTP, www., mailto:, and email text into positioned borderless URI annotations across a selected page range

Changed

  • Loaded link creation now persists reliably in incremental updates, while automatic activation snapshots existing links once per page, skips matching URI and rectangle pairs, and invalidates each changed page cache only once

Version 2.408.0

Added

  • Loaded annotations can now update their title, unique name, modification date, normalised rectangle, and standard solid, dashed, bevelled, inset, or underlined border style

Fixed

  • Loaded annotation edits now mark the annotation object dirty for incremental saves, while visual edits invalidate only the affected page's cached renders and retain other warm pages

Version 2.407.0

Added

  • THPDFViewerModel stores, clips, enumerates, removes, and clears persistent page-region highlights without modifying the PDF
  • THPDFViewer adds a highlight interaction mode with captured marquee dragging, rotation-aware PDF coordinate recovery, configurable colour, and an OnMarqueeSelect callback

Fixed

  • Viewer coordinate transforms now retain the actual render DPI below 12 and above 2400, keeping selections aligned at the 5% and 6400% zoom limits

Version 2.406.0

Added

  • THPDFViewerModel creates rotation-aware page thumbnails directly at a DPI selected for caller-supplied pixel bounds, avoiding full-size intermediate page bitmaps
  • Viewer-model page prefetch warms a centred neighbourhood asynchronously while limiting the scheduled pages to the rendered-page cache capacity

Version 2.405.0

Added

  • THPDFPageLayout now supports PDF 1.5 plTwoPageLeft and plTwoPageRight cover-spread layouts with automatic version negotiation and strict-version fallback

Fixed

  • BeginDoc now preserves the caller-selected page layout instead of always replacing it with plOneColumn

Version 2.404.0

Added

  • THPDFViewerModel creates rotation-aware snapshots of bounded PDF page regions without allocating a full-page bitmap

Version 2.403.0

Added

  • THPDFViewerModel converts points bidirectionally between PDF page space and rotation-aware Viewer coordinates at a caller-selected DPI

Version 2.402.0

Changed

  • Viewer zoom commands now use stable standard levels from 5% through 6400%, including reversible navigation around arbitrary custom values

Version 2.401.0

Added

  • THPDFViewer adds Ctrl+wheel zoom, vertical wheel scrolling, and Shift+wheel horizontal scrolling without rerendering for scroll-only input

Version 2.400.0

Added

  • THPDFViewer adds keyboard page navigation, scrolling, zoom shortcuts, and Actual Size, Fit Width, or Fit Page mode selection

Version 2.399.0

Added

  • THPDFViewer draws or prints the rotation-aware current view with deterministic aspect-preserving fit and centred placement

Version 2.398.0

Added

  • THPDFViewerModel creates caller-owned vector EMF snapshots of any loaded page or the current view, including non-destructive 90-degree view rotation

Version 2.397.0

Added

  • THPDFViewerModel saves rotation-aware page snapshots as BMP, JPEG, or PNG to files and caller-owned streams with configurable JPEG quality

Version 2.396.0

Added

  • THPDFViewer.ResetView restores Actual Size, clears view rotation and search highlights while preserving the current page, with matching reset and rotation actions and batched single-render updates

Version 2.395.0

Added

  • THPDFViewer and THPDFViewerModel add clockwise, counter-clockwise, and resettable view rotation that also applies to caller-owned page snapshots without changing the PDF page

Version 2.394.0

Added

  • THPDFViewerModel can create caller-owned page snapshots and save the current page as BMP without constructing a Viewer control

Version 2.393.0

Added

  • THPDFLoadedFormField now exposes field flags, MaxLen, page index, widget bounds, and common Required, NoExport, Multiline, and Password states
  • GetLoadedFormFieldMaxLength provides direct indexed access to loaded text-field length limits

Version 2.392.0

Added

  • SetDocumentAttachmentMetadata renames document-level embedded attachments and updates their descriptions before serialization

Version 2.391.0

Added

  • ExtractLoadedPagesTextToStream streams selected loaded-page text as UTF-8 with custom separators and optional BOM output
  • THPDFViewerModel adds form-field hit testing and deterministic keyboard navigation across page widgets
  • THPDFSignatureInfo.CertificateTimeValidity reports certificate-bound and signed-time validity classifications

Fixed

  • Loaded form fields without widget /P back-references can now be mapped through page annotation arrays

Version 2.390.0

Added

  • THPDFWatermarkTemplate.MakeCurve and THPDFPage.AddCurveWatermark add cubic Bezier curves to loaded composites and new-document authoring

Fixed

  • Loaded document metadata setters now mark the Info dictionary dirty so incremental saves persist title and author changes

Version 2.389.0

Added

  • InsertLoadedBlankPage inserts a blank page with caller-defined dimensions at an exact loaded-document position
  • ExtractLoadedPagesText aggregates text from a one-based page range with a caller-defined separator
  • GetLoadedFormFieldNameValuePairs and SetLoadedFormFieldNameValuePairs provide batch name=value form exchange through TStrings
  • CMapResourcePath supports explicit standard CMap deployment paths for services, plug-ins, and custom application layouts

Changed

  • The VCL viewer now draws search-hit rectangles and refreshes when the active hit changes on the current page, while linked outline controls follow viewer document changes
  • Page rendering now resolves inherited media boxes, rotation, and resources and correctly maps non-zero page origins at every right-angle rotation

Fixed

  • Form-name conflicts are rejected before page insertion or append begins when merge renaming is disabled, leaving the destination page count unchanged
  • Deleting loaded pages now detaches their AcroForm widget fields and removes empty field-tree branches instead of leaving references to deleted pages
  • Cursor-style search helpers and viewer-model misses no longer clear managed text-match records with raw memory operations
  • Automatic CMap discovery now passes the actual collection root to the text decoder

Version 2.388.0

Added

  • New DeletePages removes one-based page ranges from loaded PDFs, de-duplicates overlapping selections, reports progress, and rebuilds a valid page tree for saving
  • Page insertion and append merging now accept THPDFMergeOptions to copy recursive outlines, register imported AcroForm fields, and deterministically rename conflicting field names
  • New AddLoadedRadioButton creates a true parent radio field with child widgets, shared export values, and complete on/off appearance states
  • New SearchLoadedNext provides stateless page-local next-match search, while GetLoadedOutlineEntries returns complete recursive outline snapshots with parent and level data
  • New Windows certificate-store signing overloads select a current-user or local-machine certificate by SHA-1 thumbprint and sign through either CNG or legacy CSP private keys
  • New THPDFLoadedDocumentFacade exposes typed outline, form, annotation, font, and image collections with mutation and extraction helpers
  • New THPDFViewer, THPDFSearchPanel, THPDFOutlineViewer, viewer model, and viewer action classes add reusable VCL page display, navigation, zoom, search, and bookmark controls
  • New advanced printing, signature validation, page-thumbnail, loaded-image export, and typed loaded-document inspection demos cover the end-to-end workflows

Changed

  • Loaded-document printing now builds deterministic collated or uncollated physical page sequences, supports custom paper width and length, and reports printer paper codes, names, and sizes
  • System certificate enumeration now includes SHA-1 thumbprints, private-key availability, validity dates, and key-usage metadata

Fixed

  • Loaded text-search result growth no longer copies managed string records with raw memory moves, preventing invalid-pointer failures on Win64
  • Deleting loaded pages no longer frees shared page resources or leaves stale page-tree counts that reappear after save and reload

Version 2.387.0

Added

  • New PrefetchLoadedPages renders a page range into the rendered-page cache on a background worker thread, so a viewer turning pages gets instant warm-cache hits instead of waiting for each render
  • CancelLoadedPagePrefetch stops the worker and IsLoadedPagePrefetchActive reports its state; loading another document or destroying the component cancels an active prefetch automatically
  • Cached rendering and the prefetch worker are serialised internally, so RenderLoadedPageToBitmapCached stays safe to call while a prefetch is running

Version 2.386.0

Added

  • New FlattenLoadedAnnotations draws each annotation's normal appearance permanently into the page content at its rectangle and removes the annotation, so markup and form visuals survive in viewers that hide or cannot edit annotations
  • The pass follows appearance-state dictionaries through /AS, honours the appearance bounding box and matrix when fitting the rectangle, and can be limited to one annotation subtype or a page range

Version 2.385.0

Added

  • New RenderLoadedPageRegionToBitmap rasterises only a chosen user-space window of a page at the requested DPI, so very large pages can be rendered tile by tile in bounded memory at high resolutions instead of as one oversized bitmap
  • Tiles align exactly: the bitmap covers precisely the requested region, so adjacent tiles reassemble into the full page without seams

Version 2.384.0

Added

  • New GenerateLoadedPageThumbnails renders the selected pages of a loaded document and embeds them as JPEG page thumbnails, the previews shown in viewer page panels; the longest edge size and JPEG quality are configurable, and existing thumbnails are replaced in place
  • GetLoadedPageThumbnailSize reads back an embedded thumbnail's pixel dimensions, and ClearLoadedPageThumbnails removes thumbnails from the selected pages

Version 2.383.0

Added

  • EnumLoadedPageElements now reports vector path elements alongside text runs and images: each painted path yields an element with its user-space bounding box, the painting operator (stroke, fill, or both), the fill and stroke colours in force, and the segment count
  • The path walker follows q/Q nesting and cm transformations, so shapes drawn inside scaled or translated blocks report their true page coordinates

Version 2.382.0

Added

  • THPDFPrintOptions gains Duplex (simplex, long-edge, short-edge), PaperBin, and PrintQuality fields that are pushed into the printer device mode before the job starts; an explicit Orientation value is now applied as well
  • New HPDFGetInstalledPrinters lists the system printers, and HPDFGetPrinterCapabilities reports a printer's duplex and colour support, maximum copy count, paper bins (with the codes accepted by PaperBin), and supported resolutions

Version 2.381.0

Added

  • New CopyLoadedOutlinesFromDocument merges the complete bookmark tree of another loaded document into the current one, preserving titles, nesting, sibling order, and destination view parameters while remapping every destination page by a caller-supplied offset — the companion to page-append merges so combined documents keep both bookmark sets

Fixed

  • GetLoadedBookmarkPageIndex now finds bookmarks beyond the first top-level entry and inside nested levels; the previous lookup only matched later bookmarks by coincidence

Version 2.380.0

Added

  • New ImposeLoadedPagesNUp lays any page range onto grid sheets (any columns-by-rows arrangement, configurable sheet size and gutter) in reading order, scaling each page into its cell with optional aspect-ratio preservation
  • New ImposeLoadedPagesBooklet produces saddle-stitch booklet sheets: pages are padded to a multiple of four and paired in booklet order so double-sided printing and folding yields a correctly ordered booklet
  • Both imposition calls wrap the source pages as Form XObjects and append the finished sheets after the existing pages, returning the sheet count

Fixed

  • Loaded-page rendering now follows an indirect reference on the resources /XObject sub-dictionary; pages whose resources arrived as separate objects skipped their images and forms silently

Version 2.379.0

Added

  • SaveLoadedPagesAsImages gains two TIFF formats: ifTIFF writes one single-page TIFF file per page, and ifTIFFMulti aggregates the whole page range into one multi-page TIFF, unifying TIFF output with the existing BMP, JPEG, PNG, EMF, and WMF choices
  • Both TIFF paths honour the requested rendering DPI in the image resolution tags and use lossless Deflate compression

Version 2.378.0

Added

  • Loaded-page rendering now draws text rendering modes 1 (stroke) and 2 (fill then stroke) with real glyph outlines for both embedded fonts and system-font fallbacks, using the current stroke colour and line width; the clipping variants 4 to 7 paint like their base modes

Fixed

  • Twelve single-operand content operators (Tc, Tw, Tz, TL, Ts, Tr, w, J, j, M, ri, i) read their operand from the wrong token position and always applied zero; character and word spacing, horizontal scaling, leading, text rise, render mode, line width, caps, joins, and miter limit now take effect when rendering loaded pages

Version 2.377.0

Added

  • Loaded-page rendering now honours optional-content (layer) visibility: content inside BDC /OC marked sections and XObjects carrying an /OC entry is hidden when its layer is off, following the document's default configuration (/BaseState, /ON, /OFF)
  • Optional-content membership dictionaries evaluate their /P policy (AnyOn, AllOn, AnyOff, AllOff) over the member groups
  • New layer APIs on loaded documents: GetLoadedOptionalContentGroupCount, GetLoadedOptionalContentGroupName, GetLoadedOptionalContentGroupVisible, and SetLoadedOptionalContentGroupVisible to inspect and override layer states for rendering; overrides invalidate the rendered-page cache automatically

Version 2.376.1

Fixed

  • Loaded-page bitmap rendering now paints image XObjects: the Do, gs, and sh resource lookups previously missed their slash-prefixed operand names and skipped the object silently
  • The cm operator and Form XObject /Matrix values now concatenate in the correct order, so translate-plus-scale placement sequences (the standard image positioning idiom) land content at its intended page position

Version 2.376.0

Added

  • New RegisterExponentialFunction, RegisterStitchingFunction, and RegisterPostScriptFunction APIs create standalone Type 2, Type 3, and Type 4 function objects for use wherever a function reference is accepted (shadings, halftone spot and transfer functions, tint transforms)
  • RegisterPostScriptFunction validates the calculator program at registration time by trial evaluation, so malformed programs are rejected immediately instead of degrading silently in viewers
  • New RegisterSeparationFunc creates a Separation colour space with a caller-supplied tint-transform function object

Fixed

  • Rendering Type 2 (exponential) tint transforms with one- or three-component outputs no longer paints black; previously only four-component (CMYK) outputs decoded correctly
  • Rendering Type 3 (stitching) tint transforms now supports any number of sub-functions, applies the /Encode remapping, and accepts single-entry /Bounds arrays

Version 2.375.0

Added

  • Page rendering now evaluates Type 4 (PostScript calculator) tint-transform functions, so Separation and DeviceN colours and gradient shadings driven by calculator programs render their real colours instead of a grey placeholder
  • The calculator evaluator covers the complete ISO 32000-1 7.10.5 operator set: arithmetic, comparison, boolean and bitwise, stack manipulation, and if/ifelse conditionals

Fixed

  • Named colour-space selection (cs/CS operators) in loaded-page rendering now resolves resource names correctly; previously the lookup missed and the content fell back to the default colour space
  • Loaded-page rendering now follows indirect references to array-valued colour spaces such as /Separation and /DeviceN definitions stored as standalone objects

Version 2.374.0

Fixed

  • XFDF annotation import/export now preserves caret annotation default appearance data through the <defaultappearance> child and the PDF annotation DA entry

Version 2.373.0

Fixed

  • XFDF annotation import/export now preserves caret annotation fringe geometry through the fringe attribute and the PDF annotation RD entry

Version 2.372.0

Fixed

  • XFDF annotation import/export now preserves rubber stamp annotation rotation through the rotation attribute and the PDF annotation Rotate entry

Version 2.371.0

Fixed

  • XFDF annotation import/export now preserves text annotation reply relationships through inreplyto, replyType, and the PDF annotation IRT and RT entries

Version 2.370.0

Added

  • XFA numeric, date-time, and password fields with disabled horizontal scrolling now flatten to AcroForm text widgets with the PDF do-not-scroll flag

Version 2.369.0

Added

  • XFA text fields with disabled scroll policies now flatten to AcroForm text widgets with the PDF do-not-scroll flag

Version 2.368.0

Added

  • XFA text fields with multiLine="1" now flatten to AcroForm text widgets with the PDF multiline flag

Version 2.367.0

Added

  • XFA subform access restrictions now inherit into child widgets so generated AcroForm fields stay read-only when an ancestor is readOnly, protected, or nonInteractive

Version 2.366.0

Added

  • XFA choice-list flattening now maps commitOn="select" to the AcroForm commit-on-selection-change flag for generated choice fields

Version 2.365.0

Added

  • XFA choice-list flattening now maps open="always" lists to single-select AcroForm list boxes instead of drop-down combo boxes

Version 2.364.0

Added

  • XFA choice-list flattening now maps textEntry="1" combo lists to editable AcroForm combo boxes while preserving typed values outside the option list

Version 2.363.0

Added

  • XFA choice-list flattening now prefers <items save="1"> values when a field carries separate display and saved-value option lists

Version 2.362.0

Fixed

  • XFDF annotation import/export now preserves FreeText justification and tail attributes through the PDF annotation Q and IT entries
  • JBIG2 document defaults now match the documented scan-friendly settings for lossy level, isolated black-pixel cleanup and black-dot size

Version 2.361.0

Fixed

  • XFDF annotation import/export now preserves standard line leader and caption attributes, including leaderLength, leaderExtended, caption, leader-offset, caption-style, caption offset values and the import-side leaderExtend spelling used by compatible XFDF files

Version 2.360.0

Added

  • XFA flattening now suppresses output for fields and static draws concealed by presence="hidden", presence="invisible", or presence="inactive", including descendants of concealed containers

Version 2.359.0

Added

  • XFA flattening now maps field-level access="readOnly", access="protected", and access="nonInteractive" restrictions to the generated AcroForm read-only flag

Version 2.358.0

Added

  • XFA flattening now preserves <choiceList open="multiSelect"> semantics by setting the PDF multi-select flag on the generated AcroForm list box

Version 2.357.0

Added

  • XFA flattening now maps <ui><passwordEdit> fields to AcroForm text fields with the PDF password flag, preserving bound values while allowing readers to treat the field as password-style input

Version 2.356.0

Added

  • XFA flattening now honours explicit <bind match="none"> field bindings, so fields marked as unbound remain blank instead of taking same-name values from the XFA form or datasets packets

Version 2.355.0

Added

  • XFA flattening now honours simple explicit <bind match="dataRef" ref="..."> field bindings such as $record.customer.legalName, so ApplyXFAAsAcroForm and FlattenLoadedXFA preserve values stored under a different data node name before automatic same-name matching

Version 2.354.0

Fixed

  • XFDF annotation import/export now preserves link annotation BorderStyleAlt children through the PDF annotation Border array, including corner radii, width and dash pattern values

Version 2.353.0

Fixed

  • XFDF annotation import/export now preserves standard interior-color attributes for line, square, circle, polygon, polyline and redaction annotations through the PDF annotation IC color array

Version 2.352.0

Fixed

  • XFDF annotation import/export now preserves standard annotation border style and cloudy border effect attributes, including width, dashes, style and intensity

Version 2.351.0

Fixed

  • XFDF annotation import/export now preserves annotation rich text through <contents-richtext> and imports popup child geometry and open state into annotation Popup dictionaries

Version 2.350.0

Fixed

  • XFDF annotation import/export now preserves additional standard annotation attributes: text open and review state values, line endpoint styles, link and redaction coords, FreeText default style, default appearance and rotation, and square or circle fringe geometry

Version 2.349.0

Fixed

  • XFDF annotation import/export now follows ISO 19444-1 structures for lines, polygons, polylines and ink annotations: line exports include full start / end coordinate pairs, polygon and polyline data uses <vertices> child elements, ink data uses <inklist><gesture>, semicolon-separated coordinate pairs import correctly, and unsupported annotation subtypes no longer inflate the exported count

Version 2.348.0

Added

  • LoadedPageCount property, DuplicateLoadedPage, AddLoadedBlankPage, SetLoadedPageRotationValue and GetLoadedPageBoxRect round out the loaded-document page-operation API — duplicate pages, insert blank separators, set rotation and read any of the five page boxes in one call
  • GetLoadedEncryptionMethod returns the cipher name (RC4-40 / RC4-128 / AES-128 / AES-256), GetLoadedFileStructureInfo aggregates linearization / object-stream / xref-type in one call, LoadedSourceFileSize is a property, and SetLoadedPDFVersion updates the version
  • StampLoadedPageImage and StampLoadedPageImageFromFile embed a JPEG Image XObject (logo / signature image / QR code) onto a loaded page at a given rectangle, InsertLoadedText draws a single-line text run, and GetLoadedPageContentLength returns the decoded byte count
  • THPDFPrintOptions gains IgnoreHardMargin (offset printer hard margins so content is not clipped) and AutoRotate (landscape pages print landscape automatically)
  • SaveLoadedPagesAsImages gains BMPPixelFormat / BMPMonochrome (mono / 8-bit export) and JPEGScale (1 / 2 / 4 / 8 sub-sampled JPEG decode for fast thumbnails)
  • CompressLoadedDocument zlib-compresses every uncompressed stream in the loaded object graph and writes /Filter /FlateDecode, shrinking output size

Fixed

  • StampLoadedPageText and StampLoadedPageImage now transparently decompress FlateDecode content streams before appending operators — previously stamping onto a compressed /Contents silently corrupted the zlib payload and the appended text/image disappeared

Version 2.347.0

Added

  • AddLoadedOutline creates a new bookmark on a loaded PDF at any nesting level (ParentIndex = -1 for top-level), with a /Dest [page /XYZ x y zoom] target — the single highest-requested loaded-document feature, closing the gap that HotPDF could read/modify/delete bookmarks but never create them
  • SetLoadedOutlineDestination and SetLoadedOutlineURI rewrite an existing bookmark’s target page or switch it to a URI action
  • ResolveLoadedNamedDestination turns a named destination string into a zero-based page index, and AddLoadedNamedDestination registers a new anchor on the loaded document’s /Names /Dests tree
  • GetLoadedBookmarkPageIndex is a convenience lookup: pass a bookmark title, get back the page it points to

Version 2.346.0

Fixed

  • Image scaling quality now honours /Interpolate: HALFTONE stretch mode is used by default (smooth downscale) and COLORONCOLOR when the image explicitly sets /Interpolate false, so small raster images keep their hard edges where the author intended instead of always blurring

Version 2.345.0

Fixed

  • TJ array kerning adjustments are no longer discarded: the numeric elements between string runs advance the text matrix by -value × FontSize / 1000, so tightly-spaced titles and logo lettering from Word / Illustrator place glyphs at the intended offsets
  • Tw (word spacing) now also fires on the CID ideographic space (U+3000, code $3000), so justified Japanese / Chinese text gets its word spacing instead of only ASCII code 32
  • Font weight / italic detection now consults /FontDescriptor /Flags (bit 18 ForceBold) and /ItalicAngle in addition to the /BaseFont name, so subset-prefixed fonts whose name carries no -Bold suffix still render at the right weight

Version 2.344.0

Added

  • GetLoadedTrapped reads the /Trapped key from the Info dict (True/False/Unknown), where it was previously write-only — PDF/X preflight workflows can now round-trip the trap state
  • GetLoadedDocumentMetadataXML returns the raw XMP metadata stream bytes so PDF/A documents whose Info dict is absent can still expose dc:title / dc:creator / xmp:CreateDate
  • GetLoadedCollectionInfo reads the /Collection Name of a PDF Portfolio (EmbeddedFiles name tree still carries the file list)
  • GetLoadedOutlineChild descends one level into the bookmark tree, returning the /First child of a top-level outline entry, so nested chapter / sub-chapter bookmarks are no longer invisible
  • RotateLoadedPages rotates every page in a range by a given angle (accumulating onto existing /Rotate), the batch counterpart to per-page rotation
  • SetLoadedPageBoxForRange sets a page box (Media/Crop/Bleed/Trim/Art) for every page in a range in one call
  • GetLoadedViewerPreferences now also reads HideWindowUI and CenterWindow, matching the six keys the writer emits (previously only four came back)

Version 2.343.0

Fixed

  • The W n / W* n clip idiom now applies the clip: the n operator builds the pending path and calls SelectClipPath instead of discarding both the path and the pending clip, so rect / container clips written as re ... W n no longer leak their contents past the boundary
  • SetMiterLimit is now pushed to GDI before building the stroke pen, so sharp joins honour the PDF miter limit (default 4) instead of GDI’s default 10 — eliminating the long spikes on acute-angle joins
  • Type 3 glyphs declared with d0 (colour-permitting) now explicitly clear the colour-suppress flag, so a preceding d1 glyph no longer bleeds its colour suppression into a d0 glyph

Added

  • ri (rendering intent) and i (flatness) operators are now consumed and stored on the graphics state (RenderingIntent / Flatness fields), where they were previously silently skipped

Version 2.342.0

Added

  • Text rendering mode operator Tr is now consumed; mode 3 (invisible) skips painting the text run entirely, so the OCR / form-background hidden text layer no longer paints as overlapping garbage glyphs — the most common Tr case in real-world PDFs. Modes 1 / 2 (stroke) currently fall back to fill pending per-glyph outline support
  • Marked-content operators BMC / BDC / EMC and the DP / MP property variants now maintain a depth counter on the renderer, the prerequisite for a later round’s OCG / OCMD visibility evaluation; BX / EX compatibility operators maintain their own counter so the renderer knows it is inside a compatibility block

Version 2.341.0

Fixed

  • Bezier shorthand operators v and y are now handled by the page renderer, where they were previously silently skipped — rounded rectangles, circles and the curves produced by Illustrator / PowerPoint / InDesign render correctly instead of being truncated or dropped
  • DrawTextRun now honours Tz (horizontal text scaling), Tw (word spacing, applied to the space glyph) and Ts (text rise) so justified Word exports place glyphs at the right width, headings that are horizontally stretched/squeezed keep their length, and super/subscript text lifts off the baseline — previously those three text-state values were stored but never consumed

Version 2.340.0

Added

  • SearchLoadedPageTextWholeWord filters the substring matches produced by SearchLoadedPageText down to those that sit on word boundaries (the glyph before the match start and after the match end must not be a word character), providing whole-word matching without padding the search string with a trailing space
  • GetLoadedSearchHitRect collapses a match’s glyph range into a single bounding rectangle (user-space Left/Top/Right/Bottom, padded by a fraction of the font size), so a viewer can draw one highlight box per hit instead of walking the glyph array

Version 2.339.0

Added

  • ExtractLoadedPageTextColumns reconstructs multi-column text: glyphs are clustered into baselines by a Y tolerance, each row is sorted by X, and a row splits into separate columns (tab-separated) wherever the gap between consecutive glyphs exceeds a configurable multiple of the median glyph advance — the column-aware counterpart to ExtractLoadedPageTextLayout that previously declared column detection out of scope
  • THPDFPageElement now carries a BaselineRole (brNormal / brSuperscript / brSubscript) populated by EnumLoadedPageElements: a run whose font size is markedly smaller than the page median and whose Y origin sits above or below the dominant baseline is flagged

Version 2.338.0

Fixed

  • Image XObjects are now placed by transforming the unit square through the current CTM, instead of being stretched across the whole page bitmap — the previous StretchDraw(Rect(0,0,W,H)) misplaced every image on the page; images now land in the rectangle the content stream actually specifies

Added

  • /ImageMask stencil images are detected on the render side and painted with the current fill colour (PDF 8.9.6.1), where the renderer previously drew them as a plain greyscale bitmap

Version 2.337.0

Added

  • Render-side stroke style: the page renderer now honours the J (LineCap: butt/round/square), j (LineJoin: miter/round/bevel), M (MiterLimit) and d (LineDash array + phase) operators by building a geometric pen via ExtCreatePen instead of the previous fixed CreatePen(PS_SOLID, ...), so rounded joins, dashed borders and square end caps render correctly
  • Render-side gs (ExtGState) operator: the named ExtGState dictionary in /Resources/ExtGState is now consumed for LW / LC / LJ / ML / ca / CA and applied to the graphics state, where the renderer previously dropped the operator entirely
  • Graphics state extended with LineCap / LineJoin / MiterLimit / LineDash / DashPhase / FillOpacity / StrokeOpacity fields, all with PDF-default initial values

Fixed

  • Clip (W / W*) now sets the GDI polygon fill mode (ALTERNATE vs WINDING) before SelectClipPath, so even-odd and nonzero-winding clip intersections are no longer identical

Version 2.336.0

Security

  • The render-side /Indexed colour-space parser now clamps HiVal to the spec-mandated [0..255] range, closing a buffer-overread vector where a malformed HiVal let nComps × indexHigh overflow a 32-bit byte count and read past the lookup table

Added

  • AttachLoadedAnnotationMeasure writes a /Measure dictionary (PDF 1.7 §12.5.6.13) onto a Line or Polygon annotation, carrying the /NumberFormat array (unit label, decimal/fraction/round style, precision), the /Scale ratio and the /CYX isotropy factor — so a viewer can compute the real-world distance or area the shape spans

Version 2.335.0

Added

  • Render-side sh (shading) operator: axial (Type 2) and radial (Type 3) shadings are now painted instead of silently dropped, so PDFs whose backgrounds rely on Word/Excel-style gradients render their colour blend. The shading is discretised into bands along its axis and each band is filled with the colour the shading’s function evaluates to at that point

Version 2.334.0

Added

  • Render-side function-object evaluator HPDFEvalTintTransform now resolves Type 2 Exponential (C0 + xN·(C1-C0) with Domain/Range clamping), Type 0 Sampled (8/16/32-bit, Encode mapping, nearest-sample) and Type 3 Stitching (Bounds-selected sub-function recursion) — so Separation / DeviceN tint transforms and shading functions evaluate to real alternate-space colours instead of the v2.333.0 grey fallback. Type 4 PostScript calculators degrade gracefully
  • The page renderer now wires the colour-space unit’s indirect-ref resolver and decoded-stream reader to its document access at construction time, so tint-transform stream objects can be decoded through the same path as image XObjects

Version 2.333.0

Added

  • Render-side CIE-based colour spaces: CalGray, CalRGB (gamma + 3×3 matrix) and Lab (Lab→XYZ→sRGB with the 6/29 breakpoint cube) now resolve to real colours instead of degrading to black; the Bradford-adapted sRGB matrix is cached per white point so per-pixel work stays a single 3×3 multiply
  • Render-side ICCBased colour space resolves through its /Alternate (or an N-based DeviceRGB/Gray/CMYK guess when Alternate is absent), so pages carrying an ICC profile display correctly without an lcms dependency
  • Render-side Separation and DeviceN spot-colour spaces: the alternate space, tint-transform function reference and component count are parsed; the tint transform is wired through a pluggable evaluator so spot-colour pages are distinguishable from “colour not set” (full tint evaluation lands with the function engine)
  • Generic colour operators cs / CS / sc / SC / scn / SCN now handled by the page renderer, the prerequisite for every non-Device colour space to take effect on a loaded page
  • Unified colour resolution through HPDFResolveColor with the extended THPDFColorSpaceFamily and THPDFCIEParams records, replacing the per-space ad-hoc logic

Version 2.332.0

Added

  • RenderSignatureFieldAppearance paints a preset signature-field appearance template — border, light fill and up to four labelled text lines (“Digitally signed by <Name>”, “Reason: ”, “Location: ”, “Date: ”) — selected via a THPDFSignatureDisplayOptions set as a convenience wrapper around AttachSignatureFieldAppearance
  • EnumerateSystemCertificates walks a Windows certificate store (typical MY / ROOT / CA) via dynamically loaded Crypt32.dll and returns subject / issuer display names plus the raw DER for each certificate, the building block for a “pick a certificate / USB Key” signer UI

Security

  • Signature hash algorithm is SHA-256 by default with PAdES Seed Value DigestMethods already accepting SHA-256 / SHA-384 / SHA-512, so no SHA-1 signing path exists

Version 2.331.0

Added

  • RenderLoadedPageToDC draws one page straight into a caller-supplied device context (printer canvas, off-screen surface, custom TCanvas), removing the bitmap round-trip for print and high-DPI workflows
  • RenderLoadedPageToClipboard places a page on the clipboard either as a 24-bit bitmap or as an enhanced metafile (vector text), so paste-into-Word / paste-into-image-editor just works
  • PrintLoadedDocument with a THPDFPrintOptions record drives the VCL TPrinter through a page range, DPI, copies, collation, FitPage scaling and per-page render — the document library now ships its own print path instead of leaving every caller to wire one up

Version 2.330.0

Added

  • GetLoadedPageLabel reads back the /PageLabels /Nums range that covers a given page index, returning the style code, prefix and start number — the read counterpart to SetLoadedPageLabel, so labels a caller did not create itself can now be inspected and round-tripped
  • StitchLoadedPageSideBySideEx performs the side-by-side 2-up stitch with a configurable horizontal gutter and source-page scale factor, where the legacy StitchLoadedPageSideBySide was fixed to half width with no gap

Version 2.329.0

Added

  • AddLoadedRubberStampAnnotation with a THPDFRubberStampIcon enum covering all 14 standard stamp names (Approved, AsIs, Confidential, Departmental, Draft, Experimental, Expired, Final, ForComment, ForPublicRelease, NotApproved, NotForPublicRelease, Sold, TopSecret) so viewers render the familiar bitmaps without a custom appearance stream
  • SetLoadedAnnotationCloudyBorder turns a Square / Circle / Polygon annotation into a cloudy (cloud-burst) border by writing /BE /S /C /I plus the /IC interior colour array
  • SetLoadedLineAnnotationCaps sets the /LE line-end (arrowhead) styles for Line / Polyline annotations from the new THPDFLineEndStyle enum (None / OpenArrow / ClosedArrow / Butt / ROpenArrow / RClosedArrow / Slash / Diamond)

Version 2.328.0

Added

  • EnsureLoadedFieldAppearanceStream generates a /AP /N Form XObject for an existing AcroForm field from its /DA + /V + /Rect, so viewers that ignore /NeedAppearances still render the field value without a round-trip through Acrobat
  • ApplyLoadedFieldValidation attaches a Format / Keystroke / Validate script trio to a field using the Acrobat AF* helpers, covering Number, Percentage, Date, Time, Currency, ZipCode, SSN, Phone and ArbitraryMask input kinds — the caller no longer has to hand-write AFNumber_Format / AFDate_FormatEx / AFRange_Validate JavaScript
  • ApplyLoadedFieldCalculation attaches an AFSimple_Calculate script so a field aggregates the values of a named source field set via Sum / Average / Product / Minimum / Maximum

Version 2.327.0

Added

  • Visual search-and-replace SearchAndRedactReplaceLoaded: for every hit of the needle it masks the match rectangle with a chosen colour (or skips the mask with HPDF_NO_MASK) and stamps the replacement text on top, complementing the byte-level ReplaceLoadedPageText when the original font lacks a reverse char-code table or the replacement needs a different font
  • Region text extraction GetLoadedPageTextInRegion concatenates every glyph whose origin falls inside a user-space rectangle, with newlines between baselines — the building block for “copy text from this box” UI flows
  • Cursor-style SearchLoadedFirst returns the first match as a single THPDFTextMatch, so callers can walk hits without managing a whole match array

Version 2.326.0

Added

  • Document-wide MeasurementUnit property (muPoints / muPixels / muInches / muMM / muCentimeters / muTwips) so every high-level authoring coordinate is converted to PDF points through ToPDFUnit / FromPDFUnit
  • Placeholder substitution in watermark text: <%PageNo%>, <%TotPage%>, <%FileName%>, <%ShortDate%>, <%LongDate%>, <%ShortTime%>, <%LongTime%> are resolved per page when stamping, so “Page X of Y” and dated stamps are one call
  • AddTextWatermarkEx page method that combines placeholder substitution, unit-aware coordinates and a unified THPDFWatermarkBase record (angle, opacity, position presets)
  • Shape-watermark page helpers AddRectangleWatermark, AddEllipseWatermark, AddLineWatermark and AddPolygonWatermark, each wrapping the path primitives in a q/Q graphics-state pair with registered fill/stroke alpha
  • Unified THPDFWatermarkTemplate record with MakeText / MakeRectangle / MakeEllipse / MakeLine / MakePolygon factories plus a THPDFWatermarkTemplateArray composite type
  • Loaded-document watermarking: StampLoadedPageText and StampLoadedPagesText append a transparent, rotated text run to existing pages, honouring the MeasurementUnit and the same placeholder set; StampLoadedPagesComposite applies a whole template array (text + shapes) to a page range
  • Z-order control on loaded-document stamps: Underlay = True prepends the watermark stream before the existing /Contents via the array form, so the watermark renders behind the page content
  • EnumLoadedPageElements returns text runs (glyphs aggregated by baseline + font) and image XObject placements as THPDFPageElement records with bounding boxes
  • SaveLoadedPagesAsImages multi-format export: BMP / JPEG / PNG raster plus EMF / WMF vector, one file per page, with configurable DPI, file-name prefix and JPEG quality
  • GetLoadedPageMetafile vector render of one page to a TMetafile via the new THPDFPageRenderer.ExecuteToDC path, keeping text and vector paths scalable for print, clipboard and merge workflows

Version 2.325.3

Fixed

  • Aggregating batch preflight reports no longer overflows the total-bytes count when a single input file is over 2 GB

Version 2.325.2

Fixed

  • Saving a document over 2 GB with object streams enabled (UseObjectStreams) no longer writes a corrupted cross-reference stream; the object offsets and cross-reference stream position, previously narrowed to a 32-bit integer, are now carried as 64-bit values through the whole write

Version 2.325.1

Fixed

  • Four recovery-only scans used when a damaged PDF cannot be parsed normally — object-stream decompression, object-stream discovery, and two reference-repair passes — no longer read a file over 2 GB into a truncated buffer; each now skips that fallback on such a file instead of scanning corrupted data

Version 2.325.0

Added

  • EMF/WMF import now renders EMR_GRADIENTFILL rectangle gradients (GRADIENT_FILL_RECT_H / GRADIENT_FILL_RECT_V) as PDF Type 2 axial shading patterns, mapping each TRIVERTEX colour pair to an RegisterAxialGradient call and filling the rectangle with the resulting pattern; previously this record was a documented no-op, now Word/Excel/PowerPoint gradient rectangles in EMFs render with the correct left-to-right or top-to-bottom colour blend

Version 2.324.0

Added

  • EMF/WMF import now parses EMR_GDICOMMENT comments, distinguishing Adobe PDF passthrough markers (0x416F4650 = "AoFP", MS-EMF §2.3.3) from other comment types. When the Adobe marker is present the comment payload is scanned for the pdfmark keyword and surfaced via debug logging so users can identify which EMF producers emit PostScript pdfmark fragments; other comment types remain no-ops. Both HotPDF and llPDFLib previously carried only an empty stub for this record

Version 2.323.0

Added

  • EMF/WMF import now explicitly recognises EMR_GRADIENTFILL as a documented no-op (PDF Type 2/3 shading patterns could express gradient fills but viewer rendering is inconsistent and GDI's per-pixel Gouraud interpolation does not map cleanly); previously this record was silently dropped without a case-table entry

Version 2.322.0

Changed

  • PFX-based signing now routes inputs of 64 MB or larger through a streaming chunked signer (HPDFCMSSignPDFStreamChunked) that scans for the /ByteRange + /Contents placeholders in 256 KB rolling reads, digests the two byte-range windows via HPDFCMSSHA256StreamRanges, then copies the input stream to the output stream while patching the placeholder bytes in flight, so peak memory stays bounded by the 256 KB buffer instead of the entire file size; smaller inputs keep the fast in-memory Pos() + Move() path unchanged

Version 2.321.0

Added

  • Optional-content group usage dictionaries: SetOptionalContentGroupUsage attaches a /Usage entry to a registered OCG (PDF 1.7 §8.11.4.4 Table 100) so viewers auto-show/hide layers by context. Categories View / Print / Export write <Category>State = ON/OFF; Zoom writes a real-pair Min; Language / Creator write string values
  • Outline subtree copy: THPDFDocOutlineObject.CopySubtree deep-clones the entire child subtree of a node under a new parent, propagating Title / Color / Bold / Italic / Opened while minting fresh object numbers and new destinations
  • Outline topology helpers IsDescendant (cycle-safe predicate used by MoveTo) and MoveTo (re-parent a node, detaching from its old sibling chain and re-attaching as the last child of the new parent, with full /Prev / /Next / /First / /Last / /Count maintenance on every affected ancestor)

Version 2.320.0

Added

  • Nested optional-content /Order tree: BeginOptionalContentOrderGroup / AddLayerToOptionalContentOrder / EndOptionalContentOrderGroup build a labelled, arbitrarily nested presentation tree (PDF 1.7 §8.11.4.3 /Order) so the layers panel can show hierarchical groupings like "Background [Lines Fills Images]" instead of the historical flat list. When none of the new helpers are called the previous flat /Order mirroring /OCGs is preserved byte-for-byte

Version 2.319.1

Fixed

  • Loading a PDF whose embedded JBIG2 image uses the standard Huffman coding option (rather than the more common MQ arithmetic coding) no longer fails outright: the loader now retries with the alternate decoding engine before giving up, so such images load successfully regardless of which decoding engine is preferred

Version 2.319.0

Changed

  • EMF/WMF import now applies a centralised InPath gate at the ExecuteRecord entry: while a path bracket is open (BeginPath seen, EndPath/AbortPath not yet reached) only path-construction records (line/curve/polygon/move/close/end/abort plus the coordinate-system and DC-state records) reach their handlers; text and bitmap records that previously leaked into the open path are now dropped centrally, mirroring llPDFLib's entry-point guard and eliminating a class of malformed-PDF bugs from stray records inside a path bracket

Version 2.318.0

Added

  • Optional-content radio-button groups: new RegisterOptionalContentRadioGroup declares mutually exclusive layer sets whose members turn each other off (PDF 1.7 §8.11.4.3 /RBGroups); typical use is single-choice layer panels like "Draft / Review / Final"

Version 2.317.0

Added

  • THPDFDocOutlineObject.InsertBefore / InsertAfter splice a new sibling into the existing outline doubly-linked list at an arbitrary position, complementing the existing AddChild (append) and AddChildFirst (prepend) helpers so outline trees can be built in any order without detaching and re-attaching nodes
  • EMF/WMF import now explicitly recognises the ICM/palette family (EMR_SETBRUSHORGEX, EMR_SELECTPALETTE, EMR_SETCOLORADJUSTMENT, EMR_SETICMMODE, EMR_CREATECOLORSPACE, EMR_SETCOLORSPACE, EMR_DELETECOLORSPACE, EMR_GDICOMMENT) and the no-PDF-mapping family (EMR_FRAMERGN, EMR_INVERTRGN, EMR_PAINTRGN, EMR_FLATTENPATH, EMR_WIDENPATH, EMR_SETMETARGN, EMR_OFFSETCLIPRGN, EMR_PLGBLT, EMR_POLYTEXTOUTA, EMR_POLYTEXTOUTW), forwarding to the GDI reference DC where applicable without emitting to the PDF content stream; previously these records were silently dropped, now they are documented and kept consistent with the GDI side

Version 2.316.0

Added

  • New JBIG2Benchmark demo generates four PDFs from the same three-page synthetic scan, one per THPDFJBIG2Options configuration (per-image lossless, per-image LossyLevel=5, cross-page accumulated globals, rectangle symbol extraction), printing each output size so the trade-offs between the v2.310.0 scan-friendly defaults, the v2.314.0 cross-page accumulator, and the extraction modes can be compared directly

Version 2.315.0

Changed

  • The cross-page accumulated JBIG2 dictionary now auto-batches: once the running glyph-width total crosses 131071 pixels the current dictionary is frozen, emitted as one /JBIG2Globals stream, and the accumulator is reset, so the next batch starts a fresh globals stream. Mirrors llPDFLib's TotalWidth-based spilling and keeps individual globals streams at a size readers handle efficiently on very large scan runs

Version 2.314.0

Added

  • Cross-page accumulated JBIG2 symbol dictionary: opt in with THPDFJBIG2Options.AccumulateGlobalsAcrossPages := True (alongside the existing UseSymbolDictionary + UseGlobalSegments + native fallback switches) and consecutive 1-bit icJBIG2 images share one growing in-memory symbol dictionary and one /JBIG2Globals indirect stream, instead of each image emitting its own dictionary. New THPDFJBIG2SymbolDictionary holds the persistent glyph set with the same lossy / lossless matching the per-image encoder uses; new smoke_jbig2_accum_decode verifies two pages of different glyph layouts share a single globals object reference and decode back to the source pixels bit-for-bit

Version 2.313.0

Added

  • JBIG2 global-segment streams produced by the native symbol-dictionary encoder are now content-addressed at the document level via THPDFJBIG2GlobalsPool, so images that yield byte-identical globals share one /JBIG2Globals indirect stream instead of each emitting their own; new smoke_jbig2_globals_multi smoke covers three pages of identical glyphs collapsing onto a single shared globals stream

Version 2.312.0

Added

  • EMF/WMF import now covers EMR_SCALEVIEWPORTEXTEX, EMR_SCALEWINDOWEXTEX, EMR_EXCLUDECLIPRECT, EMR_CREATEDIBPATTERNBRUSHPT, EMR_SETMITERLIMIT, EMR_SETTEXTJUSTIFICATION, and EMR_SETROP2, closing the seven-record gap with llPDFLib so EMF streams emitted by older GDI toolchains no longer silently drop those records; SETMITERLIMIT and SETROP2 take effect immediately, while the others store state for a later render-side hookup without perturbing current coordinate or clip output

Version 2.311.0

Added

  • HPDFCMSSHA256StreamRanges now digests the two PDF /ByteRange windows straight from a TStream in 256 KB chunks, so multi-GB signed PDFs can be hashed without first copying the whole file into an AnsiString; closes the gap with llPDFLib's stream-based CalcHash, which the existing in-memory HPDFCMSSHA256ByteRanges could not match for very large inputs

Version 2.310.0

Changed

  • THPDFJBIG2Options now defaults to scan-friendly settings (LossyLevel = 5, RemoveIsolatedBlackPixels = True, BlackDotSize = 3) so 1-bit scanned images compress much smaller out of the box; set LossyLevel = 0 or Lossless = True to restore strict lossless matching

Performance

  • xref table growth is now geometric (small documents +N, larger documents +25%) instead of reallocating the dynamic array on every indirect object, removing the O(n²) cost that dominated loading and building large PDFs with many objects

Version 2.309.4

Added

  • Added THPDFDocOutlineObject.AddChildFirst so generated outline nodes can prepend a child item before existing siblings while preserving the saved outline order

Version 2.309.3

Added

  • Added pmUseOC to THPDFPageMode so generated documents can request the optional-content layers panel with catalog /PageMode /UseOC

Version 2.309.2

Added

  • Added title-string overloads for THPDFPage.AddTextAnnotation so generated text annotations can write the PDF /T title or author entry while preserving the existing icon, color, and open-state arguments

Version 2.309.1

Fixed

  • Clearing THotPDF.OutputStream by assigning nil now restores normal FileName output instead of leaving the document in stream-output mode

Version 2.309.0

Fixed

  • EMF/WMF import now honors EMR_EXTSELECTCLIPRGN region modes for copy, intersect, and exclude clipping while keeping EMR_SETWORLDTRANSFORM, EMR_MODIFYWORLDTRANSFORM, and EMR_SETPIXELV covered by non-GUI regression tests

Version 2.308.0

Added

  • FastReport add-on design-time registration now ships as frxHotPDFDesign, placing TfrxHotPDFExport on the FastReport VCL palette while keeping the existing runtime unit and Register entry point available for compatibility

Version 2.307.0

Added

  • SignPDFWithPFX now parses legacy PKCS#12 PBE-SHA1-3DES encrypted PFX files in addition to PBES2 AES-256-CBC profiles

Version 2.306.0

Changed

  • Repeated calls that add the same encoded image now reuse the existing PDF image XObject while preserving distinct output for different JPEG quality settings and mask relationships

Version 2.305.0

Added

  • TfrxHotPDFExport.PageRange now lets FastReport exports opt in to one-based page filtering such as 1,3-5 while reusing HotPDF's shared page-range parser

Version 2.304.0

Fixed

  • XFA-to-AcroForm table flattening now lets all-growable single auto columns inherit the table content width, so fields without their own w still receive a measurable width and preserve row spacing

Version 2.303.0

Fixed

  • XFA-to-AcroForm table flattening now lets growable text cells inherit fixed columnWidths values when they omit their own w, so row heights are measured and following rows stay separated

Version 2.302.0

Fixed

  • XFA-to-AcroForm flattening now measures growable text fields inside nested layout="tb" and wrapped layout="lr-tb" flows, and table rows now keep growable text-cell height when positioning following fields

Version 2.301.0

Fixed

  • XFA-to-AcroForm flattening now keeps text fields in layout="tb" and layout="lr-tb" flow containers when they omit an explicit h height, measuring their wrapped content height instead of skipping them as unsupported growable layout

Version 2.300.0

Fixed

  • THotPDF.ExtractObjectFromStream now returns the parsed dictionary for materialized object-stream members and no longer fabricates raw-data diagnostic keys when callers inspect loaded PDF 1.5+ object streams

Version 2.299.0

Added

  • THotPDF.DecompressAllObjectStreams is now public and forces loaded PDFs that used object streams to save with compact objects materialized as normal indirect objects instead of copying the source object-stream layout

Version 2.298.0

Fixed

  • AcroForm field creation now rejects duplicate root field names for both new documents and loaded-document editing while preserving the valid shared-parent workflow for radio button groups

Version 2.297.0

Added

  • TDBGridHotPDFExportOptions and the TDBGridHotPDFExport component now expose PDFACompliance and PDFXCompliance so DBGrid table exports can opt in to the same HotPDF standards-conformance gates used by direct document generation

Version 2.296.0

Added

  • TQRHotPDFExportFilter and TdxHotPDFExportOptions now expose PDFACompliance and PDFXCompliance so QuickReport and DevExpress exports can opt in to the same HotPDF standards-conformance gates used by direct document generation

Version 2.295.0

Added

  • TfrxHotPDFExport and TppHotPDFDevice now expose PDFACompliance and PDFXCompliance so report exports can opt in to the same HotPDF standards-conformance gates used by direct document generation

Version 2.294.0

Added

  • Form XObject and tiling pattern canvas builders now let callers compose reusable resources through typed drawing helpers before registering them for page reuse
  • THPDFExtGStateOptions now lets one ExtGState combine transparency, blend mode, line width, line cap, line join, and miter limit settings

Version 2.293.0

Added

  • Native JBIG2 encoding now supports symbol-dictionary compression with optional shared global dictionaries, rectangle and image-only extraction modes, lossy pixel-difference guards, and PDF/A fallback to CCITT where JBIG2 is not permitted
  • EMF/WMF rendering now handles TransparentBlt and MaskBlt bitmap records through PDF image mask and transparency paths
  • FastReport and ReportBuilder native export modes now cover more object-level output, including styled memo/rich text, barcode, picture, vector shape, line, clipping, frame, dash, and URL annotation paths
  • The HugeFileBenchmark demos now report working-set and peak-working-set metrics, support an opt-in memory limit, and keep generated work files separate from report output
  • The Delphi PDFOptimize demo now documents producer-side compression choices for content streams, object streams, JPEG quality, CCITT, and JBIG2 output

Fixed

  • Demo coverage checks now include English-baseline demo READMEs, map consolidated C++Builder samples to their actual files, and keep GUI demos disabled by default in routine test runs

Version 2.292.32

Added

  • EMF/WMF hatch brushes now map to PDF tiling patterns so imported CAD drawings and reports can preserve hatch texture instead of flattening those fills to solid color

Fixed

  • Loaded-document dictionary edits now mark objects dirty so SaveLoadedDocument rewrites changed PDFs instead of copying the original source after outline and object-tree edits
  • Loaded outline removal now relinks sibling bookmarks, and non-rotated underline and strikeout text decorations now emit filled rectangle operators

Version 2.292.31

Added

  • THPDFEmfOptions.ShowNullBrush now lets EMF/WMF rendering expose null-brush fills for diagnostic and CAD-style import workflows while preserving unfilled null brushes by default

Version 2.292.30

Added

  • THPDFEmfOptions.CanvasOver now lets page Canvas replay place existing PDF content above the parsed Canvas metafile while the default keeps the current Canvas-on-top order

Version 2.292.29

Added

  • THPDFEmfOptions.Redraw now lets EMF/WMF callers keep the default temporary redraw path or opt out and parse the original metafile directly

Version 2.292.28

Added

  • THPDFEmfOptions.UseFrame now lets EMF/WMF rendering clip imported output to the EMF header frame for metafiles that rely on declared frame bounds

Version 2.292.27

Added

  • THPDFEmfOptions.ShowNullPen now lets EMF/WMF rendering expose null-pen outlines for diagnostic and CAD-style import workflows while preserving invisible null pens by default

Version 2.292.26

Added

  • THotPDF.SetFormFieldTooltip now lets applications assign AcroForm /TU field hints by field name for widgets created through the existing Add... field methods

Version 2.292.25

Fixed

  • TfrxHotPDFExport native-object mode now preserves TfrxPictureView clipping and frame rendering when picture views are written directly as HotPDF image XObjects

Version 2.292.24

Added

  • TfrxHotPDFExport native-object mode now maps supported horizontal one-dimensional FastReport barcode views directly to HotPDF barcode operators, while keeping human-readable text, checksum generation, supplemental text, rotation, colored bars, and unsupported symbologies on the existing fallback path

Version 2.292.23

Added

  • TppHotPDFDevice native draw-command mode now maps supported one-dimensional ReportBuilder barcode draw commands directly to HotPDF barcode operators, while preserving the enhanced-metafile fallback for commands that need human-readable text, add-on codes, check-digit calculation, colored bars, rotation, or unsupported postal symbologies

Version 2.292.22

Fixed

  • Automatic PDF viewer launch can now be suppressed in non-interactive runs with HOTPDF_SUPPRESS_AUTO_LAUNCH=1, and the bundled test and smoke runners enable that guard by default so non-GUI regression runs do not open viewer windows

Version 2.292.21

Added

  • THPDFPage.ShowMetafileEx now has a per-call THPDFEmfOptions overload, letting callers override EMF/WMF rendering settings for one metafile draw while preserving document-level defaults

Version 2.292.20

Added

  • TfrxHotPDFExport now exposes HotPDF output controls for FastReport exports, including AutoCreateURL, FontEmbedding, NotEmbeddedFonts, ActivateProtection, UserPassword, OwnerPassword, CryptKeyLength, ProtectOptions, and EncryptMetadata

Version 2.292.19

Added

  • Added a dedicated dbGridHotPDFDesign add-on unit so design-time packages can register TDBGridHotPDFExport on the HotPDF IDE palette while keeping the DBGrid runtime export adapter usable without design-time package references

Version 2.292.18

Changed

  • HPDFParsePFX now supports PBES2/PBKDF2 profiles that use the default HMAC-SHA-1 PRF as well as explicit HMAC-SHA-256, improving compatibility with older AES-256-CBC PKCS#12 exports while keeping unsupported PBE-SHA1-3DES profiles rejected with a diagnostic

Version 2.292.17

Added

  • Added THPDFTextOutBoxResult plus THPDFPage.TextOutBoxEx and THPDFPage.WideTextOutBoxEx so wrapped text-box output can report the number of written characters, written rows, and whether the source text overflowed the box while the legacy methods keep returning the written-character count

Version 2.292.16

Added

  • Added THPDFPage.TextFromBaseLine(Boolean) for switching page text output between top-edge and baseline Y-coordinate semantics, plus THPDFPage.AppendScopedRawContent for wrapping expert raw content operators in an automatic graphics-state save and restore pair

Version 2.292.15

Changed

  • TfrxHotPDFExport native-object mode now preserves clipped memo text and FastReport character spacing when mapping prepared memo views directly to HotPDF page text operations

Version 2.292.14

Added

  • TppHotPDFDevice now exposes an opt-in RenderMode for ReportBuilder native draw-command export, mapping common text, shape, line, image, and URI hyperlink commands directly to HotPDF page operations while automatically falling back to the existing enhanced-metafile bridge for pages containing unsupported commands

Version 2.292.13

Added

  • Added THotPDF.EncryptMetadata for standard AES password encryption so callers can write /EncryptMetadata false, keep XMP /Metadata streams cleartext, and emit the matching AES-128 key derivation or AES-256 /Perms metadata flag instead of relying on the previous always-on metadata encryption behavior

Version 2.292.12

Added

  • Added creation-time AcroForm field wrappers through THPDFAcroFormField and THPDFPage.CreateTextField, CreateCheckBox, CreateRadioButton, CreateComboBox, and CreateListBox, enabling chainable tooltip, common flag, default appearance, and field or widget additional-action setup immediately after field creation

Version 2.292.11

Added

  • Added high-level image mask, transparency, per-image JPEG quality, and automatic monochrome compression helpers: AddImageAsMask, AddImageWithMask, AddImageWithTransparency, AddImageWithTransparency32, AddImageWithJpegQuality, AddMonochromeImageAuto, and the opt-in icAutoMono compression selector

Version 2.292.10

Added

  • Added AcroForm field additional-action convenience helpers for THPDFActionBuilder chains, including named wrappers for /AA /K, /AA /F, /AA /V, /AA /C, widget mouse and focus triggers, and matching clear helpers for field and annotation trigger entries

Version 2.292.9

Added

  • Added document lifecycle additional action helpers for THPDFActionBuilder chains: SetDocumentCloseAction, SetDocumentWillSaveAction, SetDocumentDidSaveAction, SetDocumentWillPrintAction, SetDocumentDidPrintAction, and matching clear methods that write catalog /AA /WC, /AA /WS, /AA /DS, /AA /WP, and /AA /DP entries

Version 2.292.8

Added

  • Added generated-page additional action support with THPDFPageActionTrigger, current-page helpers for SetPageAdditionalAction, SetPageOpenAction, SetPageCloseAction, and matching clear methods, plus THotPDF page-indexed helpers that write page /AA /O and /AA /C actions from reusable THPDFActionBuilder chains without changing the active drawing page

Version 2.292.7

Added

  • Added generated-document page label writing and article thread beads through THPDFPageLabelStyle, THotPDF.SetPageLabel, the five style-specific page-label helpers, THotPDF.ClearPageLabels, THotPDF.RegisterArticleThread, and THPDFPage.AddArticleBead

Version 2.292.6

Added

  • THPDFActionBuilder now builds advanced action dictionaries for Thread, Sound, Movie, Rendition, SetOCGState layer visibility, Trans page transitions, and GoTo3DView, with ShowLayer, HideLayer, and ToggleLayer helpers plus PDF/A/PDF/X restrictions

Version 2.292.5

Added

  • THPDFPage.SetAnnotationAdditionalAction and THotPDF.SetFormFieldAdditionalAction now attach reusable THPDFActionBuilder chains to annotation and AcroForm /AA trigger dictionaries while replacing only the selected trigger and preserving PDF/A/PDF/X action restrictions

Version 2.292.4

Added

  • THPDFNamesFacade now adds JavaScript function wrappers and array snapshots for loaded JavaScript and named destinations, THPDFActionBuilder now builds field-scoped submit/reset actions and remote page targets, and the FastReport adapter's native-object mode preserves memo backgrounds, text alignment, and frame styles

Version 2.292.3

Added

  • THPDFActionBuilder now supports remote named destinations and Launch actions, and the FastReport adapter's native-object mode maps view URLs to HotPDF URI link annotations

Version 2.292.2

Added

  • THPDFActionBuilder now supports direct page-targeted GoToPage actions, EMF/WMF file-name helpers accept per-call THPDFEmfOptions, and the FastReport adapter's native-object mode maps picture views directly to HotPDF image XObjects

Version 2.292.1

Added

  • EMF/WMF rendering now supports per-call THPDFEmfOptions overrides through the ShowEnhancedMetafile, EnhancedShowMetafile, and enhanced ShowMetafile overloads, so a single metafile can choose compression, scale, reference DC, stretch mode, and extended-pen behaviour without mutating the document-wide THotPDF.EmfOptions

Version 2.274.1

Fixed

  • Type3 glyph procedures declared with d1 now ignore colour-selection operators inside the procedure and always paint with the text's current fill colour, as the PDF specification requires; glyphs declared with d0 keep their own colours
  • The suppression applies only within the glyph replay (including nested form objects) and never affects colours selected by the surrounding page content

Version 2.274.0

Added

  • Type3 glyph procedures that declare a d1 bounding box are now clipped to it during page rendering, so malformed or oversized glyph procedures can no longer paint outside their declared bounds
  • Glyphs using the d0 form keep their unrestricted behaviour, and degenerate (empty or inverted) boxes are ignored rather than blanking the glyph

Version 2.273.0

Added

  • Page rendering now resolves simple-font /Encoding dictionaries: /Differences arrays remap character codes to named glyphs, taking priority over the font program's own character map as the PDF specification requires — documents produced by TeX and PostScript-derived toolchains, which rely heavily on /Differences, now render the intended glyphs
  • Glyph names resolve through the Adobe Glyph List (including uniXXXX forms and gNN/glyphNN subset names), through a compact font program's charset, or through a TrueType program's character map, whichever the embedded font supports
  • The predefined StandardEncoding, WinAnsiEncoding and MacRomanEncoding base encodings are honoured for codes without a /Differences override, correcting the 0x80–0x9F range that a plain Latin-1 assumption mishandles
  • Compact (Type1C) programs that rely solely on a predefined encoding — previously falling back to a system font for the whole run — now render their embedded outlines through the standard-name lookup

Version 2.272.0

Added

  • Embedded-glyph page rendering now covers simple (non-CID) Type1 fonts with a compact FontFile3 Type1C program: one-byte character codes resolve through the font program's built-in encoding to real Type 2 charstring outlines, completing embedded-outline coverage across CID and simple font flavours
  • Simple TrueType fonts additionally accept a FontFile3 OpenType program (CFF-flavoured) when no FontFile2 is present
  • Character codes the built-in encoding cannot map keep the per-glyph system-font fallback, and fonts relying solely on the predefined Standard/Expert encodings continue to use the previous whole-run fallback

Version 2.271.0

Added

  • Page rendering now supports Type3 fonts: each glyph's content-stream procedure is replayed through the renderer with the font matrix, font size, text matrix and current transformation composed, so stamps, bar-code fonts and other procedure-drawn glyphs appear in rendered output instead of being skipped
  • The /Encoding /Differences map binds character codes to glyph procedures, and glyph-space /Widths are interpreted through the /FontMatrix, keeping advances correct for non-standard glyph coordinate systems
  • Glyph procedures may reference the font's own /Resources dictionary (falling back to the page's resources) and are protected by the same recursion guard as Form XObjects

Version 2.270.0

Added

  • Embedded-glyph page rendering now covers simple (non-CID) TrueType fonts: one-byte character codes map to glyphs through the embedded font program's own cmap table, so pages using ordinary embedded TrueType fonts render with their exact glyph shapes instead of a similarly named system font
  • The cmap lookup follows a robust subtable chain — Unicode (format 4 and format 12) first, then symbol-encoded subtables with the F000 private-use mirror, then legacy Macintosh subtables (formats 0 and 6) — matching the fallback behaviour of the authoring pipeline
  • Character codes the embedded cmap cannot map fall back to the previous system-font drawing per glyph, so mixed or partially subset fonts degrade gracefully instead of dropping text

Version 2.269.0

Added

  • Embedded-glyph page rendering now covers CFF font programs: text in Type0/CIDFontType0 fonts with a FontFile3 program (CIDFontType0C, Type1C, or an OpenType wrapper) renders from the real Type 2 charstring outlines instead of substituting a similarly named system font
  • The charstring interpreter supports the full drawing operator set — lines, curves, the flex family, hint masks, and local/global subroutine calls with subroutine bias — so professionally produced CFF fonts reproduce their exact glyph shapes
  • CID-keyed CFF programs map character codes through the font's charset, keeping glyph selection correct for subset fonts whose glyph order differs from the CID order; per-glyph font-DICT selection (FDArray/FDSelect) is honoured
  • TrueType (FontFile2) and CFF (FontFile3) embedded programs now share one rendering pipeline; fonts without a usable embedded program keep the previous system-font fallback

Version 2.268.0

Added

  • Embedded-glyph page rendering: text in Type0/CIDFontType2 fonts with an embedded TrueType program (FontFile2) now renders from the font's real glyph outlines — quadratic contours, implied on-curve points, and composite glyphs are replayed as filled vector paths — instead of substituting a similarly named system font
  • Both Identity and explicit stream CIDToGIDMap layouts are supported, covering subset-embedded fonts; documents produced by HotPDF's own Unicode pipeline now round-trip through RenderLoadedPageToBitmap with the exact embedded glyph shapes
  • CID advances now honour the /W and /DW width entries and two-byte Identity-H codes step correctly, fixing text positioning for CID-keyed fonts in rendered output
  • Fonts without a usable embedded program (CFF-flavoured FontFile3, mapping failures) keep the previous system-font fallback

Version 2.267.0

Added

  • Decoded-image cache for page rendering: image XObjects repeated across pages (logos, letterheads, watermark images) now decode once per document load instead of once per draw, roughly halving render time for shared-image pages and speeding up multi-page TIFF export accordingly
  • The cache is bounded by ImageCacheMaxBytes (default 32 MB) with least-recently-used eviction, is cleared automatically when a document loads, and empties together with InvalidateRenderedPageCache after in-place edits
  • New reusable THPDFWeightedCache (unit HPDFCache): a byte-budgeted most-recently-used cache with hit/miss statistics and a SHA-256 content-hash key helper, available to host applications for caching their own expensive intermediates

Version 2.266.0

Added

  • Symbol and legacy font support in RegisterUnicodeTTF: fonts that carry only a symbol character map (Wingdings, Webdings, and similar (3,0)-cmap faces) now register with a working codepoint map instead of resolving every character to .notdef
  • Symbol codepoints are reachable both through their native U+F0xx range and through plain ASCII ('A' reaches the same glyph as U+F041), matching how viewers treat symbol-encoded text
  • Legacy fonts whose character map offers only a format 6 (trimmed table) or format 0 (byte table) subtable now fall back to those, so old Mac-heritage fonts embed correctly; the primary Unicode format 4 / format 12 paths are unchanged

Version 2.265.0

Added

  • Rendered-page cache: RenderLoadedPageToBitmapCached keeps recently rendered pages keyed by page and DPI, so re-rendering the same page (page previews, thumbnails, repeated exports) returns in microseconds instead of re-interpreting the content stream — cache hits are typically thousands of times faster
  • The cache holds up to RenderCacheCapacity pages (default 8) in most-recently-used order and returns an independent caller-owned bitmap on every call; loading a new document clears it automatically, and InvalidateRenderedPageCache clears it after in-place page edits

Version 2.264.0

Added

  • Rich-text output: THPDFPage.TextOutHTML renders a string marked up with an HTML subset — <b>, <i>, <u>, <s>, <br>, and <font size color face> with nesting — so styled paragraphs no longer require a separate SetFont/TextOut call per style change
  • Mixed font sizes on one line share a common baseline (the line's largest font sets it), and each line's leading follows its largest font, giving typographically correct output for headings mixed with body text
  • Colors accept #RRGGBB and the 16 standard HTML color names; the entities &amp; &lt; &gt; &quot; &nbsp; and numeric &#N; (including supplementary-plane code points) are decoded
  • The call returns the Y coordinate at which a following line would continue, so consecutive TextOutHTML blocks stack naturally

Version 2.263.0

Added

  • Layout-preserving text extraction: ExtractLoadedPageTextLayout reconstructs the visual arrangement of a page as plain text — glyphs are clustered into baselines and horizontal / vertical whitespace is reproduced on a character grid, so columns, indentation, and table alignment survive in the output
  • Wide gaps between text runs on the same baseline become space runs, and large baseline gaps become blank lines, making the result suitable for diffing, grepping, and feeding into text-analysis pipelines that rely on positional alignment
  • The existing ExtractLoadedPageText reading-flow extraction is unchanged; choose it when only the text content matters and the new call when the layout matters

Version 2.262.0

Added

  • Whole-tree bookmark search: FindLoadedOutlineByTitle walks the entire outline hierarchy of a loaded document (all nesting levels, not just top-level chapters) and resolves the matching bookmark's destination page, with optional partial and case-sensitive matching
  • Both direct /Dest destinations and GoTo action targets are resolved to a page index, so a found bookmark can be jumped to immediately
  • GetLoadedOutlineTitlesDeep enumerates every bookmark title in the tree in depth-first (reading) order, complementing the existing top-level-only enumeration

Version 2.261.0

Added

  • Batch attachment extraction: SaveAllLoadedEmbeddedFiles writes every embedded file of a loaded document into a target directory in one call, creating the directory when missing and returning the number of files written
  • Attachment names are sanitised before use — path separators and characters the file system rejects become underscores, so a document cannot write outside the chosen directory — and duplicate names automatically receive a _CopyN suffix before the extension

Version 2.260.0

Added

  • Multi-page TIFF export for loaded documents: SaveLoadedPagesToTiff renders the selected pages and writes them into a single TIFF 6.0 file with one image per page — the interchange format expected by document archival, scanning, and fax pipelines
  • Pages are selected with the familiar one-based range syntax ("1,3-5,7-"; empty selects every page), rendered at a caller-chosen DPI, and stored as 24-bit RGB with optional Deflate compression (on by default; pass False for uncompressed output)
  • SaveLoadedPagesToTiffStream writes the same multi-page TIFF to any TStream; both calls return the number of pages actually written

Version 2.259.0

Added

  • Digital signature verification for loaded documents: VerifyLoadedSignature re-computes the /ByteRange digest and cryptographically checks the RSA signature against the certificate embedded in the signature, reporting a precise verdict (valid, document modified after signing, signature invalid, unsupported algorithm, or malformed container)
  • GetLoadedSignatureInfo returns the signer name, subject and issuer distinguished names, certificate serial number and validity period, signing time, hash algorithm, subfilter, and /Reason//Location//ContactInfo for each signature field without touching document bytes
  • VerifyLoadedSignatureEx combines both: one call verifies and returns the populated info record, including whether the signature covers the whole document; VerifyAllLoadedSignatures checks every signature field at once
  • Supported algorithms: RSA (PKCS#1 v1.5) with SHA-1, SHA-256, SHA-384, or SHA-512 digests, covering adbe.pkcs7.detached and ETSI.CAdES.detached signatures with or without signed attributes
  • A TStream overload verifies documents loaded from streams; certificate chain and trust validation remain the caller's responsibility

Version 2.258.0

Added

  • The high-performance external JBIG2 decoder is now available in 32-bit (Win32) builds; previously it was 64-bit only. Loading PDF files with /JBIG2Decode images and ExtractLoadedImage use it by default on both platforms, decoding typically 3–9× faster than the native Pascal decoder
  • The UseExternalJBIG2Decoder switch behaves the same on 32-bit as on 64-bit: set it to False to select the native Pascal decoder

Version 2.257.1

Fixed

  • Restored the high-performance JBIG2 encoder backend in 64-bit (Win64) builds: a platform-check regression introduced while wiring up the 32-bit backend compiled the external encoder out of Win64 builds, so AddImage with icJBIG2 compression silently fell back to the native Pascal MMR encoder. Win64 now encodes through the arithmetic backend again, typically 4–8× faster with equal or better compression; THPDFJBIG2Options.UseExternalEncoder := False remains the explicit way to select the MMR fallback

Version 2.257.0

Added

  • The high-performance JBIG2 encoder backend is now available in 32-bit (Win32) builds; previously it was 64-bit only. AddImage with icJBIG2 compression uses it by default on both platforms, producing identical standards-compliant arithmetic-coded JBIG2 streams 4–7× faster than the native Pascal fallback
  • The THPDFJBIG2Options.UseExternalEncoder switch behaves the same on 32-bit as on 64-bit: set it to False to fall back to the native Pascal MMR encoder

Fixed

  • Resolved a series of 32-bit-only crashes (access violations) in the statically linked encoder support layer that made the JBIG2 encoder backend unusable in Win32 builds; encode output is verified byte-identical to the 64-bit backend and round-trips losslessly through both the bundled and the native JBIG2 decoders

Version 2.256.0

Added

  • Extended XFDF annotation support to the remaining four ISO 19444-1 Table 1 subtypes, completing full coverage of all 18 XFDF annotation elements: <fileattachment> (decodes the base64 <data> into an embedded-file stream + Filespec on import, re-encodes on export), <sound> (embedded /Sound stream with /R /B /C /E audio params), <redact> (a standard /Redact annotation with /OverlayText, /DA, /Q and /IC — distinct from the existing content-stream RedactLoadedRect mask), and <link> (<OnActivation><Action> mapped to a URI or Named action dict, with <Dest> named destinations)
  • Added a self-contained base64 codec (HPDFXFDFEncodeBase64 / HPDFXFDFDecodeBase64) so the XFDF layer does not depend on HPDFXFA; the library previously shipped only a decoder
  • Extended THPDFXFDFAccess with embedded-stream callbacks (ResolveStream / NewIndirectStream / ReadStreamBytes) wired to THotPDF.ResolveLoadedStream / NewIndirectStream / HPDFReadStreamBytes
  • Added 3 DUnitX cases to HotPDF.XFDFTests (base64 round-trip, Redact with OverlayText, Link with URI action) — full suite now 310/310 on Win32 and Win64

Version 2.255.0

Added

  • Added XFDF (ISO 19444-1) import/export: THotPDF.ExportLoadedFormToXFDF / ImportLoadedFormFromXFDF round-trip AcroForm field values through the XML Forms Data Format (the XML counterpart of FDF), covering simple and layered (dotted-name) fields, multi-select lists (multiple <value> siblings), checkbox / radio export values, and signature fields (name only, no <value> per §6.3.3.1). The output is a UTF-8 <xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"> document with the Adobe namespace as required by §5.5.2
  • Added THotPDF.ExportLoadedAnnotationsToXFDF / ImportLoadedAnnotationsFromXFDF for the 14 ISO 19444-1 Table 1 annotation subtypes HotPDF already creates (text / freetext / line / square / circle / polygon / polyline / highlight / underline / strikeout / squiggly / stamp / ink / caret), carrying the common attributes (page, rect, color, flags, name, date, title, contents, subject, creationdate, opacity, intent), type-specific geometry (QuadPoints for markup, Vertices for polygon/polyline, L for line, InkList for ink), the icon for text/stamp, and popup children. FileAttachment / Sound / Redact / Link-action subtypes are deferred to a later round
  • Added Lib/HPDFXFDFXml.pas: a self-contained lightweight XML engine (no MSXML / OmniXML dependency, builds on Delphi 5 .. RAD Studio) providing a minimal DOM (THPDFXFDFNode), a tolerant parser (BOM, comments, CDATA, processing instructions, attribute order, self-closing, UTF-8 multibyte), and a UTF-8 writer applying the ISO 19444-1 §5.8.2 escape convention (entities for & < > ", character refs for LF/CR/TAB, octal literals for other control bytes)
  • Added Lib/HPDFXFDF.pas: the XFDF business layer, decoupled from HPDFDoc via a record of function pointers (THPDFXFDFAccess) bound by HPDFDoc's implementation section (same pattern as HPDFTextExtraction). Ships colour #RRGGBB ↔ DeviceRGB and flag-name ↔ integer bit-set helpers
  • Added HotPDF.XFDFTests (8 DUnitX cases) covering the XML engine (escape round-trip, parse tolerance, nested fields, UTF-8), field export/import over a mock access record, and annotation export/import over a mock built from real THPDFDictionaryObject instances — all pass on Win32 and Win64

Version 2.254.0

Added

  • Added read-side structured invoice extraction: HPDFFacturXXMLElementText performs a word-boundary-aware substring scan for any CII/UBL element (no XML DOM, works on every supported Delphi), HPDFFacturXInvoiceSummaryFromXML and THotPDF.GetLoadedInvoiceSummary return a THPDFFacturXInvoiceSummary record with the common BT-1/2/5/27/44/106/110/112/115 fields (invoice number, issue date, currency, seller/buyer names, line/tax/grand totals), with the buyer name refined by locating the BuyerTradeParty aggregate rather than only the first ram:Name
  • Added PDF/A-3 structural-regression scan as THotPDF.GetLoadedPDFAIssues, deliberately separate from ValidateFacturXInvoice so the Factur-X container verdict stays stable (a hybrid invoice with a missing OutputIntent is still a valid container, just not a conformant PDF/A-3 file); mirrors the ISO 19005-3 assertions veraPDF raises for un-embedded fonts (fxviFontsNotEmbedded), missing OutputIntent (fxviMissingOutputIntent) and forbidden encryption (fxviEncryptedDocument), all new members of the THPDFFacturXValidationIssue enum
  • Added embedded-attachment classification via THotPDF.GetLoadedFacturXAttachments: enumerates every embedded file and classifies it under the Factur-X 1.09 spec 6.4 taxonomy (primary CII invoice, UBL or EDIFACT supplementary representation, supporting document) using the new THPDFFacturXAttachmentRole enum, so receivers can route attachments without re-deriving the role from file names
  • Added EDIFACT supplementary attachment support symmetric to UBL: THotPDF.AddEDIFACTSupplementaryFile embeds an EDIFACT message as factur-xedifact.edi (MIME text/plain, relationship Alternative), HPDFIsFacturXEDIFACTFileName recognises the file name, and DetectFacturXInvoice records it in a new THPDFFacturXInvoiceInfo.EDIFACTFileName field
  • Added PDF/A-4 / PDF/A-4f support (ISO 19005-4, Factur-X 1.09 spec footnote 2): PDFAPart now recognises '4'/'4F' (emitting pdfaid:part=4) and PDFAConformanceLevel returns empty for part 4 since PDF/A-4 drops the A/B/U levels; IsPDFA2OrLater automatically covers part 4 so existing restriction checks apply
  • Added Principle 4 visual/XML consistency check as THotPDF.ValidateVisualXmlConsistency: dumps the visible text of every page and verifies that the invoice number, seller, buyer and grand total values present in the embedded XML also appear in the human-readable representation (Factur-X 1.09 spec 5.1); a mismatch is reported as a list of missing field names, framed as a heuristic warning rather than a hard validation failure since the PDF may format or wrap values

Changed

  • The E-Invoice sample ShowValidationReport now renders the read-side invoice summary, the independent PDF/A-3 issue set, the classified attachment list, and the Principle 4 visual/XML consistency verdict alongside the existing container and Schematron business-rule checks, demonstrating the new read-side APIs on every generated PDF

Version 2.253.1

Fixed

  • Aligned the E-Invoice demo source with its regression-test assertions: TInvoiceForm = class(TForm) now uses the standard spaced declaration, and IsDefaultOutputFile introduces a per-iteration Profile local (set from GetProfile(I)) so the source carries the exact string(Profile.OutputBaseName)+ '.pdf' literal the tests check for, while avoiding the duplicate GetProfile call per loop iteration. Resolves the two long-standing EInvoiceDemoDefaultOutputUsesProfileSuffix / EInvoiceDemoUsesProjectFileAndOutputNames failures

Version 2.253.0

Added

  • Added loaded-document page rendering: THotPDF.RenderLoadedPageToBitmap(PageIndex, DPI) draws a page to a 24-bit RGB GDI TBitmap (caller frees) by interpreting the /Contents stream against a full graphics state (CTM, colours, line attributes, text state) and a current path, feeding every operator to GDI via path / text / image bridges. The supported operator set covers the common document-PDF subset: text (BT ET Tf Tc Tw Tz TL Tr Ts Td TD Tm T* Tj TJ ' "), path construction and painting (m l c v y re h S s f F f* B b B* b* n W W*), colour (rg RG g G k K), graphics state (q Q cm w), and Do for image and one level of Form XObject recursion. Colour spaces handled are DeviceRGB / Gray / CMYK and Indexed; CalRGB / Lab / ICCBased degrade to a best-effort approximation. Six new units (HPDFRenderMatrix, HPDFRenderGraphicsState, HPDFRenderColorSpace, HPDFRenderPath, HPDFRenderFontMetrics, HPDFPageRenderer) keep the renderer decoupled from HPDFDoc via a record of function-pointer accessors
  • Added HotPDF.RenderTests (3 DUnitX cases) covering text-page rendering (non-blank bitmap), page-size-matches-DPI, and out-of-range page index returns nil — all pass on Win32 and Win64

Version 2.252.0

Added

  • Added loaded-document text replace: THotPDF.ReplaceLoadedPageText and ReplaceLoadedDocumentText rewrite every occurrence of a needle by reverse-encoding the replacement through the font's char-code table (HPDFEncodeUnicode) and splicing the result into just the matched code-byte ranges of each string operand — non-matched bytes, inter-token whitespace and operators are preserved verbatim. Each /Contents stream is processed in isolation so multi-stream pages stay well-formed; compressed streams are decompressed for editing and saved uncompressed (the /Filter entry is dropped, accepting a larger file). ReplaceCount reports the number of operand rewrites performed
  • Added HPDFEncodeUnicode in HPDFTextExtraction: the reverse of HPDFDecodeCharCode, mapping a Unicode code point back to a font's char-code bytes by walking the same strategy chain in reverse (ToUnicode bfchar/bfrange, Encoding stream cidchar/cidrange + CIDToUnicode, Type0 CIDToGID/CIDIdentity, predefined WinAnsi/MacRoman tables), so an encode→decode round trip is stable for any code the decoder can resolve
  • Added HPDFSerializeStringLiteral / HPDFSerializeHexString in HPDFContentStream: reserialize raw char-code bytes back into a PDF content-stream string literal ((...) with ( ) \ and octal escapes) or hex string (<...>), mirroring the tokenizer's ReadLiteralString/ReadHexString so parse → re-serialize round trips cleanly
  • Added HPDFMatchGlyphs in HPDFContentStream: a pure-function glyph-sequence matcher extracted from SearchLoadedPageText so the search and replace paths share one matching core
  • Added THPDFPageFontResolver.LookupDecoder so the replace path can obtain a font decoder copy for reverse encoding outside the interpreter loop
  • Added HotPDF.ReplaceTests (8 DUnitX cases) covering serializer round-trips (literal/hex/high-byte escape), and end-to-end same-length, different-length, multiple-match, compressed-stream degradation and missing-needle scenarios — all pass on Win32 and Win64

Version 2.251.0

Added

  • Added loaded-document text search: THotPDF.SearchLoadedPageText and SearchLoadedDocumentText locate every occurrence of a needle by matching the Unicode glyph sequence produced by ExtractLoadedPageGlyphs, returning a THPDFTextMatchArray whose entries carry the glyph range, the user-space origin and width, and the source token/item index so a caller can later rewrite the operand bytes; case-insensitive matching uses ASCII-only folding to keep behaviour identical across the Delphi 5–XE toolchains
  • Extended the content-stream tokenizer and interpreter with byte-offset tracking: THPDFContentToken and THPDFArrayItem now record StartOfs/EndOfs spanning each operand exactly as written (including ( ) or < > delimiters), and each THPDFGlyphRecord carries TokenIndex/ItemIndex/ByteOffset pointing back to the operand and code unit that produced it — the foundation for in-place text replacement
  • Added HotPDF.SearchTests (10 DUnitX cases) covering offset-span reconstruction for literal/hex/TJ-array operands, the glyph→token back-reference, and end-to-end single/case-insensitive/multi-match/document-wide search plus the empty-needle and missing-needle edge cases — all pass on Win32 and Win64

Version 2.250.0

Fixed

  • Hardened ImportLoadedFormFromFDF: replaced the byte-level /T+space + /V+space scanner (which mis-parsed /Type /Catalog and other /T* tokens as field names, swallowed bytes across objects to the next (, and missed hex-string values) with a structural parse — each << /T ... /V ... >> field dictionary inside the /Fields array is sliced by bracket-depth tracking (respecting literal and hex string literals) and handed to HPDFParserParseSimpleDictionary, so string, hex-string, name and numeric /V values now all round-trip correctly
  • /V values carried as UTF-16BE hex strings (<FEFF...>) now keep their hex form through import: HPDFSetDictFormValue detects the FEFF BOM prefix and sets IsHexadecimal so the writer re-emits <FEFF...> instead of a garbled literal (FEFF...); checkbox / radio name values (/Yes, /Off) are preserved as names because the existing type-correction path already keeps the THPDFNameObject slot

Added

  • Added HotPDF.FDFTests (5 DUnitX cases) covering the export→import round-trip for text fields, the checkbox name-value type preservation, silent skipping of unknown field names, the UTF-16BE hex value round-trip, and the /Type keyword noise regression — all pass on Win32 and Win64

Version 2.249.0

Added

  • Added ZUGFeRD 2.5 / Factur-X 1.09 metadata support: HPDFIsFacturXVersion accepts the 2p5 version alias, the new HPDFFacturXNormalizeVersion helper maps it back to 2p0 in the emitted XMP per Factur-X 1.09 spec 6.3.2 (the XMP extension schema version is decoupled from the XML data specification version), and HPDFFacturXFileNameOK, HPDFFacturXXMLGuidelineOK and the XMP schema-name/namespace-uri/prefix triple treat 2p5 identically to 2p0; the E-Invoice sample gains a seventh profile entry (ZUGFeRD 2.5 / Factur-X 1.09, EN 16931) validated against the official 2.5 sample corpus
  • Added UBL supplementary attachment support per Factur-X 1.09 spec 6.4: THotPDF.AddUBLSupplementaryFile embeds a UBL representation as a secondary factur-xubl.xml associated file with Alternative relationship and application/xml MIME alongside the primary CII invoice (delegating to the existing AddPDFA3AssociatedFile pipeline), HPDFIsFacturXUBLFileName recognises the file name, DetectFacturXInvoice records it in a new THPDFFacturXInvoiceInfo.UBLFileName field, and the E-Invoice sample toggles dual embedding via a checkbox with BuildUBLSupplementaryXML emitting a compact UBL 2.1 EN 16931 skeleton
  • Added optional EN 16931 Schematron business-rule validation as the new HPDFEInvoiceValidator unit: ships the five official Factur-X 1.09 rule files (MINIMUM/BASIC WL/BASIC/EN16931/EXTENDED) under Lib/resources/Schematron/ and exposes HPDFValidateEInvoice which runs the container check via ValidateFacturXInvoice then evaluates every rule against the embedded XML; the MSXML-backed engine (XE2+ only, XPath 1.0 subset) flags XPath 2.0 assertions as skipped, while Delphi 7 compiles a stub that reports the engine as unavailable without affecting the container verdict; the E-Invoice sample and the EInvoiceValidation headless harness now render internal rule outcomes alongside the external validator reports

Changed

  • AddFacturXAssociatedFile now normalises the Version argument through HPDFFacturXNormalizeVersion before writing XMP, so 2p5 callers emit the spec-compliant 2p0 XMP token without changing the existing 1.0/2p0 behaviour
  • E-Invoice sample GenerateInvoicePDF gains an optional AttachUBL parameter (defaults to False, preserving existing call sites) and tags the default output name with -withUBL when the UBL attachment is requested

Version 2.248.0

Added

  • Hardened the E-Invoice demo profile index model: changed GetProfile from a 1-based case-with-else fallback to an explicit 0-based bijection (0 BASIC .. 5 EN 16931), re-sorted the dropdown order accordingly, default still EN 16931; completed the E-Invoice demo README descriptions of output files, validation status and run output for the ZUGFeRD 1.0 COMFORT and ZUGFeRD 2.0 BASIC profiles

Version 2.247.0

Added

  • Added 22 creation/write APIs for loaded documents (round 9, all constructing dictionaries on the loaded object graph and registering them to AcroForm/Page): form-field creation — text field (AddLoadedTextField), checkbox (AddLoadedCheckBox), combo box (AddLoadedComboBox), list box (AddLoadedListBox), button (AddLoadedPushButton), signature field (AddLoadedSignatureField), auto-creating/completing AcroForm and /NeedAppearances; annotation subtypes — rubber stamp (AddLoadedStampAnnotation), highlight/underline/squiggly/strikeout (AddLoadedHighlightAnnotation), rectangle/circle (AddLoadedSquareAnnotation), line (AddLoadedLineAnnotation), ink (AddLoadedInkAnnotation), polygon/polyline (AddLoadedPolygonAnnotation), caret (AddLoadedCaretAnnotation); FDF form-data interchange (ExportLoadedFormToFDF/ImportLoadedFormFromFDF); N-up imposition (StitchLoadedPage/StitchLoadedPageSideBySide); redaction masking (RedactLoadedRect)

Version 2.246.0

Added

  • Added 15 write/edit APIs for loaded documents (round 4 writes, covering form options, annotations, bookmarks, and document-level metadata): form-field option-list read (GetLoadedFormFieldOption/GetLoadedFormFieldOptions)/write (SetLoadedFormFieldOptions), field default-value read/write (GetLoadedFormFieldDefaultValue/SetLoadedFormFieldDefaultValue), field reset (ResetLoadedFormField), text-note annotation (AddLoadedTextAnnotation), free-text annotation (AddLoadedFreeTextAnnotation), annotation color (SetLoadedAnnotationColor), cross-page annotation move (MoveLoadedAnnotation), bookmark color (SetLoadedOutlineColor)/style (SetLoadedOutlineStyle)/delete (RemoveLoadedOutline), document Trapped flag (SetLoadedTrapped), optional-content group visibility (SetLoadedOCGVisibility), page-label write (SetLoadedPageLabel)

Version 2.245.0

Added

  • Added 12 write/edit APIs for loaded documents (round 3 writes): annotation-flag write (SetLoadedAnnotationFlags), hyperlink annotation add (AddLoadedLinkAnnotation), bookmark expand/collapse state (SetLoadedOutlineOpen), document open-action (SetLoadedOpenActionPage), form-field export-value read/write (SetLoadedFormFieldExportValue/GetLoadedFormFieldExportValue), form-field tooltip (SetLoadedFormFieldTooltip/GetLoadedFormFieldTooltip), form-field border width/background color (SetLoadedFormFieldBorderWidth/BackgroundColor), clear all JavaScript (RemoveLoadedJavaScriptAll), page content copy (CopyLoadedPage)

Version 2.244.0

Added

  • Added 15 write/edit APIs for loaded documents (round 2 writes, borrowing RemoveAnnotation/SetRotationAngle patterns): page-rotation write (SetLoadedPageRotation), annotation delete/contents modify/clear (RemoveLoadedAnnotation/SetLoadedAnnotationContents/ClearLoadedAnnotations), viewer-preferences write (SetLoadedViewerPreferences), date write (SetLoadedCreationDate/ModDate), Catalog version write (SetLoadedCatalogVersion), page duration/transition write (SetLoadedPageDuration/Transition), bookmark title modify (SetLoadedOutlineTitle), embedded-file delete (RemoveLoadedEmbeddedFile), form-field value write (SetLoadedFormFieldValueByIndex/ByName)

Version 2.243.0

Added

  • Added 14 write/edit APIs for loaded documents (first breakthrough beyond read-only inspection, borrowing SetXMLMetadata/InsertAnnotation/Stitch patterns): page-mode/layout write (SetLoadedPageMode/PageLayout), document-language write (SetLoadedLanguage), document-info write (SetLoadedCreator/Producer/Title/Author/Subject/Keywords), Info-key delete (RemoveLoadedInfoKey), XMP-metadata write (SetLoadedXMPMetadata), document-level JavaScript add/remove (AddLoadedDocumentJavaScript/RemoveLoadedJavaScript), page-box write (SetLoadedPageBox). These methods modify the loaded object graph; call SaveLoadedDocument to persist

Version 2.242.0

Added

  • Added 15 inspection APIs for loaded documents (round 4): page-mode/layout read (GetLoadedPageMode/PageLayout), Catalog version (GetLoadedCatalogVersion), page object number (GetLoadedPageObjectNumber), form-field flag-bit composition (GetLoadedFormFieldFlags)/NoExport detection (IsFormFieldNoExport), annotation-flag decoding (IsLoadedAnnotationHidden/Printable/Locked), unit conversion (PointsToMM/MMToPoints/PointsToInches/InchesToPoints/PointsToCm/CmToPoints)

Version 2.241.0

Added

  • Added 20 deep-inspection APIs for loaded documents (round 3): Info-dictionary key enumeration (GetLoadedInfoKeyCount/KeyName/KeyValue), form-field rect/page-index (GetLoadedFormFieldRect/PageIndex), annotation URI/popup/name/mod-date (GetLoadedAnnotationURI/PopupRect/Name/ModDate), bookmark color/style (GetLoadedOutlineColor/Style), metadata-stream detection (HasLoadedMetadata), Trailer ID (GetLoadedTrailerID), XRef type (GetLoadedXRefType), max object number (GetLoadedMaxObjectNumber), source file size (GetLoadedSourceFileSize), embedded-font count (GetLoadedEmbeddedFontCount), document language (GetLoadedLanguage), page duration/transition (GetLoadedPageDuration/Transition), form-field required flag (IsFormFieldRequired)

Version 2.240.0

Added

  • Added 20 deep-inspection APIs for loaded documents (round 2): embedded-file save to disk (SaveLoadedEmbeddedFileToDisk), set document-info fields (SetLoadedDocumentInfo), read JavaScript source (GetLoadedJavaScriptSource), named-destination enumeration (GetLoadedNamedDestinationCount/Name), OCG visibility (GetLoadedOCGVisibility), page-label details (GetLoadedPageLabelInfo), whole-document annotation/font counts (GetLoadedTotalAnnotationCount/TotalFontCount), PDF/A and PDF/X compliance detection (IsLoadedPDFA/IsLoadedPDFX/GetLoadedPDFAVersion/GetLoadedPDFXVersion), batch convenience methods (GetLoadedOutlineTitles/AllLinkURIs/ImageCountPerPage/AllPageBoxes/FormFieldNames/FormFieldValues), one-shot document summary (GetLoadedSummary returning page/annotation/font/image/form/signature counts + encryption/AcroForm/structure-tree flags)

Version 2.239.0

Added

  • Added 20 inspection APIs for loaded documents: PDF version string (GetLoadedPDFVersionString), linearization detection (IsLoadedLinearized), XMP metadata read (GetLoadedXMPMetadata), document-level JavaScript enumeration (GetLoadedJavaScriptCount/Name), page-label count (GetLoadedPageLabelCount), viewer preferences (GetLoadedViewerPreferences), structure-tree detection (HasLoadedStructureTree), signature-field count (GetLoadedSignatureFieldCount), optional-content group (OCG) enumeration (GetLoadedOCGCount/Name), OutputIntent detection (HasLoadedOutputIntent/GetLoadedOutputIntentInfo), AcroForm detection (HasLoadedAcroForm), creation/modification dates (GetLoadedCreationDate/ModDate), batch array convenience methods (GetLoadedEmbeddedFileNames/LinkURIs/AnnotationSubtypes/FontNames returning THPDFAnsiStringArray)

Version 2.238.0

Added

  • Added deep-inspection APIs for loaded documents (8 read-only methods): GetLoadedPageWidth/GetLoadedPageHeight read page dimensions (pt); GetLoadedLinkCount/GetLoadedLinkInfo enumerate hyperlink annotations (URI + rect); GetLoadedEncryptionInfo queries encryption version, key length, permission flags; GetLoadedEmbeddedFileCount/GetLoadedEmbeddedFileName enumerate document embedded files (attachments). These APIs traverse the loaded object graph without modifying it, mirroring the existing GetLoadedImageInfo/GetLoadedAnnotationInfo patterns. The LoadedDocInspector demo was updated accordingly to demonstrate page size/rotation/link counts, encryption status, and embedded-file listing

Version 2.237.0

Added

  • Added metadata-query APIs for loaded documents: GetLoadedDocumentInfo reads title, author, subject, keywords, creator, producer from the Info dictionary; GetLoadedPageRotation reads page rotation angle; GetLoadedOutlineCount/GetLoadedOutlineItem enumerate top-level bookmark-tree entries (title + destination page index). These are all read-only queries mirroring the existing GetLoadedImageInfo pattern and do not modify the document object graph

Version 2.236.0

Added

  • Added the read-side text extraction pipeline, delivered as three standalone units that compose into new THotPDF methods: HPDFCMapReader parses both ToUnicode beginbfchar/beginbfrange streams and standard CMap begincidchar/begincidrange resources (shared recursive-descent tokenizer, UTF-16BE surrogate-pair recombination, disk-backed standard CMap loading with unit-scope caching), HPDFContentStream tokenizes and interprets page content streams driving the full text-state machine (BT/ET, Tf, Tj/TJ/'/", Td/TD/Tm/T*, q/Q, inline-image BI/ID/EI skipping) into per-glyph records, and HPDFTextExtraction builds a font decoder walking the ISO 32000-1 §9.10 fallback chain (/ToUnicode/Encoding stream or named CMap → Type0 /DescendantFonts /CIDToGIDMapcid2code.txt), with built-in WinAnsi/MacRoman predefined tables so single-byte fonts resolve without disk resources
  • Added THotPDF.GetLoadedFontDecoder, THotPDF.ExtractLoadedPageGlyphs and THotPDF.ExtractLoadedPageText read-only APIs that expose the pipeline above; ExtractLoadedPageText returns a Unicode string per page with a naive Td-driven newline heuristic (reading-order clustering is intentionally deferred to a later round)
  • Added ExtractText Delphi console demo that loads a PDF argument and prints the extracted text of every page, mirroring the LoadedDocInspector read-only console layout

Changed

  • HPDFDoc now uses HPDFCMapReader, HPDFContentStream and HPDFTextExtraction in its interface section so the new THotPDF extraction methods can surface the decoder and glyph types; the three units follow the HPDFParser standalone-unit pattern (no dpk contains entry) and never reference HPDFDoc, avoiding a circular dependency by accepting a THPDFFontDocAccess record of function pointers bound to the existing ResolveLoadedDictionary / ResolveLoadedStream / HPDFReadStreamBytes helpers

Version 2.235.1

Added

  • Added the PDFOptimize console demo (Delphi): demonstrates generation-side PDF size optimization by producing multiple PDFs of the same content with different compression settings and quantifying the gain of each strategy in a side-by-side comparison — cmNone vs cmFlateDecode + UseObjectStreams object-stream packing for text/vector documents, icJpeg JpegQuality sweep vs icFlate for colour photos, icCCITT42 (G4) vs icJBIG2 lossless/lossy for dual-layer scanned documents; the console prints a size comparison table, all test images are synthesized in-memory without external files, and it is clearly noted that HotPDF compression is a generation-side capability (existing loaded PDFs cannot be recompressed)

Version 2.235.0

Added

  • Added consolidated Stamp demo (Delphi and C++Builder): merges the former Modify, MultiPageStamp, and Watermark demos into a single VCL program that overlays three independently toggleable stamp layers on a parsed page range — a content-stream text watermark (AddTextWatermark), an interactive rubber-stamp annotation (AddStampAnnotation), and a corner bitmap (AddImage + ShowImage), retaining page-range parsing (HPDFParsePageRange) and four-corner positioning
  • Added consolidated PageSizes console demo: merges the former SmallSize, NormalSize, and LargeSize demos into a single program that enumerates all THPDFPageSize enum values across the small/normal/large categories plus custom Width/Height dimensions in one pass

Changed

  • Merged the Security demo group's 5 standalone programs (Encryption, SecurityAES256, DecryptPDF, PFXSignature, SignatureField) into a single console program covering RC4-128 encryption, AES-256 R5/R6 encryption, password decryption, signature-field placeholders, and PFX signing (auto-skipped when the PFX fixture is missing)
  • Merged the AddPages and DelPages GUIs into a single AddDelPages GUI, while upgrading the C++Builder PageMultiSize and AddDelPages to match Delphi richness (Size/Orientation/custom width-height/count/label/progress)
  • Moved the FontTest glyph regression tool from Demo to Tests\Delphi\FontTest and Tests\C++Builder\FontTest, clarifying its role as a test tool rather than a feature demo

Removed

  • Removed the purely redundant TiffToPDF demo (Delphi and C++Builder); its capability is fully covered by the TIFF conversion path in ConvertTo
  • Removed the C++Builder CopyPages demo; its capability is fully covered by the more complete PDFmerge
  • Removed the Logger demo; its HPDFLogger / HPDFLog runtime logging facade usage has been migrated to the API documentation topic page Docs/zh-cn/topics/HPDFLoggerFacade.html (the library retains the HPDFLogger unit; only the demo project was deleted)

Fixed

  • Fixed the even-page deletion algorithm in the former DelPages (now merged into AddDelPages): the original loop counted a static page count against the shrinking document, actually deleting indices 1..midpoint instead of true even pages; now walks downward from the highest even page deleting 0-based indices, and fixes the global THotPDF variable leaking on each click

Version 2.234.1

修复

  • 修复 HPDFJBIG2Enc 单元编译错误(E2003 Undeclared identifier: 'Invariant'):旧版 Delphi 的 RTL 没有 TFormatSettings.Invariantatof 现改用与 HPDFXFA.XFAInvariantFormatSettings 一致的手动构造 TFormatSettings,恢复 RAD Studio 12.0 Win64 构建

Version 2.234.0

新增

  • JBIG2 图像解码新增高性能解码后端:加载侧图像提取(ExtractLoadedImage 等)默认启用该后端解码 PDF 内嵌的 JBIG2 图像
  • 新增 THotPDF.UseExternalJBIG2Decoder 属性(默认 True):设为 False 即可切回原生 Pascal 解码器作为后备

Version 2.233.0

新增

  • JBIG2 图像编码新增高性能编码后端:AddImageicJBIG2 压缩黑白位图时默认启用该后端,产生更快且标准合规的算术编码 JBIG2 流
  • 新增 THPDFJBIG2Options.UseExternalEncoder 选项(默认 True):设为 False 即可切回原生 Pascal MMR 编码器作为后备

Version 2.232.1

修复

  • 修复 JBIG2 算术 generic-region 编码器(HPDFJBIG2Codec)在高熵图像上的进位传播缺陷:MQ 算术编码器的字节输出(byte-out 与 0xFF 填充)遗漏了进位 spillover 位的清除,导致噪声、稀疏文档等高熵黑白位图被编码错误(规则的低熵图案恰好不触发,不受影响);同时将编码流终止符规范化为标准形式,确保第三方解码器可完整解析

Version 2.232.0

新增

  • JBIG2 解码后端(HPDFJBIG2Codec)扩展支持算术(MQ)编码:加载侧图像提取(ExtractLoadedImage)现可解码算术编码的 JBIG2 图像 —— 算术 generic region(GBTEMPLATE 0-3 + TPGDON)、符号字典与文本区域;此前仅支持 MMR generic region

Version 2.231.3

新增

  • 为 jbig2dec 参考解码器打开 PNG 输出支持:新增 build-libpng-vc64.bat(用 MSVC 编译 libpng 1.8 的 16 个核心对象到 Win64\libpng-*.obj,自动生成 zlib-ng 头并复用 pnglibconf.h.prebuilt),改造 build-jbig2dec-vc64.bat 在检测到 libpng 对象时自动启用 jbig2_image_png.cHAVE_LIBPNG 并链接 libpng + zlib-ng 对象,jbig2dec.exe 现支持 -t png 输出,对 annex-h.jbig2 生成 64x56 1-bit grayscale PNG,SHA-1 与 PBM 输出一致

Version 2.231.2

新增

  • 为 vendored 的 jbig2dec 参考解码器(Lib/thirdparty/jbig2dec)补齐 Windows 构建基础设施:新增 build-jbig2dec-bcc64x.bat(用 Embarcadero bcc64x 产 15 个 Delphi 可链接的 COFF64 对象,供未来 HPDFJBIG2.pas 通过 {$L} 消费)和 build-jbig2dec-vc64.bat(用 MSVC 产独立的 jbig2dec.exe 命令行解码器),并新增 config_types.h.in 模板与 .gitignore,修复 msvc.mak 缺失的对象规则

修复

  • jbig2dec 上游源码在现代 Windows 工具链下的编译与可移植性问题:用干净的现代实现替换无法编译的 1990 年代 GNU getopt(getopt.c/getopt.h,MSVC 因缺 strings.h 中止、bcc64x/C23 拒绝无原型声明);修复 jbig2dec.c::hash_image 的 64 位 size_t 截断、jbig2_segment.c::jbig2_find_segmentuint32→int 下溢、sha1.c::SHA1_Update 的 64 位位计数,以及 jbig2dec.cfread 返回值误用、%lu 格式说明符与 POSIX 弃用警告。核心 JBIG2 解码算法保持上游原样

Version 2.231.1

新增

  • 加载侧图像提取(ExtractLoadedImage)现支持多过滤器链:图像前置的 ASCIIHexDecode / ASCII85Decode / FlateDecode / LZWDecode / RunLengthDecode 等数据过滤器会按顺序解开,再交末端图像过滤器(DCTDecode / JPXDecode 或栅格)解码,例如 [/ASCII85Decode /FlateDecode]

Version 2.231.0

新增

  • 新增 CCITT 传真解码后端(HPDFCCITTDecode 单元):实现 ITU-T T.4(G3)与 T.6(G4)一维 / 二维传真解码,使加载侧图像提取(ExtractLoadedImage)现可解码 CCITTFaxDecode 双色图像,遵循 /DecodeParms 的 K / Columns / Rows / BlackIs1 / EncodedByteAlign 参数

Version 2.230.2

新增

  • 加载侧图像提取(ExtractLoadedImage)现支持每分量 1 / 2 / 4 位的 DeviceGray 与 Indexed 栅格:按位拆包并将灰度按比例缩放到 8 位

Version 2.230.1

新增

  • 加载侧图像提取(ExtractLoadedImage)现支持 DeviceCMYK 图像:4 通道 CMYK 栅格按标准公式转换为 RGB 位图

Version 2.230.0

新增

  • 新增 JBIG2 解码后端(HPDFJBIG2Codec 单元):实现 ITU-T T.6(G4 / MMR)二维解码,激活原本休眠的 THPDFJBIG2Decoder,使加载侧图像提取(ExtractLoadedImage)现可解码 JBIG2Decode 双色图像。支持 MMR 编码的 generic region(含 /JBIG2Globals 共享全局段);算术编码、符号字典、文本 / 半调区域暂不支持

Version 2.229.3

新增

  • 加载侧图像提取(ExtractLoadedImage)现支持索引色(Indexed)图像:以 Indexed 颜色空间存储的 FlateDecode / LZWDecode 栅格会按调色板查表还原为真彩位图,支持 DeviceRGB / DeviceGray / DeviceCMYK 基色与十六进制或字面量查找表

Version 2.229.2

新增

  • 加载侧图像提取(ExtractLoadedImage)现支持 JPXDecode(JPEG 2000)图像:以 JPXDecode 编码的图像 XObject 会通过 OpenJPEG 后端解码回位图,GetLoadedImageInfo 对此类图像报告 Decodable=True。至此 PDF 内嵌的 JPEG 2000 图像可被直接提取为 VCL 位图,无损 JPEG 2000 往返像素精确

Version 2.229.1

新增

  • 加载侧图像提取(ExtractLoadedImage)现支持 DCTDecode(JPEG)图像:以 DCTDecode 编码的图像 XObject 会通过 TJPEGImage 解码回位图,GetLoadedImageInfo 对此类图像报告 Decodable=True

Version 2.229.0

新增

  • 新增加载侧图像提取 API:GetLoadedImageCount / GetLoadedImageInfo / ExtractLoadedImage,可枚举已加载 PDF 中的图像 XObject 并将其解码回 VCL 位图(TBitmap)。GetLoadedImageInfo 通过 THPDFLoadedImageInfo 返回每张图像的尺寸、位深、颜色空间、过滤器与可解码标志,便于在提取前预检。本版可解码以 FlateDecode / LZWDecode / ASCIIHex / ASCII85 / RunLength 编码的 DeviceRGB 与 DeviceGray 8 位栅格;索引色、CMYK、DCTDecode(JPEG)与 JPXDecode(JPEG 2000)图像将在后续版本接入

Version 2.228.0

新增

  • 新增 TJpeg2000BitmapTBitmap 派生类):可直接读写 JPEG 2000 图像,LoadFromStream 将 JP2 / J2K 解码为位图、SaveToStream 将位图编码为 JPEG 2000 码流;支持无损(LosslessCompression)与有损质量(CompressionQuality)两种模式、灰度 / RGB / CMYK 通道,并附带低层解码器 THPDFJpeg2000Decoder 供自定义图像管线直接取用解码后的像素数据

修复

  • 恢复 JPEG 2000(JPXDecode,PDF 1.7 ISO 32000-1 7.4.9)图像支持:此前解码后端因库源损坏退化为占位桩,无法解码任何 JP2 / J2K 码流;现重新接入 OpenJPEG 2.5.4 引擎,可将灰度、RGB 与 YCbCr 图像解码为 8 位样本(高位深分量重采样为 8 位、YCbCr 自动转 RGB、子采样分量按最近邻上采样),兼容带 JP2 box 头的文件与裸 J2K 码流
  • AddImage 现可直接传入 .jp2 / .j2k / .jpt / .jpc 文件并按所选压缩方式嵌入 PDF(自动识别格式),无需先行手工转码

Version 2.227.0

变更

  • 将 GSUB/GPOS 上下文应用与 Mark 定位函数(37 个纯函数)从 HPDFDoc.pas 追加提取到 HPDFShaping.pas。这批函数覆盖 GSUB 上下文/链式上下文/反向链式替换、GPOS 上下文/链式上下文/嵌套定位、Mark-to-Base/Mark-to-Mark/Cursive/Mark-to-Ligature 定位、GDEF 类查找、Collect-GID 子集闭包等,全部接收 TBytes 表切片 + glyph ID 值参数,不触碰实例状态。HPDFDoc.pas 本轮减约 11000 行(含被提取函数之间的 forward 声明和注释块),累计六轮拆分减约 21700 行(原文件的 26%)

Version 2.226.0

变更

  • 将简单对象解析器(ParseSimpleDictionaryParseSimpleArray)从 HPDFDoc.pas 提取到新单元 HPDFParser.pas。这两个 byte 级递归下降解析器从 AnsiString 内容构建 THPDFDictionaryObject / THPDFArrayObject 树,不触碰 THotPDF 实例状态;原方法保留为转发 stub,公开 API 不变。这是巨石拆分第五轮,本轮减约 2060 行,五轮累计减约 10700 行(原文件的 13%)

Version 2.225.0

变更

  • 将 OpenType 整形原语(71 个纯函数)从 HPDFDoc.pas 提取到新单元 HPDFShaping.pas。这批函数覆盖 GSUB 覆盖表/查找/替换、GDEF 类查找、TTF 表读取器、脚本重排与整形(Arabic、Syriac、Indic 语系、Thai/Lao、Hebrew、Javanese 等),全部接收值参数(TBytes 表切片、UnicodeString run、glyph ID)从不触碰 THotPDFTHPDFPage 实例。HPDFDoc.pas 通过 implementation 段 uses HPDFShaping 访问,TGPOSValue/TGPOSValueArray 类型一并迁移。这是巨石拆分第四轮,本轮减约 3000 行

Version 2.224.0

Changed

  • Extracted the Factur-X / ZUGFeRD / XMP e-invoice helper functions (22 standalone functions) from HPDFDoc.pas into a new unit HPDFFacturX.pas. These functions cover FX/Basic/Minimum/EN16931 compliance validation, XMP metadata generation, and embedded-XML parsing, all self-contained (operating only on value parameters and TBytes, never touching THotPDF instance state). HPDFDoc.pas accesses them via uses HPDFFacturX in the implementation section; the public API is unchanged. This is the third round of HPDFDoc.pas monolith splitting, reducing cumulatively about 5600 lines over three rounds

Version 2.223.0

Changed

  • Extracted the Direct File API low-level I/O helpers (44 shared functions) from HPDFDoc.pas into a new unit HPDFDirectFileIO.pas. These byte/xref/object-body/AES-crypt read functions are shared by the loader and the Direct File subsystem; after extraction both subsystems access them via uses HPDFDirectFileIO. HPDFDoc.pas shrank by a further ~1640 lines (cumulatively ~5200 lines over two rounds). DA-specific types (THPDFDirectReadBuffer, THPDFDirectWriteBuffer, THPDFDirectIntArray) and the global buffer (GHPDFCopyBuffer) were migrated to the new unit as well

Version 2.222.0

Changed

  • Extracted preflight, compliance-check, and PDF/VT validation code from HPDFDoc.pas into a new unit HPDFPreflight.pas. The signatures of the 25 existing public methods (CreatePreflightReport, ValidatePDFVT, EmbedPreflightReportAsXMP, etc.) remain completely unchanged; their implementations now delegate to self-contained standalone functions in the new unit. HPDFDoc.pas shrank by ~3500 lines. Three new read-only accessors methods (LoadedObjectCount, GetLoadedObjectByIndex, LoadedRootObjectIndex) were added so the independent unit can enumerate the loaded document object graph

Version 2.221.0

Added

  • Full multilingual support: extracted Readme.html to the Docs/en-us directory and added translated versions for 37 other languages; updated the installer scripts (HotPDF-FULL.iss, HotPDF-TRIAL.iss) so they now automatically extract and place the language-appropriate Readme.html to the installation root based on the language selected at install time

Version 2.220.0

Added

  • Added the unified runtime logging facade THPDFLogger and global instance HPDFLog: consolidates the previously scattered compile-time debug switches into a runtime-controllable logging facade. Provides Error/Warning/Info/Debug four-level severity filtering, with simultaneous output to file, OutputDebugString (visible in the IDE Event Log), and console; the file target has 10 MB single-backup rotation; thread-safe (TCriticalSection protected); the disabled-state hot path returns after a single boolean check with zero overhead in release builds. Three diagnostic points are wired in: LoadFromFile, CreatePreflightReport, and xref-stream parse fallback, so load success/failure, preflight summary, and object-stream fallback events are written as structured records when logging is enabled. Replaces the traditional approach of editing HotPDF.inc and rebuilding the package; users can toggle diagnostic output at runtime at any time

Version 2.219.0

Added

  • Added THotPDF.GetGPOSSingleAdjustment(GID, FeatureTag, out XPlacement, YPlacement, XAdvance, YAdvance): Boolean: a standalone public query for OpenType GPOS LookupType 1 Single Adjustment. It collects GPOS lookups by any 4-byte feature tag (typically 'size' optical size / 'vhal' half-height), unpacks Extension (Type 9), then applies the existing _GPOSApplySingle to the LookupType 1 subtable, returning the XPlacement/YPlacement/XAdvance/YAdvance adjustments (1000-em, signed) for a single glyph. This completes all 9 GPOS LookupTypes to spec-complete status: the binary applier was already consumed by nested contextual kern, and this version fills the standalone query entry point to close the last GPOS gap in the spec matrix

Version 2.218.1

Added

  • Added THPDFPage.GetWideCharAdvances(Text, out TotalWidth, out Advances): returns the total width and per-glyph natural advance (including kerning) of Unicode text in a single call. Internally uses a single GDI GetTextExtentExPointW call to get both the total width and the cumulative width array, then differences to obtain per-glyph advances. The caller must pre-SetLength(Advances, Length(Text)). Useful for custom layout, table column-width calculation, signature-block layout, and other scenarios needing all glyph widths at once

Changed

  • Optimised jtJustify justified-text performance: _HPDFEmitJustifiedWideLine from v2.218.0 called GetWideTextWidth N+1 times per line (1 for total width + N prefix differences, each a full GDI round-trip). Replaced with a single GetWideCharAdvances call, reducing per-line GDI round-trips from N+1 to 1. A typical A4 full-page justify (45 lines x 80 chars) drops from ~3645 GDI round-trips to 45, about 80x improvement. The visual justify output is unchanged (same metrics engine, same kerning)

Version 2.218.0

Added

  • Added the jtJustify justified-text mode (fourth value of the THPDFJustificationType enum): when passed to WideTextOutBox, the difference between each line natural width and the box width (except the last line) is distributed across the stretchable inter-word/inter-glyph spaces within the line, so the text aligns flush to both the left and right box edges. Latin text distributes across word spaces; CJK text (Han/kana/Hangul and other scripts without inter-word spaces) distributes evenly between all adjacent glyph pairs (Japanese equal inter-character distribution). The last line and lines already at or beyond the box width retain their natural left-aligned width. Uses the ExtTextOut TJ-array emit from v2.215.0 and the GetWideTextWidth measurement from v2.216.0

Version 2.217.0

Added

  • Added THPDFPage.WideTextOutBox: Unicode multi-line word-wrap. Mirrors the contract of TextOutBox (returns the number of WideChars placed in the box) but measures with GetWideTextWidth and splits by WideChar index. Wrap rules support two script families: CJK (Han/kana/Hangul/CJK punctuation/full-width) breaks between any two glyphs (standard CJK behaviour with no inter-word spaces); Latin and other scripts break at the last space/tab, hard-breaking when no space is found. Hard line breaks (CR/LF/CRLF) are executed as-is. Fixes a bug where TextOutBox(AnsiString) split Chinese/Japanese/Korean/surrogate-pair text byte-by-byte, producing garbled line breaks

Version 2.216.0

Added

  • Added THPDFPage.GetWideTextWidth(Text: WideString): Single: Unicode text-width measurement. The existing TextWidth(AnsiString) first narrows the WideString to AnsiString then looks up the 0-255 ABC width table, yielding meaningless values for CJK/surrogate-pair/multibyte text; the new method measures the whole string with the current font via GDI GetTextExtentPoint32W (lfHeight = -1000), returning the width in user-space points (same coordinate system as TextWidth, directly usable for layout budgeting). Same measurement strategy as _XFAMeasureTextImpl
  • Added THPDFPage.GetWideTextRowCount(BoxWidth: Integer; Text: WideString): Integer: Unicode line-count prediction, mirroring the AnsiString contract of GetTextRowCount and using GetWideTextWidth so CJK/surrogate-pair text wraps and counts correctly

Version 2.215.0

Added

  • Added THPDFPage.ExtTextOut (three overloads: PWORD / WideString / AnsiString): GDI ExtTextOut-style extended text output accepting a per-glyph horizontal displacement array Dx, emitting a single [<hex> <num> ...] TJ array so the caller can precisely control each glyph origin: useful for decimal table alignment, manual kerning, justified text, form-value fill, and signature-block layout. Reuses the existing _GPOSEmitPositionedRun TJ emitter and _GPOSGlyphAdvance1000 hmtx reader; Dx is in PDF user-space points (same coordinate system as TextOut X/Y). When a Dx value equals the glyph natural advance the TJ adjustment is zero, allowing natural and overridden glyphs to be mixed in a single call. Only simple LTR text is supported; RTL bidi reordering and producer-side shaping are bypassed

Version 2.214.0

Added

  • Added THPDFPage.AttachSignatureFieldAppearance: attaches a visible appearance /AP /N Form XObject to a signature field created via AddSignatureField / AddSignedSignatureField / AddPAdESSignatureField, and returns the Form so the caller can draw the signature image, signer name, date or reason text within the widget local coordinate system; a thin border with a light-grey background serves as the default placeholder appearance
  • Added the HPDFNormalizeRect utility function (three overloads: TRect / THPDFRectangle / four Extended var parameters): reorders rectangle corner points so Left<=Right and Top<=Bottom, letting unordered input such as a mouse-dragged rectangle be safely passed to drawing APIs
  • Promoted THPDFPage.RotateCoordinate from protected to public: external callers can now directly reuse the same rotation convention as RectangleRotate to compute rotated-rectangle corners, polygon vertices, or text bounding boxes

Version 2.213.0

Added

  • Added a suite of geometric convenience methods to THPDFPage: Arc (angle-defined arc), Pie (angle-defined pie/wedge), Chord (chord shape), ArcTo (centre + radius + sweep-angle arc), Polyline, Polygon, and PolyBezier (cubic bezier spline). All methods reuse the existing MoveTo / LineTo / CurveToC / CurveArc low-level path primitives, aligning with GDI TCanvas angle and point-array semantics, so drawing arcs, pies, polylines and spline curves no longer requires hand-written operator loops

Version 2.212.0

Added

  • Added THPDFPage.SetAnnotationJavaScriptAction: ordinary annotations can now set mouse-enter, mouse-exit, down, up, focus-gained and focus-lost JavaScript actions via /AA, useful for adding interactive scripts in annotation, link and form-appearance workflows

Version 2.211.0

Added

  • Added THPDFDocOutlineObject.SetURIAction: outline nodes returned by OutlineRoot.AddChild can now switch from the default in-page /Dest to a /S /URI action, useful for providing external help, support portal or related-resource links directly in the bookmarks panel

Version 2.210.0

Added

  • Added THotPDF.AutoCreateURL: when enabled, single-line horizontal THPDFPage.TextOut automatically turns http://, https://, mailto: and www. URL text into /S /URI link annotations, useful for generating clickable links directly in reports, tables of contents and contact-info pages

Version 2.209.0

Added

  • Added THotPDF.SetOpenNamedDestinationAction and THotPDF.ClearOpenNamedDestinationAction: the document Catalog /OpenAction can now be set to jump to a named destination registered via THotPDF.RegisterNamedDestination, useful for cover pages, tables of contents or documents whose generation order may change to open at a stable section entry

Version 2.208.0

Added

  • Added THPDFPage.AddPushButtonWithNextAction: a button primary action can now chain a second PDF action via /Next, useful for executing interactive form workflows in a single click such as /ResetForm followed by showing fields, or hiding fields before running a named action

Version 2.207.0

Added

  • Enhanced THotPDF.RegisterOptionalContentGroup: added a UserToggleAllowed parameter that can write a given optional-content group to /OCProperties /D /Locked while preserving its default visibility state, for content in maps, engineering drawings and multilingual layers that should not be toggled by the viewer user

Version 2.206.0

Added

  • Added THPDFPage.AddNamedDestinationLink: page links can now directly reference named destinations registered via THotPDF.RegisterNamedDestination, emitting a local /S /GoTo action with a string /D destination name, useful for tables of contents, cross-references and documents with variable page numbering to maintain stable navigation

Version 2.205.0

Added

  • Added THotPDF.JBIG2Options and THPDFJBIG2Options: AddImage(..., icJBIG2) now passes document-level Lossless, LossyLevel and UseSymbolDictionary encoding intents to the registered JBIG2 encoder backend; defaults preserve the existing lossless MMR output path, and lossy settings are rejected when no backend is registered

Version 2.204.0

Added

  • Added THotPDF.EmfOptions and THPDFEmfOptions: enhanced EMF/WMF import can now configure fit ratio, EMF bitmap render scale, WMF bitmap render scale, colour bitmap compression and 1-bit bitmap compression per document; defaults preserve existing output behaviour, and callers can switch colour EMF bitmaps to icFlate or keep the default icJpeg

Version 2.203.0

Added

  • TfrxHotPDFExport gained an ExportMode property and TfrxHotPDFExportMode enum: the default hemPageMetafile preserves the original whole-page preview export behaviour, while hemObjectCanvas lets FastReport draw TfrxView objects one by one during the ExportObject traversal and then HotPDF imports the current page metafile, useful for FastReport integration scenarios requiring object-level export-order control

Version 2.202.0

Added

  • Added native JBIG2 monochrome image output: THPDFImageCompressionType now includes icJBIG2, and AddImage / AddImage(FileName) can write 1-bit bitmaps as PDF 1.4+ /JBIG2Decode image streams; when no external encoder backend is registered it uses the built-in lossless MMR generic-region path, and retains the extension mechanism that prioritises a registered backend

Version 2.201.0

Added

  • Added JBIG2 backend bridging and a native TDBGrid PDF export adapter: now exposes RegisterJBIG2DecoderBackend, RegisterJBIG2EncoderBackend, capability probing and encoder/decoder delegate classes, returning False when no production backend is registered; DBGridHotPDFExport can export the visible columns of a VCL TDBGrid or the visible fields of a dataset as a paginated table to a file or stream, restoring the original dataset bookmark after export

Version 2.200.4

Fixed

  • The E-Invoice demo now adds ChargeTotalAmount and AllowanceTotalAmount to the header summary for the ZUGFeRD 1.0 COMFORT profile: the ZUGFeRD 1.0 COMFORT schema requires each amount element exactly once, and missing elements caused the invoice data to fail ZUGFeRD/Factur-X business-rule validation

Version 2.200.3

Added

  • The E-Invoice demo now includes ZUGFeRD 1.0 COMFORT and ZUGFeRD 2.0 BASIC profiles: the first generates invoice XML for the legacy CrossIndustryDocument 1p0 schema, while the second uses the CrossIndustryInvoice 100 schema and zugferd-invoice.xml, and both pass the built-in Factur-X/ZUGFeRD validation
  • The E-Invoice demo now includes a PDF/A conformance-level selector, so generation can override the profile default with PDF/A-3b or PDF/A-3u

Version 2.200.2

Fixed

  • Preflight reports now mark non-PDF inputs without a PDF header as failed for loadable pages instead of accepting a fallback page count from the loader

Version 2.200.1

Fixed

  • ZUGFeRD and Factur-X validation now decodes Flate-compressed embedded invoice XML and XMP metadata from loaded PDFs, recognises attribute-style PDF/A identifiers, and accepts XRECHNUNG invoice XML files that use /AFRelationship /Source

Version 2.200.0

Added

  • Loaded Factur-X and ZUGFeRD hybrid invoices can now be checked with a structured validation report that identifies PDF/A-3 metadata, Catalog /AF registration, EmbeddedFiles name-tree registration, XMP filename consistency, profile filename rules, /AFRelationship rules, and XML guideline alignment

Version 2.199.0

Added

  • Loaded PDF/A-3 hybrid invoice files can now be inspected with Factur-X and ZUGFeRD reader APIs that expose the loaded catalog, EmbeddedFiles entries, embedded XML bytes, document XMP metadata, detected invoice profile details, and invoice XML extraction

Version 2.198.1

Added

  • Factur-X PDF/A-3 workflows now expose FacturXWarnings so callers can detect additional supporting attachments whose MIME types fall outside the recommended PDF, text, image, CSV, XML, JSON, spreadsheet, and ODS supporting-document formats without rejecting the attachment

Version 2.198.0

Added

  • PDF/A-3 Factur-X invoice embedding now accepts the French EXTENDED-CTC-FR and EXTENDED-B2B-FR conformance levels, validating them against the Factur-X 1.09 EXTENDED guideline identifier before writing the hybrid invoice metadata

Version 2.197.18

Fixed

  • PDF/A-3 Factur-X validation now treats COMFORT as a ZUGFeRD 1.0-only profile name, rejecting current factur-x.xml containers before they can write mismatched hybrid invoice metadata

Version 2.197.17

Fixed

  • PDF/A-3 ZUGFeRD 2.0 metadata now writes the legacy urn:zugferd:pdfa:CrossIndustryDocument:invoice:1p0# PDF/A extension namespace while preserving zf:Version as 2p0, matching hybrid invoice validation rules before the container is finalized

Version 2.197.16

Fixed

  • PDF/A-3 Factur-X validation now accepts German MINIMUM and BASIC WL invoice containers with AFRelationship Data, enforces Alternative relationships for German main profiles and XRECHNUNG, and still leaves fiscal eligibility and invoice business rules to XML validation

Version 2.197.15

Fixed

  • PDF/A-3 XRechnung metadata now preserves explicit Version values 1.2, 2.0, 2.1, 2.2, 2.3, and 3.0, and rejects a version that does not match the XML guideline/profile identifier

Version 2.197.14

Fixed

  • PDF/A-3 Factur-X validation now accepts EN16931 as an XMP/profile alias for EN 16931, matching current sample metadata while preserving existing EN 16931 calls

Version 2.197.13

Fixed

  • PDF/A-3 Factur-X validation now accepts short urn:factur-x.eu:1p0:basic and urn:factur-x.eu:1p0:extended XML guideline identifiers for BASIC and EXTENDED invoices while continuing to reject malformed profile strings before writing the hybrid invoice container

Version 2.197.12

Fixed

  • PDF/A-3 ZUGFeRD 1.0 metadata now accepts the legacy ZUGFeRD-invoice.xml filename, COMFORT profile, urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0# PDF/A extension namespace, and matching urn:ferd:CrossIndustryDocument:invoice:1p0 XML guideline identifiers before writing the hybrid invoice container

Version 2.197.11

Fixed

  • PDF/A-3 ZUGFeRD 2.0 metadata now accepts the zugferd-invoice.xml filename with Version 2p0, emits the ZUGFeRD PDF/A extension namespace, and validates the matching urn:zugferd.de:2p0 XML guideline identifiers before writing the hybrid invoice container

Version 2.197.10

Fixed

  • PDF/A-3 XRechnung metadata now writes fx:Version as 3.0 while keeping ordinary Factur-X metadata at 1.0, matching the profile-specific XMP version expected by XRechnung hybrid invoice workflows

Version 2.197.9

Fixed

  • PDF/A-3 Factur-X validation now checks the invoice XML guideline/profile identifier against ConformanceLevel before embedding the Associated File, so BASIC, EN 16931, EXTENDED, and XRECHNUNG metadata cannot be mixed with a different invoice XML profile

Version 2.197.8

Fixed

  • PAdES B-T CMS signing now rejects empty or non-ContentInfo DER signature-time-stamp callback results before the CMS container is written, preventing explicit timestamp workflows from silently producing an unstamped signature

Version 2.197.7

Fixed

  • PAdES E-EPES CMS signing now rejects missing or partial signature-policy-identifier options before the CMS container is built, preventing an invalid E-EPES signature from silently degrading to an E-BES-style attribute set

Version 2.197.6

Fixed

  • PAdES E-EPES signature placeholders now reject a non-empty Reason before output is written, preventing an invalid combination where the PDF Signature Dictionary /Reason entry appears together with the CMS signature-policy-identifier required by the profile

Version 2.197.5

Fixed

  • PDF/A-3 Factur-X validation now accepts an optional CountryCode policy so current German ZUGFeRD invoices reject MINIMUM and BASIC WL, enforce Alternative relationships for the main profiles, and French Factur-X invoices reject XRECHNUNG before an invalid hybrid invoice container is written

Version 2.197.4

Fixed

  • PDF/A-3 Factur-X validation now accepts an optional CountryCode policy so German ZUGFeRD invoices can enforce Alternative relationships for the main profiles and French Factur-X invoices reject XRECHNUNG before an invalid hybrid invoice container is written

Version 2.197.3

Fixed

  • PDF/A-3 Factur-X validation now rejects mismatched invoice XML filenames and profiles, so xrechnung.xml is accepted only with XRECHNUNG, factur-x.xml is used for the other Factur-X profiles, and legacy XMP version values are refused before an invalid PDF/A-3 invoice container is written

Version 2.197.2

Added

  • PDF/A-3: THotPDF.AddFacturXAssociatedFile now embeds Factur-X or ZUGFeRD invoice XML as an Associated File, registers factur-x.xml or xrechnung.xml in Catalog /AF and /Names /EmbeddedFiles, and emits the matching Factur-X XMP extension metadata for PDF/A-3 invoice workflows

Changed

  • PDF/A-3 and XAdES associated file streams now include /ModDate and raw MD5 /CheckSum in the EmbeddedFile /Params dictionary, and are also registered in the document EmbeddedFiles name tree for extraction tools that require it

Version 2.197.1

Fixed

  • PDF/A-1: cross-reference streams and compressed object streams are now suppressed under PDF/A-1 even when UseXRefStream / UseObjectStreams are enabled, so the classic cross-reference table required by ISO 19005-1 §6.1.4 is always emitted; PDF/A-2 and PDF/A-3 (PDF 1.7) keep honouring both toggles

Version 2.197.0

Changed

  • PDF/A: embedded Unicode subset fonts are now genuinely compacted — the embedded TrueType program is renumbered to a dense glyph range, its declared glyph count is reduced to the glyphs the document actually uses, and the GID-indexed tables a PDF reader never consults for a CIDFontType2 (cmap, GPOS, GSUB, hdmx, LTSH, kern) are dropped, shrinking a typical Arial subset from roughly 310 KB to about 12 KB; page content, widths and ToUnicode are left untouched while an explicit /CIDToGIDMap stream maps them onto the renumbered program and the /CIDSet is sized to match (ISO 19005-2/3 §6.2.11), and non-PDF/A output stays byte-for-byte unchanged

Version 2.196.8

Fixed

  • PDF/A-1: the document Info dictionary now stays equivalent to the XMP metadata packet; the CreationDate / ModDate strings carry the local time-zone offset that matches xmp:CreateDate / xmp:ModifyDate, and an empty Author / Title / Subject / Keywords entry is omitted instead of being written as an empty string, fixing a conformance failure where the Info and XMP values were reported as not equivalent (ISO 19005-1 §6.7.3)

Version 2.196.7

Fixed

  • PDF/A-2 & PDF/A-3: the /CIDSet stream of an embedded subset CIDFont now flags every CID the font program declares, addressing each glyph by its glyph ID rather than by Unicode code point; previously the wrong identifiers were marked and veraPDF reported the embedded subset glyphs as missing (ISO 19005-2/3 §6.2.11)

Version 2.196.6

Fixed

  • PDF/A: markup annotations (Highlight, Underline, Squiggly, StrikeOut, Caret, Ink, Polygon, PolyLine, Redact, Watermark) now carry the required /F print flag under every PDF/A level (ISO 19005-1 §6.5.3 / ISO 19005-2 & PDF/A-3 §6.3.2), and under PDF/A-2 and PDF/A-3 they also receive a normal appearance stream (/AP /N) so they are no longer rejected for lacking an appearance (ISO 19005-2/3 §6.3.3); the Highlight wash uses a Multiply blend so the underlying text stays legible
  • PDF/A: a form push-button configured with a non-standard named action is now rejected when PDFACompliance is set, leaving only the four standard named actions NextPage, PrevPage, FirstPage and LastPage (ISO 19005-1 §6.6.1)

Version 2.196.5

Fixed

  • PDF/A: a font listed in NotEmbeddedFonts is now still embedded when PDFACompliance is set, closing a conformance gap where text drawn through the TextBox / TextOutBox path could leave a non-embedded font in the output (ISO 19005 §6.3 requires every font to be embedded, with no exception)

Version 2.196.4

Fixed

  • PDF/A & PDF/X: form push-button widgets configured with an ImportData action are now rejected when PDFACompliance / PDFXCompliance is set, closing a conformance gap where the prohibited ImportData action (ISO 19005-1 §6.6.1) could still be emitted

Version 2.196.3

Added

  • XFA flatten: calculate evaluation degrades gracefully on unsupported FormCalc constructs (control flow, unknown functions) — the field is left blank rather than crashing or emitting a wrong value

Version 2.196.2

Added

  • XFA flatten: calculate evaluation now resolves .rawValue field paths, aggregates Sum(arr[*].field) over repeating subforms, and computes JavaScript this.rawValue = expr calculations through the same arithmetic core (no JavaScript engine)

Version 2.196.1

Added

  • XFA flatten: calculate scripts with FormCalc arithmetic (+ - * /, parentheses, unary minus, single field references) now compute the field value when the datasets packet carries the inputs

Version 2.196.0

Added

  • XFA flatten: groundwork for calculate-script evaluation — fields with a <calculate> are detected and routed through a value hook (transparent until the arithmetic core lands)

Version 2.195.0

Added

  • XFA <exData> rich-text flattening now turns inline <a href> elements into rendered text plus PDF URI Link annotations with invisible borders
  • XFA flatten: exData rich text degraded-markup handling — unsupported inline tags (<b>, <em>, etc.) now fall back to plain-text extraction instead of being silently skipped
  • XFA flatten: validated exData rich text rendering against the real-world corpus; the 55 previously-skipped <exData contentType="text/html"> draws are now recovered as styled text

Version 2.193.0

Added

  • XFA <exData> rich-text flattening now renders multiple <p> paragraphs stacked vertically, each occupying its own line, rather than only the first paragraph
  • Paragraphs honour the CSS text-align property on <p>: center and right shift the run group within the draw-box width; justify spreads the slack evenly across the inter-run gaps
  • Paragraph spacing is read from margin-top, margin-bottom, space-before, and space-after in the <p> style attribute, giving control over vertical gaps between paragraphs

Version 2.192.0

Added

  • Flattening an XFA <exData> rich-text draw now lays several <span> runs from one paragraph side by side, each keeping its own inline CSS — bold, italic, colour and font size — where the previous step rendered only the first span
  • Each run is placed by its measured width, so the differently styled spans flow left to right across the line without overlapping
  • Paragraph stacking with text alignment, and clickable links, follow in later updates

Version 2.191.0

Added

  • Flattening an XFA form now renders an <exData> rich-text value (a text/html draw) as a styled text run instead of skipping it — inline CSS on the span sets bold, italic, color and font size
  • This first step covers a single styled run (one paragraph, one span); multi-span flow, paragraph alignment and clickable links follow in later updates

Version 2.190.43

Fixed

  • The object-stream recovery fallback now locates a member by its position within the stream rather than treating that position as a PDF object number, so the fallback actually returns data instead of always coming up empty
  • That fallback no longer labels every recovered object as a page — only an object whose raw data declares a page is typed as one, so unrelated object-stream members no longer inflate the page count — and an object left in the indirect-object list after a parse error is now removed before it is freed

Version 2.190.42

Security

  • Importing a PKCS#12 (.pfx/.p12) key file now rejects an out-of-range PBKDF2 iteration count instead of truncating it into a 32-bit field; a crafted file can no longer request billions of key-derivation rounds (a denial of service) or wrap the count to an unintended value

Version 2.190.41

Fixed

  • Recovering a damaged compressed stream no longer accepts a partially decompressed result as success when the data is corrupt partway through; the truncated output is discarded and the next decompression configuration is tried, so callers receive complete data or a clean failure

Version 2.190.40

Fixed

  • Copying a page that uses several graphics-state (ExtGState) resources no longer maps them all to a single name and discards all but one; each copied state now receives a distinct name

Version 2.190.39

Fixed

  • Adding a hyperlink to a loaded page whose existing /Annots entry is a dangling reference or not an array no longer crashes; a fresh annotation array is installed in that case instead of casting the unusable value

Version 2.190.38

Fixed

  • Splitting or extracting pages no longer assigns hard-coded sample dimensions to an image that is missing its /Width or /Height, which had stamped unrelated documents' images with a fixed size; a missing dimension is now left untouched
  • Content-stream selection during page extraction no longer gives a fixed bonus to the object numbered 192, which had skewed stream scoring for any document that happened to use that object number

Version 2.190.37

Fixed

  • Repairing a page that references a missing image (XObject) or graphics-state (ExtGState) resource during a copy or split now resolves the source object by its object number instead of treating the number as a list position, so it copies the correct object — or none — rather than an unrelated one, and a failed copy no longer dereferences a nil result

Version 2.190.36

Fixed

  • Editing and re-saving a page whose content is split across multiple content streams no longer renders the earlier streams twice — the merged result is kept in one stream and the others are emptied, and the streams are joined with whitespace so adjacent tokens cannot fuse into an invalid one (ISO 32000-1 §7.8.2)
  • A page that has an /XObject resource but no /Font resource no longer leaves a previous page's font names in place; the font-name list is now reset instead of the image-name list

Version 2.190.35

Fixed

  • Subsetting an embedded TrueType font with a corrupt glyph-location (loca) table no longer reads out of bounds — a reversed or out-of-range offset pair is now skipped instead of underflowing into a huge copy length, and the horizontal-metrics (hmtx) table is bounds-checked before it is copied

Version 2.190.34

Fixed

  • Copying document metadata (page labels and named destinations) into a document that already has those entries no longer leaks the previous values; the entries are now replaced through the dictionary's own replace path instead of being detached without release

Version 2.190.33

Fixed

  • Loading certain PDF 1.6 documents whose pages are reconstructed from object streams no longer shares dictionary values between two page objects, which could free the same object twice when the document was released; the values are now deep-copied

Version 2.190.32

Fixed

  • Scanning page content to detect simple text no longer raises a range error on a content line that is empty after trimming or that lacks a closing parenthesis; the check now handles the empty case and bounds its scan to the string length

Version 2.190.31

Fixed

  • Rendering text that contains the code point U+FFFF no longer writes one element past the end of a font's internal glyph table; the table is grown as needed before the glyph entry is stored

Version 2.190.30

Fixed

  • BeginParagraph now rejects a paragraph index of 0 instead of reading before the start of the paragraph array, and releases any paragraph already in progress so repeated calls no longer leak
  • EndParagraph now clears its reference after freeing the current paragraph, so calling it twice no longer frees the same object a second time

Version 2.190.29

Security

  • AES initialisation vectors and keys are no longer generated from a predictable, non-cryptographic fallback when the system random source is briefly unavailable; the library now refuses to encrypt rather than producing a weak, guessable IV or key

Fixed

  • Computing an MD5 digest of an empty string no longer dereferences an invalid pointer

Version 2.190.28

Fixed

  • Rendering EMF metafiles that contain PolyDraw records now applies each point's own type flag instead of reading the next point's flag — and, for the 16-bit variant, instead of reusing the first point's flag for every point — so line, curve, and close-figure segments are drawn correctly and the parser no longer reads past the end of the point array

Version 2.190.27

Fixed

  • Decoding an LZWDecode stream that declares a TIFF Predictor 2 with a zero Columns or Colors value in its decode parameters no longer raises a division-by-zero error; the predictor step is skipped when those values cannot be used
  • The single-argument LZW decoder now fully initialises its decode parameters, removing any reliance on uninitialised stack values

Version 2.190.26

Fixed

  • Code 93 check-character calculation no longer resets the wrong weight counter, so data longer than 14 characters now produces the correct check symbols
  • Code 128 set B now encodes the lowercase letter i correctly instead of substituting a space, which had corrupted the symbol and its checksum
  • MSI barcode check-digit calculation now uses the numeric value of each digit rather than its character code, matching standard MSI readers
  • Barcodes drawn with a large module width no longer overflow an internal counter, which could produce negative or scrambled bar widths
  • Drawing a barcode whose data fails validation no longer leaks the saved font, pen, and brush objects
  • The standalone DrawText routine now restores the canvas font it actually saved, instead of resetting the caller's font to a blank default

Version 2.190.25

Fixed

  • Decoding a truncated or malformed ASCIIHexDecode, ASCII85Decode, or RunLengthDecode stream that lacks its end-of-data marker no longer loops forever consuming memory — the decoders now stop when the input is exhausted instead of re-processing a stale byte
  • The ASCIIHexDecode filter again rejects illegal hexadecimal characters; an operator-precedence error had let some out-of-range bytes slip past the validation check

Version 2.190.24

Fixed

  • Copying or merging objects whose nested dictionaries are reconstructed during document recovery no longer corrupts the dictionary or leaks memory — the routine stored object instances into slots that hold internal item records, and discarded entries without releasing them; replacements and removals now operate on the item records correctly

Version 2.190.23

Fixed

  • Embedding a Type 0 (CID) font now keeps its /ToUnicode map even when compressing the character map yields no output — the fallback path previously skipped registering the map, so text in that font could not be copied or extracted, and it could release its working streams twice; the map is now always stored, uncompressed if necessary, and each stream is released exactly once

Version 2.190.22

Fixed

  • Loading a cross-reference table that references objects with a generation number of 10 or higher — common in PDFs revised by many incremental updates — no longer writes outside the internal duplicate-detection table; such entries are now accepted without de-duplication instead of corrupting the heap, and a malformed entry whose object number reads as zero is skipped rather than indexing before the start of the table

Version 2.190.21

Fixed

  • Passing a font name of 32 characters or more to SetFont no longer overruns the fixed-size face-name field of the internal font structure — the name is now copied with the same length-limited routine already used to probe installed fonts, so an over-long face name is safely truncated instead of corrupting the stack

Version 2.190.20

Fixed

  • Adding a non-monochrome image with CCITT Group 3/4 compression, or as a 1-bit image mask, no longer corrupts the heap — the image builder previously released its stream and swallowed the conversion error on the failure path, leaving the destructor to release the same stream a second time; the error now propagates so the image object fails to build cleanly instead
  • Building the colour lookup table for an 8-bit indexed image no longer requests one more palette entry than the lookup buffer can hold, removing an out-of-bounds write that could occur when the source bitmap carries a full 256-entry palette

Version 2.190.19

Security

  • Decoding an ASCII85Decode stream that uses the z all-zeros shorthand no longer writes beyond the decode buffer — the output buffer is now sized for the maximum possible expansion, fixing a heap overflow that a crafted PDF stream could trigger

Version 2.190.18

Security

  • Importing a malformed PKCS#12 (.pfx/.p12) credential or certificate during digital signing no longer reads past the end of its buffer — an oversized ASN.1 length field that previously slipped past the bounds check is now rejected, so untrusted signing material can no longer trigger an out-of-bounds read

Version 2.190.17

Added

  • The standard document loader now reads hybrid-reference PDFs — files whose cross-reference table trailer carries an /XRefStm side section, as produced by common office exporters — so LoadFromFile loads the objects such files keep in compressed object streams instead of seeing only a partial document
  • Cross-reference streams and object streams stored without a compression filter now load correctly; ISO 32000-1 allows the /Filter key to be absent

Fixed

  • Re-saving a loaded hybrid-reference document with AES-256 protection — ActivateProtection plus SaveLoadedDocument, or EncryptFile — no longer fails with a list-index error, and the encrypted output retains every object of the source file

Version 2.190.16

Changed

  • Locating the object header and stream keyword during Direct File API rewrites no longer rescans each object's preview from the beginning or duplicates it for retry, making AES-256 encryption of a 2 GB benchmark document with 1.67 million objects about 2.3 times faster (49 to 14 seconds), decryption about 2.7 times faster (43 to 16 seconds), and a full direct rewrite drop from about 10 to 6 seconds

Version 2.190.15

Fixed

  • LoadFromFile and LoadFromStream no longer abort before parsing begins when bytes precede the %PDF header — files saved inside HTTP or Signed HTTP Exchange (SXG) wrappers, mail captures, and similar containers now reach the document recovery fallbacks instead of failing with a version-number conversion error
  • Recovery loading of documents with unusable cross-reference data now takes the page count from the live page tree instead of counting every page-type object in the file, so a page deleted by an incremental update is no longer resurrected and the reported count matches other readers
  • When a damaged document is recovered by scanning, object revisions written later in the file now take precedence over earlier revisions of the same object number, matching incremental-update semantics

Version 2.190.14

Added

  • The Direct File API now reads hybrid-reference PDFs — files whose cross-reference table carries an /XRefStm side section, as produced by common office exporters — so direct open, copy, rewrite, and AES-256 encryption see the compressed objects those files keep in object streams instead of missing them

Fixed

  • Objects freed by a newer revision of an incrementally updated PDF with a traditional cross-reference table can no longer be resurrected from an older revision during a direct rewrite
  • Free cross-reference entries no longer contribute bogus object boundaries, which could truncate objects stored near the start of a file during direct rewrites of documents with recycled object numbers

Version 2.190.13

Changed

  • Opening PDFs whose document catalog lives inside a compressed object stream with DAOpenFileReadOnly or DACopyFile no longer falls back to a full document load to discover the page count: on a 1.25 GB benchmark file the direct open dropped from about 0.9 seconds to a few milliseconds, and the lightweight copy roughly halved

Fixed

  • The Direct File API now follows the cross-reference stream /Prev chain, so incrementally updated PDFs expose all of their objects to direct open, copy, rewrite, and AES-256 encryption instead of only the most recent revision
  • Objects freed by a newer revision of an incrementally updated PDF can no longer be resurrected from an older cross-reference section during a direct rewrite

Version 2.190.12

Changed

  • The Direct File API rewrite paths — EncryptFile, DecryptFile, and DASaveAsFile after document changes — now read the source through a sliding window and aggregate output writes, so processing very large PDFs with millions of objects runs several times faster: in benchmarks on a 2 GB document, AES-256 encryption dropped from about 153 to 49 seconds, decryption from about 121 to 43 seconds, and a full direct rewrite from about 48 to 10 seconds
  • Object bodies already held in memory are no longer fetched from disk a second time while a direct rewrite copies them to the output file
  • Resolving indirect /Length references during a direct AES-256 rewrite no longer reopens the source file for each lookup

Version 2.190.11

Added

  • Form flattening is now easier to drive from application code: FlattenFormFields returns the number of AcroForm fields it flattened, while new HasFormFields and FormFieldExists helpers let applications check loaded PDFs or in-progress forms before removing interactive fields
  • The Preflight CLI demos now cover CSV output, profile and preset validation, exact single-file output paths, PDF/VT validation reports, aggregate summaries, and dashboard links, while the Preflight Report GUI demos validate profiles before generation and keep profile-filtered CSV output in CSV form

Version 2.190.10

Fixed

  • After MovePage the document once again has an active current page, matching DeletePage: drawing right after a move now works without first selecting a page, the drawing lands on the same page that was current before the move, and closing the document immediately after a move reliably writes every font through the regular path

Version 2.190.9

Fixed

  • Documents finalised right after MovePage no longer lose their fonts: the shared font data deferred from already-written pages is now always emitted at document close, even when no page is active at that moment, so every page's text keeps its font resources and renders correctly
  • Returning to an earlier page and selecting an additional font no longer overwrites a font already used on that page: resource names pending in the shared-font registry are now reserved, so each font keeps its own name and both render correctly
  • If compressing an embedded font ever fails, the font program is now stored uncompressed and the font object is completed normally, instead of producing an incomplete font entry that some viewers could not render
  • With SimpleLatinFonts enabled, text drawn with Symbol or ZapfDingbats keeps its symbolic meaning: symbolic faces are excluded from the unembedded plain-text shortcut, which would have changed which glyphs appear (ISO 32000-1 §9.6.6.2)
  • Generating PDFs no longer raises integer-overflow errors in projects compiled with overflow checking enabled when font subsetting is active, and reusing one component instance across several documents no longer leaks memory in rare workflows that restart or restructure a document mid-way

Version 2.190.8

Fixed

  • Contextual kerning no longer applies twice when a font supplies several alternative context rules in one OpenType lookup: rule subtables are now tried in order and the first match wins, as the OpenType specification requires
  • Overlapping context matches no longer stack their adjustments: after a contextual positioning rule fires, matching resumes past the matched glyph span, so repeating patterns receive each kerning adjustment exactly once
  • Hardened OpenType layout parsing against truncated or malformed fonts: nested lookup dispatch in both the positioning and substitution engines now validates the full extent of each table record before reading it

Version 2.190.7

Fixed

  • Copy/paste and text extraction now recover the original characters when OpenType features substitute a character in a chain, such as small capitals refined by stylistic alternates or oldstyle figures refined by tabular figures: the ToUnicode CMap maps the final glyph back to the source text instead of an internal Private Use Area codepoint (ISO 32000-1 §9.10.3)
  • The fractions feature (frac) no longer emits a half-converted mix of fraction and plain glyphs when the internal substitute-codepoint budget runs out mid-sequence: the affected text run now falls back to the original glyphs as a whole

Changed

  • The lookups of an OpenType feature now apply in LookupList index order as the OpenType specification requires, independent of the order the font lists them in its feature table

Version 2.190.6

Fixed

  • Multiple accents on one ligature now position correctly in right-to-left text: the second and later marks attach to their ligature component (GPOS mark-to-ligature) instead of dropping to the baseline
  • Stacked accents that share a ligature component, such as shadda followed by a vowel sign, now stack on each other instead of overlapping at the same anchor
  • Ligature component counts now follow the font's GPOS attachment data, so pre-composed ligature characters with long text-extraction mappings no longer push trailing accents out of range
  • Single supplementary-plane characters are no longer mistaken for ligatures during mark placement
  • An accent the font matches as a real ligature component is no longer drawn a second time next to the ligature
  • Ligature component metadata no longer leaks between unrelated text-output calls

Version 2.190.5

Added

  • Hanifi Rohingya text gains right-to-left cursive shaping through the new AutoShapeHanifiRohingya property: when enabled, the engine selects the font's initial, medial, final, and isolated letter forms so the script renders with its proper joining behavior
  • Tai Viet text gains visual reordering through the new sfTaiVietReorder shaping flag: vowels that precede their consonant in visual order now display in the correct position instead of following typing order
  • Meetei Mayek text gains syllable reordering through the new sfMeeteiMayekShaping flag: left vowel signs move in front of their consonant for correct visual display
  • All three scripts follow the existing opt-in model: documents that do not enable the new property or flags produce byte-identical output

Version 2.190.4

Fixed

  • Left-to-right text is no longer reversed when a character's font glyph index happens to fall into the numeric window the right-to-left detector reserves for Hebrew and Arabic codepoints; the detector now skips glyph-index payloads entirely
  • Documents mixing uncommon Latin, Greek, or Cyrillic letters from large fonts render in their original order in all cases

Version 2.190.3

Fixed

  • A lone high surrogate followed by certain BMP characters no longer forges a supplementary-plane codepoint during right-to-left detection: malformed UTF-16 input now keeps its logical order instead of being grouped and reversed as Adlam or Hanifi Rohingya text
  • Well-formed surrogate pairs for Adlam and Hanifi Rohingya are unaffected and continue to shape right-to-left

Version 2.190.2

Fixed

  • Script shaping flags are now isolated per writing system: enabling sfMeeteiMayekShaping alone no longer reorders Devanagari, Bengali, Tamil, Khmer, Myanmar, or other Indic text, and enabling sfIndicShaping or sfIndicGSUB alone no longer affects Meetei Mayek text
  • Output stays byte-identical for every script whose shaping flag is off, restoring the documented opt-in behaviour for mixed-script documents

Added

  • ApplyIndicReorder gains an overload taking an explicit feature set for flag-scoped reorder queries; the existing parameterless form keeps full-script coverage

Version 2.190.1

Fixed

  • Completed the Meetei Mayek letter classification against the Unicode Character Database: the letters PHAM, ATIYA, and GOK through BHAM (U+ABD0–U+ABDA) now start syllables, so left vowel signs and stacked marks following them reorder correctly when sfMeeteiMayekShaping is enabled
  • Words built on the very common vowel-carrier letter ATIYA previously kept their vowel signs in logical order; they now produce the same visual ordering as the rest of the Meetei Mayek block

Version 2.190.0

Fixed

  • Combining marks (accents, Arabic harakat, Hebrew niqqud, Thai and Lao vowel signs) now render at their correct position above or below the intended letter in all PDF viewers; previously they could appear shifted toward the start of the line
  • Stacked combining marks now accumulate onto the mark below them instead of collapsing onto the base letter when the font also carries a direct base anchor for the upper mark
  • Cursive connection offsets and mark-to-ligature attachments follow the PDF text-object specification (ISO 32000-1), eliminating positioning drift after decorated text
  • Text following a positioned mark or cursive run continues at the correct pen position

Changed

  • Kerning, mark positioning, and cursive attachment now combine within the same text run instead of excluding one another

Version 2.189.1

Fixed

  • Right-to-left text now applies the advance component of GPOS pair kerning to the run width, so text following a kerned right-to-left run continues at the correct position
  • Kerned right-to-left runs that carry a vertical rise apply the same advance correction on their final glyph

Version 2.189.0

Added

  • Expanded opt-in OpenType shaping with contextual GPOS placement formats, distance positioning, Khmer and Myanmar reorder integration, vertical alternates for vertical fonts, and additional typography feature switches for case forms, figure widths, scientific inferiors, numerators, denominators, and slashed zero

Changed

  • AES-256 file encryption and decryption now use a direct file rewrite path for large PDFs, avoiding full-document memory loading for supported inputs including multi-gigabyte files
  • Win32 AES-256-CBC now uses the same CPUID-gated AES-NI backend as Win64, with automatic pure-C fallback on processors without AES-NI support

Version 2.188.2

Added

  • sfStylisticAlternates now automatically applies OpenType salt substitutions during Unicode text output when the registered font exposes matching stylistic alternates

Fixed

  • GPOS pair and mark-positioning lookups now reject malformed class and anchor offsets whose large font counts could overflow 32-bit arithmetic, preventing unsafe reads from damaged or hostile font data
  • GPOS mark-positioning lookups now honor LookupFlag mark filtering, so fonts that request ignored marks, mark attachment types, or mark filtering sets no longer apply those mark anchors by mistake
  • Adlam positional shaping now uses the same Unicode map availability guard as the Syriac, N'Ko, and Mongolian shaping paths

Version 2.188.1

Fixed

  • Right-to-left Arabic and Hebrew text output now keeps GPOS pair kerning active when mark positioning is also enabled, so harakat and niqqud are anchored without losing base-glyph spacing adjustments

Version 2.188.0

Added

  • New sfFractions shaping option automatically applies OpenType frac substitutions during Unicode text output, including numerator digits, the fraction slash, and chained-context denominator digits with ToUnicode mappings back to the original text

Version 2.187.0

Added

  • New shaping options automatically apply OpenType single-substitution typography features during Unicode text output: sfSmallCaps for smcp, sfCapsToSmallCaps for c2sc, sfOldstyleFigures for onum, sfLiningFigures for lnum, sfSuperscripts for sups, sfSubscripts for subs, and sfOrdinals for ordn

Version 2.186.0

Added

  • New sfDiscretionaryLigatures and sfHistoricalLigatures shaping options automatically apply OpenType dlig and hlig lookups during Unicode text output, emitting font-native ligature glyph IDs with ToUnicode mappings while remaining off by default

Version 2.185.1

Fixed

  • Arabic Extended-B letters U+0870-U+089F now participate in producer-side Arabic joining and native GSUB positional shaping when Arabic auto-shaping is enabled, so fonts with matching OpenType Arabic features can emit connected forms with ToUnicode mappings

Version 2.185.0

Added

  • Native Arabic GSUB shaping for opt-in Arabic text output: when sfArabicGSUB is enabled, HotPDF now applies the registered font's init, medi, fina, isol, rlig, calt, and rclt lookups to logical Arabic runs and emits the resulting font-native contextual glyph IDs with ToUnicode mappings
  • New sfCursiveAttachment shaping option applies OpenType GPOS cursive entry/exit anchors during Unicode text output, allowing connected Arabic glyphs shaped through the native GSUB path to align through the font's own curs data

Version 2.184.2

Fixed

  • Right-to-left Adlam fallback text now preserves valid UTF-16 surrogate-pair order when a font cannot apply Adlam positional substitutions, and N'Ko U+07FA now acts only as a join-causing character so adjacent N'Ko letters connect without replacing U+07FA with a positional form

Version 2.184.1

Fixed

  • Mark-to-ligature placement now also covers right-to-left Arabic ligatures: a harakat on a ligature such as the Allah ligature is placed on the correct ligature component, whereas the per-component placement previously applied only to left-to-right text and right-to-left harakat stayed at the ligature's plain advance width; already-formed Arabic ligatures (for example the Allah and lam-alef ligatures) are now recognized for component tracking, and the mark-to-ligature option remains off by default

Version 2.184.0

Added

  • Producer-side cluster and component tracking for the text shaping pipeline: as ligatures are formed, the engine now records which original characters each output glyph covers and how many ligature components it carries, laying the groundwork for precise mark placement and text extraction on ligated runs
  • Combining marks are now attached to the correct component of a ligature (OpenType GPOS mark-to-ligature) when the new mark-to-ligature shaping option is enabled, for left-to-right ligated text; output is unchanged when the option is off
  • Multi-component ligatures produced by this path carry precise text-extraction mappings, so copy and paste recovers the original character sequence

Version 2.183.0

Added

  • Javanese script preprocessing for correct vowel placement: when the Javanese reordering option is enabled, the pre-base vowel signs (taling and dirga mure), which are stored after a consonant but displayed to its left, are moved ahead of the consonant cluster (including stacked conjuncts joined by pangkon) before rendering, so the text is laid out in correct visual order; output is unchanged when the option is off

Version 2.182.0

Added

  • Hebrew text preprocessing for correct vowel-point placement: when the Hebrew reordering option is enabled, the points that follow a letter (vowel points, dagesh, the shin and sin dots, and cantillation marks) are put into their canonical order before rendering, so the mark-positioning step places them correctly even when the source stores them in a different order; output is unchanged when the option is off

Version 2.181.0

Added

  • Thai and Lao text preprocessing for correct mark placement: when the Thai/Lao reordering option is enabled, the SARA AM vowel sign is split into its above and trailing parts so an accompanying tone mark lands in the right place, and stacked vowel and tone marks are put into their canonical order before rendering; this lets the mark-positioning step align tones and vowels correctly, and output is unchanged when the option is off

Version 2.180.0

Added

  • Producer-side automatic shaping for Adlam text (the West African Fula script, U+1E900-U+1E95F in the Supplementary Multilingual Plane): when the Adlam auto-shaping option is enabled, each letter is rendered in its correct cursive joining form (isolated, initial, medial, or final) using the font's OpenType positional substitutions, with the surrogate-pair encoding of these characters handled correctly and copy/paste recovering the original letters; output is unchanged when the option is off

Version 2.179.0

Added

  • Producer-side automatic shaping for N'Ko text (the West African Manding script, U+07C0-U+07FF): when the N'Ko auto-shaping option is enabled, each letter is rendered in its correct cursive joining form (isolated, initial, medial, or final) using the font's OpenType positional substitutions, and copy/paste still recovers the original letters; output is unchanged when the option is off

Version 2.178.0

Added

  • Vertical text output now applies OpenType vertical kerning: when the vertical-kerning shaping option is enabled and a vertical font carries vkrn / vpal data, the spacing between stacked glyphs is tightened or loosened according to the font's vertical pair adjustments; output is unchanged when the option is off

Version 2.177.0

Added

  • Support for reading OpenType GPOS vertical kerning (the vkrn feature) and vertical proportional alternates (the vpal feature), exposing the vertical advance adjustment a font defines between stacked glyphs in vertical writing so it can be applied to vertical text output

Version 2.176.0

Fixed

  • Kerning now applies the GPOS glyph placement offsets (horizontal XPlacement and vertical YPlacement) carried by a font's pair and single positioning, which were previously read but discarded; fonts that fine-tune individual glyph positions through their kern feature now render those offsets in addition to the advance adjustment, for both left-to-right and right-to-left text

Version 2.175.0

Fixed

  • Layered combining marks in right-to-left text (such as an Arabic letter carrying a shadda with a vowel above it, or stacked Hebrew points) are now positioned correctly: each additional mark stacks onto the mark it sits on instead of collapsing onto the base letter, matching the mark-to-mark stacking already applied to left-to-right text

Version 2.174.0

Added

  • Support for OpenType GPOS mark-to-ligature attachment (LookupType 5), reporting the placement of a combining mark (such as an Arabic vowel or Quranic mark) onto a specific component of a ligature glyph, so each mark anchors to its own part of a multi-letter ligature rather than to a single base position

Version 2.173.0

Added

  • Support for reading OpenType GPOS cursive attachment (LookupType 3), exposing the entry and exit connection anchors that cursive scripts such as Arabic Nastaliq use to align joined letters along a flowing baseline

Version 2.172.0

Added

  • Kerning is now applied to right-to-left text (such as Arabic and Hebrew) when kerning is enabled; previously the right-to-left show path positioned combining marks only and left kerning unapplied
  • OpenType GPOS contextual kerning (LookupType 7 Context and LookupType 8 Chained Context) is now emitted for both left-to-right and right-to-left text, so context-dependent kerning — notably Arabic kerning that several fonts express purely through chained-context lookups — tightens the generated output instead of being read but discarded

Version 2.171.0

Added

  • Support for OpenType GPOS contextual kerning (LookupType 7 Context and LookupType 8 Chained Context positioning), so context-dependent kerning carried by these lookups — used by Arabic and by some Latin, Hebrew and Syriac fonts — is now read from the font and made available for text positioning, complementing the existing pair-kerning support that covered only LookupType 1 and 2

Version 2.170.0

Added

  • Optional automatic application of the OpenType locl (Localized Forms) feature, selecting locale-specific letter shapes (such as Serbian and Bulgarian Cyrillic forms or Turkish dotless i) when a shaping language is set

Version 2.169.0

Added

  • Optional automatic application of the OpenType calt (Contextual Alternates) feature to text under the active script, enabled via the contextual-alternates shaping option; unencoded contextual glyphs are embedded with a ToUnicode mapping so copy and paste recover the original text

Version 2.168.0

Added

  • Optional automatic application of the OpenType rclt (Required Contextual Alternates) feature to shaped Arabic text, enabled via the contextual-alternates shaping option, so contextual letter selection no longer requires a downstream shaper

Version 2.167.0

Added

  • Automatic producer-side GSUB shaping for Devanagari and the other Indic scripts handled by the Indic reordering pipeline: when Indic GSUB shaping is enabled, each syllable is reordered and then shaped through the loaded font's OpenType Indic features (half-forms, reph, below-base and post-base forms, conjuncts and presentation forms), so clusters such as क्ष display as a single conjunct glyph instead of unshaped base letters, without relying on a viewer-side shaper
  • The new Indic GSUB shaping is a separate opt-in mode from the existing reorder-only Indic option, so generated output is unchanged unless it is enabled
  • Producer-side complex-shaper output now carries ToUnicode reverse mappings on its synthetic shaping codepoints, so copy and paste of shaped Indic clusters (and the other GSUB-shaped scripts that emit synthetic glyphs) recovers the original source text

Version 2.166.0

Added

  • Automatic producer-side shaping for the Mongolian script (U+1820-U+18AA, covering the Todo, Sibe, Manchu and Ali Gali letters as well as basic Mongolian), selecting initial / medial / final / isolated letterforms via the loaded font's OpenType GSUB tables when Mongolian shaping is enabled, so generated PDFs display correctly joined Mongolian without relying on a viewer-side shaper
  • Correct text extraction (copy and paste) for shaped Mongolian letters through ToUnicode reverse mapping

Version 2.165.1

Fixed

  • Shaped Syriac (U+0700-U+074F) and Arabic Supplement / Extended-A (U+0750-U+077F, U+08A0-U+08FF) words are now laid out right-to-left in the correct order; previously the positional glyphs of these scripts were emitted left-to-right (mirror-reversed) because their shaped forms travel as private-use synthetic codepoints that the right-to-left text splitter did not recognise

Version 2.165.0

Added

  • New SimpleLatinFonts property (default off). When enabled, printable-ASCII text drawn with a standard font (Arial, Helvetica, Times, Courier and the like) is written as a compact unembedded WinAnsi font instead of an embedded glyph-index font, so a page of plain ASCII text needs no embedded font data at all. A single-page ASCII sample drops from about 554 KB to about 2 KB. Text that is not plain ASCII — accented, CJK, right-to-left, or any text using a shaping feature — automatically keeps the embedded path and renders unchanged, and the option is ignored under PDF/A, which requires embedding

Version 2.164.0

Changed

  • A font used on several pages is now embedded only once for the whole document instead of once per page. Previously a two-page document using Arial and Arial Bold stored four copies of the font data; it now stores two, and the saving grows with the page count. The single shared copy carries the union of the glyphs used across all pages, so every page renders and extracts text identically. For example the bundled page-transition sample drops from about 118 KB to about 63 KB, and a document that embeds a full unsubsetted font on many pages shrinks dramatically

Version 2.163.3

Changed

  • The six-letter subset tag added to a subset-embedded font name (for example JEPSCD+ArialMT) is now derived deterministically from the set of glyphs actually used, instead of being generated randomly. Producing the same document twice now yields identical subset tags, keeping output reproducible and matching the ISO 32000 / PDF/A expectation that a subset tag identifies its own glyph subset

Version 2.163.2

Changed

  • Embedded TrueType and OpenType font programs are now always Flate-compressed inside generated PDFs, independent of the document Compression setting. Embedded font data shrinks by roughly half, so any document that embeds fonts is noticeably smaller — a two-page Arial sample drops from about 305 KB to about 118 KB — while on-screen rendering and text extraction stay identical

Version 2.163.1

Fixed

  • Writing text with a valid TrueType font that omits the optional hinting tables (such as an unhinted font build) no longer raises an out-of-memory error. Any text drawn with such a font, including plain Latin, now renders correctly instead of aborting the document

Version 2.163.0

Added

  • Automatic producer-side shaping for the Syriac script (U+0700-U+074F), selecting initial / medial / final / isolated letterforms via the loaded font's OpenType GSUB tables when AutoShapeSyriac is enabled, so generated PDFs display correctly joined Syriac without relying on a viewer-side shaper
  • Correct text extraction (copy and paste) for shaped Syriac letters through ToUnicode reverse mapping
  • Syriac is now recognised as a right-to-left script by RtLTextOut and ShowUnicodeText, so Syriac text is laid out right-to-left

Version 2.162.0

Added

  • Latin standard and contextual ligatures (ff, fi, fl, ffi, ffl and the long-s pairs, U+FB00-U+FB06) are now folded automatically in generated text when the sfStandardLigatures shaping feature is enabled, choosing the ligature glyph from the loaded font's OpenType liga (and clig) tables. Off by default, so existing documents stay unchanged
  • Copy, paste and text search over a folded ligature return the original letters through ToUnicode mapping, so words stay searchable after their fi or fl ligature is applied

Version 2.161.0

Added

  • Tibetan text now renders correctly when sfTibetanShaping is enabled: a root consonant with its subjoined consonants is combined into the proper stacked glyph, and vowel signs compose with their syllable, instead of being drawn as separate unstacked characters. Copy and paste returns the original Tibetan text via ToUnicode mapping. Off by default, so existing documents stay unchanged

Version 2.160.0

Added

  • Groundwork for Tibetan script rendering: the engine can now read a font's OpenType GSUB tables and combine a Tibetan syllable's stacked consonants and composed vowels into the correct glyphs, applying the font's substitution rules in the order it specifies. This release adds the shaping capability only; text output is unchanged until the feature is enabled in a later release. Off by default

Version 2.159.0

Added

  • Right-to-left combining marks - Hebrew niqqud (vowel points) and Arabic harakat - are now positioned on their base consonant within the right-to-left text run when sfMarkPositioning is enabled, using the font GPOS Mark-to-Base anchors, instead of sitting at the default position. Earlier releases positioned marks only in left-to-right scripts (Latin, Thai, Lao). Off by default, so existing documents stay unchanged

Version 2.158.0

Added

  • Mark positioning (sfMarkPositioning) now also recognises marks declared in the OpenType above-base and below-base mark features (abvm / blwm), in addition to the standard mark / mkmk features, broadening coverage for Brahmic and South-East-Asian scripts. Thai and Lao vowel and tone marks are placed on their base consonant via the font GPOS anchors. Off by default, so existing documents stay unchanged

Version 2.157.0

Added

  • Automatic producer-side shaping for Arabic Supplement (U+0750-U+077F) and Arabic Extended-A (U+08A0-U+08FF) letters - used by Sindhi, Kurdish, Rohingya and various African and Central Asian languages - now selects the correct initial, medial, final or isolated form from the loaded font's OpenType GSUB tables when AutoShapeArabic is enabled. These letters have no Unicode presentation forms, so earlier releases could only show their isolated shapes
  • Copy and paste of the newly shaped Supplement and Extended-A letters returns the original characters, via ToUnicode reverse mapping

Version 2.156.0

Added

  • The mark-positioning option (sfMarkPositioning) now also stacks marks on top of other marks using GPOS Mark-to-Mark anchors, so a base letter carrying two or more combining marks - for example a Vietnamese vowel with a circumflex and an acute, or a Thai consonant with a vowel sign and a tone mark - has each mark placed correctly above or below the previous one instead of overlapping. Still off by default, so existing documents stay byte-for-byte unchanged

Version 2.155.0

Added

  • When the new mark-positioning option (sfMarkPositioning) is enabled, combining marks - vowel signs, tone marks, and diacritics used by scripts such as Thai, Lao, and Hebrew, as well as Latin accents - are now placed over, under, or beside their base letter using the font's OpenType GPOS Mark-to-Base anchors, instead of sitting at the default position after the base. The placement is written with PDF text-positioning operators so any reader renders the marks correctly. The option is off by default, so existing documents stay byte-for-byte unchanged

Version 2.154.0

Added

  • New OpenType GPOS mark-positioning query API: GetGPOSMarkOffset and GetGPOSMarkMarkOffset report where a combining mark (such as a vowel sign, tone mark, or accent) should be placed relative to its base glyph or to another mark, by reading the font's GPOS Mark-to-Base and Mark-to-Mark anchor tables. This is a query-only capability in this release and does not change generated output

Version 2.153.0

Added

  • When the new pair-kerning option (sfKerning) is enabled, left-to-right text is now spaced using the font's OpenType GPOS kerning: closely-fitting letter pairs such as AV, To, or Wa are drawn tighter, matching professional typography. The kerning is emitted as PDF TJ arrays so any reader renders the adjusted spacing. The option is off by default, so existing documents stay byte-for-byte unchanged

Version 2.152.0

Added

  • New OpenType GPOS (glyph positioning) pair-kerning query API: GetGPOSPairAdjustment returns the kerning adjustment between a pair of glyphs and HasGPOSKerning reports whether the active font advertises GPOS kerning; both read the font's GPOS Pair and Single adjustment tables (including Extension-wrapped lookups) across all scripts. This release adds the query capability only and does not change any generated output

Version 2.151.0

Added

  • Indic scripts (Devanagari and the other supported Indic scripts) are now reordered automatically when the sfIndicShaping option is enabled: each syllable is rearranged (for example a leading Repha or a pre-base "i" vowel sign is moved to its visual position) before the text is written, so a reader that applies the font's shaping renders the cluster correctly. The option is off by default, leaving existing documents byte-for-byte unchanged

Version 2.150.0

Added

  • When Arabic auto-shaping folds letters into a presentation-form ligature (for example LAM-ALEF, or the Allah and Bismillah ligatures), the produced PDF now carries a ToUnicode reverse mapping for that ligature, so selecting or copying the text recovers the original Arabic source characters instead of the single combined ligature character. Text extraction and accessibility round-trip stay correct even though the page draws one combined glyph

Fixed

  • Custom ToUnicode reverse mappings registered through RegisterToUnicodeReverseMapping are now actually written into the saved PDF; previously they were recorded but never emitted, so the extra mappings had no effect on text extraction

Version 2.149.0

Added

  • Arabic text emitted through right-to-left text output can now be shaped automatically: enabling the AutoShapeArabic option rewrites each letter to its correct contextual form (initial, medial, final, or isolated) and folds the standard mandatory ligatures (such as LAM-ALEF) before the text is written, so the produced PDF reads correctly even in viewers that do not perform Arabic shaping themselves. The option is off by default, so existing documents are byte-for-byte unchanged. Shaping uses the font's presentation-form glyphs, so a font whose character map includes the Arabic Presentation Forms (for example Tahoma, Arial, or Segoe UI) is required

Version 2.148.1

Changed

  • The Memory Stream and PDF Info demos now produce more instructive, verifiable outputs: Memory Stream validates in-memory PDF bytes before saving, and PDF Info prints the metadata values to compare with document properties

Version 2.148.0

Added

  • XFA form fields positioned below the page—a form's lower section that sits past the first page—now flow onto a following page instead of being placed off the page edge, so all of the form's fields stay visible in the flattened output

Version 2.147.4

Added

  • When a content-sized XFA text field or label grows taller than its layout region, the flatten now flags it with a diagnostic note and keeps it whole on the page; it is not split across pages in this release

Version 2.147.3

Added

  • A growable XFA text field or label that carries no text is now given a one-line minimum height instead of collapsing to nothing, so empty content-sized form text stays visible and keeps its place in the flattened layout

Version 2.147.2

Added

  • XFA form text without an explicit width is now laid out too: a text block missing both width and height fills the available container width and wraps to fit, while one that has a height but no width is sized to the natural width of its single line of text—so the remaining width-less growable text fields and labels are kept instead of being dropped from the flattened form

Version 2.147.1

Added

  • XFA form text that specifies a width but no height now sizes its height automatically from the content: the text is wrapped to the given width and the box grows to fit the resulting lines, so width-only text fields and labels that previously dropped out of the flattened form are now kept and laid out at their content height

Version 2.147.0

Added

  • Groundwork for content-sized XFA form text: the XFA-to-AcroForm flatten engine gained an internal text-measurement capability that will size form text blocks from their content—wiring for an upcoming release; current forms are unaffected and produce identical output

Version 2.146.4

Fixed

  • Loading a PDF whose page boundaries are recorded with the vertical coordinates in descending order—as some XFA and form generators write them—no longer produces a negative page height; the page height is now always normalized to a positive value, so features that rely on it, such as automatic page breaks when drawing flowing text, work correctly for these documents
  • Drawing positions, field rectangles, text, and images on the affected loaded pages are unchanged—only the previously negative page height is corrected

Version 2.146.3

Fixed

  • Repeating data sections placed at fixed positions now paginate: when a record-driven section repeats until it outgrows the page's content area, the overflowing records continue in the next content region or on a new page instead of piling up past the page edge, and the fields belonging to one record stay together on the same page
  • Flattening an XFA form loaded from an existing PDF no longer reports correctly placed fields as lying outside the page—only content that is genuinely off the page is now flagged, so the flatten diagnostics for loaded documents are accurate

Version 2.146.2

Added

  • XFA pagination now spans multiple content areas: when a page defines several content regions, flowing content fills them in order—continuing in the next region on the same page before moving to a new page—so multi-column and multi-region form layouts paginate correctly
  • Long repeating sections now paginate across pages: a data-driven list that repeats once per record and outgrows its content area continues onto further pages without dropping any rows
  • Section breaks are now honored: a form section marked to start on a new page begins on a fresh page even when the current one still has room, while a region break moves the section to the next content area

Version 2.146.1

Added

  • XFA forms now paginate automatically: when flowing content—such as a long data-driven list or a stack of fields—grows taller than the page's content area, the overflow continues on a new page instead of running past the bottom edge; single-page forms are unaffected and produce identical output

Version 2.146.0

Changed

  • The XFA-to-AcroForm flatten now routes every flattened field and graphic through a per-item page assignment—internal groundwork for multi-page pagination in upcoming releases; single-page forms are unaffected and produce identical output

Version 2.145.4

Changed

  • XFA table and left-to-right (lr-tb) layout have been validated against real-world XFA forms—invoices, purchase orders, payment requests, and data grids—confirming that data-driven tables expand to one row per record and that every cell lands in its correct row and column, with no fields lost compared with the earlier positional handling
  • When an auto-width table column (a -1 entry in columnWidths) holds only growable cells with no measurable width, the dropped column is now reported through XFAFlattenWarnings instead of being silently omitted

Version 2.145.3

Added

  • Table columns set to automatic width (a -1 entry in columnWidths, or columns left unspecified) now size to fit their widest cell, so every cell in an auto-width column lines up at the same position across rows; tables that mix fixed and automatic column widths now lay out consistently

Version 2.145.2

Added

  • Data-driven XFA tables now expand correctly: a table row marked to repeat (with <occur>) generates one row per data record, so invoices and line-item lists flatten to a row for every entry instead of a single template row; non-content row markup no longer offsets the columns

Version 2.145.1

Added

  • XFA forms can now use table layout: a subform with layout="table" arranges its layout="row" children into aligned columns, with column widths taken from the table's columnWidths and each row's height set by its tallest cell. Flattened tables—invoices, line-item lists, data grids—now place their cells in the correct rows and columns instead of overlapping at the left edge.

Version 2.145.0

Added

  • XFA forms can now use left-to-right tiled layout: a subform with layout="lr-tb" arranges its field and drawing children side by side, wrapping to a new line when the next one would not fit the container width. Flattened forms that lay controls out in a wrapping grid—rather than a single vertical column—now position them correctly.

Version 2.144.5

Fixed

  • XFA form fields that leave out their x and/or y position—a common, valid shortcut in positioned layout where the omitted coordinate defaults to the container origin—are no longer dropped. Real-world forms whose address blocks, sections, and tables relied on this default now flatten to their full set of fields instead of silently losing them.
  • Nested sub-sections inside a top-to-bottom flowing form now advance the vertical cursor by their own content height, so sibling sections stack one below another instead of overlapping at the same position. Multi-section flowing forms now lay out in the correct vertical order.

Version 2.144.4

Added

  • XFA forms with repeating sections driven by data are now supported: a subform with an <occur max="-1"/> (or any non-default maximum) expands into one instance per matching data group in the datasets packet, with each instance binding its fields to the corresponding row values. Forms that use implicit datasets binding to generate variable-length lists or tables now flatten to the correct number of fields with the correct per-row values.

Version 2.144.3

Added

  • XFA forms can now use top-to-bottom flowing layout: a subform with layout="tb" stacks its field and drawing children vertically—each placed below the previous one—even when those children specify no explicit position. Flattened forms that rely on automatic vertical flow rather than fixed coordinates now lay their fields out correctly.

Version 2.144.2

Fixed

  • XFA forms whose first packet starts with a DOCTYPE declaration—as produced by some XFA design tools—now flatten correctly through FlattenLoadedXFA instead of failing with a missing-template error. The loader recognizes the xdp:xdp root document element even when a DOCTYPE prologue precedes it.
  • XML internal entities declared in a form's DOCTYPE (such as <!ENTITY name "value">) are now expanded wherever the matching &name; reference appears in the form, so the flattened fields carry the resolved text.

Security

  • External XML entities (SYSTEM or PUBLIC) referenced by an XFA form are never resolved while flattening: HotPDF does not fetch the referenced URL or file, guarding against XML External Entity (XXE) attacks. Such a reference expands to empty text and is reported through XFAFlattenWarnings.

Version 2.144.0

Changed

  • The XFA-to-AcroForm flatten now runs through a dedicated two-pass layout engine: element positions are computed first, then the fields and graphics are emitted. Static positional forms produce identical output; this internal change is the foundation for the flowed-layout and repeating-section support arriving in subsequent releases.

Version 2.143.5

Fixed

  • Real-world XFA forms that store their /XFA entry as a packet array now flatten correctly through FlattenLoadedXFA instead of failing with a missing-template error. This covers forms whose packet streams are individually compressed without a directly readable filter, and forms that list the configuration packet ahead of the template—both common in PDFs exported by professional XFA design tools.

Added

  • The XFA <draw> flatten now renders static text labels—form titles and field captions—as native page text, honoring the label's font family, size, and color, so they stay visible on a flattened form in readers without an XFA engine.
  • XFA push-button widgets are now converted to native AcroForm push buttons carrying their caption text, so action buttons appear on the flattened form.

Version 2.143.4

Added

  • New FlattenLoadedXFA method flattens the XFA form embedded in an already-loaded PDF into native AcroForm fields and static page graphics, completing the XFA-to-AcroForm conversion for documents opened from disk (earlier releases flattened caller-supplied XFA bytes through ApplyXFAAsAcroForm). It reads the form's /XFA entry, whether a single stream or a packet array, then removes /XFA and clears the dynamic-render flag so the result is a plain AcroForm that any PDF reader displays. It returns the number of fields created, or zero when the loaded PDF carries no XFA.
  • Both XFA flatten entry points now take an Editable option: leave it on (the default) for fillable fields, or turn it off to mark every generated field read-only.
  • Duplicate XFA field names, which are allowed in XFA but not in AcroForm, are now made unique automatically with a numeric suffix, and the rename is reported through XFAFlattenWarnings.
  • XFA templates authored against different template-schema versions are accepted; an unrecognized template namespace is noted as a warning rather than rejected, so the form still flattens.

Version 2.143.3

Added

  • The XFA-to-AcroForm flatten now reproduces the static <draw> graphics from an XFA template as native page content, so rectangles, lines, arcs, and embedded images keep their place on a flattened form in PDF readers that do not implement an XFA engine. Rectangles and lines are stroked using the XFA edge thickness and color, an arc is rendered as a smooth curve following its start and sweep angles, and an embedded PNG or JPEG image is decoded and drawn in its original box.

Version 2.143.2

Added

  • The XFA-to-AcroForm flatten now carries field styling onto the generated AcroForm fields. The XFA font family and size, text color, field border color and width, and horizontal text alignment are translated to the field's default appearance, border, and alignment, so a flattened XFA form keeps its intended look in standard PDF readers that do not implement an XFA engine. Font selection maps to the standard PDF fonts in this release; full font embedding will follow.

Version 2.143.1

Added

  • The XFA-to-AcroForm flatten performed by ApplyXFAAsAcroForm now converts numeric, date, checkbox, radio button, choice list, and digital signature fields in addition to text fields. Each XFA <ui> widget is mapped to the closest native AcroForm field: numeric and date entries become text fields, a check button becomes a checkbox (or a radio-button group when it sits inside an exclusion group), and a choice list becomes a combo box or, when set to multi-select, a list box. Field values are still taken from the form packet first, then the datasets packet.

Version 2.143.0

Added

  • New ApplyXFAAsAcroForm method converts a caller-supplied XFA (XML Forms Architecture) form into native AcroForm text fields, so static XFA forms become visible and fillable in modern PDF readers that do not implement an XFA engine. This first release covers text fields with values taken from the form or datasets packet; further field types, styling, and graphics follow. XFAFlattenWarnings reports any element that could not be converted.

Version 2.142.1

Changed

  • The PAdES Seed Value attachment helper now rejects values that would force a downstream signer to violate the PAdES profile (ETSI EN 319 142-2 V1.2.1 §4.2.6): the /SubFilter constraint must be adbe.pkcs7.detached or ETSI.CAdES.detached, and the /DigestMethod constraint cannot be MD5, SHA1, or SHA-1. The producer raises a clear diagnostic instead of silently emitting a profile-violating /SV dictionary.

Version 2.142.0

Added

  • New AddXFASignaturePacket method embeds a caller-generated XAdES / XML-DSig signature as the XFA signature packet inside the AcroForm /XFA array (ISO 32000-1 §12.7.8), for signed XFA forms. HotPDF does not generate or parse the signature: the caller produces it with an XML cryptographic library over the XFA datasets, and HotPDF embeds it as a FlateDecode packet. The same PDF/A and PDF/X rejection, single-stream mutual exclusion, and duplicate-packet guards as AddXFAPacket apply.

Version 2.141.2

Added

  • New public API RegisterDefaultColorSpace(Which, ColorSpaceCS) registers an ICCBased colour space (created with RegisterICCProfile) as the document-wide /DefaultGray, /DefaultRGB, or /DefaultCMYK mapping per ISO 32000-1 §8.6.5.6 and PDF/A Competence Center TechNote 0002 §1.3. At EndDoc the helper walks every page and adds a [/ICCBased <profile-stream>] entry under the matching /DefaultX key in the page's Resources/ColorSpace dictionary. The component count is validated against the family (DefaultGray → N=1, DefaultRGB → N=3, DefaultCMYK → N=4); calling with an empty CSName clears the mapping; per-page /DefaultX entries already present are preserved (caller overrides win). With this in place a document that mixes DeviceRGB and DeviceCMYK content can satisfy PDF/A-1 §6.2.3.3 with any single GTS_PDFA1 OutputIntent profile, because the §6.2.3.3 consistency check introduced in v2.141.1 treats DeviceX usage as absorbed once the matching Default colour space is registered.

Version 2.141.1

Changed

  • PDF/A device colour-space ↔ OutputIntent consistency check (ISO 19005-1 §6.2.3.3 + PDF/A Competence Center TechNote 0002 §4.1). EndDoc now raises when a document mixes DeviceRGB and DeviceCMYK content (a single GTS_PDFA1 OutputIntent ICC profile cannot match both colour models) or when DeviceCMYK content is paired with an RGB OutputIntent profile and vice versa. Per TN0002 §4.1, DeviceGray content is compatible with Gray, RGB, or CMYK OutputIntent profiles. Image XObjects are tracked by the colour space the producer actually emits (DeviceRGB for JPEG and 24-bit Flate, DeviceGray for CCITTFax); per TN0002 §4.3, markup annotation /C and /IC arrays count as DeviceRGB. ICCBased / CalGray / CalRGB / Lab colour spaces are exempt from the check.

Added

  • Read-only properties UsedDeviceGray, UsedDeviceRGB, and UsedDeviceCMYK on THotPDF expose the in-progress device colour-space usage flags so callers can inspect the consistency-check state before EndDoc.

Version 2.141.0

Added

  • XFA forms can now be emitted as a single /XFA stream through the new SetXFADocument method, carrying a whole XFA/XDP document in one stream (ISO 32000-1 §12.7.8) as an alternative to the per-packet AddXFAPacket array form. The two forms are mutually exclusive.
  • New XFANeedsRendering property sets the Catalog /NeedsRendering flag (ISO 32000-1 §7.7.2) so a viewer regenerates a dynamic XFA form when the document is first opened. It defaults to off, leaving non-XFA documents byte-identical.

Changed

  • The XFA documentation now shows the required xdp:xdp begin and end wrapper packets for the array /XFA form, so the packet streams concatenate into a well-formed XDP document (ISO 32000-1 §12.7.8).

Fixed

  • Embedded-file /Subtype MIME types are now written as proper PDF names with / escaped as #2f (for example /application#2fxml) per ISO 32000-1 §7.3.5, so strict readers parse the media type correctly. Affects AddPDFA3AssociatedFile and AddXAdESAssociatedFile.
  • AddXAdESAssociatedFile now rejects an empty XML payload, because an XAdES signature stream cannot be empty.

Version 2.140.5

Changed

  • The PAdES document time-stamp dictionary now emits the spec-required /Type /DocTimeStamp instead of /Type /Sig and omits the /M /Reason /Location /ContactInfo entries that the standard marks as "should not be present", improving conformance with ETSI EN 319 142-1 V1.2.1 §5.4.3.
  • The DSS Signature VRI sub-dictionary now references the same indirect streams as the DSS top-level Certs / CRLs / OCSPs arrays instead of writing duplicate stream objects, matching the ETSI EN 319 142-1 V1.2.1 §5.4.2.3 invariant and §6.3 note s) guidance to avoid duplicated certificate values.
  • The /Extensions /ESIC /ExtensionLevel value declared on the Catalog now auto-upgrades to 2 when a PAdES baseline signature with /SubFilter /ETSI.CAdES.detached is added, since standard §6.3 requirement l) is identified by Level 2; documents that only carry DSS or document time-stamp data continue to use Level 1.

Added

  • A PAdES signature can now ship intermediary CA certificates alongside the signer certificate inside CMS SignedData.certificates via the new AdditionalCertsDER option, helping a verifier build a path to the trust anchor without an external lookup (ETSI EN 319 142-1 V1.2.1 §6.3 note b).

Fixed

  • PDF/A compliance: the Unicode TTF subsetter now emits the /CIDSet bitstream on the descendant CIDFont's font descriptor when PDFACompliance is enabled. ISO 19005-1 §6.3.5 / ISO 19005-2 §6.2.11 / ISO 19005-3 §6.2.11 require subset CIDFonts to declare which CIDs are present, so without the stream a veraPDF strict check fails even when every required glyph is embedded. The bitstream is MSB-first per ISO 32000-1 §9.7.4.2 (CID 0 in byte 0 bit 7) and is only emitted under PDFACompliance, so non-PDF/A output stays byte-stable.

Version 2.140.4

Fixed

  • Incrementally saving a loaded PDF now frees an orphaned encryption dictionary left in the source (one its trailer no longer references) by marking it free in the appended cross-reference section, so readers following the latest revision no longer see the stray dictionary. The original bytes stay intact and documents without such a leftover are written exactly as before; this complements the full-save cleanup added in 2.140.3.

Version 2.140.3

Fixed

  • Saving a loaded PDF with AES-256 no longer copies a leftover encryption dictionary out of the source file. When a source document kept an orphaned encryption dictionary that its trailer no longer referenced, the output used to carry that stray dictionary alongside the active one; the saver now writes only the encryption dictionary actually in use.

Version 2.140.2

Added

  • The Adobe revocation-information signed attribute carried inside a PAdES signature now also accepts non-X.509 revocation evidence alongside the usual CRL and OCSP entries, so an industry-specific revocation token identified by its own OID can travel inside the signature.
  • A PAdES signature can now declare a CAdES content-hints attribute describing what was signed, useful in multi-signature workflows where a later signer needs to know the original content type without re-deriving it.

Version 2.140.1

Fixed

  • Encrypting a loaded document with AES-256 no longer hangs when its text strings are nested inside arrays or other non-indirect containers; such strings are now encrypted correctly instead of looping endlessly.
  • Opening or decrypting an AES-256 document no longer fails with a padding error when the file carries a leftover encryption dictionary from its source; the decryptor now skips every encryption dictionary, so all string content decrypts correctly.

Version 2.140.0

Changed

  • AES-256 encryption and decryption now use the CPU's AES-NI hardware acceleration when available, with a portable software fallback otherwise. On a typical desktop CPU this lifts AES-256-CBC throughput from about 148 MB/s to 442 MB/s for encryption (about 3× faster) and from about 147 MB/s to 832 MB/s for decryption (about 5.7× faster).
  • Opening a large password-protected PDF now uses dramatically less memory. The loader no longer caches the entire source file while recovering the encryption key and decrypting: AES-256 documents recover what they need from the parsed object model, and the legacy key-recovery scan now reads only the file tail instead of the whole file. For a multi-gigabyte encrypted document this removes a transient memory spike of roughly twice the file size.

Version 2.139.3

Fixed

  • Direct File API rewrite-and-save is dramatically faster on very large documents. When re-saving a file after a metadata or object change, the per-object copy buffer is now reused instead of being reallocated for every object, removing allocation overhead that grew with the object count. A 60,000-page / 883 MB document's rewrite-save dropped from about 189 seconds to roughly 21 seconds, while opening or copying the same file through the Direct File API stays around 2-3 seconds.

Version 2.139.2

Fixed

  • Re-saving loaded PDF 1.5+ object-stream documents and PDF 2.0 trailer documents after BeginDoc edits now keeps a valid page tree. Previously, a page dictionary recovered from an object stream could be attached without /Type /Page, causing readers to report a non-page object in the page tree after EndDoc.

Version 2.139.1

Fixed

  • Encrypted documents that combine AES-256 with a cross-reference stream (optionally alongside compressed object streams) now reopen and re-save reliably. Previously, when an encrypted stream's data happened to begin with a newline byte the loader could read that stream one byte out of alignment and intermittently corrupt the decrypted result, so a password-protected file occasionally failed to open. The stream reader now follows the data boundary exactly, and such documents open consistently.

Version 2.139.0

Fixed

  • Documents that use a cross-reference stream together with compressed object streams (PDF 1.5 and later) are now read by a standards-compliant loader. Reopening such a document and saving it again keeps the page tree intact and preserves the original object numbers; the previous loader could drop the page tree or renumber objects and lose pages in the saved copy.
  • A stream whose /Length is stored as an indirect reference is now resolved correctly while a cross-reference-stream document is loading, so its content is no longer lost.

Version 2.138.0

Fixed

  • Documents that declare an older PDF header version such as %PDF-1.3 or %PDF-1.4 while actually using a cross-reference stream now load correctly instead of opening as an empty document with no pages. Routing is decided from the real cross-reference structure rather than the declared header version, so very large files of this kind also open as expected.

Version 2.137.9

Added

  • Added CSV output for preflight reports through pfCSV in CreatePreflightReport, SavePreflightReport, and CreatePreflightReportWithProfile, using stable category,name,status,value,spec columns for spreadsheet and batch workflows.
  • The PreflightReport GUI and HotPDFPreflight CLI can now select CSV output; the CLI accepts -f csv for single-file and directory runs.

Version 2.137.8

Fixed

  • Hardened the native AES-256 buffer decrypt path so callers can assign the decrypt result back to the same AnsiString that supplied the ciphertext buffer without invalidating the input pointer.

Version 2.137.7

Added

  • Added one-based page-range string support for loaded-document page operations, including HPDFParsePageRange, range overloads for InsertPagesFromDocument and ExtractPagesToFile, and AppendPagesFromDocument.
  • Added OnPageOperationProgress so append, insert, and extract workflows can report deterministic page-level progress.

Version 2.137.6

Added

  • Added THotPDF.DACopyFile for large-file workflows that only need a page count and an original byte-for-byte saved copy without building the full normal object graph.
  • The HugeFileBenchmark demo now includes a direct-copy row while the default operation set still covers the full LoadFromFile + SaveLoadedDocument path.

Changed

  • Reduced AES-256 stream decryption memory copying by decrypting from existing buffers where possible, including loaded stream memory for large encrypted image streams.

Fixed

  • Improved file-based encrypted PDF loading so password opens no longer cache the whole source PDF just to recover raw encryption dictionary values.

Version 2.137.5

Added

  • Added Direct File API object-source editing for large-file workflows: applications can open a PDF with DAOpenFileReadOnly, inspect object counts and source bodies, replace or append object bodies, update document information, and save a full rewritten copy.
  • The HugeFileBenchmark demo now includes a direct-rewrite operation and documents HTML/CSV benchmark runs for image-only and mixed text/image huge PDFs.

Changed

  • Expanded Direct File API indexing to cover traditional xref tables and xref streams, including compressed object entries, so image-heavy PDFs and object-heavy PDFs can use the lightweight path.
  • Optimized Direct File API full rewrites by copying unchanged direct objects in source-offset order and merging contiguous ranges, greatly reducing random I/O on PDFs with hundreds of thousands of objects.

Version 2.137.4

Added

  • The GUI now covers standard text, JSON, and HTML reports, optional passwords, profile INI files, built-in presets, single-file PDF/VT validation, embedded-report PDF output, report preview, status logging, automatic output naming, and quick access to generated files.

Changed

  • Upgraded the Delphi PreflightReport demo from a console sample into an interactive VCL GUI tool for single-file preflight workflows.

Removed

  • Removed the old startup behavior that automatically created a sample PDF and report when no command-line arguments were supplied.

Version 2.137.3

Added

  • PDF/VT validation now recognizes XMP properties written as RDF attributes as well as element text, covering common pdfvtid:GTS_PDFVTVersion, pdfvtid:GTS_PDFVTModDate, and xmp:ModifyDate packet styles.

Fixed

  • Added Delphi regression coverage that keeps attribute-style PDF/VT metadata detection separate from the remaining structural PDF/VT checks.

Version 2.137.2

Changed

  • Improved embedded preflight report validation so source PDFs that legitimately end with a final line break after %%EOF keep matching their stored fingerprint.

Fixed

  • Preflight profiles saved as UTF-8 with a BOM now load correctly when the first line is a section header.
  • Hardened PDF literal string escape decoding, improving password validation and unencrypted-copy output for encrypted PDFs with escaped owner or user entries.

Version 2.137.1

Changed

  • Extended CFF parser safety to direct byte-array checks, restoring the reader position after malformed input and clearing stale layout state on failed checks.

Fixed

  • Hardened the C++Builder wrapper-compatible CFF stream loader so nil stream input returns False and resets the wrapper state instead of dereferencing the stream.

Version 2.137.0

Added

  • Added THotPDF.ValidatePDFVT with password-aware overloads for focused PDF/VT validation. The text report checks the XMP PDF/VT claim, metadata namespace, PDF/VT modification date matching, PDF/X base marker, output intent, catalog DPartRoot structure, loadable pages, and page-level DPart coverage.
  • The standalone HotPDFPreflight CLI now accepts --pdfvt to write .pdfvt.txt validation reports for a single PDF or recursive directory scan.

Version 2.136.8

Added

  • Added additional Type 1/CFF smoke coverage for malformed CFF and Type 1 streams, including stream-position preservation and stale-metadata cleanup after failed parser calls.

Changed

  • Improved Type 1 PFB and CFF parser failure handling so malformed stream checks preserve the input position and clear stale metadata instead of leaving a previous font name visible after a failed check.

Version 2.136.7

Changed

  • Expanded the Type 1/CFF smoke test with in-memory CFF data, ASCII Type 1 font data, wrapper-level PFB file loading, and wrapper-level CFF stream loading to protect both Delphi and C++Builder integration surfaces.

Fixed

  • Hardened the Type 1 PFB and CFF parser entry points so stream-based checks preserve the caller's stream position, reject malformed data safely, and expose basic Type 1/CFF font metadata through the Delphi and C++Builder wrapper paths.

Version 2.136.6

Added

  • Added Delphi feature demos for CJK Unicode text output, large multi-page document generation, PFX signing, and expanded image-compression coverage with CCITT Group 3 1D and 2D output.

Version 2.136.5

Changed

  • Preflight reports now continue when a loaded page entry cannot return a MediaBox. The report marks that page as unavailable instead of aborting, so large or inconsistent page trees still produce diagnostic output.
  • Optimized several byte-level preflight scanners to avoid repeated full-tail string copies and linear duplicate-object searches. The 10,000-page implementation-limit sample now completes within the 120-second stress-test budget.
  • The preflight stress runner now defaults to a 120-second per-file timeout, and the PreflightReport demo rebuilds cleanly after the profile-aware output path.

Version 2.136.4

Added

  • Added a preflight cookbook, a generated preflight API map, and a large-directory stress-test workflow for the HotPDFPreflight command-line tool. The stress runner isolates each PDF behind a per-file timeout and records JSON, Markdown, CSV, report, and log evidence.

Changed

  • Recorded a 1000-file baseline against D:\PDFdoc\PDF-Samples: 997 passed, 1 failed, 2 timed out, 111.422 seconds elapsed, 8.975 files per second.

Fixed

  • Fixed a full rebuild issue in the preflight fingerprint helper by declaring the helper before CreatePreflightReport uses it, so console tools that rebuild HPDFDoc.pas from source compile cleanly.

Version 2.136.3

Added

  • The standalone HotPDFPreflight CLI tool gains an --aggregate <file> option that writes a batch summary produced by THotPDF.AggregatePreflightReports after the per-file reports finish. The aggregate lists every processed PDF with status / size / warning counts and totals.

Changed

  • Works with single files and recursive directory walks, with or without --profile / --preset. The aggregate is computed from the text body of each report so filtering by profile is reflected in the summary.
  • Example: HotPDFPreflight C:\Archive -r --preset silent-actions -f json -o C:\Archive\reports --aggregate C:\Archive\Aggregate.txt writes JSON reports for every PDF plus a single batch summary.

Version 2.136.2

Added

  • The standalone HotPDFPreflight CLI tool gains --profile <file> and --preset <name> options to filter each report through a preflight profile before writing it. Works alongside -f text|json|html, -p <password>, and -r recursive directory walks.

Changed

  • The two new options are mutually exclusive (passing both, the later one wins). The preset values match what THotPDF.GetBuiltInPreflightProfile recognizes so CI pipelines can pull a canonical configuration without staging an INI file.
  • Example: HotPDFPreflight C:\Archive -r --preset silent-actions -f json -o C:\Archive\reports writes JSON reports for every PDF in the directory tree with the silent-actions preset applied.

Version 2.136.1

Added

  • The Delphi PreflightReport demo now accepts profile=<file> or preset=<name> as an additional CLI argument to filter the report through a profile before writing it. Works alongside the existing json / html / embed output format flag.

Changed

  • Examples: PreflightReport.exe Input.pdf Report.txt "" text profile=tuned.ini or preset=compact / preset=silent-actions.
  • The preset values mirror the names recognized by THotPDF.GetBuiltInPreflightProfile so the demo doubles as a profile testbed without having to author an INI file.

Version 2.136.0

Added

  • Added THotPDF.MergePreflightProfiles for layering profiles. The result is the deduplicated union of both inputs (DisableChecks and DisableWarnings are merged, DisableHints is the logical OR), useful for combining a preset such as compact with project-specific tweaks.
  • Added THotPDF.DiffPreflightProfiles for structural comparison. Returns True when two profiles are equivalent, otherwise the OnlyInA and OnlyInB out parameters list the entries exclusive to each side as newline-separated check:<name> / warn:<name> / option:hints=false tokens.

Changed

  • The two helpers complete the profile lifecycle: Load / GetBuiltIn / Save / Apply / Validate / Merge / Diff.

Version 2.135.0

Added

  • Added THotPDF.CreatePreflightReportWithProfile, a one-stop convenience wrapper that composes CreatePreflightReport, LoadPreflightProfile, ApplyPreflightProfile, and the format converters into a single call.
  • The new overload accepts a source PDF, optional password, optional profile file, and target format (pfText, pfJSON, or pfHTML) and returns the final report body. Passing an empty ProfileFile skips the profile step entirely so callers can keep a single call site regardless of whether they have a profile configured.

Changed

  • The four underlying APIs remain available so existing call chains keep working unchanged; the new wrapper is purely additive.

Version 2.134.0

Added

  • Added THotPDF.SavePreflightProfile for writing a THPDFPreflightProfile record back to an INI file. The output format matches what LoadPreflightProfile consumes, so the two functions are exact inverses for well-formed profiles.

Changed

  • Enables a 'load preset, tweak, save' workflow: pull a built-in preset with GetBuiltInPreflightProfile (v2.133.0), modify the lists or flags, then SavePreflightProfile the result for later reuse or sharing across projects.
  • Sections with no content are omitted from the output so an empty profile produces a single comment line instead of three empty section headers.

Version 2.133.0

Added

  • Added THotPDF.GetBuiltInPreflightProfile, which returns ready-to-use THPDFPreflightProfile records for common workflows so callers do not have to maintain INI files for canonical configurations.

Changed

  • Recognized names (case-insensitive): default or empty string returns an empty profile; compact disables every Hint line for shorter reports; silent-actions disables every PDF 1.7 sec 12.6.4 action warning plus EmbeddedFile and RichMedia, intended for workflows that intentionally embed multimedia or interactive actions.
  • Unknown names also return an empty profile so the function never raises on a typo; pair with ValidatePreflightProfile (v2.132.0) when the caller wants typos surfaced as errors.

Version 2.132.0

Added

  • Added THotPDF.ValidatePreflightProfile for defensive profile checking. The function walks the loaded profile's DisableChecks and DisableWarnings lists and flags any name that is not recognized by the current preflight implementation, returning the unknown names joined by ', ' in the UnknownNames out parameter.

Changed

  • Useful to detect profile files authored against a newer or older HotPDF version. Without validation a typo (OpneAction instead of OpenAction) or a renamed check would silently disable nothing.
  • The check is purely defensive; the profile itself is not modified. Callers can decide whether to abort, log a warning, or proceed with the partially-effective profile.

Version 2.131.0

Added

  • Added THotPDF.ConvertPreflightReportToVeraPDFStyle, a converter that shapes a HotPDF preflight report into a JSON document modeled on veraPDF's validation output: top-level profile, a jobs array containing itemDetails / taskResult / validationResult, plus a ruleViolations array under validationResult.details.

Changed

  • HotPDF-styled rather than wire-compatible with veraPDF; the goal is to let downstream tooling that already consumes veraPDF JSON adapt to HotPDF output with minimal field-name remapping rather than re-learning a different data layout.
  • Rule violations carry the same specification ISO clause cross-reference that the native HotPDF JSON output emits, so callers retain spec-level traceability when consuming via the veraPDF-style path.

Version 2.130.0

Added

  • Added THotPDF.EmbedPreflightReportAsXMP with two overloads (with and without an optional Password argument). The function writes a copy of the source PDF with the preflight report appended as a PDF-style comment block whose payload is XMP / RDF with the xmlns:hotpdf namespace.

Changed

  • Each report line becomes a hotpdf:<name> element. PASS / FAIL checks carry the severity as an attribute; warnings, hints, and info lines use warn, hint, and info prefixes on the element name.
  • XMP-aware tools that scan a file for xpacket markers can surface the embedded report. PDF readers continue to ignore the appended bytes because they fall outside the object graph. This is archival-friendly XMP embedding, not a spec-compliant XMP integration; the XMP payload is not referenced from the catalog /Metadata entry.

Version 2.129.0

Added

  • Added THotPDF.LoadPreflightProfile and THotPDF.ApplyPreflightProfile with a new THPDFPreflightProfile record. Profiles let callers tailor the report output without re-running the analysis, suppressing specific check / warning names or every Hint line.

Changed

  • Profile files use a simple INI-style format with [disable-checks], [disable-warnings], and [options] sections. Comments and blank lines are ignored. Empty profiles pass the report through unchanged.

Fixed

  • After filtering, the trailing Summary and Warnings lines are recomputed so the suppressed entries no longer contribute to the Failed and Warnings totals. The rest of the report passes through unchanged, so JSON / HTML converters, diff helper, validate / embed / aggregate APIs continue to work on the filtered report without code changes.

Version 2.128.2

Added

  • Added a Delphi PreflightDashboard console demo that scans a directory of PDFs and writes a self-contained static HTML dashboard: one <stem>.preflight.html per file plus an index.html summary table.

Changed

  • The dashboard shows total / passed / failed counts at the top and a table of every PDF with status, size, summary, and a link to the detailed report. Failed rows are highlighted; PASS and FAIL badges are color-coded for quick scanning.
  • Output is a static directory of files (no HTTP server required); publish the directory to a CI artifact page, serve it from any web server, or open index.html directly in a browser.

Version 2.128.1

Added

  • Added tools/validate-preflight-json.py, a Python utility that validates HotPDF preflight JSON output against the published schema (Docs/preflight-schema.json). The script reports one PASS/FAIL line per input and exits with a non-zero status when any input fails validation, so CI pipelines can gate on schema conformance.

Changed

  • Validation is strict because the schema declares additionalProperties: false on every object, so unknown fields cause a hard failure rather than silently slipping through. Required dependency is the standard jsonschema Python package.

Version 2.128.0

Added

  • Added THotPDF.AggregatePreflightReports for batch summaries. The function accepts an array of per-file preflight reports and emits a single aggregate that lists each file's pass/fail status with byte size and warning count, plus totals for passed, failed, warnings, and bytes scanned.

Changed

  • Pairs naturally with the v2.125.1 HotPDFPreflight standalone CLI: run the CLI to produce one report per PDF, then feed the report bodies into AggregatePreflightReports for a dashboard-ready batch summary.
  • Empty input arrays yield an empty result string so callers can append the aggregate to other output unconditionally without guarding against zero-file directories.

Version 2.127.0

Added

  • Added THotPDF.RepairPDFFromPreflightReport with two overloads (with and without an optional Password argument). The function applies a conservative subset of byte-level repairs to damaged PDFs: it drops trailing bytes that follow the final %%EOF marker, and appends a missing %%EOF when one is not present anywhere.

Changed

  • Returns True when at least one repair was applied; RepairsApplied is an out parameter that lists the repairs one per line, so callers can decide whether to keep the repaired file or escalate to a heavier recovery tool.
  • Object-graph repairs (rebuilding xref tables, patching stream lengths, fixing trailers) are intentionally out of scope because such fixes can make a partially-recoverable file less recoverable. The repairs in this overload are limited to operations that are unambiguously safe on well-formed and lightly-damaged PDFs alike.

Version 2.126.1

Changed

  • Published a formal JSON Schema for the preflight JSON output at Docs/preflight-schema.json, conforming to JSON Schema draft 2020-12.
  • The schema documents every top-level field (input, size, pdfVersion, xrefStyle), the checks / info / hints / warnings arrays, and the summary object so consumer pipelines can validate the JSON output before parsing.
  • The help topic now points downstream consumers at the schema file for reference.

Version 2.126.0

Added

  • Added THotPDF.ComparePreflightReports for line-by-line preflight report comparison. The function emits a unified-diff-like body where shared lines use a two-space prefix, lines unique to ReportA use , and lines unique to ReportB use .

Changed

  • Pairs naturally with LoadAndValidatePreflightReport: when a roundtrip validation fails, feed the original and current reports into ComparePreflightReports to surface exactly which lines changed.
  • The diff algorithm is a small greedy walk tuned for the deterministic key/value output of CreatePreflightReport; it produces compact diffs for typical inputs without pulling in a general-purpose LCS implementation.

Version 2.125.1

Added

  • Added a standalone Delphi console tool HotPDFPreflight for batch-running the preflight report against single files or whole directories. The tool accepts -o output directory, -f text|json|html output format, -p password, -r recursive directory walk, and -v verbose progress flags.

Changed

  • Exit codes follow standard CLI conventions: 0 success, 1 usage error, 2 input not found, 3 one or more PDFs failed preflight, so the tool can be integrated into CI pipelines and shell scripts.
  • Each report is named <basename>.preflight.<ext> with the extension picked from the requested format.

Version 2.125.0

Added

  • Added THotPDF.LoadAndValidatePreflightReport with two overloads (with and without an optional Password argument). The function extracts the report that EmbedPreflightReportInPDF previously appended, re-runs the current preflight algorithm against the source bytes, and returns True when the embedded InputFingerprint still matches the freshly-generated one.

Changed

  • Out parameters OriginalReport and CurrentReport receive both reports so callers can diff them when validation fails, identifying what changed between the time the report was embedded and the validation run.
  • Pairs naturally with EmbedPreflightReportInPDF: embed once during archival, validate any time later to detect tampering or accidental modification.

Version 2.124.2

Added

  • Added two fingerprint lines to THotPDF.CreatePreflightReport for CI stability checks. InputFingerprint emits a 64-bit FNV-1a hash of the source PDF bytes as 16 lowercase hex digits, immediately after the Size: line. ReportFingerprint emits a 64-bit FNV-1a hash of the assembled report (everything above the fingerprint line) at the end of the report.

Changed

  • CI pipelines can compare fingerprints across runs to detect unintended drift in either the input file or the report content without parsing every diagnostic line.
  • Both fingerprints are non-cryptographic; FNV-1a is deliberately chosen for low overhead and inline implementation without pulling in an external hashing module.
  • JSON output places InputFingerprint in the info array and ReportFingerprint at the tail of info; both entries carry a spec field labelled "FNV-1a 64-bit (non-cryptographic)".

Version 2.124.1

Added

  • Added two conditional incremental-update revision diagnostic lines to THotPDF.CreatePreflightReport. When IncrementalUpdates > 0, the report now includes RevisionStartXRefPositions (byte offsets of each startxref keyword in the file, ordered oldest first) and RevisionXRefTargets (the xref offsets each marker points to), so callers can trace the incremental update chain without parsing the file manually.

Changed

  • Clean and single-revision PDFs remain byte-stable: the new lines are emitted only when more than one startxref marker is found.
  • ISO 32000-1 sec 7.5.6 spec references are added in the JSON output for the new fields.

Version 2.124.0

Added

  • Added THotPDF.EmbedPreflightReportInPDF with two overloads, one with an optional Password argument for supported encrypted PDFs. The method writes a copy of the source PDF with the preflight report appended after the last %%EOF as PDF-style comment lines.
  • The Delphi PreflightReport demo gains an embed CLI argument that writes the embedded variant alongside the standalone report.

Changed

  • The report travels with the document for archive workflows: text editors, grep, and audit tools can surface it long after the file leaves the originating workstation.
  • PDF readers continue to render the document as-is because the appended bytes fall outside the object graph; the cross-reference table and trailer dictionary are untouched.

Version 2.123.1

Fixed

  • Added a regression test that hand-crafts a PDF with duplicate object numbers, a malformed xref row, and an unbalanced stream/endstream pair, then verifies that the three Phase F root-cause diagnostic lines (DuplicateObjectList, FirstMalformedXRefOffset, StreamEndStreamDelta) trigger as expected.
  • No library behavior change: the test fills a gap in the regression suite that previously only covered the clean and "not a PDF" cases.

Version 2.123.0

Added

  • Added HTML output format to THotPDF.CreatePreflightReport and THotPDF.SavePreflightReport. The THPDFPreflightFormat enum gains a third value pfHTML alongside pfText and pfJSON.

Changed

  • HTML output is a self-contained dashboard-style document with inline CSS, severity-colored rows (green for PASS, red for FAIL, yellow for WARN), per-section tables for checks, hints, info, and warnings, plus a summary card. No external CSS, JavaScript, or fonts are required.
  • Each table row includes the ISO 32000-1 / ISO 19005 / ISO 15930 / ISO 14289 spec reference when available, matching the JSON output spec field added in v2.122.1.
  • HTML output is byte-safe: ampersand, less-than, greater-than, double-quote, and single-quote are escaped; UTF-8 byte sequences pass through unchanged.
  • The Delphi PreflightReport demo accepts html as the fourth CLI argument to request HTML output.

Version 2.122.4

Added

  • Added PDF/X subset detection to preflight reports. When a PDF/X claim is detected, the new Hint PDFXVersion line names the specific subset (X-1a:2001, X-1a:2003, X-3:2002, X-3:2003, X-4, X-4p, X-5g, X-5pg, X-5n, or X-5).
  • Added PDF/UA part extraction. When a PDF/UA claim is detected, the new Hint PDFUAPart line reports the value from pdfuaid:part in the XMP metadata.

Changed

  • ISO 15930 and ISO 14289 spec cross-references are added to the JSON output for the new hint entries.
  • Clean PDFs with no PDF/X or PDF/UA claim remain byte-stable: the new hints are only emitted when the underlying claim is detected.

Version 2.122.3

Added

  • Added root-cause diagnostic lines to THotPDF.CreatePreflightReport. When a damaged PDF triggers a defect count, the report now lists actionable detail.

Changed

  • DuplicateObjectList appears whenever DuplicateObjectNumbers > 0 and lists up to five repeated object numbers, so callers can pinpoint which objects collide.
  • FirstMalformedXRefOffset appears whenever XRefMalformedEntries > 0 and gives the 1-based byte offset of the first malformed cross-reference row.
  • StreamEndStreamDelta appears whenever the stream and endstream marker counts differ and gives the signed difference, indicating how many markers are missing or duplicated.
  • Clean PDFs remain byte-stable: the new diagnostic lines are only emitted when the underlying defect counters are non-zero.

Version 2.122.2

Changed

  • Extended preflight action warnings to cover the full PDF 1.7 §12.6.4 action set. Added 15 advisory warnings: GoToRAction, GoToEAction, ThreadAction, URIAction, SoundAction, MovieAction, HideAction, NamedAction, SubmitFormAction, ResetFormAction, ImportDataAction, SetOCGStateAction, RenditionAction, TransAction, and GoTo3DViewAction.
  • Warnings are emitted only when the corresponding action token is detected; clean PDFs that contain no actions stay byte-stable.
  • The ISO 32000-1 spec cross-references in the JSON output now cover the new action warnings as well.

Version 2.122.1

Changed

  • Extended THotPDF.CreatePreflightReport JSON output with ISO specification cross-references. Every checks, hints, and warnings entry now carries a spec field naming the ISO 32000-1, ISO 19005, ISO 15930, or ISO 14289 clause for that diagnostic.
  • The plain-text report is unchanged and remains byte-stable; the spec field appears only in pfJSON output.
  • The mapping covers every check, hint, and warning emitted by the report through v2.122.0, so JSON consumers can route findings to the matching spec clause without an external lookup table.

Version 2.122.0

Added

  • Added machine-readable JSON output to THotPDF.CreatePreflightReport and THotPDF.SavePreflightReport. New THPDFPreflightFormat enum exposes pfText (default plain-text path) and pfJSON (CI-friendly JSON document) values.
  • New format-aware overloads accept the Format parameter while keeping the legacy text overloads byte-stable. Existing applications continue to work without code changes.

Changed

  • JSON output groups entries into top-level input, size, pdfVersion, and xrefStyle fields plus checks, info, hints, warnings arrays and a summary object with failed, warnings, and result counters.
  • Built-in JSON encoder escapes ", \, control bytes, and preserves UTF-8 byte sequences without requiring an external JSON library.
  • The Delphi PreflightReport demo accepts a fourth CLI argument json to request JSON output for an input PDF.

Version 2.121.36

Added

  • Added advisory warnings PDFAWithEncryption, PDFAWithJavaScript, and PDFA1WithTransparency that fire when a PDF/A-claimed document also carries encryption, JavaScript, or PDF/A-1-forbidden transparency markers.

Changed

  • Enhanced preflight reports with compliance marker hints. Reports now expose Hint PDFAClaimed, Hint PDFAPart, Hint PDFAConformance, Hint PDFXClaimed, Hint PDFUAClaimed, Hint TaggedPDF, and Hint HasTransparency lines for downstream tooling.
  • Hint lines never increment the Failed counter, and the helpers remain advisory; they do not replace a full PDF/A, PDF/X, PDF/UA, or ISO 32000 conformance engine.

Version 2.121.35

Added

  • Added pass/fail check FontsHaveEmbeddedPrograms that verifies at least one /FontFile, /FontFile2, or /FontFile3 is present whenever font resources are declared.
  • Added pass/fail check AnnotationCountConsistent that verifies the sum of widget and link annotation counts does not exceed the overall annotation count.

Changed

  • Enhanced preflight reports with content resource integrity diagnostics. Reports now include resource dictionary, font, embedded font program, image XObject, form XObject, ColorSpace, annotation, widget, and link counts.
  • Reports now include filter chain usage counts for FlateDecode, DCTDecode, CCITTFaxDecode, JBIG2Decode, LZWDecode, ASCIIHexDecode, ASCII85Decode, RunLengthDecode, and JPXDecode.

Version 2.121.34

Changed

  • Enhanced preflight reports with trailer root type diagnostics. Reports now verify that the trailer /Root indirect reference targets an object declared as /Type /Catalog.

Version 2.121.33

Changed

  • Enhanced preflight reports with trailer ID diagnostics. Reports now count hex string entries in the trailer /ID array and verify that the file identifier is present as a valid two-entry pair when an ID array is supplied.

Version 2.121.32

Changed

  • Enhanced preflight reports with trailer indirect-reference diagnostics. Reports now show the trailer /Root and /Info object references and verify that the referenced objects are defined in the file.

Version 2.121.31

Changed

  • Enhanced preflight reports with stream length coverage diagnostics. Reports now count stream /Length entries and verify that detected streams have length entries available.

Version 2.121.30

Changed

  • Enhanced preflight reports with revision marker diagnostics. Reports now count %%EOF markers and startxref sections, verify that the counts are balanced, and check that the final startxref marker appears before the final EOF marker.

Version 2.121.29

Changed

  • Enhanced preflight reports with page tree consistency diagnostics. Reports now include the declared page tree /Count and pass/fail checks that compare it, and the counted page objects, with the pages loaded by HotPDF.

Version 2.121.28

Changed

  • Enhanced preflight reports with xref table row diagnostics. Reports now include xref subsection, entry, free-entry, in-use-entry, and malformed-row counts, plus pass/fail checks for xref row syntax and whether xref coverage reaches the highest object number.

Version 2.121.27

Changed

  • Enhanced preflight reports with bounded PDF name-pair counting and additional consistency checks. Reports now distinguish catalog, page tree, and page objects; verify that object numbers are unique; and check whether trailer /Size covers the highest object number and whether trailer /Root is present.

Version 2.121.26

Changed

  • Enhanced the preflight report object and trailer diagnostics. Reports now include indirect object definition counts, highest object number, duplicate object number count, balanced stream/endstream checks, and trailer details for /Size, /Root, /Info, /ID, and /Encrypt.

Version 2.121.25

Changed

  • Enhanced THotPDF.CreatePreflightReport and THotPDF.SavePreflightReport with deeper cross-reference diagnostics. Reports now verify that the final %%EOF marker is near the end of the file, parse the last startxref offset, identify whether it targets an xref table or xref stream, and include xref table, xref stream, object stream, trailer, incremental update, and linearization counts.

Version 2.121.24

Changed

  • Expanded the preflight report helpers with password-aware overloads and richer diagnostics. Reports now include the PDF header version, xref style, resolved loaded page MediaBox entries, form field count, stream count, feature presence flags, JavaScript/action/media attachment warnings, warning totals, and pass/fail summaries for damaged files. The Delphi PreflightReport demo accepts an optional password argument for supported encrypted PDFs.

Version 2.121.23

Added

  • Added library-level preflight report helpers with THotPDF.CreatePreflightReport and THotPDF.SavePreflightReport. Applications can now generate a text summary for an input PDF covering the header, EOF marker, startxref, trailer or XRef stream, loadable page count, encryption state, catalog, page tree, page object, page box, information dictionary, root reference, indirect object count, and overall pass/fail status. The Delphi PreflightReport demo now uses these APIs directly.

Version 2.121.22

Added

  • Added a Delphi PreflightReport console demo that creates a sample PDF and writes a text report with lightweight structural checks, including the PDF header, EOF marker, loadable page count, encryption state, catalog, page tree, page box, and document information dictionary. The workflow keeps AutoLaunch disabled and can also report on an existing input PDF from the command line.

Version 2.121.21

Added

  • Added a Delphi SearchAndSelect console demo that builds a report, searches controlled text rows, and marks every matching term with PDF highlight annotations and /QuadPoints. The sample keeps AutoLaunch disabled so it is suitable for command-line and automated validation.

Version 2.121.20

Added

  • Added password loading for RC4-40 and RC4-128 Standard encrypted PDFs. Applications can now call LoadFromFile or LoadFromStream with a password, or call DecryptLoadedDocument after loading, then save an unencrypted loaded-document copy with SaveLoadedDocument. The new Delphi DecryptPDF console demo creates a password-protected sample and writes a decrypted copy without launching a PDF viewer.

Version 2.121.19

Added

  • Added a Delphi Printer console demo that generates a print-ready PDF preset. The sample writes print-focused /ViewerPreferences, page BleedBox and TrimBox entries, printable annotation flags, and a print-control ExtGState without launching a PDF viewer or sending a job to a physical printer.

Version 2.121.18

Added

  • Added a Delphi ConvertTo console demo that converts supported source graphics into PDF output files. The workflow creates separate PDF files from JPEG, BMP, TIFF, and EMF inputs with AutoLaunch disabled, making the sample suitable for command-line and automated checks.

Version 2.121.17

Added

  • Added loaded page operation helpers with InsertPagesFromDocument, ExtractPagesToFile, and MovePage. Applications can now insert pages from another loaded document, extract selected pages to a new PDF, and reorder loaded pages while keeping subsequent saves and extraction calls in the updated page order. The Delphi PageOperations demo shows the insert, extract, and reorder workflow without auto-launching a PDF viewer.

Version 2.121.16

Added

  • Expanded loaded AcroForm editing with RemoveFormField and FlattenFormFields. Applications can now remove loaded fields by index or name, or flatten loaded fields into static page content while removing the interactive AcroForm tree and widget annotations. The Delphi FormFields demo now shows descriptions, removal, and flattening without auto-launching a PDF viewer.

Version 2.121.15

Fixed

  • Added loaded bookmark title search with THotPDF.FindLoadedBookmarkPageIndex. Applications can now load an existing PDF, search the outline tree by bookmark title, and resolve matching /Dest or local GoTo action destinations to zero-based page indexes.

Version 2.121.14

Added

  • Added THPDFPage.AddTextWatermark for drawing rotated transparent text watermarks on generated or loaded pages. The new Delphi Watermark demo creates a source PDF, loads it, applies the watermark to every page, and saves the edited document.

Version 2.121.13

Added

  • Added loaded AcroForm field description inspection with GetFormFieldDescription. Applications can now read a loaded field's /TU tooltip text by index or name alongside field values, options, read-only state, and rename operations.

Version 2.121.12

Fixed

  • Added loaded choice-field option inspection with GetFormFieldOptionCount and GetFormFieldOptionValue. Applications can now load an existing combo box or list box field, enumerate its allowed /Opt values, and continue using the same loaded-form update and save workflow.