HotPDF Note di rilascio

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

Version 2.137.6

  • 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.
  • Improved file-based encrypted PDF loading so password opens no longer cache the whole source PDF just to recover raw encryption dictionary values.
  • Reduced AES-256 stream decryption memory copying by decrypting from existing buffers where possible, including loaded stream memory for large encrypted image streams.
  • The HugeFileBenchmark demo now includes a direct-copy row while the default operation set still covers the full LoadFromFile + SaveLoadedDocument path.

Version 2.137.5

  • 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.
  • 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.
  • The HugeFileBenchmark demo now includes a direct-rewrite operation and documents HTML/CSV benchmark runs for image-only and mixed text/image huge PDFs.

Version 2.137.4

  • La demo Delphi PreflightReport è stata aggiornata da console sample a strumento VCL GUI interattivo per single-file preflight workflows.
  • La GUI ora copre report standard text, JSON e HTML, password opzionali, profile INI files, preset integrati, single-file PDF/VT validation, embedded-report PDF output, report preview, status logging, automatic output naming e accesso rapido ai file generati.
  • È stato rimosso il vecchio comportamento di avvio che creava automaticamente un sample PDF e un report quando non venivano forniti command-line arguments.

2026-05-26 Version 2.137.3

  • 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.
  • Added Delphi regression coverage that keeps attribute-style PDF/VT metadata detection separate from the remaining structural PDF/VT checks.

2026-05-26 Version 2.137.2

  • Improved embedded preflight report validation so source PDFs that legitimately end with a final line break after %%EOF keep matching their stored fingerprint.
  • 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.

2026-05-26 Version 2.137.1

  • Extended CFF parser safety to direct byte-array checks, restoring the reader position after malformed input and clearing stale layout state on failed checks.
  • 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.

2026-05-26 Version 2.137.0

  • 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.

2026-05-26 Version 2.136.8

  • 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.
  • 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.

2026-05-26 Version 2.136.7

  • 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.
  • 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.

2026-05-26 Version 2.136.6

  • 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.

2026-05-26 Version 2.136.5

  • 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.

2026-05-26 Version 2.136.4

  • 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.
  • 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.
  • 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.

2026-05-25 Version 2.136.3

  • 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.
  • 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.

2026-05-25 Version 2.136.2

  • 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.
  • The two new options are mutually exclusive (passing both, the later one wins). The preset values match what THotPDF.GetBuiltInPreflightProfile recognises 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.

2026-05-25 Version 2.136.1

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

2026-05-25 Version 2.136.0

  • 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.
  • The two helpers complete the profile lifecycle: Load / GetBuiltIn / Save / Apply / Validate / Merge / Diff.

2026-05-25 Version 2.135.0

  • 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.
  • The four underlying APIs remain available so existing call chains keep working unchanged; the new wrapper is purely additive.

2026-05-25 Version 2.134.0

  • 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.
  • 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.

2026-05-25 Version 2.133.0

  • 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.
  • Recognised 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.

2026-05-25 Version 2.132.0

  • 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 recognised by the current preflight implementation, returning the unknown names joined by ', ' in the UnknownNames out parameter.
  • 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.

2026-05-25 Version 2.131.0

  • 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.
  • 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.

2026-05-25 Version 2.130.0

  • 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.
  • 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.

2026-05-25 Version 2.129.0

  • 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.
  • 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.
  • 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.

2026-05-25 Version 2.128.2

  • 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.
  • 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 colour-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.

2026-05-25 Version 2.128.1

  • 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.
  • 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.

2026-05-25 Version 2.128.0

  • 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.
  • 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.

2026-05-25 Version 2.127.0

  • 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.
  • 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.

2026-05-25 Version 2.126.1

  • 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.

2026-05-25 Version 2.126.0

  • 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 .
  • 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.

2026-05-25 Version 2.125.1

  • 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.
  • 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.

2026-05-25 Version 2.125.0

  • 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.
  • 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.

2026-05-25 Version 2.124.2

  • 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.
  • 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)".

2026-05-25 Version 2.124.1

  • 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.
  • 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.

2026-05-25 Version 2.124.0

  • 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 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.
  • The Delphi PreflightReport demo gains an embed CLI argument that writes the embedded variant alongside the standalone report.

2026-05-25 Version 2.123.1

  • 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 behaviour change: the test fills a gap in the regression suite that previously only covered the clean and "not a PDF" cases.

2026-05-25 Version 2.123.0

  • Added HTML output format to THotPDF.CreatePreflightReport and THotPDF.SavePreflightReport. The THPDFPreflightFormat enum gains a third value pfHTML alongside pfText and pfJSON.
  • HTML output is a self-contained dashboard-style document with inline CSS, severity-coloured 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.

2026-05-25 Version 2.122.4

  • 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.
  • 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.

2026-05-25 Version 2.122.3

  • Added root-cause diagnostic lines to THotPDF.CreatePreflightReport. When a damaged PDF triggers a defect count, the report now lists actionable detail.
  • 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.

2026-05-25 Version 2.122.2

  • 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.

2026-05-25 Version 2.122.1

  • 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.

2026-05-25 Version 2.122.0

  • 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.
  • 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.

2026-05-25 Version 2.121.36

  • 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.
  • 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.
  • 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.

2026-05-25 Version 2.121.35

  • 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.
  • 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.

2026-05-25 Version 2.121.34

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

2026-05-25 Version 2.121.33

  • 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.

2026-05-25 Version 2.121.32

  • 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.

2026-05-25 Version 2.121.31

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

2026-05-25 Version 2.121.30

  • 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.

2026-05-25 Version 2.121.29

  • 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.

2026-05-25 Version 2.121.28

  • 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.

2026-05-25 Version 2.121.27

  • 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.

2026-05-25 Version 2.121.26

  • 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.

2026-05-25 Version 2.121.25

  • 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.

2026-05-25 Version 2.121.24

  • 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.

2026-05-25 Version 2.121.23

  • 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.

2026-05-25 Version 2.121.22

  • 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.

2026-05-25 Version 2.121.21

  • 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.

2026-05-25 Version 2.121.20

  • 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.

2026-05-25 Version 2.121.19

  • 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.

2026-05-25 Version 2.121.18

  • 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.

2026-05-25 Version 2.121.17

  • 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.

2026-05-25 Version 2.121.16

  • 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.

2026-05-25 Version 2.121.15

  • 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.

2026-05-24 Version 2.121.14

  • 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.

2026-05-24 Version 2.121.13

  • 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.

2026-05-24 Version 2.121.12

  • 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.

2026-05-24 Version 2.121.11

  • Expanded loaded AcroForm editing with IsFormFieldReadOnly and RenameFormField. Applications can now inspect a loaded field's read-only flag, rename fields by index or name, save the loaded document, and reload it with the updated field names intact.

2026-05-24 Version 2.121.10

  • Added THotPDF.GetLoadedPageBox for inspecting page boundaries after LoadFromFile. Applications can now read a loaded page's MediaBox, CropBox, BleedBox, TrimBox, and ArtBox, including the standard fallback chain for boxes that are not declared directly.

2026-05-24 Version 2.121.9

  • Added loaded AcroForm field inspection and update APIs. Applications can now load an existing form PDF, enumerate field names and types, read and update field values, toggle a field's read-only flag, and save the loaded document with SaveLoadedDocument. The new Delphi FormFields demo shows the full load, edit, and save workflow.

2026-05-24 Version 2.121.8

  • Added THotPDF.RegisterLineGraphicsState for reusable line drawing ExtGState resources. Applications can now register line width, cap style, join style, and miter limit once, then apply the named state with THPDFPage.SetGraphicsState before stroking paths.

2026-05-24 Version 2.121.7

  • Added annotation interaction helpers for writing annotation /F flags and link /H highlight modes. Link helper methods now update LastAnnotation, so flags, highlight modes, border styles, and popup helpers can be chained consistently after link creation.

2026-05-24 Version 2.121.6

  • Added reusable Form XObject authoring APIs with page-level drawing helpers, including placement, scaling, and rotation support. Added current-transformation-matrix convenience helpers and bounded text helpers for single-line alignment, wrapped text output, and row-count calculation.

2026-05-24 Version 2.121.5

  • Added reusable Type 1 PFB and CFF parser units for HotPDF, including byte-array readers, Type 1 glyph-outline command extraction, CFF dictionary, INDEX, charset, and encoding readers, plus Type 1 PFB metadata and glyph lookup helpers. Delphi and C++Builder package projects now include the new parser units.

2026-05-24 Version 2.121.4

  • PDFACompliance='2A' and PDFACompliance='3A' now enable Tagged PDF basics without implicitly emitting a PDF/UA-1 XMP claim. PDF/A Level A files keep /MarkInfo, /StructTreeRoot, document title, language, and archival metadata, while pdfuaid metadata is emitted only when PDFUACompliance is explicitly enabled.
  • The PDF/A-2/3 smoke coverage now includes PDF/A-3A and asserts that Level A archival output does not advertise PDF/UA unless requested separately. The generated PDF/A-2A and PDF/A-3A smoke files pass veraPDF validation.

2026-05-24 Version 2.121.3

  • THPDFPage.UnicodeTextOut ora riutilizza la risorsa font Type 0 generata da RegisterUnicodeTTF per l'output Unicode dei piani supplementari, così il testo di pagina e gli stream di aspetto AcroForm condividono lo stesso percorso di codifica CID interno.
  • Il passaggio di finalizzazione condiviso mantiene ora sincronizzato l'output SMP a livello di pagina tramite FUnicodeUsedCps, /CIDToGIDMap, la voce /W del font discendente e /ToUnicode, evitando la vecchia mappa SMP locale alla pagina.

2026-05-24 Version 2.121.2

  • `THPDFPage.UnicodeTextOut` ora instrada i caratteri Unicode del piano supplementare attraverso la mappatura dei glifi del formato 12 registrata nel font della pagina quando `RegisterUnicodeTTF` ha caricato il font attivo. Gli emoji e altri valori scalari U+10000+ vengono emessi come un singolo glifo CID nel flusso di testo della pagina invece di due CID di metà surrogato.
  • La tabella CMap `/ToUnicode` converte i CID dei glifi SMP nel corrispondente paio di caratteri sostitutivi UTF-16BE, preservando l'estrazione del testo e l'accessibilità, mantenendo al contempo il percorso del font della pagina esistente `/CIDToGIDMap /Identity`.

2026-05-24 Version 2.121.1

  • I flussi di aspetto AcroForm basati su RegisterUnicodeTTF ora renderizzano i caratteri Unicode del piano supplementare, come le emoji, tramite un singolo CID interno invece di scrivere una coppia surrogata UTF-16 come due CID Identity-H. Il /CIDToGIDMap generato punta quel CID al glyph reale e /ToUnicode lo rimappa alla coppia surrogata UTF-16BE originale per l'estrazione del testo.
  • La fase di finalizzazione del font Unicode aggiorna /CIDToGIDMap, /W e /ToUnicode dopo che tutti i flussi di aspetto hanno registrato le proprie mappature CID interne tardive, in modo che il subsetting TrueType e gli aspetti dei moduli generati utilizzino l'insieme finale dei CID usati.

2026-05-23 Version 2.121.0

  • PDF 1.7 §12.6.4.13–15: le azioni multimediali (Rendition / Suono / Filmato) acquisiscono tre nuovi metodi helper per pulsanti su `THPDFPage`: `AddPushButtonWithRenditionAction` per §12.6.4.13 (collega un'annotazione Screen a un MediaRendition + MediaClipData che descrive il clip audio/video e un'operazione /OP da 0 a 4); `AddPushButtonWithSoundAction` per §12.6.4.14, con due overload (percorso del file o payload TBytes), un record THPDFSoundParams fornito dal chiamante (SampleRate / Canali / BitsPerSample / Encoding) e opzionali /Volume, /Repeat e /Synchronous; `AddPushButtonWithMovieAction` per §12.6.4.15 (fa riferimento a un'annotazione Movie tramite /Annotation e seleziona /Operation Play / Stop / Pause / Resume).
  • `AddScreenAnnotation` e `AddMovieAnnotation` ora restituiscono il dizionario dell'annotazione creata, in modo che i chiamanti possano concatenarlo all'helper di azione corrispondente. La modifica della firma da `procedure` a `function` è compatibile con l'ABI di Delphi; i chiamanti esistenti che li invocano e scartano il risultato continuano a compilare e generano file PDF identici a livello di byte.
  • Implementazione standard: ogni componente genera le voci obbligatorie specificate nella documentazione, oltre ai campi opzionali più comunemente necessari (Sound/Volume/Repeat/Synchronous; Rendition/JS). I parametri di riproduzione dei media, i parametri dello schermo, il selettore di riproduzione e il mix audio sono stati deliberatamente omessi; le impostazioni predefinite del lettore coprono il 95% dei casi e i componenti rimangono minimali.
  • PDF/A (tutti i livelli) e PDF/X (tutti i profili) rifiutano tutte e tre le azioni multimediali all'ingresso, fornendo una diagnostica di riferimento ISO (ISO 19005-1 §6.6.1 / ISO 19005-2 §6.5.1 / ISO 19005-3 §6.5.1 / ISO 15930). I meccanismi di annotazione preesistenti relativi a `AddScreenAnnotation` / `AddSoundAnnotation` / `AddMovieAnnotation` rimangono attivi.
  • L'azione Rendition associa il file system MediaClipData con le autorizzazioni dei media /P /TF (TEMPACCESS) secondo la sezione §13.2.6.1, Tabella 280, che rappresenta il livello di autorizzazione minimo che consente all'utente di passare i dati ai codec audio/video della piattaforma.
  • I flussi di azione audio impostano i valori predefiniti per i campi opzionali (Volume=1.0, Repeat=false, Synchronous=false) e li emettono solo quando il chiamante passa valori diversi da quelli predefiniti, mantenendo il dizionario dell'azione il più compatto possibile per il caso più comune.
  • Sound stream metadata (/R sample rate / /C channels / /B bits per sample / /E encoding) is caller-supplied via the new THPDFSoundParams record. The v2.16-era AddSoundAnnotation entry point still hard-codes 22050 / 16-bit / Stereo / Signed; the new Sound action path avoids that pitfall so callers can play 44.1 kHz mp3, 8 kHz µ-law telephony audio, or any other source at the correct rate.
  • Verificato con le nuove versioni Win32 e Win64. I test `smoke_multimedia_actions` (che coprono tutti e quattro i tipi di azione e la concatenazione di annotazioni schermo/video) e `smoke_multimedia_actions_pdfa_pdfx` (che includono 8 asserzioni che verificano 3 azioni in formato PDF/A e PDF/X) sono stati superati. Il test di regressione `smoke_button_actions` continua a passare dopo la refactoring delle procedure `AddScreenAnnotation` e `AddMovieAnnotation` in funzioni.

2026-05-23 Version 2.120.15

  • Correzione: EndDoc serializzava il grafo degli oggetti PDF prima che venissero applicate due modifiche successive (il subsetter di TrueType dalla versione v2.84.0 e lo stamper automatico di /Tabs /S conforme a PDF/UA-1 §7.18.3 dalla versione v2.94.0), quindi nessuna di queste modifiche veniva applicata al file generato. I documenti che utilizzavano RegisterUnicodeTTF + AddTextField includevano l'intero file di font (~1 MB per il latino / ~14 MB per il CJK) invece della porzione necessaria (~150 KB / ~500 KB), mancava il prefisso di subset a sei lettere "AAAAAA" in /BaseFont, il flusso /CIDSet nel FontDescriptor era assente (veraPDF segnalava un errore conforme a ISO 19005-1 §6.3.5 / -2 -3 §6.2.11), e i PDF conformi a PDF/UA-1 che non includevano la chiave §7.18.3 /Tabs /S nelle pagine con annotazioni generavano errori nella regola 21-001 di Matterhorn e nell'errore PAC 3 "Tabs".
  • Entrambi i modificatori ora vengono eseguiti PRIMA di SaveToStream / SaveToFile. Questo processo esamina l'elenco degli oggetti indiretti e scrive il file PDF. L'output è identico in termini di byte alla versione v2.120.14 per i documenti che non registrano un font TTF Unicode né abilitano PDFUACompliance; in questi casi, entrambi i modificatori erano già operazioni non attive, quindi il riordino modifica solo i documenti per i quali l'output della versione v2.120.14 era stato interrotto in modo silenzioso.
  • Verificato con il test Win32 smoke_unicode_ttf_subset (il subset occupa il 33,6% dei byte del file Arial su disco; sono stati risparmiati 676 KB; /BaseFont prefisso UYENHH+ArialMT, coerente tra Type 0 / CIDFontType2 / FontDescriptor.FontName) e con il test Win32 smoke_pdfua_annot_structparents (/Tabs /S stampato nel dizionario della pagina annotata; tutte le cinque asserzioni relative a §7.18.3 + la struttura delle annotazioni sono corrette).

2026-05-23 Version 2.120.14

  • PDF/UA-1: è stata implementata una rigorosa verifica della struttura e del ruolo (ISO 14289-1 §7.7 + ISO 32000-1 §14.7.3). Con PDFUACompliance abilitato, AddStructureElement ora rifiuta qualsiasi ruolo "/S" che non sia uno dei 41 tipi di struttura standard definiti nella Tabella 333 di PDF 1.7 §14.8.4 (Document / Part / Art / Sect / Div / BlockQuote / Caption / TOC / TOCI / Index / NonStruct / Private / H / H1..H6 / P / L / LI / Lbl / LBody / Table / TR / TH / TD / THead / TBody / TFoot / Span / Quote / Note / Reference / BibEntry / Code / Link / Annot / Ruby / RB / RT / RP / Warichu / WT / WP / Figure / Formula / Form), né un ruolo personalizzato che il chiamante ha pre-registrato tramite AddStructRoleMap. L'eccezione diagnostica include la stringa del ruolo problematico, fa riferimento a PDF/UA-1 §7.7 / Tabella 333 e suggerisce la correzione tramite AddStructRoleMap. Anche un ruolo vuoto viene rifiutato con un messaggio specifico. Senza questa verifica, i ruoli non conformi verrebbero inseriti silenziosamente nell'albero della struttura e causerebbero errori "tipo di struttura sconosciuto" nei tool veraPDF / PAC a valle.
  • La nuova funzione viene attivata solo quando PDFUACompliance è impostato su True; le chiamate che non utilizzano UA mantengono il comportamento precedente alla versione v2.120.14, byte per byte. Tutte le quattro versioni di AddStructureElement (la versione base con 4 argomenti di tipo AnsiString, la versione con 6 argomenti /Alt + /ActualText introdotta nella versione v2.88.0, la versione con 7 argomenti /ID introdotta nella versione v2.95.0 e la versione con l'enumerazione THPDFStandardStructureType introdotta nella versione v2.119.41) convergono sullo stesso percorso, quindi è sufficiente un'unica condizione. La versione con l'enumerazione passa sempre un nome definito nella Tabella 333 e quindi supera sempre il controllo; gli utilizzatori preferiscono questa versione per eliminare errori di battitura o problemi di sensibilità alle maiuscole/minuscole (ad esempio, 'Para' rispetto a 'P', 'Lbody' rispetto a 'LBody') durante la compilazione.
  • v2.119.41 ha già introdotto l'enum THPDFStandardStructureType (41 nomi di specifiche raggruppati in 5 bucket di ruoli PDF: §14.8.4.1 Grouping / §14.8.4.2 Block-level / §14.8.4.3 Inline-level / §14.8.4.4 Ruby+Warichu / §14.8.4.5 Illustration), StandardStructureTypeToName(T) per la conversione da enum a nome e IsStandardStructureType(Name) per la validazione lato chiamante; v2.120.14 integra queste funzionalità nel punto di ingresso AddStructureElement, in modo che il controllo rigoroso sia automatico. Una nuova funzione helper privata, _IsCustomRoleInRoleMap, esamina l'array dinamico FStructRoleMap utilizzando CompareMem, che è sicuro per i byte, e corrisponde correttamente ai nomi di ruolo personalizzati non ASCII negli host CP_ACP=65001.

2026-05-23 Version 2.120.13

  • Correzione: la sorgente di HotPDF v2.120.12 non veniva compilata in RAD Studio perché le due overload di EnableShapingFeatureForSubset si trovavano all'interno della sezione pubblicata di THotPDF, cosa che Delphi rifiuta con l'errore E2266 ("solo uno dei metodi sovrascritti può essere pubblicato"). Nella versione v2.120.13, le due overload sono racchiuse in una coppia di sezioni pubbliche locali, in modo che la stessa API pubblica venga compilata correttamente con dcc32/dcc64; le proprietà e le funzioni di supporto circostanti rimangono pubblicate senza modifiche. Non ci sono modifiche al comportamento a runtime.

2026-05-23 Version 2.120.12

  • Abilita la funzionalità di shaping per i subset (completamento della fase 8f): THotPDF.EnableShapingFeatureForSubset (FeatureTag) / the L'implementazione di THPDFShapingFeature enum include un'iterazione su ogni lookup GSUB associato alla funzionalità richiesta, nella versione v2.119.49. SetGSUBScript / SetGSUBLanguage imposta lo stato di selezione della lingua, enumerando ogni potenziale GID sostitutivo per LookupType 1 (Single — delta rispetto ai glifi Coverage + array substituteGlyphIDs di Format 2), LookupType 2 (Multiple — Sequence.substituteGlyphIDs[]), LookupType 3 (Alternate — AlternateSet.alternateGlyphIDs[]), LookupType 4 (Ligature — Ligature.ligatureGlyph), LookupType 5 / 6 (Contextual / Chained Contextual — ricorsione nei lookup SequenceLookupRecord nidificati con un limite di profondità di 8), LookupType 7 (Extension — de-wrapping automatico al tipo di lookup effettivo) e LookupType 8 (Reverse Chained — substituteGlyphIDs[]), e combina tramite OR i GID in FUnicodeExtraUsedGlyphs, in modo che il subsetter EndDoc della versione v2.84.0 includa tutti i glifi che la funzionalità può generare nel subset del font incorporato. La fase 8f integra la funzionalità MarkUnicodeGlyphUsed a livello di glifo della versione v2.119.50, con un'opzione di attivazione a livello di funzionalità per i chiamanti il cui processo di creazione abilita una funzionalità in modo universale.
  • L'enumerazione sovrascrive ogni valore di THPDFShapingFeature, indirizzandola al set di tag OpenType a 4 byte convenzionale: sfArabicGSUB → init / medi / fina / isol / rlig; sfStandardLigatures → liga; sfContextualLigatures → clig + rlig; sfStylisticAlternates → salt; sfIndicShaping → nukt / akhn / rphf / rkrf / pref / half / vatu / cjct / pres / blws / abvs / psts / haln / pstf; sfContextualAlternates → rclt + calt. La sovrascrittura stringa accetta qualsiasi tag OpenType a 4 byte per un targeting preciso, oltre ai casi dell'enumerazione inclusa. Attenzione al gonfiore delle sottosezioni: l'abilitazione di funzionalità ampie (ad esempio, aalt Access All Alternates, alcune font includono ogni glifo in uno script) può includere una grande frazione dell'insieme di glifi della font nella sottosezione, vanificando il lavoro di riduzione delle dimensioni della versione 2.84.0; i chiamanti dovrebbero preferire Phase 9 MarkUnicodeGlyphUsed quando conoscono i GID emessi. Disattivato per impostazione predefinita, attivazione esplicita. Chiude l'ultima fase rimanente della roadmap del motore GSUB, fase 8.
  • Le regole di gestione degli errori sono state aggiornate alla versione v2.119.50: non viene registrata alcuna font, non è presente la tabella GSUB, il tag non è di 4 byte, la funzionalità è assente nel percorso (script, lingua), la catena di lookup è vuota; ogni condizione che indica "niente da fare" viene gestita silenziosamente (senza eccezioni). Le chiamate ripetute sono idempotenti (la bitmap viene unita tramite OR). La ricorsione nidificata delle sottotabelle contestuali di Formato 1/2 verrà implementata in una versione futura; il Formato 3 è dominante nelle font reali ed è implementato. I client che necessitano di una copertura contestuale precisa per il Formato 1/2 possono ricorrere a MarkUnicodeGlyphUsed a livello di singolo glifo.

2026-05-23 Version 2.120.11

  • ToUnicode CMap caller-side reverse mapping (Phase 8d completion): three new public methods on THotPDF let callers register additional (substitute codepoint, original Unicode source codepoint sequence) reverse mappings into the EndDoc Adobe-Identity-UCS ToUnicode CMap. The v2.119.61 / v2.119.62 / v2.119.65 release series added 35 hard-coded bfchar entries for the Arabic ligatures (LAM-ALEF / YEH-HAMZA / Allah / Bismillah) and Latin Alphabetic Presentation Forms (fi / fl / ffi / ffl / ff / ſt / st) that HotPDF's producer-side shaping pipeline emits automatically; v2.120.11 closes Phase 8d by letting callers register their own mappings for the substitute glyphs they drive via the v2.119.43-50 GSUB engine APIs (GetSingleSubstituteGlyph, GetMultipleSubstituteGlyphs, GetAlternateGlyph, ApplyLigatureSubstitution, ApplyContextualSubst, ApplyReverseChainedContextualSubst).
  • `RegisterToUnicodeReverseMapping (SubstCodepoint, SourceCodepoints) registra una voce (sequenza di sostituzione → sequenza di origine). Gli utilizzi tipici includono: dopo una sostituzione multipla (1 GID → N GIDs), viene emessa la sequenza di sostituzione e viene registrata la mappatura inversa in modo che il lettore possa copiare/incollare e tornare al codepoint originale; dopo la sostituzione di lighe (N GIDs → 1 GID di ligatura), viene emessa la ligatura e viene registrato il codepoint della ligatura, invertendolo nella sequenza di origine di N elementi (ad esempio, una ligatura contestuale CALT arbitraria viene invertita nei suoi codepoint componenti). `ClearToUnicodeReverseMappings` elimina tutte le registrazioni effettuate dal chiamante; `ToUnicodeReverseMappingCount` indica il numero di registrazioni in sospeso.
  • EndDoc emette e aggiunge le voci registrate dal chiamante come blocchi bfchar aggiuntivi dopo il blocco predefinito di 35 voci, suddividendoli automaticamente in sottoblocchi di 100 voci per ogni Adobe CMap e in conformità con le specifiche dei file CIDFont (Technical Note #5014) §1.4.2 e il limite dell'operatore bfchar. I codepoint BMP emettono 4 cifre esadecimali; i codepoint SMP emettono una coppia surrogata UTF-16BE (8 cifre esadecimali) in base alle specifiche di Adobe CMap. L'ordine di registrazione viene preservato, quindi la semantica "ultima scrittura sovrascrive" dei bfchar dei lettori PDF consente ai chiamanti di avere un comportamento deterministico di override in caso di conflitti con le 35 voci predefinite (un chiamante che registra una mappatura personalizzata per <FB01> "fi" sovrascrive l'impostazione predefinita di v2.119.65 nel lettore). I chiamanti che non chiamano mai RegisterToUnicodeReverseMapping mantengono la ToUnicode CMap identica in termini di byte rispetto alla baseline di v2.120.10. SetFormUnicodeFontDict ('', nil) reimposta il percorso e cancella il registro del chiamante, in modo che la successiva registrazione del font Unicode inizi senza problemi.

2026-05-23 Version 2.120.10

  • Il motore di shaping del testo per il Myanmar (fase 8f.10) registra il Myanmar (tag OpenType mymr) come la decima e ultima scrittura Indic in HotPDF, coprendo sia il blocco principale del Myanmar (U+1000-U+109F: Birmano, Mon, Sgaw Karen, Pwo occidentale, Shan, Rumai Palaung, Pa'o) sia l'estensione A (U+AA60-U+AA7F). È stata introdotta una nuova funzione ApplyMyanmarReorder per la riorganizzazione preliminare e una funzione GetMyanmarCategory per la ricerca di codepoint, entrambe riutilizzabili tramite il dispatcher ApplyIndicReorder.
  • La struttura sillabica più complessa nel batch è Kinzi 3-CP. Il prefisso (U+1004 + U+103A + U+1039) all'inizio della sillaba viene rilevato, messo da parte ed emesso all'inizio dell'output secondo R8; la vocale pre-base E (U+1031) si sposta all'inizio della sillaba secondo R10; quattro consonanti mediali Y / R / W / H (U+103B-U+103E) vengono raccolte ed emesse in un ordine fisso Y → R → W → H secondo R9, indipendentemente dall'ordine di origine.
  • ASAT (U+103A) e VIRAMA (U+1039) vengono entrambi trattati come virama per la gestione delle consonanti sovrapposte. DOT BELOW (U+1037) viene renderizzato sotto la base; gli altri segni di tono vengono renderizzati sopra. ANUSVARA (Bindu) viene renderizzato sopra; VISARGA viene posizionato dopo. La Repha non viene applicata.
  • Due chiavi di registro `IndicScripts` (blocco principale e Extended-A) condividono le stesse funzioni di ordinamento per il Myanmar, quindi le consonanti Extended-A e i segni di tono Pa'o Karen vengono gestiti in modo trasparente dal dispatcher.
  • **Completa l'elaborazione batch per le scritture Indic non-Devanagari, suddivisa in 11 fasi** (fasi 8f.0-8f.10): include l'infrastruttura e 10 scritture Indic registrate, tra cui Devanagari, Bengali, Gujarati, Tamil, Telugu, Kannada, Malayalam, Sinhala (famiglia Brahmic SIA), Khmer e Myanmar (Sud-Est Asiatico).
  • Per Unicode 16.0 §16.3 (Myanmar) e la specifica di shaping OpenType per il Myanmar.

2026-05-23 Version 2.120.9

  • Il motore di shaping del testo Khmer (fase 8f.9): registra il Khmer (tag OpenType khmr, blocco Unicode U+1780-U+17FF) come la nona scrittura indiana in HotPDF e la prima scrittura del Sud-Est asiatico. Una nuova funzione ApplyKhmerReorder esegue una pre-elaborazione di riordino e GetKhmerCategory esegue la ricerca del punto di codice, entrambe riutilizzabili tramite il dispatcher ApplyIndicReorder.
  • Struttura sillabica indipendente (diversa dal modello Brahmico R1-R5 utilizzato nelle fasi 8f.1-8f.8): le vocali pre-base (E / AE / AI / OE / OO / AU) vengono spostate all'inizio della sillaba; i segni di traslazione (MUUSIKATOAN, TRIISAP) e altri segni superiori vengono indirizzati al buffer superiore; il Bindu (NIKAHIT) viene renderizzato sopra; il Visarga (REAHMUK, YUUKALEAPINTU) viene renderizzato dopo.
  • Gestione dei sottoscritti COENG: ogni COENG (U+17D2) + una coppia di consonanti forma un gruppo di consonanti sovrapposte che rimane nel buffer principale nell'ordine originale, consentendo alle funzionalità 'pres' / 'blws' GSUB del font di gestire il posizionamento dei sottoscritti. Sono supportati i sottoscritti nidificati.
  • Nessuna modifica a Repha: le scritture Khmer non formano una rappresentazione visiva di Repha, quindi `Ra + COENG + Consonante` rimane nell'ordine originale anziché ruotare verso la fine della sillaba.
  • Per Unicode 16.0 §16.4 (Khmer) e la specifica OpenType per la formattazione Khmer.

2026-05-23 Version 2.120.8

  • PAdES adbe-revocationInfoArchival CMS attributo firmato (Fase 9 di PAdES): emette l'OID privato di Adobe 1.2.840.113583.1.1.8 che contiene i valori di revoca CRL e OCSP all'interno della firma CMS stessa. Adobe Acrobat privilegia questo attributo per la verifica della revoca della firma, rispetto alle ricerche nel dizionario DSS e ai download di OCSP/CRL da rete; questo è fondamentale per i PDF validabili offline e per la migliore interoperabilità con Adobe Acrobat.
  • Nuovi campi in `THPDFCMSSignOptions`:
    • AdobeCRLsDER: array of TBytes - ogni elemento è una singola `CertificateList` (RFC 5280) in formato DER, nello stesso formato dei flussi `/CRLs` di DSS.
    • AdobeOCSPsDER: array of TBytes - ogni elemento è una `BasicOCSPResponse` SEQUENCE (RFC 6960 §4.2.1) in formato DER. Nota: non il wrapper `OCSPResponse` esterno; le chiamate con risposte OCSP complete devono prima estrarre la stringa di octetti `responseBytes.response` per ottenere la `BasicOCSPResponse`.
  • Attivazione: attributo emesso quando almeno uno dei due array non è vuoto. Il valore predefinito, vuoto (entrambi gli array), mantiene la stabilità a livello di byte nella versione v2.120.7.
  • ASN.1 DER secondo le specifiche Adobe: RevocationInfoArchival ::= SEQUENCE { crl [0] EXPLICIT SEQUENCE OF CRL OPTIONAL, ocsp [1] EXPLICIT SEQUENCE OF BasicOCSPResponse OPTIONAL, otherRevInfo [2] EXPLICIT SEQUENCE OF OtherRevInfo OPTIONAL }. HotPDF gestisce [0] e [1]; [2] (otherRevInfo per sistemi di revoca non X.509) rimane al di fuori dello scopo.
  • Forma del filo (entrambe le diramazioni popolate): 30 A0 30 <...> A1 30 <...>
  • **Coesiste con il dizionario DSS:** questo attributo è *complementare* (e non una sostituzione) al dizionario PAdES-B-LT DSS (a livello di catalogo, `/DSS /Certs /OCSPs /CRLs /VRI`, introdotto in v2.110.0). I validatori PAdES rigorosi (EU DSS, mTOM) tendono a riconoscere il DSS; Adobe Acrobat riconosce `adbe-revocationInfoArchival`. Per la massima interoperabilità, popolate entrambi i livelli con gli stessi byte CRL/OCSP tramite `AddPAdESDSSCRL` / `AddPAdESDSSOCSP` e `AdobeCRLsDER` / `AdobeOCSPsDER`.
  • Il wrapper `HPDFCMSBuildSignedData` con 4 argomenti azzera i nuovi campi, in modo che i pacchetti CMS legacy rimangano identici in termini di byte.
  • Per Adobe Acrobat PDF Reference + RFC 5280 (CRL) + RFC 6960 (OCSP).

2026-05-23 Version 2.120.7

  • PAdES content-time-stamp, firma CMS dell'attributo (PAdES Fase 8): genera id-aa-ets-contentTimestamp (OID 1.2.840.113549.1.9.16.2.20, ETSI EN 319 122-1 §5.2.8 + RFC 5126 §5.11.4) contenente un RFC 3161 TimeStampToken che dimostra che il contenuto del documento esisteva al momento dichiarato dalla TSA prima che il firmatario lo firmasse. Distinto da signature-time-stamp (attributo non firmato della Fase 4, successivo alla firma).
  • Nuovo campo `THPDFCMSSignOptions`: `GetContentTimeStamp: THPDFCMSTimestampCallback`. Progetto speculare a `GetSignatureTimeStamp` della versione v2.120.3: HotPDF invoca il callback con l'hash SHA-256 del documento (lo stesso hash presente nell'attributo `messageDigest`), e include il TimeStampToken DER restituito come valore dell'attributo content-time-stamp all'interno di SignedAttributes.
  • Valore predefinito `nil` = nessuna timestamp emessa. Chi chiama può assegnare una closure che implementa un TSA (Timestamping Service) RFC 3161 su HTTP. Se viene restituito un `TBytes` vuoto, l'operazione viene saltata silenziosamente (degradazione controllata quando il TSA non è raggiungibile).
  • **Punti finali TSA gratuiti** (nessuna sottoscrizione richiesta) per casi d'uso non qualificati: http://timestamp.digicert.com, http://timestamp.sectigo.com, http://timestamp.globalsign.com/tsa/r6advanced1, https://freetsa.org/tsr, http://timestamp.apple.com/ts01. Gli scenari qualificati eIDAS richiedono un QTSA commerciale; la firma per usi non legali funziona con i punti finali gratuiti (con limitazioni di velocità, ma adeguati per i flussi di lavoro tipici).
  • Callback contract: viene invocata una volta per ogni operazione di firma, *prima* che gli attributi firmati vengano sigillati. I byte TST diventano parte di ciò che viene firmato, quindi la firma stessa copre il contenuto e il timestamp; ecco perché si tratta di un attributo firmato (a differenza del timestamp della firma, che non è firmato e si trova in `unsignedAttrs` dopo la firma).
  • Il wrapper `HPDFCMSBuildSignedData` con 4 argomenti imposta `GetContentTimeStamp:=nil` per mantenere identiche le vecchie bundle CMS.
  • Responsabilità del chiamante: i segnaposto PAdES richiedono l'attributo ContentsBytes dimensionato per la firma e il timestamp del contenuto (TST) (circa 4-8 KB in genere). Per i flussi di lavoro B-T che combinano il timestamp del contenuto e il timestamp della firma, considerare entrambi i TST. Il valore predefinito di 16 KB per AddPAdESSignatureField(Profile='B-T') è sufficiente per la maggior parte delle combinazioni.
  • Secondo ETSI EN 319 122-1 V1.2.1 §5.2.8 + RFC 3161 §6 + RFC 5126 §5.11.4.

2026-05-23 Version 2.120.6

  • PAdES signer-attributes-v2 signedAssertions [2] branch (PAdES Fase 7): chiude il terzo e ultimo campo. SignerAttributeV2 OPZIONALE. Consente al firmatario di allegare asserzioni firmate, identificate da OID (asserzioni SAML 2.0, token JWT in formato compatto, attestazioni OAuth, token di attestazione specifici per l'organizzazione), all'interno della firma CMS.
  • Nuovo record `THPDFSignedAssertion`: `SignedAssertionID` (OID puntato che identifica il tipo di asserzione) più `AssertionBody: TBytes` (qualsiasi sequenza di byte pre-codificata definita dallo schema dell'OID; tipicamente una stringa di byte che contiene il codice XML SAML o la forma compatta JWT). Se `AssertionBody` è vuoto, il campo ANY viene omesso, lasciando solo `signedAssertionID` (valido secondo le specifiche per le asserzioni di tipo booleano registrate tramite OID).
  • Nuovo campo `THPDFCMSSignOptions`: `SignedAssertions: array di THPDFSignedAssertion`. Sono supportate più asserzioni; HotPDF avvolge la sequenza in `[2] EXPLICIT` (tag `0xA2`).
  • La condizione per l'emissione di `SignerAttributeV2` ora si attiva se almeno uno dei tre campi OPZIONALI è popolato. Se tutti e tre i campi sono popolati, viene generato il seguente output: SignerAttributeV2 SEQUENCE { [0] claimed..., [1] certified..., [2] signedAssertions... } nell'ordine specificato nel campo.
  • ASN.1 secondo ETSI EN 319 122-1 §5.2.6: SignedAssertion ::= SEQUENCE { signedAssertionID OBJECT IDENTIFIER, signedAssertion ANY DEFINED BY signedAssertionID OPTIONAL }. Struttura dati per una singola asserzione con corpo: A2 30 30 06 .
  • Utilizza `CMSEncodeOIDFromString` (v2.120.1) per la codifica degli OID, accettando qualsiasi OID in notazione puntata.
  • Il wrapper `HPDFCMSBuildSignedData` con 4 argomenti imposta il nuovo campo a zero, in modo che i pacchetti CMS legacy rimangano identici in termini di byte.
  • signer-attributes-v2 收口: all three OPTIONAL fields ([0] claimedAttributes, [1] certifiedAttributesV2, [2] signedAssertions) now wired through Phases 5/6/7. Full ETSI EN 319 122-1 §5.2.6 attribute coverage from the PAdES producer side.
  • Secondo ETSI EN 319 122-1 V1.2.1 §5.2.6 + ALLEGATO A.1.

2026-05-23 Version 2.120.5

  • Il branch `certifiedAttributesV2` (Fase 6 di PAdES): emette certificati di attributi X.509 (RFC 5755) all'interno della sequenza `SignerAttributeV2`, in aggiunta o al posto di `claimedAttributes` [0] della versione v2.120.4. Questo permette al firmatario di allegare certificati di ruolo rilasciati da un'autorità di attributi (AA) che supportano crittograficamente l'identità/capacità dichiarata.
  • È stato aggiunto il nuovo campo `THPDFCMSSignOptions`: `CertifiedAttributeCertsDER: array di TBytes`. Ogni elemento è il certificato `AttributeCertificate` (RFC 5755) codificato in DER che il chiamante ha ricevuto dall'autorità di certificazione (AA). HotPDF li emette esattamente in una sequenza `CertifiedAttributesV2` racchiusa da `[1] EXPLICIT` (tag `0xA1`).
  • L'attributo `signer-attributes-v2` viene ora emesso quando uno qualsiasi dei seguenti elementi è non vuoto: `ClaimedRoles` oppure `CertifiedAttributeCertsDER`. Quando entrambi sono popolati, viene creata una sequenza `SignerAttributeV2` che contiene `[0]` + `[1]`, rispettando l'ordine specificato.
  • ASN.1 DER wire format (solo per CertifiedAttributesV2): A1 30 dove ogni ACn è la sequenza AttributeCertificate fornita dal chiamante, esattamente come definita in RFC 5755. La scelta tra AttributeCertificate e OtherAttributeCertificate viene determinata dall'input DER del chiamante (entrambe le alternative iniziano con un tag SEQUENCE 0x30; HotPDF non esamina il contenuto).
  • Il wrapper `HPDFCMSBuildSignedData` con 4 argomenti reimposta il nuovo campo, in modo che i pacchetti CMS legacy rimangano identici in termini di byte rispetto alla versione v2.119.27.
  • Ambito: le `signedAssertions` [2] (token SAML / JWT / OID arbitrari) sono ancora in fase di implementazione e saranno disponibili nella prossima fase.
  • Secondo ETSI EN 319 122-1 V1.2.1 §5.2.6 + ALLEGATO A.1 + RFC 5755.

2026-05-23 Version 2.120.4

  • PAdES signer-attributes-v2, firma digitale CMS: emette l'attributo id-aa-ets-signerAttrV2 (OID 0.4.0.19122.1.1, ETSI EN 319 122-1 §5.2.6), consentendo al firmatario di dichiarare i ruoli dichiarati (ad esempio, "Direttore Finanziario", "Rappresentante Autorizzato") all'interno del pacchetto CMS. Sostituisce la versione v1 signerAttr (RFC 5126 §5.10), che è stata deprecata, per le nuove firme.
  • Nuova voce `THPDFClaimedRole`: `RoleOID` (identificatore OID dell'attributo, tipicamente un OID di ruolo organizzativo o l'ID `1.3.6.1.5.5.7.20.1 id-id-aa-PERMrole`) + `RoleValue` (stringa UTF-8 contenente l'etichetta del ruolo leggibile).
  • È stato aggiunto il nuovo campo `THPDFCMSSignOptions`. `ClaimedRoles: array di THPDFClaimedRole`. Sono supportati più ruoli; ciascuno diventa un `Attribute` all'interno della sequenza `claimedAttributes [0]`. Un array vuoto (valore predefinito) sopprime l'attributo, mantenendo la stabilità a livello di byte introdotta in v2.120.3 per le chiamate che non hanno optato per questa funzionalità.
  • ASN.1 DER secondo ETSI EN 319 122-1 §5.2.6 + ALLEGATO A.1 (modulo DEFINITIONS EXPLICIT TAGS): SignerAttributeV2 SEQUENCE { [0] EXPLICIT ClaimedAttributes } dove ClaimedAttributes ::= SEQUENCE OF Attribute. Ogni ruolo viene serializzato come Attribute { type OID, values SET OF UTF8String }. Il tag EXPLICIT significa che 0xA0 avvolge letteralmente la SEQUENCE OF interna (il tag interno 0x30 viene preservato).
  • L'identificatore univoco (OID) è stato codificato manualmente: 04 00 81 95 32 01 01 (arco 0.4.0.19122.1.1; base-128 e continuazione di 19122 → 0x81 0x95 0x32). In futuro, i valori personalizzati potranno utilizzare la funzione CMSEncodeOIDFromString a partire dalla versione v2.120.1.
  • **Ambito:** solo L'implementazione di `claimedAttributes [0]` è stata completata in questa fase. `certifiedAttributesV2 [1]` (certificati di attributi X.509 secondo RFC 5755) e `signedAssertions [2]` (token in stile SAML/JWT) richiedono ulteriori componenti e rimangono al di fuori dell'ambito fino a quando non si presenterà una richiesta specifica.
  • La funzione wrapper `HPDFCMSBuildSignedData` con 4 argomenti imposta la lunghezza di `ClaimedRoles` a zero, in modo che i pacchetti CMS legacy rimangano identici per quanto riguarda i byte rispetto alla versione v2.119.27.
  • Per ETSI EN 319 122-1 V1.2.1 §5.2.6 + EN 319 142-1 V1.2.1 §6.3 Tabella 1, riga signer-attributes-v2 (OPZIONALE, 0 o 1).

2026-05-23 Version 2.120.3

  • PAdES: l'attributo CMS non firmato signature-time-stamp (PAdES Fase 4) viene emesso come id-aa-signatureTimeStampToken (OID 1.2.840.113549.1.9.16.2.14, RFC 3161 §6 + ETSI EN 319 122-1 §5.3) all'interno del set [1] IMPLICIT unsignedAttrs di SignerInfo. Fornisce il percorso signature-time-stamp per il servizio trusted-time PAdES-B-T (Tabella 1: B-T *deve essere fornito* tramite signature-time-stamp *o* document-time-stamp).
  • È stato aggiunto un nuovo tipo di metodo anonimo `THPDFCMSTimestampCallback`: `reference to function(const SigValueSHA256: TBytes): TBytes`. HotPDF invoca il callback con l'hash SHA-256 di `SignerInfo.signatureValue` (l'impronta del messaggio secondo la RFC 3161, sezione 2.4.2) e incorpora il token TimeStamp DER restituito come valore dell'attributo.
  • Nuovo campo `THPDFCMSSignOptions`: `GetSignatureTimeStamp`. Il valore predefinito è `nil`, il che significa che non viene utilizzato alcun timestamp; le chiamate a PAdES-B-T assegnano una closure che gestisce l'interazione HTTP/RFC 3161 con il TSA e restituisce i byte del TST. Se vengono restituiti byte TBytes vuoti, l'operazione viene saltata senza errori (ad esempio, il TSA non è raggiungibile, ma la firma deve comunque essere inclusa).
  • La gestione della rete, dell'autenticazione e degli account TSA rimane nel codice chiamante; HotPDF si limita a trasferire il risultato nell'attributo `unsignedAttrs`. Questo si integra perfettamente con la dimensione predefinita esistente di `AddPAdESSignatureField(Profile='B-T', ContentsBytes >= 16384)`.
  • ASN.1 wire: La sequenza SignerInfo ora può opzionalmente contenere un `[1] IMPLICIT SET OF Attribute` (tag `0xA1`) che contiene un attributo `signature-time-stamp` il cui valore è il `TimeStampToken ContentInfo` fornito dal chiamante, esattamente come è.
  • Il wrapper `HPDFCMSBuildSignedData` con 4 argomenti imposta `GetSignatureTimeStamp:=nil` in modo che i pacchetti CMS legacy rimangano identici per quanto riguarda i byte.
  • Secondo RFC 3161 §6 + ETSI EN 319 122-1 §5.3 + EN 319 142-1 V1.2.1 §6.3 Tabella 1, nota q (B-T può utilizzare sia la firma con timestamp che il timestamp del documento per la temporizzazione affidabile).

2026-05-23 Version 2.120.2

  • PAdES commitment-type-indication CMS Supporto per l'attributo SignedAttribute (PAdES Fase 3): genera l'attributo id-aa-ets-commitmentType (OID 1.2.840.113549.1.9.16.2.16, ETSI EN 319 122-1 §5.2.3 + RFC 5126 §5.11), che dichiara il tipo di impegno assunto dal firmatario tramite la firma (ad esempio, prova di origine / ricevuta / consegna / mittente / approvazione / creazione).
  • È stato introdotto un nuovo tipo enumerativo `THPDFCommitmentType`: `ctNone` (valore predefinito, sopprime l'attributo), `ctProofOfOrigin`, `ctProofOfReceipt`, `ctProofOfDelivery`, `ctProofOfSender`, `ctProofOfApproval`, `ctProofOfCreation` (sei OID standard `id-cti-ets-*` derivati da RFC 5126 §5.11.1, arc `1.2.840.113549.1.9.16.6.{1..6}`), e `ctCustom` (il chiamante fornisce un OID arbitrario tramite il nuovo campo `CommitmentTypeOID`).
  • Attivazione: emessa ogni volta che `THPDFCMSSignOptions.CommitmentType` non è `ctNone`. Il valore predefinito vuoto mantiene la stabilità a livello di byte nella versione v2.120.1 per le chiamate che non hanno optato per questa funzionalità.
  • **Responsabilità del chiamante (PAdES Parte 1 §6.3 Tabella 1, nota d):** quando si emette l'indicazione del tipo di impegno, la voce `Reason` nel dizionario della firma deve essere assente (mutua esclusione). HPDFCMS non visualizza lo stato del dizionario della firma; il chiamante sceglie una delle due opzioni tramite `AddPAdESSignatureField(Reason='', ...)` più `CommitmentType` oppure lasciando `CommitmentType=ctNone` e fornendo `Reason`.
  • Struttura ASN.1 DER: CommitmentTypeIndication SEQUENCE { commitmentTypeId OBJECT IDENTIFIER }. Il campo CommitmentTypeQualifier (RFC 5126 §5.11.2) viene omesso poiché i sei OID standard id-cti-ets-* non definiscono qualificatori. Le implementazioni personalizzate che richiedono qualificatori possono estendere la libreria.
  • Il wrapper `HPDFCMSBuildSignedData` con 4 argomenti imposta il nuovo campo `CommitmentType` a zero, in modo che i pacchetti CMS legacy rimangano identici in termini di byte rispetto alla versione v2.119.27.
  • Secondo ETSI EN 319 122-1 §5.2.3 + RFC 5126 §5.11 + ETSI EN 319 142-1 V1.2.1 §6.3, tabella 1, nota d.

2026-05-23 Version 2.120.1

  • PAdES signature-policy-identifier CMS Supporto per l'attributo SignedAttribute (Fase 2 di PAdES): emette l'attributo id-aa-ets-sigPolicyId (OID 1.2.840.113549.1.9.16.2.15, ETSI EN 319 122-1 §5.2.9 + RFC 5126 §5.8) che dichiara la politica di firma utilizzata. Richiesto da PAdES-E-EPES (Parte 2 V1.2.1 §5.4 Tabella 2: *deve essere presente*); può essere presente in tutti gli altri livelli di PAdES.
  • Nuovi campi nel record `THPDFCMSSignOptions`: `SignaturePolicyOID` (stringa OID che fa riferimento al documento di policy), `SignaturePolicyHash` (hash del documento di policy), `SignaturePolicyHashAlgOID` (OID dell'algoritmo di hash, predefinito a SHA-256 se vuoto) e `SignaturePolicyURI` (qualificatore SPuri opzionale secondo RFC 5126 §5.8.1, OID `1.2.840.113549.1.9.16.5.1`, che fa riferimento all'URL del documento di policy).
  • Attivazione: l'attributo della policy viene generato solo quando sia `SignaturePolicyOID` che `SignaturePolicyHash` sono valorizzati dal chiamante. Valori predefiniti vuoti indicano che l'attributo viene soppresso; i firmatari di base mantengono la stabilità a livello di byte con l'output della versione 2.120.0.
  • La nuova funzione di supporto `CMSEncodeOIDFromString` codifica stringhe OID in formato a punti in DER secondo X.690 §8.19 (i primi due componenti sono combinati come `40*arc1 + arc2`, i componenti successivi sono in base 128 con bit di continuazione). Gli OID delle policy sono specifici per ogni azienda, quindi il produttore non può codificarli direttamente come sequenze di byte.
  • Struttura ASN.1 DER: SignaturePolicyId SEQUENCE { sigPolicyId OBJECT IDENTIFIER, sigPolicyHash OtherHashAlgAndValue [, sigPolicyQualifiers SEQUENCE OF SigPolicyQualifierInfo] }. Il qualificatore SPuri racchiude l'URL come IA5String (tag 0x16) all'interno di un SigPolicyQualifierInfo.
  • Compatibilità: le chiamate a v2.120.0 che non compilano i nuovi campi di policy producono un output identico a livello di byte. Il wrapper `HPDFCMSBuildSignedData` a 4 argomenti imposta a zero i nuovi campi, in modo che i bundle CMS legacy rimangano invariati.
  • Secondo ETSI EN 319 122-1 §5.2.9 + ETSI EN 319 142-2 V1.2.1 §5.4 Tabella 2 + RFC 5126 §5.8.

2026-05-23 Version 2.120.0

  • Conformità agli attributi CMS di base di PAdES (Fase 1 di PAdES): `SignPDFWithPFX` ora emette l'attributo firmato **ESS signing-certificate-v2** (RFC 5035 / OID `1.2.840.113549.1.9.16.2.47`) per impostazione predefinita, proteggendo l'identità del certificato di firma da attacchi di sostituzione. ETSI EN 319 142-1 V1.2.1 §6.3 Tabella 1 indica che questo *deve essere fornito* per tutti i livelli di base (B-B / B-T / B-LT / B-LTA).
  • La baseline PAdES ora omette l'attributo `signing-time` del CMS per impostazione predefinita. La Tabella 1 impone una cardinalità di 0 per i profili baseline (il tempo di firma dichiarato è contenuto nella voce ` /M` del dizionario della firma, come specificato nella nota g della Tabella 1). La versione precedente v2.119.27 includeva `signing-time` indipendentemente dal profilo, il che veniva rifiutato dai verificatori PAdES rigorosi (EU DSS, modalità baseline PAdES di Adobe Acrobat).
  • Nuova API pubblica: `THPDFPAdESLevel` (un'enumerazione con 8 valori che coprono i livelli base B-B / B-T / B-LT / B-LTA, estesi E-BES / E-EPES / E-LTV e il formato legacy `adbe.pkcs7`), `THPDFCMSSignOptions` (una struttura con opzioni per il livello, l'ora di firma, l'attivazione di `signing-cert-v2` e un timestamp UTC), `HPDFCMSDefaultOptions(Level)` (una funzione di supporto che restituisce i valori predefiniti conformi alle specifiche per ogni livello) e `HPDFCMSBuildSignedDataEx` (un costruttore CMS basato su opzioni).
  • Compatibilità con le versioni precedenti: la firma `HPDFCMSBuildSignedData` con quattro argomenti della versione v2.119.27 viene mantenuta come un wrapper leggero e produce un output identico a livello di byte (il certificato di firma v2 è assente, l'ora di firma è quella richiesta). I client che hanno calcolato l'hash del pacchetto CMS della versione v2.119.27 nei test continuano a funzionare correttamente.
  • Modifica del comportamento nell'output PDF firmato: qualsiasi chiamante di `THotPDF.SignPDFWithPFX` che utilizzi un segnaposto PAdES (`AddPAdESSignatureField`, SubFilter `ETSI.CAdES.detached`) ora genera firme che superano la rigorosa convalida di base PAdES. Chi desidera l'insieme di attributi legacy della versione 2.119.27 deve utilizzare direttamente `HPDFCMSBuildSignedDataEx` con `HPDFCMSDefaultOptions(palLegacy_adbePkcs7)`.
  • ASN.1 DER structure secondo RFC 5035 §3: `SigningCertificateV2 SEQUENCE { certs SEQUENCE OF ESSCertIDv2 }` con l'identificatore di algoritmo SHA-256 omesso (regola DER di valore predefinito X.690 §11.5), hash del certificato SHA-256, e `IssuerSerial` che riutilizza l'estrazione esistente dell'emittente e del numero di serie da `CMSExtractIssuerAndSerial`.
  • Secondo ETSI EN 319 142-1 V1.2.1 §6.3 Tabella 1 e RFC 5035 §3.

2026-05-23 Version 2.119.77

  • È stato aggiunto il supporto per la lingua Sinhala (Fase 8f.8). Il Sinhala ('sinh', U+0D80-U+0DFF) diventa l'ottava lingua Indic registrata. Sono stati introdotti i nuovi metodi `ApplySinhalaReorder` e `GetSinhalaCategory` in THotPDF.
  • Funzionalità Sinhala: include Repha (Ra=U+0DBB + Halant=U+0DCA AL-LAKUNA); tre matre pre-base (E=U+0DD9, EE=U+0DDA, AI=U+0DDB) – uniche per avere tre matre pre-base; 3 matre divise (U+0DDC O, U+0DDD OO, U+0DDE AU) con decomposizione Unicode canonica; U+0DDD OO è composta da 3 parti (E + AA + AL-LAKUNA).
  • Il dispatcher `ApplyIndicReorder` ora gestisce la lingua Sinhala in modo trasparente (il registro IndicScripts è ora un array[0..7]).
  • 21 nuovi test DUnitX. In totale, 187 test su 187 sono stati superati su Win32 e Win64.
  • Per Unicode 16.0 §12.11 (Sinhala) e le specifiche di shaping OpenType per il Sinhala.

2026-05-23 Version 2.119.76

  • È stato aggiunto il supporto per la lingua Malayalam (Fase 8f.7). Il Malayalam ('mlym', U+0D00-U+0D7F) diventa la settima scrittura Indic registrata. Sono stati introdotti i nuovi metodi `ApplyMalayalamReorder` e `GetMalayalamCategory` in THotPDF.
  • Caratteristiche del Malayalam: include Repha (Ra=U+0D30 + Halant=U+0D4D, CHANDRAKKALA); I-matra (U+0D3F) è basata sulla posizione successiva, come in Tamil (unica rispetto a Devanagari/Bengali/Gujarati che usano una base precedente); basi pre-E/EE/AI; 3 matre separate (U+0D4A O / U+0D4B OO / U+0D4C AU) con decomposizione canonica pre+post; lettere chillu (U+0D54-U+0D56, U+0D7A-U+0D7F) e DOT REPH (U+0D4E) classificate come consonanti.
  • Il dispatcher `ApplyIndicReorder` ora supporta Malayalam in modo trasparente (il registro IndicScripts è ora un array[0..6]).
  • Sono stati aggiunti 21 nuovi test DUnitX, che includono la copertura della categoria chillu/DOT-REPH. In totale, 166 test su 166 sono stati superati su Win32 e Win64.
  • Per Unicode 16.0 §12.10 (Malayalam) e le specifiche di shaping OpenType per il Malayalam.

2026-05-23 Version 2.119.75

  • È stato aggiunto il supporto per la lingua Kannada (GSUB engine roadmap, fase 8f.6). Kannada ('knda', U+0C80-U+0CFF) diventa la sesta scrittura indic registrata. Sono stati introdotti i nuovi metodi pubblici `ApplyKannadaReorder` e `GetKannadaCategory` in `THotPDF`.
  • In Kannada, esistono caratteri Repha (Ra=U+0CB0 + Halant=U+0CCD) simili a quelli presenti in Devanagari, bengali, gujarati e telugu. Come in telugu, in Kannada non esistono matre pre-base; ogni matra in Kannada è sopra-base, sotto-base, post-base o divisa.
  • Sono state divise 5 matre utilizzando la decomposizione canonica Unicode 16.0: U+0CC0 II → U+0CBF (sopra) + U+0CD5 (dopo); U+0CC7 EE → U+0CC6 (sopra) + U+0CD5 (dopo); U+0CC8 AI → U+0CC6 + U+0CD6 (entrambe sopra); U+0CCA O → U+0CC6 (sopra) + U+0CC2 (dopo); **U+0CCB OO è divisa in tre parti:** U+0CC6 (sopra) + U+0CC2 (dopo) + U+0CD5 (dopo) — la prima divisione in tre parti è gestita dalla famiglia di formattatori Phase 8f.
  • Sopra la base: matre (R3): I (U+0CBF), E (U+0CC6), AU (U+0CCC), segno di lunghezza AI (U+0CD6). Sotto la base: matre vocaliche R/RR (U+0CC3-U+0CC4), matre vocaliche L/LL (U+0CE2-U+0CE3). Sotto la base: AA (U+0CBE), U/UU (U+0CC1-U+0CC2), segno di lunghezza sotto la base (U+0CD5).
  • Il dispatcher `ApplyIndicReorder` applica automaticamente la corretta gestione per il Kannada tramite il registro (ora array[0..5]).
  • Test: Sono stati aggiunti 21 nuovi test DUnitX, inclusi tutti i 5 casi di split-matra, oltre a una verifica dedicata in tre parti per OO. In totale, 145 test su 145 sono stati superati su Win32 e Win64.
  • Per Unicode 16.0 §12.9 (Kannada) e le specifiche di shaping OpenType per il Kannada.

2026-05-23 Version 2.119.74

  • È stato aggiunto il supporto per la lingua Telugu (GSUB engine roadmap, fase 8f.5). Il Telugu ('telu', U+0C00-U+0C7F) diventa la quinta scrittura indicata registrata. Sono stati introdotti i nuovi metodi pubblici `ApplyTeluguReorder` e `GetTeluguCategory` in `THotPDF`.
  • Telugu presenta caratteristiche simili a Devanagari, bengali e gujarati, come il Repha (Ra=U+0C30 + Halant=U+0C4D). A differenza di tutti gli altri sistemi di scrittura indiani precedenti, non ci sono pre-matre; ogni matra in Telugu è sopra, sotto o divisa rispetto alla base.
  • Sopra la base, segni diacritici (R3): AA/I/II/E/EE/O/OO/AU più segno di lunghezza. Sotto la base, segni diacritici (R4): U/UU/R vocalico/RR (U+0C41-U+0C44), segno di lunghezza per AI (U+0C56), segni diacritici per L/LL vocalici (U+0C62-U+0C63).
  • La sillaba "AI" (U+0C48) viene scomposta in U+0C46 (E sopra la base) + U+0C56 (segno di lunghezza "AI" sotto la base) durante il riordino.
  • Il dispatcher `ApplyIndicReorder` applica automaticamente la lingua Telugu tramite il registro (ora array[0..4]).
  • Test: Sono stati aggiunti 17 nuovi casi di test DUnitX. In totale, 124 test su 124 superano i test su Win32 e Win64.
  • Per Unicode 16.0 §12.8 (Telugu) e le specifiche di shaping OpenType per il Telugu.

2026-05-23 Version 2.119.73

  • È stato aggiunto il supporto per la lingua Tamil (GSUB engine roadmap, fase 8f.4). Il Tamil ('taml', U+0B80-U+0BFF) diventa la quarta scrittura indicata registrata. Sono stati introdotti i nuovi metodi pubblici ApplyTamilReorder e GetTamilCategory in THotPDF.
  • Le differenze del Tamil rispetto ad altri sistemi di scrittura brahminici: NON è presente la Repha (nel Tamil, tradizionalmente non si forma una Repha visiva); l'I-matra (U+0BBF) è POST-base, unica tra i sistemi di scrittura brahminici; la II (U+0BC0) è sopra-base; E/EE/AI (U+0BC6-U+0BC8) sono pre-base; ci sono 3 matre divise (U+0BCA O = U+0BC6+U+0BBE, U+0BCB OO = U+0BC7+U+0BBE, U+0BCC AU = U+0BC6+U+0BD7).
  • Halant è denominato PULLI in Tamil a U+0BCD. `ApplyIndicReorder` Il dispatcher applica in modo trasparente la lingua Tamil tramite il registro (ora array[0..3]).
  • Test: Sono stati aggiunti 20 nuovi casi di test DUnitX. In totale, 107 test su 107 passano su Win32 e Win64.
  • Per Unicode 16.0 §12.7 (Tamil) e le specifiche di shaping OpenType per il Tamil.

2026-05-23 Version 2.119.72

  • È stato aggiunto il supporto per la lingua Gujarati (GSUB engine roadmap, fase 8f.3). Il Gujarati ('gujr', U+0A80-U+0AFF) diventa la terza scrittura indic registrata, dopo il Devanagari e il Bengali. Sono stati introdotti nuovi metodi pubblici, `ApplyGujaratiReorder` e `GetGujaratiCategory`, in `THotPDF`.
  • Riorganizzazione delle regole: R1 Repha (Ra=U+0AB0 + Halant=U+0ACD), R2 pre-base (U+0ABF I), R3 sopra-base (U+0AC5 CANDRA E, U+0AC7 E, U+0AC8 AI – nota che sopra-base in Gujarati è come in Devanagari, NON come pre-base in Bengali), R4 sotto-base (U+0AC1-U+0AC4, U+0AE2-U+0AE3), R5 post-base (U+0ABE AA, U+0AC0 II, U+0AC9 CANDRA O, U+0ACB-U+0ACC O/AU). Nessuna separazione delle matre.
  • Il dispatcher `ApplyIndicReorder` seleziona automaticamente il Gujarati tramite il registro `IndicScripts` (ora array[0..2]). L'integrazione di `BuildUnicode*FieldContent` con `sfIndicShaping` include il Gujarati senza modifiche all'integrazione.
  • Test: Sono stati aggiunti 18 nuovi test DUnitX, inclusi i test R3 per una copertura più completa, al fine di distinguere la gestione delle vocali E/AI del gujarati da quella del bengali. In totale, 87 test su 87 passano su Win32 e Win64.
  • Per Unicode 16.0 §12.6 (Gujarati) e le specifiche di shaping OpenType per il Gujarati.

2026-05-23 Version 2.119.71

  • È stato aggiunto il supporto per la lingua bengali (roadmap del motore GSUB, fase 8f.2). Il bengali ('beng', U+0980-U+09FF) diventa la seconda scrittura indic registrata, dopo il Devanagari. Sono stati introdotti nuovi metodi pubblici, `ApplyBengaliReorder` e `GetBengaliCategory`, nell'oggetto `THotPDF`, in modo simile all'API Devanagari della fase 8e.
  • Regole di riordino del bengali: R1 Repha (Ra=U+09B0 + Halant=U+09CD), R2 matre pre-base (I=U+09BF, E=U+09C7, AI=U+09C8 — nota: E/AI sono pre-base nel bengali, a differenza del Devanagari che è sopra-base), R4 sotto-base (U+09C1-U+09C4, U+09E2-U+09E3), R5 post-base (U+09BE, U+09C0, U+09D7). Non ci sono matre sopra-base nel blocco principale del bengali.
  • Decomposizione delle matrici: `U+09CB` Oo e `U+09CC` AU vengono espansi nei loro componenti visivi durante il riordino (U+09C7 + U+09BE / U+09C7 + U+09D7) in modo che la pipeline GSUB li visualizzi nelle posizioni canoniche pre e post.
  • Il dispatcher `ApplyIndicReorder` instrada in modo trasparente i codepoint bengali all'elemento bengali; le funzioni di supporto `BuildUnicode*FieldContent` con `sfIndicShaping` impostato ora supportano il bengali insieme al Devanagari, senza modifiche all'integrazione.
  • Test: Sono stati aggiunti 18 nuovi casi di test DUnitX che coprono Bengali R1/R2/R4/R5, la decomposizione, la preservazione dei congiunti, il passaggio di script misti, l'idempotenza e l'equivalenza del dispatcher. In totale, 69 test su 69 sono stati superati su Win32 + Win64.
  • Per Unicode 16.0 §12.2 (Bengali) e le specifiche di shaping OpenType per il bengali.

2026-05-23 Version 2.119.70

  • Aggiornamento completo del motore di shaping per Devanagari (roadmap del motore GSUB, Fase 8f.1): `ApplyDevanagariReorder` ora applica la sequenza completa di 5 regole (R1 Repha + R2 pre-base + R3 sopra-base + R4 sotto-base + R5 post-base) invece del sottoinsieme R1 + R2-only presente in v2.119.55. L'ordine dei cluster di output è il seguente: `[pre-matras] + [base + halant + nukta + bindu/visarga/ modifier] + [above-matras] + [below-matras] + [post-matras] + [Repha]`.
  • Conservazione delle ligature: i gruppi di consonanti-halant-consonanti rimangono raggruppati nel blocco di base; il riordino interessa solo le matre e le Repha. L'operazione viene eseguita in un'unica passata ed è idempotente.
  • Modifiche nel comportamento rispetto alla versione v2.119.69: per le sillabe contenenti matre superiori/inferiori/post-base (o cluster di più matre), il flusso di byte PDF ora riflette il layout di riordino canonico. Il rendering visivo dopo GSUB/GPOS rimane invariato. Gli input contenenti solo R1 Repha o R2 pre-base I-matra (il sottoinsieme della versione v2.119.55) producono un output identico a livello di byte.
  • Test: Sono stati aggiunti 8 nuovi test DUnitX che coprono individualmente R3, R4 e R5, l'ordine di più matre, la preservazione delle congiunzioni sotto le matre, la combinazione di Repha con elementi sopra e sotto, e l'idempotenza di più matre. In totale, 51 test su 51 sono stati superati su Win32 e Win64.
  • Per Unicode 16.0 §12.1 (Devanagari) e le specifiche di shaping Devanagari di OpenType.

2026-05-23 Version 2.119.69

  • Infrastruttura di shaping per le lingue Indic (roadmap del motore GSUB, fase 8f.0): è stata rifattorizzata la pre-pass di riordino Devanagari v2.119.55 / v2.119.67 in un framework di dispatch indipendente dallo script. Nuovi tipi `TIndicScriptInfo` / `TIndicCategoryFunc` / `TIndicFindSyllableFunc` / `TIndicReorderFunc` e un nuovo registro `IndicScripts` consentono l'integrazione di nuovi script Indic tramite puntatori a funzione.
  • Il nuovo metodo pubblico `ApplyIndicReorder(Wide)` invia ogni carattere di `Wide` al suo script registrato corrispondente e applica le callback di sillabazione e riordino di tale script. Il contenuto non indic rimane invariato.
  • Le tre funzioni di supporto `BuildUnicode*FieldContent` ora invocano `ApplyIndicReorder` (invece del wrapper specifico per Devanagari) quando `sfIndicShaping` è presente in `FShapingFeatures`. La fase 8f.0 include solo il supporto per Devanagari; le fasi successive, da 8f.2 a 8f.10, aggiungono Bengali, Gujarati, Tamil, Telugu, Kannada, Malayalam, Sinhala, Khmer e Myanmar, mantenendo questa integrazione.
  • La funzione `ApplyDevanagariReorder` esistente è stata mantenuta come un wrapper specifico per il Devanagari per garantire la compatibilità con le versioni precedenti v2.119.55. L'output non è cambiato rispetto alla versione v2.119.67.
  • Per Unicode 16.0 §12 (script del Sud Asia) e ISO 32000-1 §9.10.

2026-05-22 Version 2.119.68

  • Fase 8c.6 — Generazione di GID a livello di produttore tramite mappatura di codepoint sintetici nell'area di utilizzo privato: due nuovi metodi pubblici in THotPDF consentono ai chiamanti di generare GID sostitutivi che non hanno un codepoint Unicode naturale, allocando codepoint sintetici PUA (U+E000-U+F8FF) su richiesta. `AssignSyntheticCodepointForGID (GID; out SyntheticCP): Boolean` alloca lo slot PUA disponibile successivo, riflette l'assegnazione in `FUnicodeCpToGid + FAcroFormUnicodeAdvances +` una nuova tabella di ricerca `FUnicodeSyntheticCpForGID` per GID, in modo che la pipeline di codifica esadecimale esistente del produttore emetta il codepoint sintetico come un token di 4 cifre esadecimali che il lettore consumatore risolve tramite `/CIDToGIDMap` per ottenere il glifo sostitutivo. `GetSyntheticCodepointForGID (GID): Word` interroga le assegnazioni esistenti (restituisce 0 quando non è stato assegnato alcun codepoint sintetico). Entrambi i metodi sono idempotenti: chiamate ripetute con lo stesso GID restituiscono lo stesso codepoint sintetico.
  • Consente la generazione lato produttore per le sostituzioni GSUB specifiche del font che non hanno codepoint di presentazione Unicode: le forme di cluster Devanagari (le uscite 'akhn' / 'rphf' / 'pres' / 'blws' / 'psts' / 'haln' si trovano tipicamente nei GID interni del font), le alternative stilistiche ('salt' / 'ss01-20' senza codepoint), le ligature discretionary ('dlig' / 'hlig' glifi specifici del font) e le sostituzioni di sequenze di variazioni ideografiche CJK. Insieme alle API del motore GSUB v2.119.43-50 e al modulo di subsetting MarkUnicodeGlyphUsed v2.119.50, i chiamanti possono ora creare pipeline di shaping complete lato produttore che emettono GID di sostituzione arbitrari tramite la pipeline esadecimale basata su codepoint esistente.
  • La durata dello stato: le mappature sintetiche persistono fino a quando non viene chiamata nuovamente RegisterUnicodeTTF o BeginDoc (entrambe reimpostano tutti gli stati specifici della font, inclusa la tabella sintetica). L'intervallo PUA U+E000-U+F8FF fornisce 6400 slot, sufficienti per l'insieme di sostituzioni GSUB di qualsiasi font. La mappatura inversa CMap ToUnicode è responsabilità del chiamante: i codepoint PUA sintetici non hanno codepoint di origine da mappare inversamente; i chiamanti preoccupati per l'estrazione del testo dovrebbero racchiudere l'emissione del testo nel contenuto PDF contrassegnato con la proprietà /ActualText, specificando i codepoint di origine originali. I PDF generati da chiamanti che non invocano AssignSyntheticCodepointForGID sono identici a livello di byte all'output di v2.119.67 (i nuovi metodi sono helper stateless di query / allocazione esplicita; non hanno effetti collaterali automatici). Questa commit completa la matrice delle funzionalità della fase 8 del motore GSUB.

2026-05-22 Version 2.119.67

  • La riorganizzazione Devanagari viene applicata automaticamente in una fase preliminare (roadmap del motore GSUB, Fase 8e): le tre funzioni helper BuildUnicode*FieldContent ora invocano automaticamente il metodo ApplyDevanagariReorder v2.119.55 quando sfIndicShaping è incluso in FShapingFeatures. Questa fase preliminare analizza l'input da sinistra a destra, applicando le due riorganizzazioni specifiche per Devanagari (riposizionamento di Repha per la Ra-Halant iniziale della sillaba e spostamento della I-matra U+093F all'inizio del suo gruppo sillabico) in modo che il flusso di codepoint generato corrisponda all'ordine di lettura visivo. Il motore GSUB del lettore applica quindi la catena di shaping Indic ('nukt' / 'akhn' / 'rphf' / 'rkrf' / 'pref' / 'half' / 'vatu' / 'cjct' / 'pres' / 'blws' / 'abvs' / 'psts' / 'haln') sui codepoint riorganizzati per produrre i glifi finali del cluster.
  • Ambito: La fase 8e fornisce solo il riordino lato produttore. L'applicazione delle catene GSUB lato produttore (dove il produttore esegue la formazione dei cluster al momento della generazione del PDF, anziché affidarsi al lettore) è stata rimandata alla fase 8c.6 perché la maggior parte delle sostituzioni GSUB in Devanagari utilizza GID specifici del font senza codepoint Unicode Presentation Form. A differenza dell'arabo/latino, dove i blocchi Forms-A/Forms-B forniscono sostituzioni raggiungibili tramite codepoint, il Devanagari non ha un intervallo Presentation Form equivalente in Unicode. La mappatura dei codepoint sintetici PUA nella fase 8c.6 sbloccherà l'emissione GSUB lato produttore per il Devanagari e per altri script indiani/del Sud-Est asiatico in cui i GID di sostituzione sono specifici del font.
  • Il contenuto non in Devanagari viene elaborato tramite la funzione `ApplyDevanagariReorder` mantenendo l'identità dei byte (il metodo analizza solo le sillabe Devanagari; altri intervalli di codepoint vengono emessi senza modifiche). I file PDF in cui la funzione `sfIndicShaping` viene disabilitata (impostazione predefinita) producono un output identico a quello della versione v2.119.66. Insieme al livello di funzionalità v2.119.55 (che espone `GetDevanagariCategory` e `ApplyDevanagariReorder` come metodi pubblici), questa modifica completa l'integrazione della riorganizzazione Devanagari lato produttore: le applicazioni che abilitano `sfIndicShaping` non devono più riordinare i dati in anticipo o chiamare manualmente `ApplyDevanagariReorder` prima di chiamare `BuildUnicode*FieldContent` — HotPDF lo fa automaticamente.

2026-05-22 Version 2.119.66

  • Integrazione automatica di 'rclt' (Alternative Contestuali Richieste): il nuovo metodo THotPDF.ApplyArabicGSUBContextualRefinement (Wide) è simile a v2.119.63 ApplyArabicGSUBRefinement, ma applica la sostituzione contestuale (GSUB Tipo 5 / 6) tramite l'API v2.119.47 ApplyContextualSubst invece della sostituzione di ligatura (Tipo 4). 'rclt' codifica le sostituzioni contestuali richieste, utilizzate tipicamente dai font arabi per varianti posizionali aggiuntive oltre alla mappatura Forms-B dello static walker v2.85.0, e dai font del Sud-Est asiatico / dell'India per forme riordinate a livello di cluster che dipendono dal contesto dei vicini.
  • Gestione dell'output a lunghezza variabile: a differenza di ApplyLigatureSubstitution (N GID di input -> 1 GID sostitutivo), ApplyContextualSubst può produrre M GID sostitutivi da N GID di input. Quando una regola contestuale viene attivata, TUTTI i GID sostitutivi devono essere raggiungibili tramite codepoint di presentazione Unicode tramite una cmap inversa (FB00-FDFF + FE70-FEFF, circa 770 codepoint esaminati) affinché la sostituzione venga eseguita; se uno qualsiasi dei sostituti non ha una mappatura inversa, la finestra di input viene mantenuta invariata (un'emissione parziale corromperebbe la sequenza). L'intervallo della cmap inversa è stato ampliato per coprire le forme di presentazione latina/armena/ebraica (FB00-FB4F) e l'intera gamma araba, in modo che le sostituzioni 'rclt' di qualsiasi script possano essere emesse.
  • È stato aggiunto un nuovo membro dell'enumerazione `THPDFShapingFeature`, `sfContextualAlternates` (aggiunto alla fine per la compatibilità con le versioni precedenti; le chiamate esistenti che utilizzano `FShapingFeatures` continuano a funzionare senza modifiche). Questa funzionalità è stata integrata nelle tre funzioni `BuildUnicode*FieldContent`, che sono ora controllate da `sfContextualAlternates` in `FShapingFeatures` (opzionale, disattivata per impostazione predefinita). Questa funzionalità è indipendente da `FAutoShapeArabic`: la funzionalità `'rclt'` può essere applicata a script diversi dall'arabo (latino, ebraico, indic). I GID sostitutivi vengono ora gestiti tramite `MarkUnicodeGlyphUsed` per il subsetter della versione 2.84.0. Questa operazione non ha effetti se il font non ha regole `'rclt'` o se i GID sostitutivi non contengono codepoint di Presentation Form. I file PDF generati quando `sfContextualAlternates` è disattivato sono identici a quelli generati con la versione 2.119.65.

2026-05-22 Version 2.119.65

  • Le ligature standard di 'liga' latina (roadmap del motore GSUB, fase 8b): il nuovo metodo THotPDF.ApplyLatinLigatureRefinement (Wide) è parallelo a v2.119.63 ApplyArabicGSUBRefinement, ma si rivolge alle forme alfabetiche latina/armena/ebraica in U+FB00-U+FB4F. Scorre la stringa di input in modalità "Wide", crea un array GID parallelo tramite FUnicodeCpToGid e interroga la funzionalità 'liga' (ligature standard) del font tramite l'API v2.119.43-50 ApplyLigatureSubstitution in ogni posizione. Se viene eseguita una sostituzione di ligatura E il GID sostitutivo è raggiungibile tramite un punto di codice della forma alfabetica Unicode, la finestra del punto di codice sorgente viene sostituita con il punto di codice del sostituto. Integrato nei tre helper BuildUnicode*FieldContent (a riga singola, a più righe e per i campi AcroForm/AP di tipo "comb"), controllato da sfStandardLigatures in FShapingFeatures (opzionale, stabile a livello di byte quando non impostato).
  • Passo opzionale secondario per 'clig' (Ligature Contestuali): quando `sfContextualLigatures` è incluso in `FShapingFeatures`, il metodo ripercorre il risultato precedente a 'liga' applicando 'clig' per identificare ligature contestuali specifiche del font, oltre al set standard di fi / fl / ffi / ffl. Ogni GID di sostituzione generato viene passato attraverso `MarkUnicodeGlyphUsed` per il subsetter TTF della versione v2.84.0. La cmap inversa esegue una scansione lineare di circa 80 codepoint (FB00-FB4F); le sostituzioni sono sparse e il costo è trascurabile.
  • ToUnicode CMap bfchar block extended from 28 to 35 entries: 7 new entries cover the Latin Alphabetic Presentation Forms FB00 (ff -> f + f), FB01 (fi -> f + i), FB02 (fl -> f + l), FB03 (ffi -> f + f + i), FB04 (ffl -> f + f + l), FB05 (ſt -> long s + t), FB06 (st -> s + t). Consumer-side text extraction (copy / paste / accessibility) now restores the original ASCII letter sequence when a Latin ligature codepoint appears in the PDF text stream. PDFs whose callers leave sfStandardLigatures off (the default) emit byte-identical to v2.119.64 output. Scope: only emits ligature substitutes reachable through Alphabetic Presentation Form codepoints — decorative / discretionary Latin ligatures with no Unicode codepoint (font-specific GIDs) cannot be emitted through this path and remain reserved for Phase 8c.6 GID-level emit.

2026-05-22 Version 2.119.64

  • API pubblica per interrogare l'avanzamento dei codepoint (roadmap del motore GSUB, fase 8c.5): il nuovo metodo THotPDF.GetCodepointAdvance (CP: Cardinal) espone la cache /W della versione v2.76.0, consentendo alle applicazioni che implementano algoritmi di word-wrap personalizzati al di fuori dell'helper BuildUnicodeMultilineFieldContent di interrogare l'avanzamento reale e scalato per qualsiasi codepoint, derivato dalla tabella hmtx del font tramite la cmap memorizzata nella cache. Dopo la catena di post-elaborazione delle ligature statiche v2.119.32 / v2.119.58 / v2.119.60 / v2.119.62 e il perfezionamento GSUB a livello di GID v2.119.63, che genera codepoint di ligature (LAM-ALEF FEF5-FEFC, YEH-HAMZA FBEA-FBFB, Allah FDF2, Bismillah FDFD e forme di presentazione sostituite da GSUB in FB50-FDFF / FE70-FEFF), il metodo restituisce l'avanzamento hmtx reale del glifo di ligature, che è generalmente più stretto della somma degli avanzamenti dei codepoint originali, in modo che i budget di word-wrap delle applicazioni siano coerenti con il rendering lato client.
  • Miglioramento dell'euristica per la gestione del contenuto di campi Unicode multiriga: il percorso di fallback v2.65 (utilizzato quando la cache /W non è disponibile, ad esempio nel percorso RegisterUnicodeFontDict invece di RegisterUnicodeTTF) trattava precedentemente tutti i codepoint >= U+2E80 come caratteri larghi (1.0 em). Le forme di presentazione arabe (FB50-FBFF, Forms-A, FC00-FDFF, Forms-A, ligature + Quranic FDF0-FDFD, FE70-FEFF, Forms-B, forme di base + LAM-ALEF) sono in realtà caratteri stretti (circa 0.55 em in media nella maggior parte dei font arabi), non larghi. La versione v2.119.64 indirizza questi tre intervalli di forme di presentazione arabe al percorso stretto (0.5 em) nell'euristica di fallback, correggendo un caso limite in cui le ligature arabe emesse dai passaggi successivi v2.119.32 / v2.119.58 / v2.119.60 / v2.119.62 / v2.119.63 avrebbero altrimenti ricevuto avanzamenti errati di 1.0 em quando la cache non è popolata.
  • Restituisce 0 per il percorso tipico in cui non sono disponibili informazioni (nessun font registrato, cache non ancora popolata, codepoint superiore a BMP, codepoint senza un glifo nella cmap del font). È una funzione pura, senza effetti collaterali, e può essere chiamata da qualsiasi contesto dopo che RegisterUnicodeTTF ha avuto successo. I file PDF il cui font caricato ha la cache /W popolata e che non utilizzano il nuovo metodo di query producono un output byte-identico alla versione v2.119.63. La fase 8c.5 conclude la roadmap del motore GSUB, implementando la pipeline di shaping automatico per l'arabo lato produttore a livello di funzionalità. Le fasi 8c.1-8c.5 insieme forniscono passaggi successivi con tabelle statiche (4 famiglie di ligature) + mappatura inversa ToUnicode + perfezionamento GSUB a livello di GID + query di avanzamento pubblica, il tutto per rendere il rendering delle ligature arabe lato produttore byte-accurato con la visualizzazione lato consumatore.

2026-05-22 Version 2.119.63

  • Raffinamento a livello di GID per la funzionalità 'rlig' di GSUB (roadmap del motore GSUB, Fase 8c.2): il nuovo metodo THotPDF.ApplyArabicGSUBRefinement (Wide) analizza la stringa Wide dall'inizio alla fine, creando un array GID parallelo tramite la cmap memorizzata (FUnicodeCpToGid), e in ogni posizione con GID diverso da zero, interroga la funzionalità 'rlig' (ligature richieste) del font tramite l'API ApplyLigatureSubstitution v2.119.43-50. Se viene eseguita una sostituzione di ligature E il GID del carattere sostitutivo è raggiungibile tramite un codepoint di forma di presentazione araba Unicode (scansione inversa della cmap tra U+FB50-U+FDFF + U+FE70-U+FEFF, circa 690 codepoint), la finestra di codepoint del carattere originale viene sostituita con il codepoint del carattere sostitutivo. I caratteri sostitutivi vengono passati anche a MarkUnicodeGlyphUsed per il subsetter TTF v2.84.0.
  • Integrato immediatamente nei tre helper BuildUnicode*FieldContent dopo la catena statica di post-elaborazione a livello di codepoint (LAM-ALEF / YEH-HAMZA / Allah / Bismillah) nelle versioni v2.85.0 / v2.119.32 / v2.119.58 / v2.119.60 / v2.119.62. Integra la tabella statica selezionando le regole 'rlig' specifiche del font che le quattro famiglie codificate in modo hard-coded non includono; esempi tipici includono varianti contestuali nei font persiani / urdu / sindhi / curdi (Vazirmatn, Markazi Text, Lateef, Scheherazade, Amiri) che mappano a Forme di Presentazione Unicode oltre l'insieme LAM-ALEF / YEH-HAMZA / Allah / Bismillah. Funziona solo quando FAutoShapeArabic è true E sfArabicGSUB non è in FShapingFeatures (un meccanismo di esclusione reciproca preserva il percorso "guidato dal chiamante" della versione v2.119.59) E il font caricato ha una tabella GSUB.
  • L'ambito di questa modifica è limitato alle sostituzioni le cui GID sono raggiungibili tramite un codepoint del modulo di presentazione tramite la cmap. Le sostituzioni specifiche del font GSUB che si posizionano su GID arbitrarie (senza una mappa inversa dei codepoint) non possono essere emesse tramite questo percorso; è necessario un'emissione completa a livello di GID nella pipeline del produttore, riservata alla fase 8c.5+. La mappa inversa della cmap è una scansione lineare di circa 690 codepoint per ogni tentativo di sostituzione; le sostituzioni sono rare nella pratica, quindi il costo è trascurabile. I PDF il cui font caricato non ha contenuto GSUB 'rlig' o le cui sostituzioni non hanno codepoint del modulo di presentazione producono un output byte-identico alla versione v2.119.62 (in questi casi, il metodo è un'operazione di sicurezza senza effetti). Con questa modifica, la pipeline automatica di shaping arabo lato produttore del motore GSUB acquisisce una funzionalità di piegatura di ligature consapevole del font, che va oltre la catena di tabelle statiche predefinite.

2026-05-22 Version 2.119.62

  • Bismillah phrase-level ligature post-pass (GSUB engine roadmap Phase 8c.4): the v2.85.0 producer-side Arabic shaper now folds the 22-codepoint canonical Bismillah phrase "بسم الله الرحمن الرحيم" ("In the name of God, the Most Gracious, the Most Merciful") into a single U+FDFD ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM codepoint. Runs FIRST in the post-pass chain (before LAM-ALEF / YEH-HAMZA / Allah folds) so the full phrase is detected before the الله sub-phrase gets folded by the v2.119.60 Allah post-pass. Each letter position matches the base codepoint or any of its v2.85.0 Forms-B shaped variants (R-joining letters 3 variants each, D-joining 5 variants each); the three space positions require U+0020 exactly. Phrase-level detection on the canonical un-vowelled spelling.
  • La CMap ToUnicode è stata estesa con una 28a voce "bfchar" che mappa U+FDFD alla sequenza sorgente completa di 22 codepoint (BEH + SEEN + MEEM + SPACE + ALEF + LAM + LAM + HEH + SPACE + ALEF + LAM + REH + HAH + MEEM + NOON + SPACE + ALEF + LAM + REH + HAH + YEH + MEEM). L'estrazione del testo lato consumatore (copia/incolla/accessibilità) ora ripristina la frase originale di 22 codepoint anziché il singolo glifo ligatura, completando il comportamento di andata e ritorno per le quattro famiglie di ligature con tabella statica (LAM-ALEF / YEH-HAMZA / Allah / Bismillah).
  • Known limitations (deliberate scope reductions): tatweel (U+0640) between letters not matched; harakat / diacritics between letters not matched (canonical fold targets un-vowelled Bismillah); non-breaking space U+00A0 or multiple spaces between words not matched (only single ASCII U+0020); alternative spellings (الرحمٰن with superscript alef) not matched; phrase must appear exactly without trailing modifiers. False-positive risk is essentially zero because the canonical 22-codepoint sequence is uniquely Bismillah by intent. Other Quranic honorifics (FDFA SALLALLAHOU ALAYHE WASALLAM, FDFB JALLAJALALOUHOU) and single-word ligatures (FDF3 AKBAR / FDF4 MOHAMMAD / FDF5 SALAM / etc.) remain out of scope because those source words also appear as ordinary Arabic terms in non-religious text and would generate false positives.

2026-05-22 Version 2.119.61

  • ToUnicode CMap reverse-mapping for Arabic ligatures (GSUB engine roadmap Phase 8c.3): the v2.83.0 RegisterUnicodeTTF Adobe-Identity-UCS CMap is now extended with 27 bfchar entries that override the bfrange identity mapping for every ligature codepoint emitted by the v2.85.0 producer-side Arabic shaper post-pass chain. Each entry restores the source codepoint sequence on consumer-side text extraction, fixing the limitation where copy / paste from PDF readers previously returned a single ligature character (e.g., "ﷲ" for Allah) rather than the original source word ("الله"). Bfchar takes precedence over bfrange per Adobe CMap and CIDFont Files Specification.
  • Copertura: 8 voci LAM-ALEF U+FEF5-U+FEFC (ligatura obbligatoria v2.119.32, 4 varianti di ALEF × 2 forme) → coppie sorgente LAM + ALEF / ALEF MADDA / ALEF HAMZA SOPRA / ALEF HAMZA SOTTO; 18 voci della famiglia YEH-HAMZA U+FBEA-U+FBFB (v2.119.58, include le forme iniziali FBF8 e FBFB che l'elaborazione automatica successiva non produce, ma che i chiamanti possono utilizzare direttamente) → coppie sorgente YEH-HAMZA + ALEF / AE / WAW / U / OE / YU / E / ALEF MAKSURA; 1 voce Allah U+FDF2 (v2.119.60) → sequenza sorgente di quattro codepoint ALEF + LAM + LAM + HEH. Con questa sezione, l'operazione di copia/incolla/accessibilità è completa per le tre famiglie di ligature con tabella statica.
  • Stabilità dei byte per contenuti non arabi: il blocco bfchar aggiunge circa 700 byte di testo PostScript non compresso al flusso CMap, che FlateDecode riduce tipicamente a circa 150-200 byte. I PDF senza contenuti arabi continuano a generare lo stesso layout del flusso /ToUnicode; l'estensione è aggiuntiva all'interno dello stesso oggetto FlateDecode indiretto. Tutti i lettori consumer (Adobe Reader, Foxit, PDF.js, Apple Preview, ecc.) rispettano la precedenza di bfchar rispetto a bfrange e applicano correttamente la mappatura inversa. Il blocco di 27 elementi è codificato in modo fisso nel testo CMap (non è necessaria alcuna personalizzazione specifica per ogni PDF); nelle future versioni 8c.4 verranno aggiunti ulteriori elementi bfchar per la ligatura Bismillah U+FDFD.

2026-05-22 Version 2.119.60

  • Allah ligature static post-pass: the v2.85.0 producer-side Arabic shaper now folds the four-codepoint sequence ALEF + LAM + LAM + HEH (الله in standard Arabic) into the single codepoint U+FDF2 ARABIC LIGATURE ALLAH ISOLATED FORM after the v2.119.32 LAM-ALEF and v2.119.58 YEH-HAMZA post-passes finish. Same model as the two earlier ligature post-passes: detect the source sequence in any combination of raw and shaped forms, emit a single codepoint output, trust the font to have the ligature glyph at the Unicode-defined cmap entry. This is the first slice of the GSUB engine roadmap Phase 8c (producer-side automatic Arabic GSUB shaping pipeline) — codepoint-level ligature folding for the most prevalent Arabic religious ligature.
  • Source-letter form matching covers all valid combinations after the v2.85.0 walker has shaped the sequence: ALEF in raw U+0627 or isolated FE8D or final FE8E form (R-joining, no init / medi); LAM in raw U+0644 or any of the four shaped forms FEDD-FEE0 (D-joining, full 4 positional forms); HEH in raw U+0647 or any of the four shaped forms FEE9-FEEC (D-joining). A typical standalone "الله" word emerges from the walker as FE8D + FEDF + FEE0 + FEEA (ALEF isol + LAM init + LAM medi + HEH final), which folds to FDF2. PDFs without the Allah codepoint sequence emit byte-identical to v2.119.59 output.
  • Known limitations of codepoint-level ligature folding: (1) Output is the isolated form FDF2 only — Unicode does not define final / initial / medial forms for the Allah ligature, but in practice Allah is almost always rendered standalone, so the single FDF2 codepoint suffices for visual rendering. (2) Consumer-side text extraction (copy / paste / accessibility) yields the single character "ﷲ" rather than the four-character word "الله" because the ToUnicode CMap has not yet been extended to reverse-map FDF2 to its 4-codepoint source. A future Phase 8c.3 installment will add the bfchar reverse mapping. (3) Font dependency: the loaded TTF / OTF must have a cmap entry mapping U+FDF2 to its Allah glyph; mainstream Arabic fonts (Noto Sans Arabic, Amiri, Scheherazade, Lateef, Markazi Text, Tahoma / Times New Roman Arabic) all include it. Other Quranic ligatures (FDF0 / FDF1 / FDF3-FDFB Allah-family honorifics, FDFD Bismillah) plus GID-level GSUB integration for font-specific substitutions are reserved for future Phase 8c.2-8c.4 installments.

2026-05-22 Version 2.119.59

  • Il nuovo framework di attivazione della pipeline di shaping lato producer (roadmap del motore GSUB, Fase 8a): la nuova enumerazione `THPDFShapingFeature` e il tipo di set `THPDFShapingFeatures` definiscono i flag delle funzionalità previsti per le fasi 8a-8e dell'integrazione di shaping del testo lato producer. I cinque membri dell'enumerazione sono `sfArabicGSUB` (implementato in questa release), `sfStandardLigatures` (Fase 8b, futuro), `sfContextualLigatures` (Fase 8b, futuro), `sfStylisticAlternates` (Fase 8d, futuro) e `sfIndicShaping` (Fase 8e, futuro). `THotPDF` acquisisce una proprietà `ShapingFeatures` di tipo `THPDFShapingFeatures` con valore predefinito `[]` (tutte le funzionalità disattivate); le chiamate in `v2.119.32-58` producono un output identico a livello di byte finché la proprietà rimane al suo valore predefinito.
  • sfArabicGSUB funge da mutex rispetto al sistema di shaping arabo basato su tabella statica della versione v2.85.0. Quando sfArabicGSUB è incluso in ShapingFeatures, le tre funzioni helper BuildUnicode*FieldContent (per contenuti su una sola riga, su più righe e per elementi combinati) nell'AcroForm saltano completamente l'applicazione dello shaping arabo (_ApplyArabicShaping): non viene eseguita la riscrittura dei codepoint in quattro posizioni della versione v2.85.0, né la fase di post-elaborazione LAM-ALEF della versione v2.119.32, né la fase di post-elaborazione YEH-HAMZA + vocale della versione v2.119.58. Il chiamante è responsabile di gestire la selezione dello shaping arabo tramite le API del motore GSUB v2.119.43-50 (SetGSUBScript ('arab') + GetSingleSubstituteGlyph rispetto ai tag delle funzionalità 'init' / 'medi' / 'fina' / 'isol' + MarkUnicodeGlyphUsed per la chiusura del subsetter v2.84.0). Insieme a sfArabicGSUB, i chiamanti che utilizzano font arabi come Noto Sans Arabic / Amiri / Scheherazade / Markazi Text o font simili possono ora gestire l'intero shaping arabo lato font durante la fase di creazione, invece di fare affidamento sulla soluzione di fallback basata su tabella statica.
  • Companion Arabic capability API: two new public methods GetArabicJoiningClass (CP) and GetArabicPosition (Wide, Index) mirror the v2.119.53 GetSyriacJoiningClass / v2.119.54 GetMongolianJoiningClass pattern, exposing the internal joining-class table and 4-position contextual walker the static shaper uses. Callers driving Arabic GSUB shaping manually no longer need to re-derive joining-class data per codepoint — they can reuse the cumulative v2.85.0 / v2.119.35 / v2.119.52 / v2.119.57 table that already covers basic Arabic (U+0600-U+06FF), Arabic Supplement (U+0750-U+077F), and Arabic Extended-A (U+08A0-U+08FF). With this slice landed, the user's two-item request "Forms-A FBEA-FBFB 装饰类合字 (v2.119.58) + Producer-side 自动 Arabic GSUB shaping pipeline (this release)" is fulfilled at the capability + opt-in framework layer. Full producer-side automatic GSUB application inside TextOut / BuildUnicode*FieldContent (auto cmap-to-GID + per-position GSUB substitute + substitute GID emit, with no caller code) remains reserved for the deeper Phase 8c integration commits.

2026-05-22 Version 2.119.58

  • YEH-HAMZA + ligatura lettera vocalica: la funzione di shaping arabo lato server, versione v2.85.0, ora combina le 8 coppie di ligature codificate nel blocco Arabic Presentation Forms-A, da U+FBEA a U+FBFB, in singoli punti di codice di ligatura, dopo l'esecuzione del processo "walker" a 4 posizioni e il processo LAM-ALEF (versione v2.119.32). Utilizza lo stesso modello e la stessa integrazione di LAM-ALEF (sostituzione obbligatoria tramite tabella statica, con 2 forme di output per ogni ligatura). Le coppie coperte sono: YEH-HAMZA + ALEF -> FBEA/FBEB (arabo standard / persiano / urdu), YEH-HAMZA + AE U+06D5 -> FBEC/FBED (kashmiri / uigur), YEH-HAMZA + WAW -> FBEE/FBEF (arabo standard), YEH-HAMZA + U U+06C7 -> FBF0/FBF1 (uigur / kazako / kirghiso), YEH-HAMZA + OE U+06C6 -> FBF2/FBF3 (stesso), YEH-HAMZA + YU U+06C8 -> FBF4/FBF5 (stesso), YEH-HAMZA + E U+06D0 -> FBF6/FBF7 (stesso), YEH-HAMZA + ALEF MAKSURA -> FBF9/FBFA (arabo standard).
  • YEH-HAMZA viene abbinato nella sua forma originale U+0626 o in una qualsiasi delle sue forme modificate v2.85.0 (FE89 isolata, FE8A finale, FE8B iniziale, FE8C mediale); la vocale successiva viene abbinata nella sua forma originale o in una qualsiasi delle sue varianti a forma "Forms-A" v2.119.57 (FBD7-FBD8 per U, FBD9-FBDA per OE, FBDB-FBDC per YU, FBE4-FBE7 per E) o nelle varianti a forma "Forms-B" v2.85.0 (FE8D-FE8E per ALEF, FEED-FEEE per WAW, FEEF-FEF0 per ALEF MAKSURA). La selezione della forma finale (base + 1) segue la regola LAM-ALEF: quando YEH-HAMZA è stato trasformato nella forma finale FE8A o nella forma mediale FE8C (cioè, è preceduto da una lettera a doppia connessione), la ligatura viene emessa nella sua forma finale; altrimenti, viene emessa la forma isolata.
  • Ambito di applicazione: solo le forme isolate e finali (output a 2 forme) vengono generate da questa fase successiva. Le forme iniziali definite in Unicode, FBF8 (YEH-HAMZA + E) e FBFB (UIGHUR YEH-HAMZA + ALEF MAKSURA), non vengono prodotte; le applicazioni che necessitano di queste varianti a tre forme devono utilizzare i lookup contestuali concatenati 'rlig' / 'clig' del font tramite ApplyContextualSubst. Altre regioni di ligatura araba (Allah U+FDFA / FDFB, ligature decorative a FC00-FDC7) richiedono l'utilizzo di GSUB 'rlig' / 'dlig' e rimangono al di fuori dell'ambito del generatore di tabelle statiche. I file PDF che non contengono YEH-HAMZA seguiti da una delle otto vocali supportate producono risultati identici alla versione v2.119.57; la nuova fase successiva viene eseguita solo per le specifiche sequenze di 2 codepoint.

2026-05-22 Version 2.119.57

  • Persian / Urdu / Sindhi / Kashmiri / Uyghur / Kazakh / Kyrgyz Arabic Extended letter coverage: the v2.85.0 producer-side Arabic shaper joining-class table now spans the entire U+0672-U+06D5 range per Unicode 16.0 ArabicShaping.txt, closing the "Persian/Urdu Form-B 扩展" work-item that was deferred when v2.119.35 shipped the 9-letter Persian/Urdu core and v2.119.52 added the ALEF WASLA / NOON GHUNNA / HEH variants. About 80 letters are added to the joining-class table covering REH / DAL / SEEN / SAD / TAH / AIN / FEH / QAF / KAF / GAF / LAM / NOON / HEH / WAW / YEH variants — so adjacent letters now pick correct positional forms regardless of which Arabic Extended-A letter sits next to them.
  • 26 delle nuove lettere classificate hanno inoltre voci statiche di Presentation Forms-A in U+FB52-U+FBFC e ora sono mappate direttamente dal shaper della tabella statica senza richiedere uno shaper GSUB del font: 15 lettere congiuntive D a 4 forme (TTEHEH U+067A → FB5E-FB61, BEEH U+067B → FB52-FB55, TEHEH U+067F → FB62-FB65, BEHEH U+0680 → FB5A-FB5D, NYEH U+0683 → FB76-FB79, DYEH U+0684 → FB72-FB75, TCHEHEH U+0687 → FB7E-FB81, VEH U+06A4 → FB6A-FB6D, PEHEH U+06A6 → FB6E-FB71, NG U+06AD → FBD3-FBD6, NGOEH U+06B1 → FB9A-FB9D, GUEH U+06B3 → FB96-FB99, RNOON U+06BB → FBA0-FBA3, HEH DOACHASHMEE U+06BE → FBAA-FBAD che è la lettera 'h' standard dell'urdu, E U+06D0 → FBE4-FBE7 per l'arabo kazako/kirghiso), e 11 lettere congiuntive R a 2 forme (DAHAL U+068C → FB84-FB85, DDAHAL U+068D → FB82-FB83, DUL U+068E → FB86-FB87, KIRGHIZ OE U+06C5 → FBE0-FBE1, OE U+06C6 → FBD9-FBDA, U U+06C7 → FBD7-FBD8, YU U+06C8 → FBDB-FBDC, KIRGHIZ YU U+06C9 → FBE2-FBE3, VE U+06CB → FBDE-FBDF, YEH BARREE U+06D2 → FBAE-FBAF che è la 'yeh' finale di parola in urdu, YEH BARREE WITH HAMZA ABOVE U+06D3 → FBB0-FBB1).
  • Le due lettere HEH DOACHASHMEE e YEH BARREE meritano una menzione speciale perché i loro slot Forms-A (FBAA-FBAD e FBAE-FBAF) erano stati erroneamente assegnati da un bug nella versione v2.119.52 alle lettere U+06C2 HEH GOAL WITH HAMZA ABOVE e U+06C3 TEH MARBUTA GOAL. Con la versione v2.119.56, queste associazioni errate sono state eliminate e, con la versione v2.119.57, i slot sono stati associati alle lettere originali corrette, risolvendo definitivamente il problema. Le lettere nell'intervallo U+0672-U+06D5 che non hanno voci Presentation Forms-A in Unicode 16 (circa 50 codepoint aggiuntivi, principalmente varianti di REH / DAL / SEEN / SAD / TAH / AIN / FEH / QAF / KAF senza forme predefinite) continuano a partecipare all'analisi della classe di collegamento, in modo che i caratteri vicini si adattino correttamente; le lettere stesse vengono elaborate come codepoint grezzi e si affidano alle tabelle di ricerca GSUB del font, utilizzando il motore GSUB v2.119.43-50, per la loro selezione della forma. Compilato con 78018 linee; i file PDF che non contengono questi nuovi codepoint sono identici a quelli della versione v2.119.56.

2026-05-22 Version 2.119.56

  • Correzione di un bug relativo alla formattazione dell'arabo: la versione v2.119.52 ha introdotto mappature errate per due caratteri della regione Urdu/Sindhi nelle Presentation Forms-A dell'arabo. Il carattere U+06C2 HEH GOAL WITH HAMZA ABOVE era mappato a FBAA-FBAD, che in realtà è l'intervallo di codepoint per U+06BE HEH DOACHASHMEE; i lettori consumer avrebbero reso il glifo Urdu "Goal-Heh-with-Hamza" come il glifo Urdu standard "Heh-Doachashmee". Il carattere U+06C3 TEH MARBUTA GOAL era mappato a FBAE-FBAF, che in realtà è l'intervallo di codepoint per U+06D2 YEH BARREE; i lettori avrebbero reso "Teh-Marbuta-Goal" come la parola Urdu "Yeh-Barree". Secondo Unicode 16.0, né U+06C2 né U+06C3 hanno voci pre-codificate Presentation Forms-A; entrambi devono passare invariati come codepoint raw (i lettori consumer li visualizzano correttamente tramite la cmap del font e qualsiasi formattazione basata su GSUB).
  • Correzione: le due voci errate presenti nella tabella di ricerca "_ArabicShape Presentation Forms-A" del formattatore arabo lato produttore nella versione v2.85.0 sono state eliminate; U+06C2 e U+06C3 ora vengono gestiti tramite il percorso di trasmissione e vengono emessi senza modifiche. Le voci relative alla classe di collegamento della versione v2.119.52 (D per U+06C2, R per U+06C3) sono state mantenute in modo che le lettere adiacenti possano ancora utilizzare le forme posizionali corrette quando questi caratteri compaiono in una parola. Questa correzione influisce solo sui file PDF che contengono U+06C2 o U+06C3 con AutoShapeArabic abilitato; i file PDF che non contengono questi due codepoint sono identici a livello di byte rispetto all'output della versione v2.119.55. La versione di accompagnamento v2.119.57 estende la copertura di Forms-A a ulteriori lettere persiane, urdu, sindhi, kashmiri, uiguri, kazake e kirghize, inclusi i caratteri HEH DOACHASHMEE e YEH BARREE, che erano stati erroneamente associati nella versione v2.119.52.

2026-05-22 Version 2.119.55

  • Funzionalità di shaping per la scrittura Devanagari: due nuovi metodi pubblici in THotPDF coprono il paradigma di shaping per le scritture indiane che non si adatta al meccanismo di "walker" a 4 posizioni utilizzato per l'arabo, il siriaco e il mongolo (v2.85.0 + v2.119.32-54). GetDevanagariCategory (CP) restituisce la categoria sillabica indic semplificata (0 = Altro, 1 = Consonante, 2 = Vocale indipendente, 3 = Matra, 4 = Virama, 5 = Nukta, 6 = Bindu, 7 = Visarga, 8 = Danda, 9 = Cifra, 10 = ZWJ, 11 = ZWNJ, 12 = Modificatore) secondo Unicode 16.0 §12.1 + IndicSyllabicCategory.txt; la tabella copre l'intero blocco Devanagari U+0900-U+097F, inclusi i caratteri Marwari, Sindhi e Vedic in U+0978-U+097F.
  • ApplyDevanagariReorder (Wide) analizza la stringa di input da sinistra a destra e applica la fase preliminare di riordino Devanagari a ogni sillaba Devanagari incontrata, restituendo una stringa Unicode riordinata pronta per l'elaborazione da parte di cmap e GSUB. Il contenuto non Devanagari (latino, cifre, punteggiatura, altri sistemi di scrittura) viene mantenuto inalterato. Sono implementati due tipi di riordino (i due più comuni nel rendering Devanagari): (1) Repha: quando una sillaba inizia con Ra (U+0930) + Halant (U+094D) + consonante, la coppia (Ra, Halant) viene spostata alla FINE della sillaba in modo che la funzione GSUB 'rphf' del font la sostituisca con il glifo Repha che si posiziona visivamente sopra e a destra della base della sillaba; (2) Pre-base I-matra: U+093F viene spostato all'INIZIO della sillaba (dopo aver rimosso eventuali Repha) in modo che l'elaborazione GSUB da sinistra a destra lo visualizzi davanti al gruppo di consonanti, corrispondendo al suo ordine di rendering visivo.
  • La pipeline di chiamata applica la riorganizzazione di Devanagari al testo nell'ordine logico, quindi imposta il sottoscritto 'deva', quindi itera sui codepoint riordinati applicando le funzionalità GSUB ('nukt' / 'akhn' / 'rphf' / 'rkrf' / 'half' / 'vatu' / 'cjct' / 'pres' / 'blws' / 'abvs' / 'psts' / 'haln') tramite GetSingleSubstituteGlyph + ApplyLigatureSubstitution + ApplyContextualSubst, quindi emette i GID risultanti al flusso di testo PDF, chiamando MarkUnicodeGlyphUsed (GID) per ogni emissione per il subsetter v2.84.0. Con la Fase A (chiusura Arabic Extended-A v2.119.52) + Fase B (capacità siriana v2.119.53) + Fase C (capacità mongola v2.119.54) + Fase D (capacità Devanagari Indic v2.119.55) completate, il divario della matrice "formattazione mongola / siriana / Devanagari" è completamente colmato. Fuori dall'ambito: script Devanagari Indic non (Bengali, Tamil, Telugu, Gujarati - ognuno ha i propri dati di categoria e regole di riordinamento), regole di riordinamento oltre Repha + I-matra di base, e formattazione Devanagari automatica lato produttore all'interno di TextOut / BuildUnicode*FieldContent (riservato per la Fase 8 della roadmap del motore GSUB).

2026-05-22 Version 2.119.54

  • Capacità di formattazione del mongolo: due nuovi metodi pubblici su THotPDF espongono la ricerca della classe di collegamento del mongolo (U+1800-U+18AF) e l'analisi contestuale a 4 posizioni, in modo che i chiamanti possano controllare la formattazione del testo mongolo lato produttore. GetMongolianJoiningClass (CP) restituisce la classe di collegamento del mongolo Unicode 16.0 §13.5 (0 = U non collegato, 2 = D duale, 4 = T trasparente / selettore di variazione) per qualsiasi punto di codice; la tabella copre il mongolo di base e le estensioni di lettere Todo, Sibe, Manchu e Ali Gali (U+1820-U+1878 + U+1887-U+18A8 + ALI GALI DAGALGA U+18A9 + MANCHU ALI GALI LHA U+18AA) e classifica NIRUGU (U+180A), i tre Free Variation Selectors FVS1-FVS3 (U+180B-U+180D) e i segni vocalici Ali Gali BALUDA / THREE BALUDA (U+1885-U+1886) come trasparenti. GetMongolianPosition (Wide, Index) analizza il testo circostante, saltando i segni trasparenti, e restituisce 0 = isolato, 1 = finale, 2 = iniziale o 3 = mediale per la lettera all'indice (a base 0).
  • Come per il siriano (v2.119.53), il mongolo NON ha forme di presentazione pre-codificate in Unicode: ogni font in grado di gestire il mongolo (Mongolian Baiti, Noto Sans Mongolian, Noto Serif Mongolian, ecc.) utilizza la formattazione posizionale tramite le lookup OpenType GSUB nelle sue funzionalità 'init', 'medi', 'fina' e 'isol', sotto il tag di script 'mong'. Pertanto, la versione v2.119.54 segue lo stesso modello di funzionalità della v2.119.53; le applicazioni devono combinare l'output posizionale con le API del motore GSUB (SetGSUBScript ('mong'), GetSingleSubstituteGlyph rispetto al tag di funzionalità posizionale appropriato, MarkUnicodeGlyphUsed per il subsetter v2.84.0) per generare GID formattati che vengono emessi direttamente nel flusso di testo PDF.
  • Il mongolo è scritto verticalmente, dall'alto verso il basso, nella sua modalità di scrittura nativa; il componente opera in base all'ordine logico dei punti di codice (predecessore/successore nel flusso di punti di codice), indipendentemente dall'orientamento visivo. La resa effettiva dall'alto verso il basso viene gestita al momento dell'emissione del file PDF tramite /WMode 1 (scrittura verticale) o rotazione della matrice del font, e non dal componente di shaping. La classificazione di Free Variation Selectors come trasparente significa che il componente risolve correttamente le forme posizionali anche quando un FVS segue una lettera; la ricerca GSUB del font, sotto le funzionalità 'fina', 'medi', 'init' e 'isol', seleziona automaticamente la variante condizionata da FVS quando un FVS si verifica nella sequenza di input. La shaping del Devanagari (lingue indiane) rimane riservata per le versioni future perché richiede una fase di riordinamento preliminare specifica per le lingue indiane, come definito in UAX #38 (riordinamento di virama, gruppi di consonanti e pre-basi), che non si adatta al componente a 4 posizioni utilizzato per l'arabo, il siriaco e il mongolo. La shaping automatica del mongolo all'interno di TextOut / BuildUnicode*FieldContent rimane riservata per la Fase 8 della roadmap del motore GSUB.

2026-05-22 Version 2.119.53

  • Funzionalità di formattazione siriana: due nuovi metodi pubblici su THotPDF espongono la ricerca della classe di collegamento siriana (U+0700-U+074F) e l'analisi contestuale a 4 posizioni, in modo che i chiamanti possano controllare la formattazione del testo siriano lato produttore. GetSyriacJoiningClass (CP) restituisce la classe di collegamento Unicode 16.0 SyriacShaping.txt (0 = U non collegato, 1 = R collegamento a destra, 2 = D collegamento duale, 4 = T trasparente / NSM) per qualsiasi punto di codice; la tabella copre tutte le 35 lettere siriane nel blocco base, oltre alle estensioni persiane e sogdiane (BHETH / GHAMAL / DHALATH persiani a U+072D-U+072F, ZHAIN / KHAPH / FE sogdiani a U+074D-U+074F) e classifica l'ALAPH sovrascritto (U+0711) e i segni di combinazione siriani (U+0730-U+074A) come trasparenti. GetSyriacPosition (Wide, Index) analizza il testo circostante, saltando i segni trasparenti, e restituisce 0 = isolato, 1 = finale, 2 = iniziale o 3 = mediale per la lettera all'indice (a base 0).
  • A differenza dell'arabo (che ha blocchi di forme di presentazione pre-codificate B U+FE70-U+FEFF e blocchi A U+FB50-U+FBFF che consentono a HotPDF di riscrivere direttamente i codepoint in varianti formattate), il blocco siriano NON ha forme di presentazione pre-codificate in Unicode: ogni font compatibile con il siriano (Estrangelo Edessa, Serto Jerusalem, East Syriac Adiabene, Noto Sans Syriac, ecc.) utilizza la formattazione posizionale tramite lookup GSUB OpenType nelle sue funzionalità 'init', 'medi', 'fina' e 'isol'. Pertanto, la versione 2.119.53 include solo il livello di funzionalità; il chiamante compone l'output posizionale con le API del motore GSUB 2.119.43-50 (SetGSUBScript ('syrc'), GetSingleSubstituteGlyph rispetto al tag di funzionalità posizionale appropriato, MarkUnicodeGlyphUsed per il subsetter 2.84.0) per produrre GID formattati che vengono emessi direttamente nel flusso di testo PDF.
  • La gestione delle forme terminali di Alaph: la sezione Unicode §9.3 documenta due funzionalità terminali contestuali ("fin2" applicata dopo DALATH / RISH, "fin3" applicata dopo FINAL LAMADH) che i font siriaci utilizzano per sostituire il glifo finale di Alaph. La versione v2.119.53 classifica Alaph (U+0710) come un carattere di base che si unisce a destra e restituisce solo 0 (isolato) o 1 (finale); le applicazioni che necessitano della differenziazione tra "fin2" e "fin3" devono utilizzare le lookup contestuali concatenate del font tramite `ApplyContextualSubst` con tali tag di funzionalità. La gestione della forma delle scritture mongola e Devanagari (Indic) rimane riservata per le versioni future: la scrittura mongola utilizza i selettori di variazione libera più l'armonia vocalica, la Devanagari richiede una fase di riordinamento Indic in base a UAX #38, e nessuna delle due corrisponde all'algoritmo a 4 posizioni utilizzato per la scrittura siriaca. La gestione automatica della forma della scrittura siriaca all'interno di `TextOut` / `BuildUnicode*FieldContent` rimane riservata per la fase 8 della roadmap del motore GSUB.

2026-05-22 Version 2.119.52

  • Estensione per la formattazione della famiglia di caratteri arabi: il modulo di formattazione araba statico lato server, versione 2.85.0, ora copre i caratteri rimanenti dell'estensione araba (ALEF WASLA U+0671, NOON GHUNNA U+06BA, varianti di HEH U+06C0-U+06C3), il blocco supplementare arabo U+0750-U+077F (lettere arabe africane utilizzate in Hausa, Wolofal e altre lingue africane) e la nuova regione dell'estensione araba U+08A0-U+08FF (arabo coranico + lettere estese di Wolofal/Hausa + segni di combinazione coranici). Le classi di collegamento sono prese da Unicode 16.0 ArabicShaping.txt e applicate durante l'analisi posizionale a quattro posizioni nella versione 2.85.0, in modo che i caratteri vicini scelgano la forma corretta (init / medi / fina / isol) indipendentemente dalla variante araba adiacente.
  • Le lettere che hanno forme di presentazione statiche predefinite nel blocco Arabic Presentation Forms-A (U+FB50-U+FBFF) ora vengono mappate direttamente a tali forme, senza richiedere un shaper GSUB OpenType: ALEF WASLA -> FB50/FB51 (giunzione a destra, due forme), NOON GHUNNA -> FB9E/FB9F (giunzione doppia secondo Unicode, ma solo due forme predefinite; init/medi si adattano elegantemente a isol), HEH WITH YEH ABOVE -> FBA4/FBA5 (giunzione a destra, due forme), HEH GOAL -> FBA6/FBA7/FBA8/FBA9 (giunzione doppia, tutte e quattro le forme), HEH GOAL WITH HAMZA ABOVE -> FBAA/FBAB/FBAC/FBAD (giunzione doppia, tutte e quattro le forme), TEH MARBUTA GOAL -> FBAE/FBAF (giunzione a destra, due forme). Insieme alla post-pass obbligatoria della ligatura LAM-ALEF della versione 2.119.32 e al sottoinsieme di 9 lettere principali per il persiano/urdu della versione 2.119.35, lo shaper statico ora copre praticamente tutto il testo arabo moderno, persiano, urdu, sindhi, pashto, curdo, uiguro, coranico e arabo africano (hausa, wolofal, ecc.) senza dipendere dalla tabella GSUB del font.
  • L'estensione araba (U+0750-U+077F) e la regione di lettere arabe estese A più recente (U+08A0-U+08C7) non hanno forme di presentazione statiche pre-codificate; le loro voci di classe di collegamento consentono ai caratteri vicini di essere visualizzati correttamente, ma le lettere stesse rimangono come punti di codice grezzi e si affidano a un font consapevole di GSUB (o alle API del motore GSUB v2.119.43-50, gestite dal chiamante) per la loro corretta disposizione. La regione dei segni di combinazione coranici dell'arabo esteso A (U+08CA-U+08E1, U+08E3-U+08FF) è classificata come trasparente (collegamento T), quindi l'analisi della posizione dei caratteri vicini le ignora, in linea con il trattamento esistente per i caratteri harakat U+064B-U+065F. Il testo che non include questi caratteri estesi rimane identico in termini di byte rispetto all'output di v2.119.51. La disposizione del mongolo, del siriaco e del Devanagari (modelli di disposizione diversi dall'arabo) rimangono riservate per revisioni future.

2026-05-22 Version 2.119.51

  • Supporto per contenitori XFA (XML Forms Architecture) lato produttore: PDF 1.7 §12.7.6 + §12.7.8 consente a un AcroForm di contenere una voce /XFA insieme (o al posto) dell'array statico /Fields. Il nuovo metodo THotPDF.AddXFAPacket (PacketName, XMLBytes) registra un pacchetto XFA con un nome specifico; i nomi tipici sono 'template' (layout del modulo + script), 'datasets' (associazione dati), 'config' (configurazione del visualizzatore), 'connectionSet', 'localeSet', 'stylesheet', 'xfdf', 'xmpmeta', 'signature' e 'sourceSet'. Ogni pacchetto registrato diventa uno stream compresso con FlateDecode all'interno del documento, e l'array /XFA alterna stringhe PDF contenenti i nomi dei pacchetti con riferimenti agli stream nell'ordine di registrazione, in modo che il layout sia deterministico a livello di byte. I metodi THotPDF.ClearXFAPackets e THotPDF.XFAPacketCount completano l'interfaccia API.
  • Solo supporto a livello di contenitore: HotPDF non analizza l'XML XFA, non implementa il motore di layout dinamico XFA, non esegue FormCalc o JavaScript all'interno del modello XFA e non convalida la struttura del modello. Il chiamante crea l'XML XFA (solitamente tramite Adobe LiveCycle Designer o manualmente, in base alla specifica XFA 3.3) e HotPDF emette i byte così come sono. I lettori che dispongono di un motore XFA (versioni precedenti di Acrobat/Reader, FormsCentral, alcuni prodotti per chioschi) visualizzano il modulo; i lettori senza un motore XFA (Adobe Reader DC a partire dal 2017, la maggior parte dei lettori open source) mostrano i campi AcroForm di riserva se il documento è un flusso di lavoro ibrido AcroForm + XFA.
  • Conformità a PDF/A e PDF/X: le sezioni ISO 19005-1 §6.4.2 / ISO 19005-2 §6.4.2 / ISO 19005-3 §6.4.2 vietano esplicitamente i moduli XFA (il motore di layout dinamico non è archiviabile in modo deterministico). I flussi di lavoro di pre-stampa ISO 15930 rifiutano completamente i moduli interattivi. `AddXFAPacket` genera un errore immediato se `PDFACompliance` o `PDFXCompliance` non sono vuoti, con il riferimento alla specifica pertinente. Vengono generati errori per nomi di pacchetti duplicati. Vengono generati errori se `PacketName` è vuoto o se `XMLBytes` è vuoto. `RequirePDFVersion (pdf15)` incrementa automaticamente la versione del documento. Il dizionario `AcroForm` viene ora generato se `/Fields` contiene almeno una voce OPPURE se è stato registrato almeno un pacchetto XFA; le chiamate precedenti alla versione v2.119.51 che non registrano alcun pacchetto mantengono un output `/AcroForm` identico in termini di byte.

2026-05-22 Version 2.119.50

  • Il modulo di subsetting TTF ora gestisce i glifi sostituiti da GSUB: la nuova funzione `THotPDF.MarkUnicodeGlyphUsed (GID: Word)` include un glifo nel subset nella versione 2.84.0, indipendentemente dal fatto che la cmap contenga o meno un codepoint corrispondente a quel glifo. Nella versione 2.84.0, la funzione deriva l'insieme dei glifi utilizzati da `FUnicodeUsedCps` tramite la cmap, quindi tutti i glifi sostituiti introdotti da GSUB – varianti stilistiche, ligature, varianti contestuali, l'intero output delle API di query di Fase 1-6 – erano precedentemente invisibili al modulo di subsetting e il lettore visualizzava `.notdef` al loro posto. Dopo aver emesso qualsiasi GID restituito da `GetSingleSubstituteGlyph / GetMultipleSubstituteGlyphs / GetAlternateGlyph / ApplyLigatureSubstitution / ApplyContextualSubst / ApplyReverseChainedContextualSubst` in un flusso di testo PDF, il chiamante ora chiama `MarkUnicodeGlyphUsed (GID)` una volta per ogni GID emesso per includerlo nel subset incorporato.
  • L'helper è idempotente (chiamate ripetute con lo stesso GID non hanno effetto), sicuro (i GID maggiori o uguali a FUnicodeNumGlyphs vengono ignorati silenziosamente, le chiamate effettuate prima di qualsiasi RegisterUnicodeTTF non hanno effetto) e si integra con la fase di chiusura dei glifi compositi v2.84.0 all'interno di _BuildSubsetTTF: i chiamanti devono solo contrassegnare il GID del glifo sostitutivo di livello superiore; i componenti compositi vengono automaticamente inclusi tramite l'esistente processo _TTFWalkCompositeClosure. L'insieme viene allocato in modo pigro alla prima chiamata e viene reimpostato a vuoto ad ogni RegisterUnicodeTTF ('', nil), insieme al resto dello stato del sottoinsieme. Con l'implementazione della Fase 9, ogni query API GSUB delle Fasi 1-7 può essere utilizzata in modo sicuro con l'emissione del sottoinsieme senza che i glifi sostitutivi vengano esclusi dal font incorporato.

2026-05-22 Version 2.119.49

  • L'API di selezione dello script/langsys GSUB di OpenType: cinque nuovi metodi pubblici su `THotPDF` consentono ai chiamanti di associare le tabelle di ricerca GSUB a uno script e una lingua specifici, invece del fallback storico allo script DFLT/langsys predefinito. `SetGSUBScript` ('latn' / 'arab' / 'cyrl' / 'hani' / 'kana' / 'deva' / 'beng' / 'taml' / ecc.) seleziona un tag di script OpenType; la stringa vuota predefinita mantiene il comportamento della versione v2.119.43-48 (preferire 'DFLT', altrimenti viene utilizzato il primo script). `SetGSUBLanguage` ('ENG ' / 'TUR ' / 'AZE ' / 'JAN ' / 'KOR ' / 'ARA ' / ecc., con spazi finali per riempire 4 byte) seleziona un tag di lingua OpenType; una stringa vuota rappresenta la langsys predefinita dello script. Entrambe le impostazioni persistono durante le query GSUB e vengono reimpostate su stringhe vuote durante `RegisterUnicodeTTF` ('', nil).
  • Tre nuove funzioni di supporto per le enumerazioni espongono le informazioni fornite dal font caricato: `GetGSUBScripts`: `TGSUBStringArray` restituisce ogni tag di script nell'ordine della lista `ScriptList`; `GetGSUBLanguages (ScriptTag)` restituisce ogni tag di lingua associato allo script specificato (con un segnaposto '' all'indice 0 quando lo script ha un `LangSys` predefinito); `GetGSUBFeatures (ScriptTag, LangTag)` restituisce ogni tag di caratteristica (ad esempio, 'liga', 'salt', 'aalt', 'ss01' fino a 'ss20') pubblicizzato dal percorso (script, lingua) nell'ordine di `LangSys featureIndices`. L'uso di `ScriptTag` o `LangTag` vuoti utilizza lo stesso meccanismo di fallback "DFLT-first" / `default-LangSys` delle API di sostituzione, quindi i chiamanti possono utilizzare `GetGSUBFeatures ('', '')` per enumerare le caratteristiche del percorso predefinito senza prima esaminare la lista degli script.
  • Semantica di selezione "rigorosa" rispetto alla soluzione di riserva: quando SetGSUBScript è impostato su un tag che il font caricato non dichiara, le successive query GSUB restituiscono risultati vuoti o senza effetto; il motore NON esegue automaticamente un fallback a DFLT, quindi i chiamanti possono facilmente capire che lo script scelto non è disponibile. Quando SetGSUBLanguage è impostato su un tag non riconosciuto, allora esegue il fallback al valore predefinito di LangSys dello script, come raccomandato nella specifica OpenType. I sette metodi di sostituzione GSUB esistenti (GetSingleSubstituteGlyph / GetMultipleSubstituteGlyphs / GetAlternateGlyphCount / GetAlternateGlyph / ApplyLigatureSubstitution / ApplyContextualSubst / ApplyReverseChainedContextualSubst) mantengono le loro interfacce pubbliche identiche; solo la funzione helper interna _GSUBFindFeatureLookups aggiunge due parametri aggiuntivi che tutti e sette i punti di chiamata ora indirizzano. Con l'API Script / LangSys e la matrice LookupType 1-8 implementate, il motore GSUB è completo per l'uso basato esclusivamente sulle funzionalità; le fasi successive della roadmap (pipeline di shaping automatico + subsetter TTF) mirano all'integrazione lato produttore piuttosto che a nuove superfici di query.

2026-05-22 Version 2.119.48

  • OpenType GSUB Reverse Chained Contextual Single Substitution (LookupType 8): la nuova funzione `THotPDF.ApplyReverseChainedContextualSubst (const InputGIDs; StartIndex; FeatureTag; out OutGID): Boolean` è l'ultimo tipo di lookup GSUB disponibile. Il tipo 8 esegue una sostituzione singola 1:1 contestuale, in cui il carattere sostitutivo viene selezionato in base all'indice di copertura del carattere di input, e la sua caratteristica distintiva è che i chiamanti devono applicarla in ordine di scansione inverso su una sequenza di più caratteri (dalla fine all'inizio), poiché ogni carattere sostitutivo potrebbe dipendere dal contesto futuro che non deve essere ancora stato sostituito. Questa funzione è un'applicazione a singolo punto: il chiamante gestisce il ciclo di scansione inversa. Sono supportati il formato di copertura 1 + 2, il flag di lookup che tiene conto dell'input, del backtracking e dell'anteprima (tutti consapevoli della possibilità di saltare), e l'estensione (LookupType 7).
  • Caso d'uso canonico: alcune varianti contestuali arabe/siriache/N'Ko/indiane la cui forma finale dipende dalla forma specifica del glifo successivo. Alcuni font implementano anche questa funzionalità per la disambiguazione di sequenze latine. A differenza di LookupType 5/6, il Type 8 non ha meccanismi di lookup nidificati, poiché la sostituzione è intrinsecamente 1:1. Se non viene trovata alcuna corrispondenza, viene restituito False; OutGID = InputGIDs[StartIndex] (corrispondenza approssimativa che rispetta il contratto di GetSingleSubstituteGlyph v2.119.43).
  • Chiude la matrice LookupType: con la versione v2.119.48, ogni tipo di Lookup GSUB OpenType (da 1 a 8) ha una funzionalità pubblica dedicata in THotPDF. L'API di selezione dello script/linguaggio, l'integrazione automatica della pipeline di shaping e il caricamento automatico dei glifi sostitutivi dal subsetter TTF rimangono riservati alle fasi 7-9; i chiamanti sono ancora responsabili di contrassegnare i glifi sostitutivi scelti nel subset del font incorporato e di gestire autonomamente il ciclo di scansione inversa.

2026-05-22 Version 2.119.47

  • OpenType GSUB Sostituzione contestuale e contestuale concatenata (LookupType 5 + 6): la nuova funzione THotPDF.ApplyContextualSubst (const InputGIDs; StartIndex; FeatureTag; var OutGIDs; out ConsumedLen): Boolean rappresenta un unico punto di accesso che copre sia il LookupType 5 (contesto solo in input) che il LookupType 6 (backtracking / input / anticipazione del contesto) in tutti e tre i formati di sottotabella: Formato 1 (sequenze di ID di glifi letterali), Formato 2 (sequenze di classi ClassDef) e Formato 3 (sequenze di tabelle Coverage, la forma canonica utilizzata dalla maggior parte dei font moderni). Gli utenti canonici sono 'rclt' (Alternative contestuali richieste: forme posizionali arabe init/medi/fina/isol quando il font le gestisce tramite GSUB), 'clig' (ligature contestuali), 'calt' (alternative contestuali) e le funzionalità di shaping Indic 'pres' / 'blws' / 'psts' / 'half' / 'pstf' / 'cjct'.
  • Il dispatcher per i lookup nidificati SequenceLookupRecord: quando una regola contestuale corrisponde, ogni voce di SequenceLookupRecord avvia un lookup nidificato in una posizione specifica all'interno della sottosequenza di input corrispondente. La nuova funzione helper _GSUBApplyNestedLookup fa parte della LookupList di GSUB, risolve in modo trasparente i wrapper di Extension e invia i risultati agli applicatori Single (Tipo 1) / Multiple (Tipo 2) / Alternate (Tipo 3, prima alternativa) / Ligature (Tipo 4). Il dispatcher tiene traccia degli indici di MatchPositions[] in tempo reale, in modo che le voci successive di SequenceLookupRecord continuino a indirizzare le posizioni di lavoro corrette, anche quando una sostituzione Multiple espande 1→N o una sostituzione Ligature comprime N→1 glifi attorno ad esse. I lookup nidificati di tipo 5 / 6 / 8 (ricorsivi contestuali) sono stati intenzionalmente rimandati; nella maggior parte dei font reali, i lookup nidificati sono collegati a Tipo 1 / 4.
  • Quando viene trovata una corrispondenza, il metodo restituisce True insieme alla sequenza di glifi di output che dovrebbe sostituire InputGIDs[StartIndex..StartIndex+ConsumedLen-1]. La lunghezza di OutGIDs può differire da ConsumedLen quando vengono attivate ricerche nidificate 1→N o N→1. ConsumedLen rappresenta sempre l'intervallo totale di input che la regola contestuale ha elaborato (inclusi i glifi saltati da LookupFlag tra i glifi significativi); una tipica chiamata a un ciclo di scansione avanza di ConsumedLen ed emette OutGIDs. Se non viene trovata alcuna corrispondenza, viene restituito False, OutGIDs è vuoto e ConsumedLen = 1, mantenendo lo stesso comportamento sicuro e senza effetti collaterali delle funzioni ausiliarie v2.119.43-46. Il flag LookupFlag (Fase 4) viene applicato durante l'intera corrispondenza contestuale: le operazioni di backtracking, input e lookahead ignorano tutti i glifi contrassegnati per l'omissione. Script / LangSys rimangono fissati al valore predefinito DFLT per questa sezione; l'API di selezione è valida solo nella Fase 7.

2026-05-22 Version 2.119.46

  • OpenType GSUB Extension Lookups (LookupType 7): il motore GSUB ora estrae automaticamente le sottotabelle di sostituzione di Extension, un livello di indirezione definito dalla specifica OpenType per font di grandi dimensioni in cui la sottotabella di sostituzione effettiva si trova al di là della portata di 16 bit di Offset16 di LookupList. Ogni API pubblica v2.119.43-45 (GetSingleSubstituteGlyph / GetMultipleSubstituteGlyphs / GetAlternateGlyphCount / GetAlternateGlyph / ApplyLigatureSubstitution) segue automaticamente l'indirezione a 32 bit a sottotabelle reali di LookupType 1 / 2 / 3 / 4. Questa modifica nella struttura binaria risolve il problema dei font OpenType CJK / Indic di grandi dimensioni (Noto Sans CJK, Noto Sans Devanagari, ecc.) le cui tabelle GSUB superano i 64 KB e che avevano già implementato le loro lookup dietro wrapper di LookupType 7; in precedenza, questi font apparivano come privi di funzionalità in HotPDF.
  • Parsing della tabella OpenType GDEF (definizione dei glifi): RegisterUnicodeTTF ora memorizza nella cache anche la tabella GDEF del font, se presente. Tre sottotabelle GDEF controllano la logica di gestione di LookupFlag: GlyphClassDef classifica ogni GID come base (1) / ligatura (2) / segno diacritico (3) / componente (4); MarkAttachClassDef etichetta ogni glifo di segno diacritico con una classe di collegamento; MarkGlyphSetsDef (v1.2+) dichiara set denominati di glifi di segni diacritici. Sono implementati sia il formato ClassDef 1 (startGlyphID + classValueArray) che il formato 2 (classRangeRecords ordinati); vengono accettati tutti gli header GDEF v1.0 / v1.1 / v1.2 (l'elemento itemVariationStore della versione v1.3 viene ignorato). I font senza una tabella GDEF tornano al comportamento di base della versione v2.119.43-45 ("nessun glifo viene ignorato"), in modo da preservare l'output byte-identico per le applicazioni che utilizzano font privi di GDEF.
  • OpenType GSUB: il flag di LookupFlag viene ora gestito correttamente: tutte le API pubbliche di GSUB leggono il flag di LookupFlag di ogni tabella di Lookup (e l'opzionale uint16 trailing markFilteringSet quando LookupFlag.useMarkFilteringSet è impostato) e saltano i glifi di input contrassegnati per l'omissione. I bit di flag definiti nella specifica vengono rispettati: 0x0002 ignoraBaseGlyphs (salta la classe 1 di GDEF.GlyphClassDef), 0x0004 ignoraLigatures (salta la classe 2), 0x0008 ignoraMarks (salta la classe 3), 0x0010 useMarkFilteringSet (solo i segni nell'insieme MarkGlyphSet denominato partecipano) e il byte alto markAttachmentType (solo i segni con la classe MarkAttachClassDef richiesta partecipano). Per la sostituzione di lighe (LookupType 4), questo è particolarmente importante: le lighe arabe 'rlig' / indiche 'akhn' i cui componenti sono separati da glifi di segni (ad esempio, LAM + Fatha + ALEF) ora corrispondono correttamente quando il flag LookupFlag.ignoreMarks è impostato, e il valore ConsumedCount restituito include i segni saltati, in modo che il ciclo di scansione del chiamante salti ogni glifo di input assorbito. Il bit 0x0001 (rightToLeft) è specifico per GPOS e rimane ignorato per i lookup di GSUB.
  • Le stesse restrizioni continuano ad applicarsi: i font senza una tabella GSUB, le chiamate che passano un tag non di 4 byte, le funzionalità che lo script DFLT del font non dichiara, i GID che non sono coperti da alcuna sottotabella e, ora, i glifi di input ignorati da LookupFlag restituiscono tutti il risultato sicuro e inattivo v2.119.43-45. Le cinque firme API pubbliche sono stabili a livello di byte; solo la ricerca interna gestisce la dispatch delle estensioni, il rispetto di LookupFlag e la classificazione GDEF. L'API di selezione dello script/langsys, l'integrazione automatica della pipeline di shaping e il subsetter TTF che estrae automaticamente i glifi sostitutivi rimangono riservati per le revisioni future.

2026-05-22 Version 2.119.45

  • OpenType GSUB Ligature Substitution (LookupType 4): la nuova funzione THotPDF.ApplyLigatureSubstitution (const InputGIDs: array of Word; StartIndex; FeatureTag; out OutGID; out ConsumedCount): Boolean combina una sequenza di più glifi in un singolo glifo ligatura. Gli utenti canonici sono 'liga' (Ligature standard - fi / fl / ffi / ffl), 'clig' (Ligature contestuali), 'dlig' (Ligature discrezionali), 'hlig' (Ligature storiche), 'rlig' (Ligature richieste - LAM-ALEF arabo e simili quando il font controlla la formattazione tramite GSUB) e le funzionalità di ligatura per gli script indic ('akhn', 'pres', 'blws', 'psts'). Il chiamante passa la sequenza di ID di glifo post-cmap e una posizione iniziale basata su 0; in caso di corrispondenza completa, l'helper restituisce True, OutGID = il glifo di sostituzione della ligatura e ConsumedCount = il numero totale di componenti di input utilizzati (>= 2 nella pratica). In caso di mancata corrispondenza, restituisce False, OutGID = 0, ConsumedCount = 1, in modo che il chiamante possa avanzare di un passo e continuare la scansione. L'implementazione rispetta la convenzione OpenType secondo cui le voci di LigatureSet sono in genere elencate dalla più lunga alla più corta, consentendo ai font con prefissi sovrapposti (ad esempio, una ligatura "ffi" a tre componenti insieme a una ligatura "ff" a due componenti) di ottenere la corrispondenza più lunga. Stesso contratto di sicurezza delle funzioni v2.119.43/.44: tag vuoti / non a 4 byte, nessuna GSUB, funzionalità non pubblicizzata, StartIndex fuori intervallo e nessuna sottotabella LookupType 4 corrispondente nella posizione restituiscono l'operazione sicura (False / OutGID = 0 / ConsumedCount = 1). La funzione LookupFlag per saltare i marcatori, l'integrazione di GDEF GlyphClassDef, l'applicazione automatica durante l'emissione del testo e l'estrazione automatica dei glifi di ligatura dal subsetter TTF sono riservate per revisioni future.

2026-05-22 Version 2.119.44

  • OpenType GSUB Sostituzione multipla (LookupType 2): la nuova funzione THotPDF.GetMultipleSubstituteGlyphs (InputGID, FeatureTag, var OutGIDs) restituisce un glifo di input come una sequenza di glifi sostitutivi. L'utente principale è la funzionalità di composizione/decomposizione di glifi 'ccmp', che divide le lettere latine accentate precomposte in base + segni di combinazione per il posizionamento successivo dei segni. La funzione di supporto percorre lo stesso percorso DFLT script / default LangSys / FeatureList / LookupList della funzione GetSingleSubstituteGlyph v2.119.43 e applica ogni sottotabella LookupType 2 collegata alla funzionalità richiesta rispetto a InputGID; la prima corrispondenza vince. OutGIDs viene reimpostato all'ingresso in modo che i chiamanti non debbano pre-cancellare. Una sequenza vuota consentita dalla specifica (glyphCount = 0, eliminazione canonica del glifo Unicode) viene segnalata come Result = True con Length(OutGIDs) = 0 in modo che il chiamante possa eliminare il glifo di input dalla sequenza.
  • OpenType GSUB Sostituzione alternativa (LookupType 3): due nuovi metodi espongono l'intero ciclo di sostituzione di glifi alternativi per le caratteristiche stilistiche. THotPDF.GetAlternateGlyphCount (InputGID, FeatureTag) restituisce il numero di forme alternative che un font offre per InputGID in base a FeatureTag, e THotPDF.GetAlternateGlyph (InputGID, FeatureTag, AlternateIndex) restituisce il glifo alternativo all'indice richiesto, a partire da 0. Gli utilizzi principali sono 'aalt' (Accesso a tutte le alternative), 'salt' (Alternative stilistiche), 'titl' (Alternative per titoli) e 'ss01' attraverso 'ss20' (Set stilistici 1-20) quando utilizzati con LookupType 3 invece di LookupType 1; in v2.119.43, GetSingleSubstituteGlyph ignorava silenziosamente queste sottotabelle, quindi le chiamate a 'aalt' in precedenza mostravano solo le sostituzioni transitive di LookupType 1. Questa coppia consente agli utenti di esplorare esplicitamente i cicli di glifi decorativi (diverse forme di 'a', 'g', '7'), le varianti di maiuscole e le alternative dei set stilistici. Se AlternateIndex è al di fuori dell'intervallo o negativo, viene restituito InputGID invariato, in modo che gli utenti possano eseguire controlli in modo sicuro.
  • Entrambe le funzioni rispettano le stesse protezioni di sicurezza della versione v2.119.43: i font senza una tabella GSUB, le chiamate che passano un tag non di 4 byte, le funzionalità che lo script DFLT del font non dichiara, e i GID che non sono coperti da una sottotabella di tipo LookupType 2/3, restituiscono l'operazione sicura e senza effetti (False + OutGIDs vuoti per Multiple; 0 / InputGID per Alternate). Le sottotabelle di tipo LookupType 1/4-8 incontrate nella catena di lookup della funzionalità vengono ignorate silenziosamente in questa versione. Il filtraggio tramite LookupFlag, l'integrazione di GDEF GlyphClassDef, l'API di selezione dello script/langsys, l'integrazione automatica della pipeline di shaping e il caricamento automatico dei glifi sostituiti selezionati dal subsetter TTF rimangono riservati per le revisioni future; le chiamate sono comunque responsabili di contrassegnare i glifi scelti nel subset del font incorporato.

2026-05-22 Version 2.119.43

  • OpenType GSUB: la nuova funzione THotPDF.GetSingleSubstituteGlyph (InputGID, FeatureTag) percorre la catena GSUB ScriptList / FeatureList / LookupList del font, utilizzando il LangSys predefinito dello script DFLT, e applica ogni sottotabella di tipo LookupType 1 (sostituzione singola) associata alla funzionalità richiesta, restituendo l'ID del glifo sostituito. Le funzionalità più comuni per le alternative stilistiche sono 'salt' (alternative stilistiche), 'ss01' attraverso 'ss20' (set stilistici 1-20), 'aalt' (usa tutte le alternative), 'titl' (alternative per titoli), 'subs' / 'sups' (pedice / apice), 'frac' (frazioni) e 'ordn' (ordinali); sono supportate tutte le funzionalità OpenType di 4 byte la cui catena di funzionalità contiene sottotabelle di tipo LookupType 1. Sia il formato di copertura 1 (array di glifi ordinato, ricerca binaria) che il formato 2 (record di intervalli) sono supportati. Sia il formato di sostituzione singola 1 (delta) che il formato 2 (array di sostituzione) sono implementati. RegisterUnicodeTTF ora memorizza nella cache l'offset/la lunghezza della tabella GSUB insieme a cmap, in modo che le operazioni di lettura GSUB durante l'interrogazione evitino di scansionare nuovamente la directory della tabella. Se un font non ha una tabella GSUB, se la chiamata passa un tag di 4 byte che lo script DFLT del font non pubblicizza, o se i GID non sono presenti nella copertura della ricerca, viene restituito InputGID invariato, quindi l'API può essere chiamata in modo sicuro come sostituzione o passaggio diretto. Le sottotabelle di tipo LookupType 2-8 incontrate nella catena di funzionalità vengono ignorate silenziosamente in questa prima fase; le catene di sostituzione multipla / sostituzione alternativa / sostituzione di lighe e l'integrazione della pipeline di shaping automatica sono riservate per le revisioni future.

2026-05-22 Version 2.119.42

  • AcroForm: la sezione /DR Resources ora accetta più font Unicode. Nella versione 2.56.0, SetFormUnicodeFontDict tiene traccia di un solo font fornito dall'utente, che diventa il font predefinito di AcroForm /DA; i moduli multilingue che richiedono script diversi per campo (ad esempio, arabo + CJK + latino in un unico PDF) dovevano creare manualmente il dizionario /DR /Font. La nuova funzione THotPDF.RegisterAcroFormFont (LogicalName, FontDict) registra un font Unicode aggiuntivo con qualsiasi nome logico, lo rende disponibile per le stringhe /DA per campo (/ 12 Tf) e lo emette nel dizionario /DR /Font di AcroForm insieme al font predefinito della versione 2.56.0. L'ordine di registrazione viene preservato, quindi il /DR emesso è deterministico. Le collisioni di nomi con il font predefinito di SetFormUnicodeFontDict o un font precedentemente registrato generano un errore con il nome incriminato. Anche i nomi logici vuoti o FontDict null generano un errore. Il percorso di reset di SetFormUnicodeFontDict ('', nil) ora pulisce anche il registro dei font aggiuntivi, in modo che un nuovo flusso di lavoro Unicode inizi da uno stato pulito. Consentito in tutti i livelli PDF/A / PDF/X: i font Unicode compositi sono metadati strutturali del modulo, non script interattivi.

2026-05-22 Version 2.119.41

  • Un'enumerazione di tipo struttura standard che copre la tabella 333 della sezione §14.8.4 di PDF 1.7: la nuova enumerazione THPDFStandardStructureType elenca i circa 40 ruoli di struttura prescritti dalle specifiche, raggruppati in base al loro ruolo PDF (Raggruppamento: Documento / Parte / Articolo / Sezione / Divisione / Citazione / Didascalia / Indice / TOC / TOCI / Indice / Non strutturato / Privato; Livello blocco: H / H1-H6 / P / L / LI / Lbl / LBody / Tabella / TR / TH / TD / THead / TBody / TFoot; Livello inline: Span / Citazione / Nota / Riferimento / Voce bibliografica / Codice / Collegamento / Annotazione; Ruby + Warichu: Ruby / RB / RT / RP / Warichu / WT / WP; Illustrazione: Figura / Formula / Modulo). Due funzioni di supporto a livello di unità convertono l'enumerazione nei nomi PDF esatti specificati: StandardStructureTypeToName (T) restituisce il nome, che fa distinzione tra maiuscole e minuscole, utilizzato come chiave /S dell'elemento di struttura, e IsStandardStructureType (Name) verifica una stringa Ansi arbitraria rispetto all'insieme standard, in modo che i chiamanti possano verificare in anticipo i nomi di ruolo personalizzati e indirizzarli tramite AddStructRoleMap quando necessario. Una nuova overload dell'enumerazione AddStructureElement accetta direttamente THPDFStandardStructureType, eliminando l'errore di battitura / il rischio di distinzione tra maiuscole e minuscole ("Para" rispetto a "P", "Lbody" rispetto a "LBody") delle overload con stringhe aperte, inoltrando allo stesso codice di base. Le overload esistenti basate su stringhe Ansi rimangono identiche a livello di byte per i chiamanti che utilizzano nomi personalizzati o indirizzati tramite RoleMap.

2026-05-22 Version 2.119.40

  • Strumenti per impostare gli attributi degli elementi strutturali: tre nuovi strumenti consentono di compilare gli attributi di stringa di testo PDF specifici per ogni elemento, che si abbinano a v2.88.0 /Alt + /ActualText e v2.95.0 /ID. THotPDF.SetStructureElementLanguage (Elem, BCP-47 Lang) scrive PDF 1.7 §14.9.2 /Lang, sovrascrivendo la lingua predefinita del documento per i contenuti sottostanti a questo elemento fino a quando non viene applicata un'altra sovrascrittura /Lang; l'uso tipico è per citazioni in un'altra lingua o sezioni di contenuto misto. THotPDF.SetStructureElementExpansionText (Elem, ExpansionText) scrive §14.9.5 /E, l'espansione dell'abbreviazione letta dai lettori di schermo al posto di un acronimo (ad esempio, 'NASA' → 'National Aeronautics and Space Administration') e il valore raccolto durante l'estrazione dei contenuti. THotPDF.SetStructureElementTitle (Elem, Title) scrive §14.7.5.2 /T, il titolo leggibile che distingue l'elemento dai fratelli con lo stesso ruolo nell'albero della struttura (il pannello "Tag" di Acrobat visualizza /T accanto al nome del ruolo). Tutti e tre sono semplici strumenti di impostazione con semantica "no-op" quando il valore è vuoto, un valore nil-Elem genera un errore e sono consentiti in tutti i livelli PDF/A e PDF/X poiché le chiavi sono metadati strutturali.

2026-05-22 Version 2.119.39

  • Completamento della famiglia di trigger per i campi modulo AcroForm: tre nuovi helper si uniscono ad AttachFieldKeyStrokeAction (v2.119.37) per chiudere la tabella 12.7.5.3 di PDF 1.7. THotPDF.AttachFieldFormatAction installa /AA /F (evento di formattazione, si attiva quando il valore visualizzato del campo deve essere riformattato dopo un commit; l'uso tipico è applicare maschere di valuta, data o separatore delle migliaia tramite AFNumber_Format / AFDate_FormatEx). THotPDF.AttachFieldValidateAction installa /AA /V (evento di validazione, si attiva dopo che l'utente ha inserito un nuovo valore; l'uso tipico è verificare l'intervallo o validare l'input tramite regex tramite event.rc := false). THotPDF.AttachFieldCalculateAction installa /AA /C (evento di calcolo, si attiva quando qualsiasi campo dipendente cambia in base all'ordine di calcolo del catalogo /AcroForm /CO; l'uso tipico è calcolare totali o tasse). Tutti e quattro i wrapper condividono la stessa ricerca FFormFields /T, la semantica di sostituzione idempotente "ultimo che chiama vince" e le protezioni JavaScript per PDF/A + PDF/X. Altri trigger chiave nello stesso dizionario /AA (trigger di annotazione /E /X /D /U /Fo /Bl e i tre trigger di campo modulo correlati) vengono preservati senza modifiche. Rielaborazione interna: AttachFieldKeyStrokeAction ora delega a un helper condiviso _InstallFieldTriggerJSAction; le chiamate esistenti a v2.119.37 vedono messaggi di eccezione identici a livello di byte.

2026-05-22 Version 2.119.38

  • RegisterUnicodeTTF ora cattura le mappature tra codepoint e glifi del piano multilingue supplementare (SMP, U+10000-U+10FFFF) dalla sottotabella di formato 12 della cmap del font caricato. Le versioni precedenti eliminavano silenziosamente le voci del SMP perché la ricerca codepoint-glifo era un array di dimensioni BMP; la versione v2.119.38 aggiunge una lista sparsa parallela (FUnicodeCpToGidSMP) che viene popolata insieme all'array BMP. Il nuovo metodo pubblico GetUnicodeGlyphForCodepoint(Cp) restituisce l'ID del glifo per qualsiasi codepoint Unicode fino a U+10FFFF (effettua una ricerca binaria nella lista SMP per i codepoint superiori al BMP), oppure 0 (.notdef) quando il codepoint non è mappato nella cmap del font caricato. Questa è una funzionalità aggiuntiva: la pipeline di codifica esadecimale lato produttore, lo stream /CIDToGIDMap e la CMap ToUnicode rimangono ancorati al BMP, quindi per scrivere un carattere SMP in un flusso di testo PDF, i chiamanti devono ancora emettere coppie surrogate UTF-16BE. L'emissione completa di flussi di testo con consapevolezza delle surrogate è riservata a una revisione futura. I font con formato 4 ricevono una lista SMP vuota come previsto.

2026-05-22 Version 2.119.37

  • Nuovo helper per attivare azioni tramite tasti sulla form: `THotPDF.AttachFieldKeyStrokeAction(FieldName, JavaScriptBody)` individua il widget del form specificato tramite il suo valore `/T` e installa un'azione JavaScript `/AA /K` in modo che i lettori PDF eseguano lo script ad ogni pressione di un tasto durante l'inserimento del testo. I casi d'uso includono la validazione dell'input in tempo reale (numerico/data/espressione regolare), la mascheratura dell'input e gli aggiornamenti dei campi calcolati attivati dalle modifiche in un altro campo. Questo helper è idempotente: le chiamate ripetute sostituiscono l'elemento `/K` preservando al contempo qualsiasi altra chiave di attivazione già presente nel dizionario `/AA` (formato `/F`, validazione `/V`, ricalcolo `/C`, sfocatura `/Bl`, messa a fuoco `/Fo`, ecc.). Tutti i livelli di PDF/A (ISO 19005-1 §6.6.1, -2/-3 §6.5.1) e tutti i livelli di PDF/X (ISO 15930 pre-stampa) vietano le azioni JavaScript, quindi questo helper genera immediatamente un errore con il riferimento alla specifica pertinente se uno dei flag di conformità non è vuoto. Si basa sul dizionario degli eventi di attivazione PDF 1.7 §12.6.3 e sulla tabella 246 del campo del form `/K` (PDF 1.7 §12.7.5.3).

2026-05-22 Version 2.119.36

  • BeginTaggedContent ora accetta quattro proprietà opzionali della sequenza di contenuto contrassegnato (Lang / Alt / ActualText / ExpansionText) come definito in PDF 1.7 §14.8.4 Tabella 322 e le emette come un singolo dizionario di proprietà inline BDC, insieme alla voce MCID esistente. Lang contiene il tag di lingua naturale BCP-47 per il blocco di testo (utilizzato dai lettori di schermo e dall'estrazione di testo consapevole della lingua); Alt è la descrizione alternativa per i blocchi di testo non testuali o decorativi; ActualText è il testo di sostituzione utilizzato dall'estrazione del contenuto e dalla copia e incolla al posto della sequenza di glifi visibile (essenziale per le legature e i glifi stilizzati in cui il carattere visibile differisce dal testo semantico sottostante); ExpansionText contiene la chiave /E che espande le abbreviazioni. I parametri vuoti saltano la voce corrispondente, quindi il dizionario inline contiene solo le chiavi che il chiamante popola esplicitamente, e il percorso di chiamata legacy con due argomenti rimane identico in termini di byte rispetto all'output di v2.119.35. L'escape delle stringhe letterali PDF (parentesi e backslash) è automatico; per i payload non ASCII (ActualText CJK, Alt Indic, ecc.), i chiamanti pre-codificano i propri byte come UTF-16BE con il BOM U+FEFF e impacchettano il risultato nell'argomento AnsiString. L'API di basso livello corrispondente BeginMarkedContentMCIDProps è anch'essa esposta per i chiamanti che necessitano di un controllo diretto di BDC senza il cablaggio di alto livello di StructElem.

2026-05-22 Version 2.119.35

  • La parte principale di Arabic Extended-A, un sottoinsieme di 9 lettere persiane/urdu, ora è inclusa nel formattatore a quattro posizioni lato produttore nella versione v2.85.0. Con AutoShapeArabic abilitato, le seguenti lettere vengono mappate ai rispettivi glifi Arabic Presentation Forms-A U+FB50-U+FBFF in base allo stesso algoritmo di contesto di collegamento utilizzato per il blocco arabo di base: PEH U+067E, TCHEH U+0686, JEH U+0698, KEHEH U+06A9, GAF U+06AF, FARSI YEH U+06CC (persiano principale), oltre a TTEH U+0679, DDAL U+0688, RREH U+0691 (urdu retroflesso principale). Le lettere con doppia connessione espongono l'intero set isolato/finale/iniziale/mediale; le lettere con connessione a destra (JEH / DDAL / RREH) espongono solo le forme isolate/finali, come previsto dal modello di formattazione arabo. Altre lettere di Arabic Extended-A (ALEF WASLA U+0671, NOON GHUNNA U+06BA, varianti di HEH U+06C0-U+06C3, supplemento arabo completo U+0750-U+077F) rimangono invariate e saranno gestite in una revisione futura. Il testo arabo non persiano/urdu rimane identico all'output della versione v2.119.34.

2026-05-22 Version 2.119.34

  • La gestione dei nomi PDF ora decodifica le sequenze di escape ISO 32000-1 #XX durante l'importazione o la copia di oggetti PDF. I nomi delle risorse, i nomi dei colori speciali, i nomi dei ruoli strutturali e altri oggetti nome, come /PANTONE#20216#20CVC, vengono ora elaborati da HotPDF mantenendo i loro valori byte originali, invece di essere copiati con un simbolo di numero doppio.

2026-05-22 Version 2.119.33

  • La gestione delle date in PDF ora segue più da vicino le regole delle stringhe di data definite in ISO 32000-1. Le informazioni del documento, le date derivate da XMP e i timestamp delle firme utilizzano il valore TDateTime fornito dalla chiamata, invece di sostituire silenziosamente con l'ora corrente, mentre l'analizzatore accetta i campi di data opzionali standard e i suffissi di fuso orario senza corrompere i campi di data/ora locali.
  • Il filtro di importazione PDF ora dispone di funzioni di supporto esplicite per ASCIIHexDecode, ASCII85Decode e RunLengthDecode, e il valore predefinito di EarlyChange per LZWDecode ora corrisponde al valore predefinito di PDF, che è 1. Questo migliora la compatibilità con le pagine importate o copiate che utilizzano filtri di flusso PDF obsoleti.

2026-05-21 Version 2.119.32

  • La ligatura obbligatoria Arabic LAM-ALEF ora viene gestita all'interno del motore di shaping lato server nella versione v2.85.0. Quando AutoShapeArabic è abilitato, qualsiasi sequenza di U+0644 LAM (nella forma originale o in una delle sue quattro forme modificate FEDD-FEE0) seguita da una delle quattro varianti di ALEF (MADDA U+0622, HAMZA-above U+0623, HAMZA-below U+0625, semplice U+0627; nella forma originale o modificata) viene trasformata in un'unica glifa di ligatura dal blocco U+FEF5-U+FEFC. La forma della ligatura, connessa o isolata, viene selezionata in base al fatto che la LAM sia stata trasformata in una forma finale (FEDE) o mediale (FEE0) dal meccanismo di shaping a quattro posizioni. Altre ligature obbligatorie arabe (Allah U+FDFB e ligature decorative) richiedono ancora un motore GSUB completo e rimangono al di fuori dell'ambito del modello di shaping basato su tabelle statiche. Il testo che non include LAM-ALEF e le chiamate con AutoShapeArabic disabilitato rimangono identici all'output della versione v2.119.31. Tre helper Unicode AcroForm /AP (a riga singola, multi-linea, combinati) ereditano automaticamente questa modifica tramite il punto di ingresso condiviso _ApplyArabicShaping.

2026-05-21 Version 2.119.31

  • Nuovo adattatore di esportazione per il sistema ExpressPrinting di DevExpress: `dxHotPDFExportReportLinkToFile` / `dxHotPDFExportReportLinkToStream` accettano qualsiasi `TBasedxReportLink` (la famiglia di link astratti che collega cxGrid / cxRichEdit / cxScheduler / cxPivotGrid e componenti simili stampabili a `TdxComponentPrinter`) e inviano ogni pagina renderizzata a HotPDF invece dell'esportatore `dxPSExportToPDF` di DevExpress. L'adattatore replica il ciclo di esportazione interno di DevExpress: ricostruisce il report, quindi per ogni pagina, disegna la pagina su un `TMetafileCanvas` e la visualizza in HotPDF come metafile migliorato. Le opzioni esposte includono Titolo / Autore / Oggetto / Parole chiave / VersionePDF / Compressione / Risoluzione di rendering. Condivide le stesse limitazioni del bridge metafile degli adattatori FastReport / QuickReport / ReportBuilder: nessun campo AcroForm, nessuna struttura, nessuna conformità PDF/A / PDF/X. L'adattatore si trova in `Lib/Addons/DevExpress/` e non è incluso nel file `HotPDF*.dpk` principale.

2026-05-20 Version 2.119.30

  • Nuova classe di dispositivo ReportBuilder: `TppHotPDFDevice` deriva da `TppGraphicsDevice`, quindi si integra nella catena standard di pubblicazione → dispositivo di ReportBuilder quando assegnata a `TppReport.PrinterDevice` o a `TppPublisher.Device`. Ogni pagina viene renderizzata su un `TMetafileCanvas` temporaneo (creato in `BeforeRenderPage`, finalizzato in `AfterRenderPage`), catturata come un `TMetafile` e indirizzata tramite l'importatore EMF di HotPDF (`HPDFEmf.ShowEnhancedMetafile`). Le proprietà espongono Titolo / Autore / Argomento / Parole chiave / `PDFVersion` / `CompressionLevel` / `Compressed`; `SetOutputStream` indirizza i byte PDF a un `TStream` fornito dal chiamante. Condivide le stesse limitazioni del ponte metafile degli adattatori FastReport / QuickReport: nessun campo AcroForm, nessuna struttura, nessuna conformità PDF/A / PDF/X. L'adattatore si trova in `Lib/Addons/ReportBuilder/` e non è incluso nel file `HotPDF*.dpk` principale.

2026-05-20 Version 2.119.29

  • È stato aggiunto un nuovo filtro di esportazione QuickReport: `TQRHotPDFExportFilter` deriva da `TQRExportFilter`, quindi si integra nel normale flusso di lavoro `MyReport.ExportToFilter(MyFilterInstance)` senza modifiche al core di QuickReport. L'adattatore raccoglie i metadati per pagina che QuickReport memorizza già nella cache in `QRPrinter.PageList` e li invia all'importatore EMF di HotPDF (`HPDFEmf.ShowEnhancedMetafile`). Le proprietà espongono Titolo, Autore, Oggetto, Parole chiave, Versione PDF, Livello di compressione e Compressione; `SetOutputStream` indirizza i byte PDF a un `TStream` fornito dal chiamante invece che su disco. Condivide le stesse limitazioni del bridge dei metadati dell'adattatore FastReport: nessun campo AcroForm, nessuna struttura, nessuna conformità PDF/A / PDF/X. L'adattatore si trova in `Lib/Addons/QuickReport/` e non è incluso nel file `HotPDF*.dpk` principale.

2026-05-20 Version 2.119.28

  • Nuovo adattatore di esportazione FastReport 4 / FastReport VCL: `TfrxHotPDFExport` deriva da `TfrxCustomExportFilter`, quindi si integra nel normale flusso di lavoro `MyReport.Export(MyExportInstance)` senza modifiche al core di FastReport. L'adattatore instrada ogni pagina preparata attraverso l'importatore EMF di HotPDF (tramite `TfrxPreviewPages.DrawPage` di FastReport → `TMetafileCanvas` → `HotPDF.ShowEnhancedMetafile`), in modo che il contenuto vettoriale e raster della pagina, renderizzato dal motore di layout standard di FastReport, venga preservato senza codice di emissione per singolo oggetto. Le proprietà espongono Titolo / Autore / Oggetto / Parole chiave / `PDFVersion` / `CompressionLevel` / `RenderDPI` per controllare il PDF risultante. Limitazioni: nessun campo AcroForm, nessuna struttura, nessun supporto per PDF/A / PDF/X (questi richiedono una pipeline di emissione per singolo oggetto, prevista per una revisione futura). L'adattatore è incluso in `Lib/Addons/FastReport4/` e NON è incluso nel file `HotPDF*.dpk` principale; gli utenti devono aggiungerlo al proprio progetto insieme al pacchetto FastReport corrispondente.

2026-05-20 Version 2.119.27

  • Nuova funzionalità di firma PDF basata su PFX, THotPDF.SignPDFWithPFX(InputPDFPath, OutputPDFPath, PFXFilePath, Password), carica un file PDF non firmato che contiene già un segnaposto per il campo della firma, analizza il file PFX / PKCS#12, crea un oggetto CMS SignedData (RFC 5652) completo sui byte coperti da /ByteRange e scrive il PDF firmato in un'unica operazione. È inoltre disponibile una versione basata su TStream per flussi di lavoro in memoria. La dimensione del campo /Contents del PDF deve essere sufficientemente grande per contenere l'esadecimale DER di CMS; il valore predefinito di 8192 byte è sufficiente per RSA da 1024/2048 bit. Sono supportati solo file PFX con PBES2 + AES-256-CBC (limite del parser PKCS#12 v2.119.26).
  • Nuova unità HPDFCMS: costruttore di SignedData per CMS. HPDFCMSBuildSignedData compone ContentInfo → SignedData → SignerInfo con contenuto separato id-data, attributi firmati (contentType + messageDigest + signingTime, ordinati in ordine crescente DER secondo RFC 5652 §5.4), identificatore del firmatario IssuerAndSerialNumber estratto dal certificato X.509, algoritmo di firma RSA + SHA-256 e il certificato X.509 racchiuso in [0] certificati IMPLICIT. Espone anche HPDFCMSSHA256ByteRanges per il digest a due finestre in streaming e HPDFCMSBytesToHex per l'iniezione del segnaposto /Contents. Chiude lo stack di firma interno avviato con HPDFASN1 (v2.119.23) + HPDFRSA (v2.119.24) + estensioni HPDFCrypt (v2.119.25) + HPDFPFX (v2.119.26).

2026-05-20 Version 2.119.26

  • Nuova unità HPDFPFX: parser di contenitori PKCS#12 / PFX. Legge i file .pfx / .p12 da OpenSSL ≥ 3.0, certutil di Windows 11+ e Keychain Access di macOS, decrittografa i payload SafeBag con PBES2 (PBKDF2-HMAC-SHA-256 + AES-256-CBC) ed estrae i parametri della chiave privata RSA e del certificato X.509 in formato DER. Restituisce un record THPDFPFXKeyMaterial contenente CertDER, Modulus, PublicExponent e PrivateExponent, che il codice CMS / di firma successivo può utilizzare direttamente. Una password errata viene rilevata tramite l'errore di rimozione del padding PKCS#7 che si verifica a seguito di una chiave AES non valida. I file legacy PBE-SHA1-3DES generano un avviso con un chiaro suggerimento per riesportare utilizzando `-keypbe AES-256-CBC -certpbe AES-256-CBC`.

2026-05-20 Version 2.119.25

  • Sono state aggiunte nuove primitive crittografiche: cifrario inverso AES-256 con AES256DecryptBlock + AES256CBCDecryptPKCS7 + AES256CBCDecryptNoPad (in conformità a FIPS-197 §5.3, che integra le funzionalità di crittografia esistenti), HMAC-SHA-256 (RFC 2104) e PBKDF2-HMAC-SHA-256 (RFC 8018 §5.2). Sono state verificate rispetto ai vettori HMAC definiti in RFC 4231 e agli output di riferimento standard di PBKDF2-SHA-256. Insieme al decoder ASN.1 della versione 2.119.23 e alle primitive RSA della versione 2.119.24, questo completa le fondamenta crittografiche necessarie per il percorso di decrittazione SafeBag PBES2-AES-256 utilizzato nei file PKCS#12 / PFX moderni (OpenSSL ≥ 3.0 / Windows 11+).

2026-05-20 Version 2.119.24

  • Nuova unità HPDFRSA: aritmetica intera a precisione multipla + elevazione modulare RSA + codifica EMSA PKCS#1 v1.5. Sufficientemente grande per firmare con chiavi RSA reali da 2048/4096 bit. Insieme al decoder ASN.1 di v2.119.23, questo completa i primitivi crittografici necessari per la pipeline di firma PDF basata su PFX imminente. Nessuna API rivolta all'utente utilizza ancora questo componente; si tratta di un'infrastruttura interna in attesa dei livelli PKCS#12 + CMS.

2026-05-20 Version 2.119.23

  • Nuova unità HPDFASN1: un decoder BER/DER compatto per il sottoinsieme ASN.1, necessario per consentire a HotPDF di leggere keystore PKCS#12, certificati X.509 e contenitori CMS/PKCS#7 SignedData. Espone THPDFASN1Node (descrittore Tag-Length-Value analizzato), THPDFASN1ParseNode e i metodi di accesso /ParseAt, Content, /ToInteger, /ToBigInt, /ToOID, /ToString, nonché gli iteratori FirstChild, NextSibling e Children. Rifiuta esplicitamente le forme BER a lunghezza indefinita e le codifiche con numeri di tag elevati (>= 31), rispecchiando il sottoinsieme rigoroso di DER. Questa è un'infrastruttura interna per la pipeline di firma PFX integrata che arriverà nelle prossime versioni; al momento, nessuna API esposta dipende da essa.

2026-05-20 Version 2.119.22

  • Nuovi overload per le annotazioni PolyLine e Polygon con metadati completi: THPDFPage.AddPolylineAnnotation e AddPolygonAnnotation acquisiscono due nuovi overload che accettano un array di vertici THPDFCurrPoint e un record THPDFPolyExtras opzionale. Il record extras espone le voci opzionali di ISO 32000-1 §12.5.6.9, ovvero /IC (colore interno), /BE (bordo nuvoloso, con /I (intensità)), /IT (intento: PolyLineDimension / PolyLineFlight / PolygonCloud / PolygonDimension) e /LE (stili di terminazione della linea) per PolyLine. Utilizzare HPDFDefaultPolyExtras() per un record iniziale con valori a zero. I nuovi overload verificano che siano forniti almeno due vertici e incrementano automaticamente la versione del documento (PDF 1.5 / 1.6 / 1.7 a seconda dell'intento). I precedenti overload "interleaved-Single" continuano a compilare senza modifiche.

2026-05-20 Version 2.119.21

  • Nuove funzionalità per l'annotazione Linea: la funzione `AddLineAnnotation` ora offre una terza implementazione che accetta un record `THPDFLineExtras` per controllare le opzioni facoltative specificate nella tabella 175 della sezione §12.5.6.7 di PDF 1.6/1.7, come il colore interno (`/IC`) per le frecce e i diamanti, la lunghezza della linea guida (`/LL`), l'estensione della linea guida (`/LLE`), l'offset della linea guida (`/LLO`, PDF 1.7), un flag per la didascalia (`/Cap`) con la posizione (`/CP`, `/Inline` o `/Top`, PDF 1.7) e l'offset della didascalia (`/CO`), e lo scopo (`/IT`, `LineArrow` o `LineDimension`). Utilizzare `HPDFDefaultLineExtras()` per inizializzare il record a zero. La nuova implementazione aggiorna automaticamente la versione del documento a PDF 1.6 (o 1.7 quando vengono richieste le opzioni `/LLO`, `/CP` e `/CO`). Le due implementazioni precedenti continuano a generare output identico in termini di byte, e vengono scritti solo gli elementi per i quali il chiamante effettivamente richiede.

2026-05-20 Version 2.119.20

  • Nuovi pulsanti di azione "baShow" e "baImportData": THPDFButtonAction ora include "baShow" (che è il contrario di "baHide" e imposta "/H" su "false" per mostrare nuovamente un widget nascosto) e "baImportData" (/S /ImportData /F filespec per caricare i dati del modulo FDF al clic, ISO 32000-1 §12.7.5.4). "baShow" è consentito secondo le specifiche per PDF/A e PDF/X; "baImportData" è bloccato in entrambi i casi, secondo ISO 19005-1 §6.6.1 e ISO 15930 per la pre-stampa, rispettivamente.
  • Nuova funzione "Hide/Show" per campi multipli: THPDFPage.AddPushButtonWithHideAction(FieldName, Caption, Targets, Hide, Rectangle, Flags) accetta un array di nomi di campi di destinazione e un valore booleano esplicito per "Hide", in modo che un singolo pulsante possa alternare la visibilità di più elementi in un solo clic. Se l'array "Targets" è vuoto, viene generato un errore. Sia PDF/A che PDF/X supportano questa funzione (solo la visibilità degli elementi).

2026-05-20 Version 2.119.19

  • Nuovo controllo utente SubmitForm /Flags: THPDFPage.AddPushButtonWithSubmitAction(FieldName, Caption, URL, Rectangle, SubmitFlags) espone l'intero set di flag della tabella 237, sezione 12.7.5.2 dello standard ISO 32000-1, tramite il nuovo tipo THPDFSubmitFormFlags. Gli utilizzatori possono ora combinare sffExportFormatHTML / sffXFDF / sffSubmitPDF (formato di invio), sffGetMethod (HTTP GET o POST), sffIncludeAnnotations, sffSubmitCoordinates, sffCanonicalFormat, sffIncludeNoValueFields, sffIncludeAppendSaves, sffExclNonUserAnnots, sffEmbedForm e altri, sostituendo il valore /Flags 0 (FDF + POST) codificato in modo fisso del percorso legacy baSubmitURL. La funzione esistente AddPushButtonWithAction(.., baSubmitURL, ..) continua a generare /Flags 0 per garantire la compatibilità a livello di byte. Stesse restrizioni PDF/A / PDF/X di baSubmitURL: consentito in PDF/A, bloccato in PDF/X.

2026-05-20 Version 2.119.18

  • Sono stati aggiunti tipi di azioni per pulsanti estesi: THPDFButtonAction ora include baNamed e baHide. baNamed emette un'azione /S /Named /N (ISO 32000-1 §12.6.4.11) adatta ai quattro comandi di navigazione standard NextPage / PrevPage / FirstPage / LastPage (PDF/A consente tutti e quattro secondo ISO 19005-1 §6.6.1) e alle estensioni di Acrobat come Print e SaveAs. baHide emette un'azione /S /Hide /T /H true (§12.6.4.10) che nasconde il campo del modulo denominato quando viene premuto il pulsante. Entrambi i tipi di azione sono conformi alle specifiche PDF/A e PDF/X; solo baJavaScript / baResetForm / baSubmitURL mantengono i loro meccanismi di conformità esistenti.

2026-05-20 Version 2.119.17

  • Nuovo registro di destinazioni denominate: `THotPDF.RegisterNamedDestination(Name, PageIndex, FitMode, ...)` registra una destinazione simbolica nell'albero dei nomi del catalogo `/Names /Dests` (ISO 32000-1 §12.3.2.3). Le azioni "Vai a" / "Vai a relativo" e le voci dell'indice /Dest possono quindi fare riferimento a una destinazione per nome anziché codificare direttamente i numeri di pagina, il che mantiene i riferimenti incrociati stabili in caso di inserimento/eliminazione/riordino di pagine. Il nuovo enum `THPDFDestinationFitMode` copre tutti e otto i modi di adattamento specificati (XYZ, Fit, FitH, FitV, FitR, FitB, FitBH, FitBV). Il metodo genera un'eccezione se il nome è vuoto, se `PageIndex` è al di fuori dell'intervallo o se il nome è duplicato; incrementa automaticamente la versione del documento a PDF 1.2 quando necessario. Non ci sono restrizioni PDF/A / PDF/X: le funzioni di navigazione sono consentite in tutti i profili.

2026-05-20 Version 2.119.16

  • Sono state aggiunte nuove opzioni di stile per le linee di annotazione /LE in `THPDFPage.AddLineAnnotation`, che ora include un'estensione che accetta stili di terminazione di inizio e fine linea. L'intero set definito nella tabella 176 della sezione ISO 32000-1 §12.5.6.7 è ora disponibile tramite il nuovo enum `THPDFLineEndingStyle`: `None`, `Square`, `Circle`, `Diamond`, `OpenArrow`, `ClosedArrow`, `Butt`, `ROpenArrow`, `RClosedArrow`, `Slash`. Le annotazioni di linea possono ora essere renderizzate come vere e proprie frecce, marcatori di dimensionamento o indicatori all'interno di Adobe Acrobat / Foxit, senza che l'applicazione host debba disegnare manualmente le punte di freccia sulla pagina. L'estensione precedente a quattro parametri continua a funzionare in modo identico.

2026-05-20 Version 2.119.15

  • Nuovo stile per la struttura (segnalibri): THPDFDocOutlineObject ora espone le proprietà Colore, Grassetto e Corsivo (ISO 32000-1 §12.3.3 Tabella 153 /C e /F). Il pannello della struttura può ora visualizzare i segnalibri a colori e con enfasi in grassetto o corsivo, utile per raggruppare i capitoli, evidenziare sezioni incomplete o che richiedono attenzione e per uniformarsi allo stile del marchio. Il colore predefinito è clNone (nessuna voce /C emessa, identica all'output precedente); Grassetto e Corsivo predefiniti sono false. Impostare le proprietà dopo l'aggiunta di un elemento figlio aggiorna il dizionario della struttura in tempo reale; impostare il colore su clNone o sia Grassetto che Corsivo su false rimuove le voci /C e /F.

2026-05-20 Version 2.119.14

  • Nuovo registro JavaScript a livello di documento: THotPDF ora espone RegisterDocumentJavaScript(Name, Body). Ogni voce registrata viene serializzata nell'albero di nomi del catalogo /Names /JavaScript (ISO 32000-1 §7.7.4.4 + §12.6.4.16) come un dizionario indiretto /S /JavaScript /JS. Le azioni dei widget AcroForm e le azioni di apertura del documento possono invocare la funzione registrata per nome tramite il motore JavaScript del visualizzatore (Acrobat, Foxit). Questo è utile per condividere una libreria di funzioni di supporto per la convalida, la formattazione o i calcoli tra molti widget, senza duplicare il codice JavaScript in ogni dizionario /A. Il metodo genera un errore in qualsiasi livello di conformità PDFA (ISO 19005-1 §6.6.1) e in qualsiasi livello di conformità PDFX (ISO 15930 flussi di lavoro di pre-stampa), e rifiuta nomi e corpi vuoti, nonché registrazioni di nomi duplicati.

2026-05-20 Version 2.119.13

  • Nuovo supporto per le miniature delle pagine: THPDFPage ora espone SetPageThumbnail(ImageIndex) e ClearPageThumbnail. I visualizzatori PDF (Acrobat, Foxit, visualizzatori del browser) utilizzano la voce /Thumb della pagina (ISO 32000-1 §12.3.4) per visualizzare un'anteprima predefinita nel pannello di navigazione senza rasterizzare la pagina, il che è particolarmente utile per archivi ricchi di immagini, dove il rasterizzatore del visualizzatore sarebbe lento. L'helper riutilizza qualsiasi immagine registrata tramite AddImage / AddImageFromFile, quindi i chiamanti possono preparare una bitmap di anteprima ridimensionata e allegarla con una singola chiamata; SetPageThumbnail(-1) o ClearPageThumbnail rimuovono una miniatura precedentemente allegata. Gli indici di immagine non validi generano un'eccezione descrittiva.

2026-05-20 Version 2.119.12

  • Correzione della conformità PDF/A: la funzione AddPushButtonWithAction ora genera un'eccezione quando vengono utilizzati i tipi di azione baJavaScript o baResetForm, indipendentemente dal livello di conformità PDFA (PDF/A-1/2/3). Le norme ISO 19005-1 §6.6.1 / ISO 19005-2 §6.5.1 / ISO 19005-3 §6.5.1 vietano l'utilizzo di JavaScript, ResetForm e ImportData in tutti i livelli PDF/A. Le azioni baSubmitURL (SubmitForm), baURI e baNone rimangono consentite in PDF/A; SubmitForm è presente nell'elenco delle azioni consentite nella sezione §6.6.1. In precedenza, i pulsanti potevano contenere azioni non consentite anche quando PDFACompliance era abilitato, poiché la protezione v2.119.54 copriva solo i percorsi Catalog /AA e OpenAction a livello di documento.
  • Correzione della conformità PDF/X: la funzione AddPushButtonWithAction ora genera un'eccezione quando vengono utilizzati i tipi di azione baJavaScript, baResetForm o baSubmitURL, indipendentemente dal livello di conformità PDFX. I flussi di lavoro di pre-stampa ISO 15930 escludono la programmazione interattiva, la modifica dei moduli e l'invio dei moduli a endpoint esterni.

2026-05-20 Version 2.119.11

  • Correzione della conformità PDF/A: i controlli del tipo di annotazione PDF/A impediscono il completamento. Le funzioni AddScreenAnnotation, Add3DAnnotation e AddRichMediaAnnotation ora generano un'eccezione quando PDFACompliance è abilitata a qualsiasi livello (PDF/A-1/2/3). Le norme ISO 19005-1 §6.5.2 / ISO 19005-2 §6.6.1 / ISO 19005-3 §6.6.1 vietano i sottotipi di annotazione Screen, 3D e RichMedia (multimedia / Estensione Adobe Livello 3) in tutti i livelli PDF/A. Gli stessi controlli sono implementati anche in PDFXCompliance: i flussi di lavoro di pre-stampa ISO 15930 rifiutano i sottotipi multimedia.
  • Correzione della conformità a PDF/A-1: le funzioni AddWatermarkAnnotation e AddRedactAnnotation ora generano un'eccezione quando PDFACompliance è impostato su PDF/A-1. Le annotazioni "Watermark" (PDF 1.6) e "Redact" (PDF 1.7) sono sottotipi di annotazioni incompatibili con la base PDF 1.4 di PDF/A-1 (ISO 19005-1 §6.5.2). PDF/A-2 e PDF/A-3 (con base PDF 1.7) continuano a supportare entrambi i tipi di annotazione.

2026-05-20 Version 2.119.10

  • Correzione della conformità PDF/A: `AddImageWithSMask` e `AddImageWithSMask32` ora generano un'eccezione quando `PDFACompliance` è impostato su PDF/A-1. ISO 19005-1:2005 §6.4 proibisce tutti gli effetti di trasparenza; uno stream /SMask di un'immagine attiva la composizione della trasparenza soft-mask. Pre-composita l'immagine su un colore di sfondo e passa il risultato a `AddImage()`, oppure utilizza PDF/A-2 o versioni successive per il supporto della trasparenza. PDF/A-2 e PDF/A-3 continuano a consentire la trasparenza soft-mask delle immagini.

2026-05-20 Version 2.119.9

  • Correzione della conformità PDF/A: `SetTransparencyGroup` e `SetTransparencyGroupICC` ora generano un'eccezione quando `PDFACompliance` è impostato su PDF/A-1. ISO 19005-1:2005 §6.4 proibisce tutti gli effetti di trasparenza; i gruppi di trasparenza a livello di pagina (dizionario `page /Group /S /Transparency`) attivano il modello di composizione della trasparenza per l'intera pagina, il che costituisce una violazione diretta del §6.4. PDF/A-2 e PDF/A-3 continuano a consentire i gruppi di trasparenza a livello di pagina.

2026-05-20 Version 2.119.8

  • Correzione della conformità PDF/A: RegisterHalftoneState ora genera un'eccezione quando PDFACompliance è attivo e viene fornito un dizionario halftone personalizzato (ovvero, HTDefaultName = false). ISO 19005-1:2005 §6.2.9 e ISO 19005-2:2011 / ISO 19005-3:2012 §6.3.7 consentono solo il nome letterale "/Default" per ExtGState /HT; i dizionari halftone personalizzati (di tipo 1, 5, 6, 10, 16) sono vietati. Passare HTDefaultName=True per ripristinare il valore predefinito del halftone continua a funzionare in tutti i livelli PDF/A.
  • Correzione della conformità PDF/A: RegisterSoftMaskState ora genera un'eccezione quando PDFACompliance è impostato su PDF/A-1 e viene fornito un dizionario soft-mask personalizzato (parametro SMaskDict). ISO 19005-1:2005 §6.4 proibisce tutti gli effetti di trasparenza; un valore /SMask diverso da None attiva la trasparenza del soft-mask. È ancora consentito passare SMaskNone=True per reimpostare i soft-mask. PDF/A-2 e PDF/A-3 continuano a consentire la trasparenza del soft-mask.

2026-05-20 Version 2.119.7

  • Correzione della conformità PDF/A: AddDocumentAttachment (incorporamento di file a livello di documento tramite Catalog /Names /EmbeddedFiles) ora genera un errore quando PDFACompliance è attivo per PDF/A-1 o PDF/A-3. ISO 19005-1:2005 §6.1.11 vieta esplicitamente la chiave /EmbeddedFiles nel dizionario Names del documento in PDF/A-1. Per PDF/A-3, gli allegati di documenti devono essere registrati tramite AddPDFA3AssociatedFile() per includere l'array /AF e la chiave /AFRelationship richiesti, come specificato in ISO 19005-3:2012, Appendice E. PDF/A-2 continua a consentire gli allegati di documenti, purché i file allegati siano essi stessi conformi a PDF/A.

2026-05-20 Version 2.119.6

  • Correzione della conformità PDF/A: l'utilizzo di font standard (Arial, Helvetica, Times New Roman, Courier New, Symbol, ZapfDingbats) con l'opzione StandardFontEmulation abilitata genera ora un'eccezione descrittiva quando PDFACompliance è attivo. ISO 19005-1:2005 §6.3 e ISO 19005-2:2011 / ISO 19005-3:2012 §6.3 richiedono che tutti i font siano incorporati nei file conformi; il percorso di emulazione dei font standard genera un riferimento a un font non incorporato, il che costituisce una violazione diretta del §6.3. Gli utenti devono impostare StandardFontEmulation su false oppure utilizzare RegisterUnicodeTTF() con i file dei font effettivi per l'output PDF/A.
  • Correzione della conformità PDF/A: le font non standard sono ora sempre incorporate quando PDFACompliance è attivo, indipendentemente dall'impostazione della proprietà FontEmbedding. L'ottimizzazione FontEmbedding = false viene silenziosamente sovrascritta in modalità PDF/A per soddisfare il requisito di incorporamento di tutte le font specificato nella sezione §6.3.

2026-05-20 Version 2.119.5

  • Correzione della conformità PDF/A: le azioni JavaScript e le voci /AA (azioni aggiuntive) a livello di catalogo sono ora bloccate quando PDFACompliance è attivo. ISO 19005-1:2005 §6.6.1/§6.6.2 e ISO 19005-2:2011 / ISO 19005-3:2012 §6.5.1/§6.6.2 vietano tutti i tipi di azioni JavaScript e proibiscono la chiave /AA nel dizionario del catalogo. La chiamata a SetActionScript con qualsiasi valore di PDFACompliance genera ora un'eccezione descrittiva. Come misura di sicurezza aggiuntiva, i percorsi di emissione di OpenAction JavaScript e Catalog /AA in EndDoc sono anch'essi controllati per saltare silenziosamente l'output quando PDFACompliance è attivo, garantendo che nessuna chiave non conforme venga scritta, nemmeno tramite percorsi interni.

2026-05-20 Version 2.119.4

  • Correzione della conformità PDF/A: AcroForm /NeedAppearances viene ora forzatamente impostato su false quando PDFACompliance è attivo, indipendentemente dall'impostazione di AutoFormAppearances. ISO 19005-1:2005 §6.9 e ISO 19005-2:2011 / ISO 19005-3:2012 §6.4 richiedono che questa chiave sia assente o impostata su false nei file conformi. In precedenza, se AutoFormAppearances era disabilitato mentre PDFACompliance era attivo, /NeedAppearances veniva impostato su true, generando un file non conforme.

2026-05-20 Version 2.119.3

  • Correzione della conformità PDF/A: le sottosezioni di CIDFont incorporate ora includono un flusso /CIDSet nel FontDescriptor quando PDFACompliance è attivo. ISO 19005-1:2005 §6.3.5 e ISO 19005-2:2011 / ISO 19005-3:2012 §6.2.11 richiedono che le sottosezioni di CIDFont contengano un bitstream /CIDSet che indica quali valori CID sono presenti nel programma di font incorporato. HotPDF utilizza la codifica Identity-H, dove il CID è uguale al codepoint Unicode, quindi il CIDSet viene creato direttamente dall'insieme di codepoint utilizzati nel documento. Il bitstream è compresso con FlateDecode e allegato al FontDescriptor esistente come oggetto stream indiretto. Questo corregge una lacuna precedentemente non rilevata in tutti i livelli PDF/A (la precedente verifica di conformità indicava erroneamente che questa funzionalità era già implementata).

2026-05-20 Version 2.119.2

  • Correzione della conformità a PDF/A-2 e PDF/A-3: il dizionario di aspetto delle annotazioni (/AP /N) viene ora generato automaticamente per i tipi di annotazioni che non sono link o popup (TextNotes, FreeText, Line, Square, Circle, Stamp, FileAttachment) quando PDFACompliance è impostato su un livello PDF/A-2 o PDF/A-3. ISO 19005-2:2011 §6.3.3 e ISO 19005-3:2012 §6.3.3 richiedono che ogni tipo di annotazione abbia almeno un dizionario di aspetto (con la forma XObject "N"). Viene generato un XObject di forma vuoto e minimale per soddisfare il requisito strutturale; la maggior parte dei visualizzatori PDF utilizza il proprio rendering integrato per i tipi di annotazioni standard, indipendentemente dal contenuto dello stream /AP. Le annotazioni di tipo Link e Popup sono esplicitamente escluse dallo standard e rimangono invariate. Questo requisito non si applica a PDF/A-1 (ISO 19005-1 §6.5.3 limita solo il formato di /AP quando è presente, non la sua presenza).

2026-05-20 Version 2.119.1

  • Correzione della conformità PDF/A: tutti i tipi di annotazioni non di tipo Widget (note di testo, timbri, linee, forme, collegamenti ipertestuali, collegamenti GoTo, collegamenti GoToR, collegamenti URI) ora impostano automaticamente il flag /F Print (bit 3 = 1, valore 4) quando PDFACompliance è attivo. L'ISO 19005-1:2005 §6.5.3 e l'ISO 19005-2:2011 / ISO 19005-3:2012 §6.3.2 stabiliscono che ogni dizionario di annotazioni deve contenere una chiave /F con il bit Print impostato. In precedenza, solo le annotazioni di tipo Widget (campi modulo) avevano questo flag; tutti gli altri tipi di annotazioni lo omettevano, rendendo i file prodotti non conformi.
  • Correzione della conformità a PDF/A-1: i gruppi di contenuto opzionali (livelli) sono ora bloccati quando PDFACompliance è impostato su un livello PDF/A-1 ('A' o 'B'). ISO 19005-1:2005 §6.1.13 vieta la chiave /OCProperties nel dizionario Catalog; la chiamata a RegisterOptionalContentGroup in modalità PDF/A-1 genera ora un'eccezione descrittiva che invita i chiamanti a utilizzare PDF/A-2 o versioni successive se è necessario il contenuto opzionale. Anche l'emissione di /OCProperties alla fine del documento è stata disabilitata per prevenire una non conformità silenziosa, anche se i gruppi di contenuto opzionali fossero stati registrati.

2026-05-20 Version 2.119.0

  • Supporto per il contenitore XAdES-in-PDF secondo ETSI EN 319 142-2 V1.2.0 §6.2 (chiusura della serie B/C/D, parte 3). Incorpora i byte XML firmati XAdES forniti dal chiamante come un PDF EmbeddedFile, registra il Filespec nell'array /AF del catalogo e imposta /AFRelationship in base all'enumerazione PDF 2.0 specificata dal chiamante. Si tratta solo di un wrapper lato produttore: la effettiva costruzione della firma XAdES (XML-DSig + Proprietà Qualificanti ETSI EN 319 132-1 + timestamp RFC 3161 incorporato in xades:UnsignedSignatureProperties) è responsabilità della libreria crittografica XML del chiamante (ad esempio, Apache Santuario, .NET SignedXml, libxmlsec, Saxon con estensioni XAdES, ecc.).
  • Nuovo metodo `THotPDF.AddXAdESAssociatedFile(FileName, XMLBytes, Description, MimeType, Relationship)`. Valori predefiniti: MimeType `'application/xml'` (comunemente anche `'application/vnd.etsi.asic-e+zip'` per gli archivi ASiC-E), Relationship `'Source'` (il file XML firmato XAdES è il contenuto principale del documento). Restituisce il dizionario Filespec indiretto in modo che i chiamanti possano aggiungere metadati aggiuntivi o creare riferimenti incrociati da voci personalizzate del catalogo.
  • Indipendentemente da PDF/A: a differenza di `AddPDFA3AssociatedFile` nella versione v2.108 (che richiede PDFACompliance='3*'), questa funzione non ha restrizioni legate a PDF/A; XAdES-in-PDF costituisce una famiglia di profili a sé stante, come specificato in PAdES Part 2 V1.2.0 §6.
  • È stato corretto un bug critico in `_EscapePDFNameBytes` (PDF 1.7 ISO 32000-1 §7.3.5 + Tabella 2). La funzione di escape precedente convertiva solo i byte al di fuori dell'intervallo [0x21..0x7E] e il carattere '#'; i delimitatori PDF (`/ ( ) < > [ ] { } %`) dovevano essere convertiti in `#XX` all'interno dei nomi, ma erano rimasti letterali. Nomi come `/Subtype /application/xml` venivano quindi interpretati da lettori rigorosi come due token di nome separati (/application seguito da /xml), causando problemi nel riconoscimento di EmbeddedFile /Subtype. Nella versione 2.119, tutti e 10 i delimitatori vengono convertiti secondo le specifiche; i nomi che non sono delimitatori (la stragrande maggioranza delle emissioni di HotPDF) rimangono identici a livello di byte. I tipi MIME di PDF/A-3 Annex E (versione 2.108) ora vengono generati correttamente (`/application#2Fxml` invece di `/application/xml` errato).
  • La serie PAdES B/C/D è stata completata con 3 commit: v2.117 (profili estesi E-BES / E-EPES / E-LTV secondo la Parte 2 §5) + v2.118 (valori iniziali secondo ISO 32000-1 §12.7.5.5 + Parte 2 §4.2.6) + v2.119 (XAdES-in-PDF + correzione dell'escape dei delimitatori secondo la Parte 2 §6.2). Insieme a v2.109 - v2.116, HotPDF copre l'intera gamma di funzionalità PAdES, inclusi i profili di base, i profili estesi, il timestamp del documento, le informazioni di validazione DSS, le estensioni ESIC, i vincoli di firma tramite valori iniziali e il contenitore XAdES-in-PDF.
  • Compilazione pulita per Win32 e Win64; le versioni di base dalla v2.108 alla v2.118 sono state ricompilate senza modifiche. Sono stati aggiunti nuovi test "smoke" per `smoke_pades_xades` con 2 percorsi positivi (file XML firmati XAdES come `/AFRelationship /Source` e archivio ASiC-E come `/Data`) e 4 percorsi di rifiuto (nome file vuoto, byte XML vuoti, tipo MIME vuoto, relazione non valida). Il verificatore Python esegue entrambi i percorsi di `Filespec` end-to-end, inclusi le forme di escape `/Subtype /application#2Fxml` e `/Subtype /application#2Fvnd.etsi.asic-e+zip`. I test "smoke" per PDF/A-3, PAdES e PDF/X della versione v2.108 sono stati rieseguiti e hanno avuto esito positivo.

2026-05-20 Version 2.118.0

  • I valori di seed PAdES, conformi a ISO 32000-1 §12.7.5.5 + ETSI EN 319 142-1 V1.2.1 §5.5 + ETSI EN 319 142-2 V1.2.0 §4.2.6 (passo 2 di 3 della serie B/C/D), sono un dizionario associato a un campo di firma che limita le opzioni che lo strumento di firma del lettore può scegliere per quel campo specifico: quale gestore utilizzare, quale SubFilter, quale metodo di digest, se le informazioni di revoca sono obbligatorie e quale versione minima di PDF è richiesta.
  • Nuovo metodo `THotPDF.AttachPAdESSeedValue(FieldName, SubFilters, DigestMethods, ForceSubFilter, ForceDigestMethod, AddRevInfo, MinPDFVersion, ForceMinPDFVersion)`. Cerca il campo di firma specificato nell'elenco dei campi di AcroForm (che deve essere già stato creato tramite una precedente chiamata a `AddPAdESSignatureField` o `AddDocumentTimestampSignature`) e associa una sottodirezziario /SV con i vincoli forniti dal chiamante.
  • Vengono emesse voci di "Seed Value" (come specificato nella Tabella 234):
    • `/Type /SV`
    • `/SubFilter` array di nomi — ad esempio, [/ETSI.CAdES.detached]
    • `/DigestMethod` array di nomi — ad esempio, [/SHA256 /SHA384 /SHA512]
    • `/AddRevInfo` booleano — lo strumento di firma deve includere OCSP/CRL nel CMS
    • `/V` numero — versione minima di PDF (ad esempio, 1.7)
    • `/Ff` interi, flag di bit (Tabella 235) — ogni parametro "Force*" imposta il bit corrispondente, quindi lo strumento di firma DEVE rispettare il vincolo (bit 2 = forza SubFilter, bit 3 = forza V, bit 6 = forza AddRevInfo, bit 7 = forza DigestMethod)
  • Regole di conformità alle specifiche: PAdES Parte 2 V1.2.0 §4.2.6 vieta l'utilizzo di valori iniziali che potrebbero costringere gli strumenti di firma a violare il profilo PAdES (ad esempio, specificando il SubFilter PKCS#1). HotPDF non applica questa regola lato produttore; è responsabilità del chiamante fornire solo valori consentiti dalle specifiche (`'adbe.pkcs7.detached'` o `'ETSI.CAdES.detached'` per SubFilter, SHA-256+ per DigestMethod). Il commento di documentazione fornisce informazioni dettagliate su questa limitazione.
  • Compilazione pulita per Win32 e Win64; le versioni di base da v2.108 a v2.117 sono state ricompilate senza modifiche. Il nuovo componente "smoke_pades_seedvalue" crea un campo PAdES-B-T e applica un insieme completo di vincoli di Seed Value (il SubFilter è limitato a ETSI.CAdES.detached, il DigestMethod è limitato a SHA256/384/512, AddRevInfo è impostato su true, MinPDFVersion è impostato su 1.7, tutte le opzioni forzate sono impostate). Il verificatore Python esamina il sotto-dizionario /SV e verifica la struttura di ogni elemento; inoltre, testa il percorso di rifiuto per i "FieldName" sconosciuti.
  • Serie, passaggio 3 (v2.119): Il contenitore XAdES-in-PDF, secondo la parte 2, versione 1.2.0, paragrafo 6, conclude la serie B/C/D. Dal lato del produttore, si tratta di un wrapper leggero che utilizza le funzionalità esistenti di HotPDF per EmbeddedFile / Catalog /AF (helper PDF/A-3, versione v.108), oltre alla semantica di /AFRelationship prevista dalla parte 2, versione 1.2.0, paragrafo 6.2.2, per i payload XML firmati con XAdES.

2026-05-20 Version 2.117.0

  • Profili PAdES estesi conformi a ETSI EN 319 142-2 V1.2.0 §5 (serie B/C/D, fase 1 di 3). La parte 1 definisce combinazioni fisse di attributi CMS; la parte 2 §5 definisce una famiglia parallela di profili "estesi" (E-BES / E-EPES / E-LTV) con maggiore flessibilità negli attributi CMS, per le applicazioni che richiedono funzionalità superiori rispetto alla configurazione di base (ad esempio, implementazioni aziendali con più policy, profili CAdES personalizzati all'interno dell'involucro PAdES).
  • `AddPAdESSignatureField`: il parametro del profilo ora accetta tre valori aggiuntivi, oltre ai quattro nomi di base:
    • `'E-BES'` — firma di base e univoca tramite l'attributo ESS del certificato di firma (equivalente a CAdES-BES all'interno dell'inviluppo PAdES). Budget predefinito di 16 KB per i contenuti.
    • `'E-EPES'` — E-BES + attributo di identificatore di politica di firma esplicito. Budget predefinito di 16 KB; in genere, il chiamante passa 18-20 KB per adattare i byte dell'OID della politica e dei qualificatori.
    • `'E-LTV'` — validazione a lungo termine con catena di certificati flessibile tramite attributo CMS + incorporamento della revoca. Aumenta automaticamente a un minimo di 20 KB (simile a B-LT).
  • Il formato interno utilizzato lato server è identico sia per i profili di base che per quelli estesi: tutti e sette utilizzano il SubFilter `ETSI.CAdES.detached`, lo stesso schema di sentinella `/ByteRange` + `/Contents` e la stessa infrastruttura DSS + ESIC (v2.110 / v2.116). La distinzione tra i livelli risiede interamente nella composizione degli attributi firmati CMS, che è prodotta dalla libreria crittografica del chiamante. La stringa del profilo varia solo nella diagnostica di validazione e nel budget predefinito di `/Contents`; HotPDF non codifica CAdES-BES rispetto a CAdES-EPES rispetto a CAdES-T direttamente nel dizionario PDF.
  • Aggiornata la documentazione di supporto di PAdES per evidenziare le responsabilità del chiamante, come specificato nella parte 2, versione 1.2.0, sezione 4.2: selezione dell'hash SHA-256 (eliminazione graduale di SHA-1), un singolo oggetto SignerInfo per ogni campo Sig, assenza di certificati di attributo RFC 5755 e il requisito di E-EPES di includere l'attributo firmato signature-policy-identifier. Gli elementi relativi al dominio del chiamante rimangono al di fuori dell'ambito del produttore, ma il contratto è ora esplicitamente definito nell'interfaccia API.
  • Compilazione pulita per Win32 e Win64; le baseline da v2.108 a v2.116 sono state ricompilate senza modifiche. `smoke_pades_signature` è stato esteso con 3 nuovi campi (SigEBES / SigEEPES / SigELTV), testando ogni nuovo valore di profilo attraverso i percorsi di ridimensionamento automatico, budget esplicito e budget predefinito. Il verificatore Python è stato esteso per analizzare tutti e 7 i campi e verifica l'estensione Catalog ESIC (portato avanti dalla versione 2.116).
  • Passo 2 della serie B/C/D: la versione 2.118 aggiunge i valori iniziali (PDF 1.7 §12.7.5.5 + ETSI EN 319 142-1 V1.2.1 §5.5 + Parte 2 V1.2.0 §4.2.6) in modo che i campi di firma PAdES possano dichiarare vincoli per il gestore/SubFilter/metodo di digest che il lettore deve rispettare durante la firma. Passo 3: la versione 2.119 aggiunge il supporto per il contenitore XAdES-in-PDF secondo la Parte 2 V1.2.0 §6 (XML firmato XAdES incorporato come EmbeddedFile + associazione Catalog /AF).

2026-05-20 Version 2.116.0

  • Aggiornamento di PAdES in base alle ultime versioni normative di ETSI e alla decisione di attuazione di eIDAS: ETSI EN 319 142-1 V1.2.1 (2024-01, pubblicato) + ETSI EN 319 142-2 V1.2.0 (2025-03, bozze aggiuntive di profili + famiglia di profili estesi + XAdES-in-PDF) + ETSI TS 119 142-3 V1.1.1 (2016-12, PAdES-DTS Document Time-stamp) + EU 2015/1506 (riconoscimento del settore pubblico). Le baseline di HotPDF v2.109 - v2.111 (B-B / B-T / B-LT / B-LTA + timestamp autonomo) continuano a soddisfare lo stesso formato, e questa versione risolve due problemi relativi alla generazione dei file che sono stati evidenziati dalle nuove versioni delle specifiche.
  • L'elemento del dizionario `/Type "DSS"` (EN 319 142-1 V1.2.1 §5.4.2.2). L'elemento `/Type` è facoltativo, ma se presente, deve essere il nome `/DSS`. HotPDF ora lo genera immediatamente, in modo che i validatori rigorosi che controllano `/Type` prima di analizzare il resto del dizionario riconoscano immediatamente la struttura.
  • ESIC extensions dictionary (TS 119 142-3 §5.1, raccomandato). Nuovo metodo `EnsurePAdESESICExtensions` che scrive in modo idempotente le seguenti informazioni nel catalogo ogni volta che viene invocato un helper PAdES: `<< /Extensions << /ESIC << /BaseVersion /1.7 /ExtensionLevel 1 >> >> >>`. I validatori (Adobe Acrobat pre-flight, EU DSS, callas pdfaPilot) utilizzano questa voce per identificare il documento come un contenitore PAdES che dichiara le estensioni di livello 1 per PDF 1.7 + ESIC.
  • Correzione di un bug critico nel percorso di andata e ritorno di `EnsurePAdESDSS`. Nelle versioni precedenti alla v2.116, la funzione ausiliaria risolveva nuovamente il dizionario DSS ad ogni chiamata tramite `Catalog.GetIndexedItem(FindValue('DSS'))`, il che restituiva il collegamento indiretto `THPDFLink` memorizzato nel catalogo, invece del dizionario DSS effettivo. La conversione a `THPDFDictionaryObject` causava silenziosamente un errore di tipo nel puntatore, facendo sì che ogni chiamata successiva a `AddPAdESDSSCertificate` / `AddPAdESDSSOCSP` / `AddPAdESDSSCRL` / `AddPAdESDSSVRI` saltasse silenziosamente l'aggiunta all'array (il riferimento all'array si risolveva in null, `FindValue` restituiva -1, e la condizione "if-Idx-less-than-zero-Exit" veniva eseguita). La correzione nella v2.116 memorizza nella cache il riferimento effettivo al dizionario nel campo `FPAdESDSSDict`, in modo che le chiamate successive accedano direttamente alla cache. Il test `smoke_pades_dss` ora genera correttamente 2 certificati + 1 OCSP + 1 CRL + 1 voce VRI (precedentemente, solo il primo certificato veniva inserito in `/DSS`, mentre gli array `/OCSPs` e `/CRLs` erano vuoti).
  • Aggiornamenti alla documentazione relativi alle funzioni di supporto PAdES, che evidenziano le responsabilità del chiamante, come specificato nella parte 2, versione 1.2.0, sezione 4.2: eliminazione graduale di SHA-1 (i chiamanti devono utilizzare SHA-256+ per CMS), un solo oggetto SignerInfo per firma PDF (parte 2, sezione 4.2.1 h / parte 1, sezione 4.1 a), i certificati degli attributi RFC 5755 non devono essere utilizzati (parte 2, sezione 4.2 g), e i documenti PAdES-DTS non devono contenere dizionari VRI (TS 119 142-3, sezione 6.3 h – DSS è sufficiente). Il formato interno di HotPDF, lato produttore, soddisfa già tutte e quattro le condizioni; il commento informa i chiamanti su cosa le loro librerie di costruzione CMS devono fare.
  • Compilazione pulita per Win32 e Win64; i test di verifica delle firme PAdES, dei DSS e dei timestamp dei documenti, insieme ai loro verificatori, sono tutti superati. Le estensioni del verificatore: `smoke_pades_dss` ora verifica `/Type /DSS` e `Catalog /Extensions /ESIC /BaseVersion /1.7 /ExtensionLevel 1`; `smoke_pades_doctimestamp` verifica la stessa estensione ESIC e accetta un rettangolo di area zero e con la pagina invertita verticalmente (`[0 H 0 H]` dove H è l'altezza della pagina). La documentazione di controllo e le note tecniche sono state aggiornate per fare riferimento a EN 319 142-1 V1.2.1 / Parte 2 V1.2.0 / TS 119 142-3 / EU 2015/1506.

2026-05-20 Version 2.115.0

  • PDF/X (ISO 15930) chiusura della serie di produttori (4/4): tipi di annotazioni e azioni proibiti secondo ISO 15930-1:2001 / ISO 15930-3:2002 / ISO 15930-7:2010 + ISO 32000-1 §12.5.6 / §12.6.4. I flussi di lavoro di stampa PDF/X utilizzano solo il contenuto stampabile visibile; le annotazioni multimediali, i file incorporati e le azioni interattive non hanno alcuna funzione nella stampa, quindi gli strumenti di pre-stampa (Adobe Acrobat, Enfocus PitStop, callas pdfaPilot) rifiutano i documenti che li contengono.
  • Tipi di annotazione non consentiti (rifiutati in qualsiasi caso di conformità PDFX ∈ {X-1a, X-3, X-4}):
    • FileAttachment: la stampa non elabora i file incorporati.
    • Suono: i contenuti multimediali non sono adatti ai flussi di lavoro di stampa.
    • Filmato: stessa motivazione relativa ai contenuti multimediali.
    Ogni punto di accesso (AddFileAttachmentAnnotation, AddSoundAnnotation, AddMovieAnnotation) ora genera un errore con il messaggio di diagnostica specificato e il valore di PDFXCompliance quando viene chiamato in qualsiasi profilo PDF/X.
  • Azioni non consentite (rifiutate in qualsiasi contesto di conformità PDF/X): Avvia, JavaScript, InviaModulo, ImportaDati, Video, Audio, ReimpostaModulo. I flussi di lavoro di prepressione devono evitare di attivare qualsiasi programma esterno; il file PDF deve essere utilizzato solo dalla stampante/RIP e non deve essere eseguito. La funzione AddLaunchLink ora genera un errore in qualsiasi profilo PDF/X (le altre azioni non sono esposte come API pubbliche da HotPDF, quindi vengono gestite automaticamente).
  • La serie PDF/X è ora completamente funzionale: v2.112 (opzionale + identità XMP + Trapped /Name) + v2.113 (OutputIntent + ICC GTS_PDFX) + v2.114 (controllo della trasparenza + applicazione delle dimensioni della casella di pagina) + v2.115 (impedisce l'aggiunta di annotazioni/azioni). Sono coperti tutti e tre i profili standard del settore (X-1a:2001, X-3:2002, X-4:2010). Chi chiama continua a creare contenuti di pre-stampa a livello di pagina (corretti valori CMYK, incorporamento dei font tramite il subsetter TTF v2.84, dimensioni di TrimBox corrispondenti al design, BleedBox quando è richiesto uno sbleeding), ma tutti i controlli di conformità strutturale sono implementati.
  • Compilazione pulita per Win32 e Win64; le baseline da v2.108 a v2.114 sono state ricompilate senza modifiche. `smoke_pdfx_optin` è stato esteso con 4 nuovi test di rifiuto (TestRejectFileAttachmentAnnot, TestRejectSoundAnnot, TestRejectMovieAnnot, TestRejectLaunchAction) che generano il tipo proibito in uno dei tre profili PDF/X e confermano un rifiuto corretto. In totale, i test ora coprono 11 scenari: 3 emissioni positive e 8 percorsi di rifiuto.
  • In questa release, sono state corrette due serie di versioni multiple parallele: PAdES (ETSI EN 319 142, versione 2.109 - 2.111, 3 commit, con supporto per B-B / B-T / B-LT / B-LTA e timestamp autonomo) e PDF/X (ISO 15930, versione 2.112 - 2.115, 4 commit, con tutti i controlli strutturali a livello di produttore per X-1a / X-3 / X-4).

2026-05-20 Version 2.114.0

  • PDF/X (ISO 15930) serie di implementazioni, sezione 3/4: gestione della trasparenza e applicazione delle dimensioni della pagina secondo ISO 15930-1:2001 / ISO 15930-3:2002 / ISO 15930-7:2010 + ISO 32000-1 §14.11.2. Questa sezione copre due restrizioni indipendenti che si applicano a ogni pagina; la struttura è simile al modello di trasparenza e funzionalità della pagina di PDF/A-1 nella versione v2.103.
  • Trasparenza (sezione 7.5): RegisterExtGState rifiuta valori alpha di riempimento inferiori a 1 (/ca), valori alpha di contorno inferiori a 1 (/CA) o modalità di fusione al di fuori di {Normale, Compatibile} quando PDFXCompliance è 'X-1a' o 'X-3'. PDF/X-1a (ISO 15930-1:2001) e PDF/X-3 (ISO 15930-3:2002) richiedono una base PDF 1.3, che precede la trasparenza PDF 1.4. PDF/X-4 (ISO 15930-7:2010, base PDF 1.6) consente esplicitamente la trasparenza, quindi il controllo non viene attivato con X-4. La diagnostica spiega la causa e suggerisce di passare a X-4 se è necessaria la trasparenza.
  • Applicazione delle caselle di pagina (§14.11.2): il nuovo metodo `EnsurePDFXPageBoxes` esamina ogni pagina e richiede la presenza di almeno una tra `/TrimBox` o `/ArtBox`. La sola `MediaBox` non è sufficiente perché rappresenta la tela di progettazione, non le dimensioni effettive della pagina che la tipografia deve conoscere per la rifilatura. In caso di caselle di pagina mancanti, viene generato un errore con l'indice della pagina (a partire da 1), il riferimento alla sezione della specifica e la firma consigliata per la chiamata a `SetTrimBox`. Il controllo `PDFXCompliance` alla fine del documento chiama automaticamente `EnsurePDFXPageBoxes` dopo il controllo `OutputIntent`.
  • Schema di chiamata tipica: dopo aver impostato PDFXCompliance, Trapped e AddPDFXOutputIntent, ogni pagina del documento deve includere `CurrentPage.SetTrimBox(Left, Bottom, Right, Top)` con le dimensioni del prodotto finito (ad esempio, 0 0 612 792 per US Letter, 0 0 595 842 per A4). L'uso di BleedBox è consigliato, ma non obbligatorio.
  • Compilazione pulita per Win32 e Win64; le baseline da v2.108 a v2.113 sono state ricompilate senza modifiche. `smoke_pdfx_optin` è stato esteso con: chiamata positiva a `SetTrimBox` in ciascuno dei 3 profili, gestione del rifiuto di `TrimBox` mancante, gestione del rifiuto di trasparenza X-1a (la chiamata a `RegisterExtGState` con `ca=0.5` genera un errore), gestione del percorso positivo per la trasparenza consentita X-4 (la stessa chiamata ha successo e `ExtGState` viene registrato). Il verificatore Python esamina ogni dizionario `/Type /Page` e verifica che sia presente almeno uno tra `/TrimBox` e `/ArtBox` per ogni pagina.
  • La versione v2.115 di PDF/X chiude la serie con il blocco di tipi di azione proibiti (JavaScript / Launch / SubmitForm / ImportData / Movie / Sound), tipi di annotazione proibiti (Movie / Sound / FileAttachment / Screen) e il rifiuto di AcroForm /XFA. I flussi di lavoro di stampa non prevedono l'uso di queste funzionalità; gli strumenti di controllo preliminare per utenti finali le segnalano come errori critici.

2026-05-19 Version 2.113.0

  • PDF/X (ISO 15930), serie di aggiornamenti, parte 2/4: applicazione obbligatoria di OutputIntent e profilo ICC secondo ISO 15930-1:2001 §6.2.2 / ISO 15930-3:2002 §6.2.2 / ISO 15930-7:2010 §6.2 + ISO 32000-1 §14.11.5. Ogni profilo PDF/X richiede almeno una voce di tipo /Type /OutputIntent /S /GTS_PDFX che specifica le condizioni di stampa di destinazione e fornisce il flusso del profilo ICC /DestOutputProfile; le tipografie utilizzano queste informazioni per abbinare i colori del PDF alla combinazione di macchina da stampa, carta e inchiostro utilizzata.
  • Una nuova funzione helper `AddPDFXOutputIntent(OutputConditionIdentifier, Info, ICCProfileStream, NumComponents, AlternateCS)` replica la funzionalità del wrapper PDF/A v2.102, ma genera il sottotipo GTS_PDFX invece di GTS_PDFA1. Verifica che `ICCProfileStream` non sia nullo e che `OutputConditionIdentifier` non sia vuoto; chiama `RegisterICCProfile` per incorporare il profilo (gestisce automaticamente la corrispondenza dello spazio colore alternativo con `NumComponents`) e `AddOutputIntent` per creare il dizionario `OutputIntent`.
  • Applicazione delle regole di EndDoc: quando PDFXCompliance è impostato, EnsurePDFXOutputIntent esamina l'array OutputIntents e richiede almeno una voce con /S /GTS_PDFX + /DestOutputProfile. In caso di voce mancante, viene generato un errore con il suggerimento dell'identificatore registrato (FOGRA39 per la stampa offset, CGATS TR 001 SWOP per il mercato nordamericano, Japan Color 2001 Coated per i mercati asiatici).
  • Flusso di lavoro tipico PDF/X: 1) `Doc.PDFXCompliance := 'X-4'`, 2) `Doc.Trapped := 'False'`, 3) caricare il profilo ICC CMYK (FOGRA39 / SWOP / ecc.) in un oggetto `TStream`, 4) `Doc.AddPDFXOutputIntent('FOGRA39 (ISO 12647-2:2004)', '', ICCStream, 4, 'DeviceCMYK')`, 5) progettare il contenuto, 6) `Doc.EndDoc` genera l'OutputIntent collegato dall'array /OutputIntents nel catalogo; gli strumenti di pre-flight (Adobe Acrobat, Enfocus PitStop, callas pdfaPilot) verificano l'associazione di gestione del colore.
  • Compilazione pulita per Win32 e Win64; le baseline v2.108, v2.109, v2.110, v2.111 e v2.112 sono state completamente ricompilate senza modifiche. `smoke_pdfx_optin` (originariamente v2.112) è stato esteso per: registrare un profilo ICC fittizio e aggiungere `AddPDFXOutputIntent` in ciascuna delle 3 emissioni di profili (X-1a → FOGRA39 CMYK, X-3 → SWOP CMYK, X-4 → sRGB RGB) e aggiungere un percorso di rifiuto che verifica che la mancata presenza di `OutputIntent` generi un errore. Il verificatore Python è stato esteso per scorrere ogni dizionario e confermare la presenza dell'entry `/Type /OutputIntent /S /GTS_PDFX` con `/DestOutputProfile`.
  • Le slice PDF/X rimanenti: la versione 2.114 aggiunge il controllo della trasparenza (X-1a / X-3 rifiutano alpha < 1 per fill/stroke e BM non-Normal; X-4 consente la trasparenza) e l'applicazione delle regole per le PageBox (ogni pagina deve avere TrimBox o ArtBox secondo la sezione §14.11.2); la versione 2.115 conclude la serie con il blocco di azioni proibite come /annot /XFA (Movie / Sound / FileAttachment / Screen / JavaScript / Launch / SubmitForm / ImportData / XFA, tutti rifiutati perché i workflow di stampa non prevedono queste funzionalità).

2026-05-19 Version 2.112.0

  • Iniziata la serie di prodotti per la prepressione PDF/X (ISO 15930). PDF/X è la famiglia ISO per l'invio di file PDF pronti per la stampa a tipografie commerciali; i profili X-1a (CMYK e colori speciali rigorosi), X-3 (gestione del colore tramite ICC) e X-4 (trasparenza PDF 1.6 + ICCN) sono i tre più utilizzati nel settore. La versione 2.112 è la prima parte di un progetto in quattro fasi: aggiunta di una proprietà opzionale e metadati di identificazione. L'audit completo e la roadmap per le prossime quattro versioni sono archiviati in .superpowers/specs/2026-05-19-pdfx-compliance-audit.md.
  • La nuova proprietà `PDFXCompliance: AnsiString` in THotPDF accetta `''` (disabilitato, predefinito), `'X-1a'` (ISO 15930-1:2001), `'X-3'` (ISO 15930-3:2002) o `'X-4'` (ISO 15930-7:2010). Impostare un valore diverso da una stringa vuota abilita automaticamente tutti i requisiti che HotPDF può soddisfare strutturalmente per quel profilo.
  • Nuova proprietà `Trapped: AnsiString` (obbligatoria in base a PDFXCompliance) che accetta i valori `'True'`, `'False'` o `'Unknown'`. La famiglia di formati PDF/X richiede questa voce in DocInfo, in modo che la tipografia sappia se il file PDF è già stato sottoposto al processo di "trappolatura" o se è necessario applicarlo nella fase di pre-stampa. Viene emessa come un oggetto PDF /Name (e non come una stringa), in conformità con la norma ISO 32000-1 §14.11.6.1; ad esempio, `<< /Trapped /False >>`.
  • Identificazione dei metadati XMP: il pacchetto ora pubblicizza `xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/"` con `` impostato sulla stringa esatta specificata (`PDF/X-1:2001`, `PDF/X-3:2002` o `PDF/X-4`) e (per X-1a + X-4) `` impostato sul nome completo del profilo (`PDF/X-1a:2001` o `PDF/X-4:2010`). Adobe Acrobat, Enfocus PitStop e callas pdfaPilot riconoscono il documento come un candidato PDF/X.
  • Validazione di EndDoc: rifiuta valori di profilo sconosciuti, rifiuta valori di "/Trapped" vuoti o non riconosciuti, richiede un titolo e aggiorna automaticamente la versione del PDF al valore minimo obbligatorio specificato nel profilo (X-1a/X-3 → PDF 1.3, X-4 → PDF 1.6). L'abilitazione della crittografia insieme a PDFXCompliance genera un errore; chiamare EnableEncrypt (o `ActivateProtection := True`) provoca un'eccezione con una descrizione chiara che indica che i flussi di lavoro PDF/X devono ispezionare ogni oggetto senza gestione delle password.
  • L'utente continua a definire l'OutputIntent e il profilo ICC, oltre a TrimBox/ArtBox, spazi colore validi per la pre-stampa e l'incorporamento corretto dei font (ed evita la trasparenza per X-1a/X-3) per garantire la piena conformità a PDF/X. Le versioni v2.113 - v2.115 colmano queste lacune: v2.113 aggiunge `AddPDFXOutputIntent` (intent obbligatorio /GTS_PDFX), v2.114 aggiunge un controllo sulla trasparenza e l'applicazione delle regole per PageBox, v2.115 conclude la serie con i controlli per azioni/annotazioni/XFA non consentite.
  • Compilazione pulita per Win32 e Win64; le versioni di base v2.108, v2.109, v2.110 e v2.111 sono state ricompilate senza modifiche. Il nuovo test "smoke_pdfx_optin" genera tre file PDF (uno per profilo) e verifica lo spazio dei nomi XMP, i valori GTS_PDFXVersion e GTS_PDFXConformance, oltre a DocInfo /Trapped /Name, e verifica anche i percorsi di rifiuto per profili non validi, valori "Trapped" vuoti o sconosciuti e conflitti di crittografia.
  • La serie di note PAdES nelle versioni v2.109 / v2.110 / v2.111 copre i casi d'uso B-B / B-T / B-LT / B-LTA e l'uso autonomo dei timestamp. La versione v2.112, originariamente pianificata (un PDF con solo timestamp ETSI.RFC3161), è di fatto implicita: la funzione `AddDocumentTimestampSignature` dalla versione v2.111 funziona su un documento nuovo senza una firma interna, quindi la serie PAdES è considerata completa con 3 commit e la versione v2.112 viene riallocata a PDF/X. Tutti i profili di base ETSI EN 319 142-1 sono supportati.

2026-05-19 Version 2.111.0

  • PAdES producer series, versione 3/4: supporto per la firma del timestamp del documento PAdES-B-LTA secondo ISO 32000-1 §12.8.5 + ETSI EN 319 142-1 §5.7. Il timestamp del documento è una seconda firma applicata DOPO che la firma di validazione a lungo termine è completa; copre l'intero file dello stato a lungo termine (firma originale + DSS) e dimostra che il materiale a lungo termine esisteva in un momento certificato. Questo è il profilo di archiviazione richiesto per la conservazione regolamentata dall'UE, che va oltre la durata del certificato CA originale.
  • Nuova funzione `THPDFPage.AddDocumentTimestampSignature(FieldName, ContentsBytes)` di supporto. A differenza di una firma PAdES standard, un timestamp di documento ha:
    • SubFilter `/ETSI.RFC3161` (un TimeStampToken RFC 3161, non CAdES).
    • Un rettangolo di widget con area zero (un timestamp non ha un aspetto visibile; contiene solo metadati crittografici).
    • Nessun campo /Reason, /Location o /ContactName (questi sono inclusi negli attributi firmati TST, non nel dizionario della firma).
    • Budget predefinito di byte per /Contents di 16 KB (il chiamante può passare un valore inferiore, fino a un minimo di 1 KB; un TST RFC 3161 completo con la catena di certificati è tipicamente di 4-8 KB).
  • La portata del generatore termina al formato binario: l'helper crea il dizionario segnaposto /Type /Sig con il SubFilter specifico del timestamp e un segnale /ByteRange + /Contents per la correzione successiva tramite PreparePDFForSigning + InsertSignatureHex. Il chiamante ottiene i byte TST effettivi secondo RFC 3161 da un'autorità di timestamp affidabile (TSA, ad esempio DigiCert / GlobalSign / FreeTSA tramite HTTP POST) e li inserisce. Il tipico flusso di lavoro di archiviazione PAdES-B-LTA prevede: 1) emissione della firma base PAdES-B-LT (v2.109), 2) popolamento di Catalog /DSS con la catena di certificati + OCSP/CRL (v2.110), 3) salvataggio come aggiornamento incrementale, 4) aggiunta del campo timestamp del documento sopra i byte dello stato LT (v2.111), 5) richiesta del timestamp al TSA sull'intervallo di byte, 6) inserimento dei byte del timestamp.
  • Compilazione pulita per Win32 e Win64; le versioni di base v2.108, v2.109 e v2.110 sono state ricompilate senza modifiche. Il nuovo componente "smoke_pades_doctimestamp" genera un campo "SigInner" conforme a PAdES-B-LT, oltre a un campo di timestamp del documento "DocTS", tramite una nuova funzione di supporto. Il verificatore Python assicura che la firma interna abbia "/SubFilter /ETSI.CAdES.detached", che il widget di timestamp abbia un rettangolo di area zero, che il dizionario "/V" del timestamp abbia "/SubFilter /ETSI.RFC3161" e non contenga i campi "/Reason", "/Location", "/ContactName", e che "/Contents" sia un segnaposto di 16 KB (32768 caratteri esadecimali).
  • La funzionalità PAdES rimanente: la versione 2.112 (opzionale) aggiunge la possibilità di includere PDF con timestamp ETSI.RFC3161 autonomi (nessuna firma interna CAdES, solo un documento contenitore di timestamp).

2026-05-19 Version 2.110.0

  • PAdES producer series, versione 2/4: supporto per il dizionario Document Security Store (DSS) secondo la norma ISO 32000-2 §12.8.4.3 + ETSI EN 319 142-1 §5.6. PAdES-B-LT (e B-LTA) richiedono che le informazioni relative alla validazione, come la catena di certificati, le risposte OCSP e le CRL, siano incorporate direttamente nel file PDF, in modo che le firme possano essere verificate anche molto tempo dopo la firma originale, senza la necessità di accedere a server PKI esterni.
  • Nuovi strumenti in THotPDF:
    • EnsurePAdESDSS — crea in modo "lazy" il dizionario indiretto /DSS con i suoi array /Certs, /OCSPs, /CRLs e un sottodizionario /VRI vuoto; le chiamate successive restituiscono il dizionario esistente.
    • AddPAdESDSSCertificate(CertDERBytes) — aggiunge un certificato X.509 codificato in DER come stream indiretto a /DSS /Certs; restituisce l'oggetto stream indiretto per l'uso nei riferimenti VRI.
    • AddPAdESDSSOCSP(OCSPDERBytes) — aggiunge una risposta OCSP BasicOCSPResponse a /DSS /OCSPs.
    • AddPAdESDSSCRL(CRLDERBytes) — aggiunge la lista di revoca dei certificati a /DSS /CRLs.
    • AddPAdESDSSVRI(SigContentsHexSHA1, Certs, OCSPs, CRLs) — crea una voce VRI specifica per ogni firma, indicizzata con l'hash SHA-1 in MAIUSCOLO dei byte di /Contents della firma (la chiave richiesta dalla specifica); ogni voce contiene gli array /Cert, /OCSP e /CRL che fanno riferimento agli stream indiretti creati in precedenza.
  • La portata del generatore di firme termina al formato binario. Il chiamante calcola ancora l'hash SHA-1 del contenuto firmato finale e fornisce i certificati DER-codificati, le risposte OCSP e le CRL dalla propria infrastruttura PKI. Il flusso di lavoro tipico è il seguente: si crea una firma di base PAdES-B-T (versione 2.109), quindi si aggiungono certificati, risposte OCSP e CRL al DSS per la verifica a lungo termine, quindi si aggiungono voci VRI che collegano le informazioni di validazione a specifiche firme.
  • Compilazione pulita per Win32 e Win64; le versioni di base v2.108 e v2.109 sono state ricompilate senza modifiche. Il nuovo test "smoke_pades_dss" crea un campo di firma PAdES-B-LT, aggiunge 2 certificati + 1 OCSP + 1 CRL a DSS e aggiunge una voce VRI con un digest esadecimale di test. Il verificatore Python analizza la struttura del dizionario DSS: il riferimento a /DSS nel catalogo, gli array /Certs, /OCSPs e /CRLs, verifica il conteggio degli elementi, la corrispondenza della chiave VRI e la corrispondenza dei riferimenti di certificato/OCSP/CRL nella voce VRI con gli array DSS di livello superiore.
  • Rimangono le funzionalità PAdES: la versione 2.111 implementa la firma temporale del documento PAdES-B-LTA (secondo campo Sig con SubFilter ETSI.RFC3161 che copre l'intero file LT); la versione 2.112 (opzionale) aggiunge file PDF autonomi contenenti solo la firma temporale.

2026-05-19 Version 2.109.0

  • Iniziato il lavoro per il generatore di firme digitali PAdES (ETSI EN 319 142). La versione v2.109 aggiunge un'interfaccia di alto livello all'infrastruttura di firma esistente ISO 32000-1 §12.8 (v2 dell'helper AddSignedSignatureField) che codifica in modo fisso il SubFilter richiesto da PAdES e convalida il profilo di conformità. L'audit completo e la roadmap a 4 versioni sono archiviati in .superpowers/specs/2026-05-19-pades-compliance-audit.md.
  • Nuova funzione `THPDFPage.AddPAdESSignatureField(FieldName, Rect, Profile, Reason, Location, ContactName, ContentsBytes, Flags)`. Il parametro Profile seleziona il livello di base ETSI EN 319 142-1: 'B-B' (CAdES di base, senza timestamp), 'B-T' (con timestamp affidabile RFC 3161, minimo per l'uso legale nell'UE), 'B-LT' (con informazioni di validazione DSS per la verifica a lungo termine) o 'B-LTA' (con firma di timestamp del documento per l'archiviazione). Tutti e quattro utilizzano il SubFilter 'ETSI.CAdES.detached'; il parametro profile varia le informazioni diagnostiche e il budget predefinito per i byte /Contents. Altre stringhe di profilo generano un errore, in base all'enumerazione ETSI.
  • Budget automatico per i contenuti: PAdES-B-B + B-T predefinito a 16 KB (il chiamante può specificare un valore inferiore; noi imponiamo un limite minimo di 64 byte, ereditato dalla versione 2.108). PAdES-B-LT aumenta automaticamente fino a un minimo di 20 KB (CAdES + catena di certificati + dati OCSP/CRL). PAdES-B-LTA aumenta automaticamente fino a un minimo di 24 KB (B-LT + timestamp del documento). I valori più grandi forniti dal chiamante vengono accettati; l'helper aumenta solo il limite minimo.
  • Ambito del produttore: il wrapper crea il dizionario segnaposto /Type /Sig con /SubFilter /ETSI.CAdES.detached, /Reason, /Location, /ContactName e /M (data di firma), e il sentinella /ByteRange + /Contents per la correzione successiva tramite PreparePDFForSigning + InsertSignatureHex. La gestione effettiva dei byte CMS / CAdES, il recupero del timestamp RFC 3161, la raccolta OCSP/CRL e la costruzione del dizionario DSS rimangono responsabilità del chiamante; queste operazioni richiedono una libreria crittografica esterna (OpenSSL, Bouncy Castle, Windows CAPI, ecc.) che esula dall'ambito del produttore PDF.
  • Compilazione pulita per Win32 e Win64. Il nuovo componente "smoke_pades_signature" genera quattro campi di firma PAdES (B-B / B-T / B-LT / B-LTA) e verifica che i valori di profilo non validi generino errori. Il verificatore Python asserisce che AcroForm /SigFlags sia 3, che ogni widget abbia /FT /Sig e un riferimento indiretto a un dizionario /Type /Sig con /SubFilter /ETSI.CAdES.detached, e che la lunghezza esadecimale del segnaposto in /Contents corrisponda alla dimensione prevista (aumentata automaticamente).
  • Tra le funzionalità PAdES ancora da implementare: la versione 2.110 aggiunge il costruttore del dizionario /DSS (Document Security Store) per le informazioni di validazione PAdES-B-LT (catena di certificati + OCSP/CRL); la versione 2.111 aggiunge il campo di firma di timestamp autonomo per l'archiviazione PAdES-B-LTA; la versione 2.112 (opzionale) aggiunge i PDF con timestamp solo ETSI.RFC3161.

2026-05-19 Version 2.108.0

  • PDF/A-2 + PDF/A-3: la serie di produttori è stata completata (4/4): ISO 19005-3 Allegato E, file associati. Una nuova funzione di supporto di alto livello, `AddPDFA3AssociatedFile(FileName, MimeType, Description, Relationship, FileBytes)`, consente di allegare un file arbitrario (fattura XML, foglio di calcolo sorgente, metadati JSON, ecc.) a un contenitore ibrido PDF/A-3 e di registrarlo nell'array /AF del catalogo, utilizzando la semantica /AFRelationship definita nella sezione E.4.
  • Flusso di container ibrido: un caso d'uso tipico è la fatturazione PDF/A-3 in stile ZUGFeRD, in cui la rappresentazione leggibile della fattura è contenuta nel flusso della pagina PDF e la sorgente XML leggibile dalle macchine è inclusa come file associato. La chiave `/AFRelationship` indica ai consumatori come il file allegato si relaziona al contenuto visibile: 'Source' (dati originali), 'Data' (dati grezzi visualizzati dal PDF), 'Alternative' (rappresentazione alternativa), 'Supplement' (materiale supplementare), 'Unspecified' (nessuna delle precedenti).
  • Spec gating: `AddPDFA3AssociatedFile` genera un errore se il valore di `PDFACompliance` non è PDF/A-3 (l'Appendice E è specifica per la parte 3), con un messaggio che suggerisce l'uso di `AddFileAttachmentAnnotation` per PDF/A-2, e che nota che PDF/A-1 §6.1.11 proibisce completamente gli allegati. Un `FileName` o `MimeType` vuoti generano un errore; un valore `Relationship` non valido genera un errore con l'elenco specificato nella sezione §E.4.
  • La struttura di emissione: uno stream EmbeddedFile indiretto contiene `/Type /EmbeddedFile` + `/Subtype ` + `/Params <>` + i byte del file. Il dizionario Filespec indiretto contiene `/Type /Filespec` + `/F` + `/UF (entrambi = FileName)` + opzionalmente `/Desc` + `/EF <>` + `/AFRelationship (chiave dell'Appendice E)`. L'array `/AF` nel catalogo viene creato in modo pigro alla prima aggiunta e viene esteso con chiamate successive. Il dizionario Filespec restituito consente alle chiamate di aggiungere opzionali chiavi aggiuntive (ad esempio, `/CI checksum/info`) quando necessario.
  • Compilazione pulita per Win32 e Win64. La nuova build "smoke_pdfa3_associated" crea una fattura ibrida PDF/A-3B con una vera fattura XML allegata come sorgente di "/AFRelationship", quindi verifica tre percorsi di rifiuto: PDF/A-1 rifiutato, PDF/A-2 rifiutato, "/AFRelationship" non valido rifiutato. Il verificatore Python asserisce il grafo del dizionario Filespec/EmbeddedFile (Type / F / UF / Desc / AFRelationship / EF F UF / EmbeddedFile Type / Subtype #2F escape / Params Size).
  • La superficie di produzione per PDF/A-2 + PDF/A-3 è ora completamente "audit-closed" (opzione v2.105 con wrapper e XMP, copertura vietata per annotazioni/azioni nella versione v2.106, limiti di implementazione della sezione v2.107 §6.1.13, allegato E con file associati nella versione v2.108). Poiché PDF/A-1 (versioni v2.101-104) e PDF/UA-1 (versioni v2.94-v2.100) sono già conformi in modo rigoroso, HotPDF copre ora l'intera matrice di produzione archivistica/di accessibilità PDF/A-1/2/3 + PDF/UA-1, dall'inizio alla fine.

2026-05-19 Version 2.107.0

  • PDF/A-2 + PDF/A-3 producer series, sezione 3/4: implementazione dei limiti definiti in ISO 19005-2 §6.1.13 + ISO 19005-3 §6.1.13. La sezione PDF/A-1 §6.1.13 è significativamente meno restrittiva (non prevede un limite massimo rigido per la lunghezza delle stringhe), quindi il nuovo controllo viene applicato solo quando PDFACompliance è impostato su PDF/A-2 o versioni successive ('2*' / '3*').
  • Il nuovo metodo pubblico EnsurePDFAImplementationLimits convalida i valori controllati dal chiamante nel documento rispetto ai limiti definiti nelle specifiche: le stringhe Doc.Title, Author, Subject, Keywords e Lang devono essere ≤ 32767 byte; le dimensioni di MediaBox di ogni pagina devono rientrare nell'intervallo [3..14400] unità. EndDoc invoca automaticamente il validatore quando PDFACompliance è impostato su PDF/A-2/3; i chiamanti possono anche invocarlo direttamente durante la compilazione per eseguire controlli preliminari.
  • I limiti, soddisfatti di default e documentati nel rapporto di audit, sono i seguenti: intervallo di interi (-2³¹..2³¹-1), intervallo di numeri reali (±3.403×10³⁸, quasi zero ≥1.175×10⁻³⁸), lunghezza del nome ≤127 byte, numero massimo di oggetti indiretti ≤8388607, livello di nidificazione q/Q ≤28, numero massimo di coloranti DeviceN ≤32, CID ≤65535. I percorsi di emissione di HotPDF non superano mai questi limiti perché sono legati alle strutture dati controllate dal produttore. Il validatore si concentra sulle stringhe fornite dal chiamante e sui margini della pagina, perché questi sono gli unici limiti che un chiamante reale può superare.
  • Form XFA (§6.4.2): HotPDF non genera AcroForm /XFA né Catalog /NeedsRendering. Entrambi vengono soddisfatti automaticamente in PDF/A-1/2/3; questo è documentato nel rapporto di controllo per evitare che estensioni future dei produttori li reintroducano.
  • .notdef glyph (§6.2.11.8 in PDF/A-2): la specifica vieta agli operatori di visualizzazione del testo di fare riferimento a .notdef. La gestione dei font di HotPDF evita questo problema quando i chiamanti utilizzano font TTF Unicode registrati (nella versione v2.74-v2.86), poiché il produttore associa ogni punto di codice a un glifo reale o rifiuta la registrazione. La responsabilità di gestire i percorsi di emissione del testo grezzo è a carico del chiamante; questo è documentato nel rapporto di controllo.
  • Spazio dei nomi XMP (§6.6.2): la specifica vieta l'utilizzo degli attributi "bytes" o "encoding" nell'intestazione del pacchetto XMP. La funzione BuildXMPPacket genera un'intestazione minimale (id="W5M0MpCehiHzreSzNTczkc9d") senza nessuno di questi attributi, il che soddisfa automaticamente i requisiti di tutte le parti PDF/A.
  • Compilazione pulita per Win32 e Win64. Sono stati aggiunti nuovi test "smoke" per "smoke_pdfa2_limits" con tre percorsi: il test PDF/A-2 supera i limiti; il test PDF/A-1 supera il limite di 32768 byte per il titolo (senza attivare la sezione §6.1.13); il test PDF/A-2 con un titolo di 32768 byte viene rifiutato con un messaggio diagnostico relativo alla specifica. Le precedenti baseline PDF/A-2/3 sono state ricompilate senza modifiche.
  • Rimane la parte relativa al producer per PDF/A-2/3: la versione v2.108 implementa PDF/A-3 Annex E, che riguarda i file associati (la funzionalità ibrida specifica per PDF/A-3: l'array /AF nel catalogo, contenente le specifiche dei file con la chiave /AFRelationship, insieme a EmbeddedFile /Params /CheckSum e /ModDate).

2026-05-19 Version 2.106.0

  • PDF/A-2 + PDF/A-3: implementazione della serie di funzionalità "producer slice 2/4", con copertura di PDF/A-2 §6.3.1 + §6.5.1 (e delle sezioni identiche di PDF/A-3 §6.3.1 + §6.5.1). Le restrizioni relative alle annotazioni e alle azioni, già attivate nella versione v2.104 per qualsiasi impostazione PDFACompliance non vuota, continuano a funzionare inalterate con PDF/A-2/3. La versione v2.106 conferma questo comportamento, aggiorna i messaggi diagnostici per fare riferimento alle sezioni specifiche delle diverse varianti PDF/A e documenta i sottotipi proibiti aggiunti in PDF/A-2, che HotPDF gestisce nativamente (senza percorsi di emissione pubblici).
  • Matrice delle azioni proibite: PDF/A-1 vieta 6 azioni (Avvia / Suono / Filmato / Reimposta modulo / Importa dati / JavaScript). PDF/A-2 + PDF/A-3 estendono l'insieme di azioni proibite a 13, aggiungendo Nascondi / Imposta stato OCG / Rendition / Trans / GoTo3DView, oltre all'insieme di sottotipi obsoleti / no-op. AddLaunchLink continua a generare errori; HotPDF non dispone di un'opzione pubblica che implementa le altre 12 azioni, quindi queste vengono automaticamente soddisfatte.
  • Matrice dei tipi di annotazione non consentiti: PDF/A-1 vieta l'uso di FileAttachment, Sound e Movie. PDF/A-2 e PDF/A-3 eliminano il divieto di FileAttachment (allentato nella versione v.105), ma aggiungono 3D e Screen all'elenco dei tipi non consentiti. Le funzioni AddSoundAnnotation e AddMovieAnnotation continuano a generare errori in tutte le versioni di PDF/A; HotPDF non supporta l'emissione di contenuti 3D o Screen, quindi queste funzionalità sono soddisfatte di default.
  • Aggiornamento dei messaggi diagnostici: le tre funzionalità v2.104 (AddSoundAnnotation, AddMovieAnnotation, AddLaunchLink) ora fanno riferimento a tutte e tre le sezioni specifiche pertinenti nel testo dell'errore (ad esempio, "PDF/A-1 §6.5.2 / PDF/A-2 §6.3.1 / PDF/A-3 §6.3.1"), in modo che gli sviluppatori possano vedere il divieto unificato. Il messaggio AddLaunchLink elenca inoltre l'insieme esteso di azioni proibite per PDF/A-2/3.
  • Compilazione pulita per Win32 e Win64. Il nuovo test "smoke smoke_pdfa2_annot_action" verifica le tre funzionalità per tutti e sei i livelli PDF/A-2/3 (2B, 2U, 2A, 3B, 3U, 3A); ogni chiamata verifica l'eccezione prevista con una diagnostica §6.3.1 / §6.5.1. I test di baseline PDF/A-1 precedenti (smoke_pdfa1_compliance / smoke_pdfa1_forbidden / smoke_pdfa1_annot_action) e il test v2.105 smoke_pdfa2_compliance sono stati ricompilati senza modifiche.
  • Rimangono le funzionalità relative a PDF/A-2/3: la versione v2.107 applica i limiti di implementazione definiti in ISO 19005-2 §6.1.13 (intervalli di byte per interi/reali/stringhe/nomi, nidificazione q/Q, coloranti DeviceN, CID, confini di pagina) + §6.4.2 XFA + §6.2.11, che impone una rigorosa conformità per i tipi 3 e per il carattere ".notdef"; la versione v2.108 implementa l'Allegato E di PDF/A-3, relativo ai file associati (contenitori ibridi PDF con tipi di file incorporati arbitrari).

2026-05-19 Version 2.105.0

  • È stata avviata una serie di quattro versioni per la conformità a PDF/A-2 (ISO 19005-2:2011) + PDF/A-3 (ISO 19005-3:2012). L'audit e la roadmap sono stati archiviati in .superpowers/specs/2026-05-19-pdfa2-pdfa3-compliance-audit.md. La versione v2.105 introduce l'opzione di attivazione del livello wrapper, estensioni dello spazio dei nomi XMP pdfaid, l'aggiornamento automatico della versione base del PDF a 1.7 e un allentamento selettivo delle restrizioni rigorose di PDF/A-1 introdotte nelle versioni v2.101-104, che sono esplicitamente consentite dalle specifiche PDF/A-2 / PDF/A-3.
  • La proprietà PDFACompliance ora accetta sei nuovi valori, oltre ai valori esistenti '' / 'A' / 'B': '2A' / '2B' / '2U' (livelli A / B / U di PDF/A-2) e '3A' / '3B' / '3U' (livelli A / B / U di PDF/A-3). Il livello U è la nuova categoria "solo preservazione di Unicode" introdotta da PDF/A-2 (testo visibile e estraibile in Unicode, senza la necessità di PDF con tag).
  • BuildXMPPacket esteso: l'elemento `` ora riflette il numero di parte analizzato (1 / 2 / 3) e `` riflette la lettera del livello analizzata (A / B / U). I validatori come veraPDF identificano la parte PDF/A del documento tramite questa coppia. In conformità a ISO 19005-2 §6.6.4 + ISO 19005-3 §6.6.4 Tabella 8.
  • Auto-incremento: PDFACompliance '2*' / '3*' incrementa automaticamente la versione del documento a PDF 1.7 perché sia PDF/A-2 che PDF/A-3 si basano su ISO 32000-1 (PDF 1.7). PDF/A-1 rimane ancorato a PDF 1.4.
  • v2.103: allentata la restrizione sulla trasparenza: RegisterExtGState genera ora un'eccezione solo quando si utilizza una modalità di fusione alfa trasparente / non normale, se PDFACompliance è impostato su PDF/A-1 rigoroso ('A' o 'B'). PDF/A-2 / PDF/A-3 §6.4 consentono esplicitamente la trasparenza (con requisiti specifici come la presenza di OutputIntent e le modalità di fusione denominate complete di PDF 1.4), quindi PDFACompliance impostato su '2*' / '3*' consente che la chiamata venga eseguita.
  • v2.104: le restrizioni relative a FileAttachment sono state allentate. La funzione `AddFileAttachmentAnnotation` genera ora un'eccezione solo in modalità PDF/A-1 restrittiva. Nel PDF/A-2 §6.3.1, sono proibiti solo i tipi di annotazione 3D/audio/video, mentre `FileAttachment` è consentito ed è alla base del workflow ibrido di file associati nell'Allegato E del PDF/A-3. Le altre restrizioni relative alle annotazioni/azioni (annotazioni audio/video; azione "Launch") rimangono attive in tutte le varianti PDF/A, in conformità con le sezioni condivise §6.3.1 e §6.5.1.
  • Nuovi metodi helper di THotPDF, PDFAPart / PDFAConformanceLevel / IsPDFA1Strict / IsPDFA2OrLater, rendono la gestione dei valori più efficiente. Le funzionalità PDF/A esistenti nelle versioni v2.101-104 ora utilizzano questi helper per un codice più pulito e messaggi di errore più chiari che suggeriscono di passare a PDF/A-2 / PDF/A-3 quando appropriato.
  • Compilazione pulita per Win32 e Win64; le baseline v2.101-104 (smoke_pdfa1_compliance / smoke_pdfa1_forbidden / smoke_pdfa1_annot_action) sono state ricompilate senza modifiche. Il nuovo test smoke smoke_pdfa2_compliance genera quattro file PDF (livelli 2B / 2U / 2A / 3U), verifica la gestione della trasparenza nella versione v2.103, la gestione degli allegati nella versione v2.104 e include due percorsi di validazione (un livello '4Q' non valido viene rifiutato; il controllo della trasparenza PDF/A-1 è ancora attivo). Il verificatore Python verifica la conformità XMP pdfaid:part e la corrispondenza per ogni livello, e il livello 2A presenta l'ereditarietà del Tagged-PDF.
  • Rimangono le funzionalità relative a PDF/A-2/3: la versione 2.106 estende l'insieme delle azioni proibite da 6 a 13 (sono state aggiunte le azioni Hide, SetOCGState, Rendition, Trans, GoTo3DView; sono state eliminate le azioni obsolete e quelle senza effetto) e modifica i divieti relativi ai tipi di annotazione (sono stati aggiunti i tipi 3D e Screen, è stato rimosso il tipo FileAttachment); la versione 2.107 applica i limiti di implementazione di ISO 19005-2 §6.1.13 e introduce restrizioni per XFA; la versione 2.108 implementa i file associati dell'Allegato E di PDF/A-3 (PDF ibridi contenitori).

2026-05-19 Version 2.104.0

  • La serie di aggiornamenti PDF/A-1 per il produttore è completa (slice 4/4): sono state eliminate le funzionalità non consentite (FileAttachment, Sound, Movie) secondo la sezione §6.5.2 e il sottotipo di azione di avvio secondo la sezione §6.6.1. Con l'implementazione della versione v2.104, tutte le 17 lacune riscontrate durante l'audit PDF/A-1 del 2026-05-19 (.superpowers/specs/2026-05-19-pdfa1-compliance-audit.md) sono state risolte: le quattro aree principali (§5, §6.7.11 identificazione, §6.1.3 divieto di crittografia, §6.2.2 OutputIntent, §6.4 trasparenza) e le varie funzionalità non consentite.
  • §6.5.2 tipi di annotazione non consentiti: AddFileAttachmentAnnotation, AddSoundAnnotation e AddMovieAnnotation generano ora un'eccezione in PDFACompliance, con un messaggio di errore che indica la sezione specifica della documentazione. Secondo le specifiche, "i tipi FileAttachment, Sound e Movie non devono essere consentiti" per evitare dipendenze da contenuti esterni e elementi multimediali nei file di archivio.
  • §6.6.1 Azione di avvio: `AddLaunchLink` ora genera un'eccezione in `PDFACompliance` con un messaggio diagnostico che specifica l'obiettivo dell'avvio. Secondo la specifica, "Le azioni di avvio, suono, filmato, ripristino modulo, importazione dati e JavaScript non devono essere consentite". Gli altri cinque sottotipi di azioni proibite (suono/filmato/ripristino modulo/importazione dati/JavaScript) non hanno un punto di ingresso pubblico in HotPDF che li generi, quindi sono soddisfatti di default senza meccanismi di controllo espliciti.
  • PDFUACompliance e PDFACompliance, combinati, ora funzionano correttamente in tutte e quattro le varianti di PDF/A. Le due opzioni si sovrappongono: il livello A eredita l'attivazione automatica di PDFUACompliance per i PDF con tag; entrambi i wrapper applicano le proprie protezioni specifiche (Sospetti/Schede/Lingua per PDF/UA; Crittografia/Trasparenza/Annotazioni/Azione per PDF/A) senza interferenze.
  • Riepilogo della chiusura delle verifiche: tutti i requisiti strutturali del formato file §6 relativi a PDF/A-1 che HotPDF può soddisfare sono ora stati risolti. Le responsabilità del chiamante rimanenti (§6.1.5 equivalenza Info-XMP, §6.2.3.3 corrispondenza tra spazio colore e OutputIntent, §6.3 specifiche dei font, dove il lavoro precedente nelle versioni da v2.74 a v2.86 per PDF/UA ha già gestito la maggior parte) sono allineate con le corrispondenti responsabilità del chiamante in PDF/UA-1.
  • Compilazione pulita per Win32 e Win64; v2.103, la build di test smoke_pdfa1_forbidden viene ricompilata correttamente. Il nuovo test smoke smoke_pdfa1_annot_action verifica tutti e quattro i percorsi (AddFileAttachmentAnnotation, AddSoundAnnotation, AddMovieAnnotation, AddLaunchLink) all'interno di PDFACompliance e verifica che ogni chiamata generi un errore con un codice di diagnostica §6.5.2 o §6.6.1.
  • L'area di produzione di PDF/A-1 è ora completamente chiusa per audit. Le estensioni future di PDF/A-2 (basata su ISO 19005-2:2011 e PDF 1.7, che consente trasparenza e livelli) e PDF/A-3 (ISO 19005-3:2012, che consente file incorporati per flussi di lavoro ibridi) rimangono potenziali candidati futuri, in attesa della richiesta degli utenti.

2026-05-19 Version 2.103.0

  • Serie di produttori PDF/A-1, sezione 3/4: sono stati risolti i problemi relativi alla trasparenza (sezione 6.4) (problema critico #15) e alla funzione di trasferimento /TR in ExtGState (sezione 6.2.8) (problema #14). Due sezioni della sezione 6, relative ai percorsi esistenti del produttore HotPDF, sono soddisfatte senza modifiche al codice: il filtro LZW (HotPDF utilizza solo FlateDecode nel suo percorso di scrittura) e l'interpolazione delle immagini (/Interpolate) (HotPDF non utilizza mai /Interpolate). Questi aspetti sono ora documentati come automatici nel rapporto di controllo.
  • §6.4 La trasparenza vieta l'uso di valori alpha diversi da 1.0 e modalità di fusione diverse da Normal/Compatible. La funzione RegisterExtGState ora verifica la conformità a PDF/A: un valore alpha inferiore a 1 per il riempimento genera un errore (PDF/A-1 richiede /ca = 1.0); un valore alpha inferiore a 1 per il tratto genera un errore (/CA = 1.0); una modalità di fusione diversa da `Normal` o `Compatible` genera un errore. Tutte e tre le verifiche indicano la sezione della specifica e il valore errato. Lo stato Esteso predefinito (senza chiavi alpha, senza modalità di fusione) e i valori espliciti consentiti (alpha pari a 1.0, modalità di fusione Normal/Compatible) rimangono invariati.
  • §6.2.8 ExtGState impedisce l'utilizzo della chiave di funzione di trasferimento /TR (obsoleta; PDF/A-1 consente solo /TR2 con il valore /Default, ed è preferibile evitarlo). RegisterTransferFunctionState ora genera un'eccezione in modalità PDFACompliance con un messaggio di errore chiaro. Chi ha bisogno di funzioni di trasferimento per i flussi di lavoro PDF/X può comunque utilizzare la funzione ausiliaria al di fuori della modalità PDFACompliance.
  • §6.1.10 LZW + §6.2.4 Interpolate: la conformità è documentata come soddisfatta naturalmente dai percorsi di generazione esistenti di HotPDF (solo writer FlateDecode, senza emissione di "/Interpolate"). Non sono necessarie modifiche al codice; è stato segnalato nei commenti del rapporto di controllo in modo che i chiamanti futuri non li reintroducano.
  • Compilazione pulita per Win32 e Win64; v2.102. La ricompilazione di `smoke_pdfa1_compliance` avviene senza errori. Il nuovo test `smoke smoke_pdfa1_forbidden` verifica tutti e tre i percorsi controllati (ca<1, CA<1, BM=Multiply, registrazione /TR) e verifica che i percorsi consentiti (ca=1.0, CA=1.0, BM=Normal/Compatible, senza alpha) continuino a funzionare. Non è presente alcun verificatore; il test stesso verifica tramite try/except che ogni chiamata controllata generi un'eccezione.
  • Nella versione v2.104, è stata implementata la parte rimanente del modulo PDF/A-1, che risolve i tipi di annotazione proibiti (§6.5.2) (FileAttachment, Sound, Movie), le regole per le annotazioni /F /AP (§6.5.3), i tipi di azione proibiti (§6.6.1) (Launch, Sound, Movie, ResetForm, ImportData, JavaScript) e i campi modulo /A /AA + /NeedAppearances (§6.9). Dopo il rilascio della versione v2.104, il modulo PDF/A-1 sarà completamente chiuso per le verifiche.

2026-05-19 Version 2.102.0

  • PDF/A-1 (ISO 19005-1:2005) producer series slice 2/4: è stato risolto il problema §6.2.2 relativo a OutputIntent e alla mancanza del profilo ICC. Una nuova funzione di alto livello `AddPDFAOutputIntent(OutputConditionIdentifier, Info, ICCProfileStream, NumComponents, AlternateCS)` semplifica l'operazione, combinando le chiamate precedenti a `RegisterICCProfile` e `AddOutputIntent('GTS_PDFA1', ...)` in un'unica operazione. PDF/A-1 richiede rigorosamente una voce con `/Type /OutputIntent /S /GTS_PDFA1` e un flusso ICC `/DestOutputProfile` valido; in assenza di questa voce, i file conformi non possono riprodurre accuratamente i colori su diverse piattaforme.
  • La funzione `EnsurePDFAOutputIntent` aggiunta al controllo `PDFACompliance` esegue le seguenti operazioni: itera l'elenco degli `OutputIntent` registrati, cerca almeno una voce con `/S /GTS_PDFA1` e `/DestOutputProfile`. In caso di assenza, viene generato un messaggio di errore che indica la sezione specifica e indirizza gli utenti a `AddPDFAOutputIntent`. In conformità con la sezione §6.2.2 e l'Appendice A.
  • Tipico flusso di lavoro di archiviazione: passare un flusso di profilo ICC sRGB IEC61966-2.1 per PDF/A ottimizzato per lo schermo, FOGRA39 / GRACoL per la stampa, oppure il profilo CMYK registrato appropriato per la pre-stampa. Il valore di NumComponents deve essere 1 (Gray), 3 (RGB / Lab) o 4 (CMYK) secondo la tabella 66 di PDF 1.7 §8.6.5.5; l'helper inoltra la validazione a RegisterICCProfile.
  • L'helper valida: un OutputConditionIdentifier vuoto genera un errore (la sezione §6.2.2 richiede l'identificatore); un ICCProfileStream nullo genera un errore (DestOutputProfile è obbligatorio). Non restituisce alcun valore; l'OutputIntent viene registrato automaticamente in FOutputIntents e reso disponibile tramite il percorso di serializzazione esistente del catalogo /OutputIntents.
  • Compilazione pulita per Win32 e Win64; `v2.101 smoke_pdfa1_compliance` aggiornato per chiamare `AddPDFAOutputIntent` (utilizzando un file ICC fittizio di 192 byte; le chiamate reali utilizzano un file ICC valido). Un nuovo caso di validazione verifica che la mancanza di `OutputIntent` in `PDFACompliance` generi un errore con la diagnostica §6.2.2. Il verificatore Python è stato esteso per controllare l'array `Catalog /OutputIntents`, analizzando le voci per trovare `/S /GTS_PDFA1` con un riferimento indiretto a `/DestOutputProfile`.
  • Sono stati risolti i seguenti problemi relativi a PDF/A-1: la versione 2.103 risolve i problemi relativi a (trasparenza, CRITICO), (filtro LZW), (interpolazione delle immagini) e (ExtGState /TR); la versione 2.104 risolve i problemi relativi a (allegati/audio/video), (regole per le annotazioni /F /AP), (azioni di avvio/audio/video/reset modulo/importazione dati/JavaScript) e (campi modulo /A /AA e /NeedAppearances).

2026-05-19 Version 2.101.0

  • È stata avviata una serie di quattro versioni di conformità PDF/A-1 (ISO 19005-1:2005) lato produttore, con l'opzione di attivazione del livello di wrapper. La relazione completa dell'audit, che identifica 17 aree di miglioramento, è archiviata in `.superpowers/specs/2026-05-19-pdfa1-compliance-audit.md`; la versione v2.101 introduce le funzionalità di base (proprietà PDFACompliance, identificazione XMP pdfaid, rigore per Titolo/Lingua, protezione contro i conflitti di crittografia). Le versioni v2.102 - v2.104 colmano le restanti lacune relative alla gestione del colore, alla trasparenza, ai font e alle annotazioni/azioni.
  • Nuova proprietà `PDFACompliance: AnsiString` che accetta '' (disabilitato, predefinito), 'A' (Livello A: visuale + PDF con tag + accessibilità) o 'B' (Livello B: solo conservazione visiva). I valori non validi generano un errore al termine del documento. In conformità con la norma ISO 19005-1:2005 §5, i livelli di conformità.
  • Impostando `PDFACompliance` su "A", anche `PDFUACompliance` viene abilitato automaticamente (il livello A eredita i requisiti di PDF con tag dalla sezione 6.8, che corrispondono ai requisiti di struttura logica della sezione 7 di PDF/UA-1). Entrambi i meccanismi possono essere combinati senza conflitti; il layer v2.94 PDF/UA-1 Lang/Title/Suspects si sovrappone ai controlli v2.101 PDF/A.
  • Impostando uno qualsiasi di questi livelli, la funzione `FEnableXMPMetadata` viene abilitata automaticamente, in modo che il documento contenga il flusso /Metadata XMP richiesto. Secondo la sezione §6.7.2, i metadati nel catalogo sono obbligatori.
  • BuildXMPPacket esteso: quando PDFACompliance non è vuoto, il pacchetto XMP dichiara `xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/"` insieme a `1` e `A` (o `B`). I validatori come veraPDF si basano esattamente su questa tripla per classificare il documento come candidato PDF/A-1A o 1B. Come specificato in §6.7.11, Tabella 6, schema di identificazione PDF/A.
  • Titolo / Rigore della lingua: Quando PDFACompliance è abilitato e Doc.Title è vuoto, viene generato un errore (PDF/A-1 §6.7.3 richiede dc:title in XMP, equivalente a Info /Title). Il rigore della lingua rispecchia il comportamento di PDFUACompliance nella versione 2.94 (§6.8.4 per il livello A), quindi gli autori devono scegliere un tag BCP-47 valido invece di ricevere un fallback silenzioso a "en".
  • Protezione contro i conflitti di crittografia: secondo la sezione 6.1.3, il trailer del file non deve contenere "/Encrypt". La funzione EnableEncrypt (la funzione interna chiamata quando vengono impostate le opzioni OwnerPassword/UserPassword/Protection) ora genera un'eccezione con un messaggio di errore chiaro quando PDFACompliance non è vuoto. La funzione EndDoc segnala il conflitto tramite lo stesso percorso, in modo che i chiamanti visualizzino l'errore prima della serializzazione.
  • La responsabilità del chiamante include ancora: generare un OutputIntent PDF/A-1 valido con profilo ICC (correzione della versione 2.102), evitare la trasparenza (versione 2.103), evitare tipi di annotazioni/azioni proibiti (versione 2.104) e creare una struttura semantica reale per il livello A (coperto dagli strumenti per PDF con tag versione 2.96-2.99).
  • Compilazione pulita per Win32 e Win64; la build di base smoke_pdfua_link_contents viene ricompilata correttamente. Il nuovo test smoke smoke_pdfa1_compliance genera sia file PDF di livello A che di livello B, e verifica tre percorsi di validazione (livello Z non valido, titolo vuoto, conflitto tra crittografia e PDFACompliance). Il verificatore Python verifica la presenza di xmlns:pdfaid + pdfaid:part=1 + corrispondenze per pdfaid:conformance, dc:title, e il livello A include inoltre /MarkInfo /Marked true + Catalog /Lang + /StructTreeRoot + xmlns:pdfuaid (ereditarietà automatica).

2026-05-19 Version 2.100.0

  • Corrette le lacune rimanenti nella copertura delle annotazioni di collegamento /Contents secondo PDF/UA-1 §7.18.5, rilevate durante l'audit del 2026-05-19. La versione v2.95 ha aggiunto la proprietà Description a AddURILink; la versione v2.100 estende lo stesso supporto per la descrizione alternativa ai tre punti di ingresso rimanenti per i collegamenti: AddGoToLink (salto all'interno del documento), AddGoToRLink (salto tra file) e AddLaunchLink (avvio di file esterni).
  • Ogni funzione ausiliaria acquisisce un parametro finale opzionale `const Description: AnsiString = ''`. Quando questo parametro non è vuoto, il dizionario delle annotazioni contiene una voce `/Contents (Description)`; in modalità `PDFUACompliance`, una descrizione vuota genera un errore con un messaggio chiaro che identifica il link target problematico, impedendo che una descrizione alternativa mancante venga ignorata silenziosamente. Il valore predefinito vuoto garantisce la compatibilità con le versioni precedenti al di fuori della modalità PDFUACompliance.
  • Secondo PDF/UA-1 §7.18.5, in modo rigoroso: "I collegamenti devono contenere una descrizione alternativa tramite la loro chiave Contents, come descritto in ISO 32000-1:2008, 14.9.3." Questa specifica si applica a tutti i tipi di annotazioni di collegamento, non solo ai collegamenti URI; le nuove firme di supporto rendono questo aspetto uniforme.
  • Flusso di lavoro tipico: `Page.AddGoToLink(R, 1, 700, 'Vai alla pagina 2: Metodologia'); Page.AddGoToRLink(R, 'companion.pdf', 0, -1, false, 'Apri il documento di accompagnamento per le tabelle dati complete'); Page.AddLaunchLink(R, 'readme.txt', false, 'Apri il file README nell'editor di testo predefinito');`
  • Compilazione pulita per Win32 e Win64; la build di base smoke_pdfua_figure è stata ricompilata correttamente. Il nuovo test smoke smoke_pdfua_link_contents crea un documento di 2 pagine con tre annotazioni Link nella pagina 0 (GoTo alla pagina 1, GoToR a 'companion.pdf', Launch a 'readme.txt') e verifica anche il percorso di eccezione empty-Description per PDFUACompliance per tutte e tre le annotazioni. Il verificatore Python asserisce che ogni annotazione Link contiene /Subtype /Link, il tipo di azione corrispondente /S /GoTo (o /GoToR o /Launch) e un valore /Contents corrispondente alla descrizione fornita.
  • Riepilogo della conformità PDF/UA-1: con la versione v2.100, tutti e quattro i punti di ingresso per le annotazioni di collegamento soddisfano ora la sezione §7.18.5. Insieme alla chiusura dell'audit della versione v2.94 (Suspects, Tabs, Lang), della versione v2.95 (URI Contents, Bit 10, ID) e della serie di strumenti semantici per PDF taggati delle versioni v2.96-v2.99 (Heading, List, Table, Figure), la conformità PDF/UA-1 di HotPDF è ora completamente verificata sia a livello di wrapper rigoroso rispetto alle specifiche che a livello di API intuitive.

2026-05-19 Version 2.99.0

  • Sono stati aggiunti `BeginTaggedFigure(Parent, AltText, BBox): FigureElem` e `EndTaggedFigure` come quarta e ultima parte della serie di strumenti semantici per PDF/UA-1 §7.3 (Grafica). Questi elementi racchiudono operazioni di disegno fornite dal chiamante (oggetti immagine, percorsi vettoriali, rettangoli riempiti) all'interno di una struttura Figure, con l'attributo di layout `/Alt` obbligatorio e l'attributo `/BBox` opzionale.
  • `/Alt` è obbligatorio (non è previsto un valore predefinito vuoto). Secondo PDF/UA-1 §7.3, in modo rigoroso: "I tag delle figure devono includere una rappresentazione alternativa o un testo sostitutivo che rappresenti il contenuto contrassegnato con il tag della figura". Un testo `Alt` vuoto genera un errore con una diagnostica chiara che indirizza i chiamanti all'overload di `AddStructureElement` con 6 argomenti nella versione 2.88, se `/ActualText` (e non `/Alt`) è il meccanismo di testo alternativo appropriato.
  • La BBox opzionale è un array di 4 valori [llx, lly, urx, ury] che descrive il riquadro di delimitazione della figura nello spazio utente predefinito, e viene allegato come /A << /O /Layout /BBox [...] >> secondo ISO 32000-1 14.8.5.4.5, che definisce il proprietario dell'attributo Layout. Passare un array vuoto per omettere completamente l'attributo BBox. Una BBox con un numero di elementi errato (1/2/3/5 o più) genera un errore, utilizzando il rettangolo specificato come guida.
  • Flusso di lavoro tipico: `Fig := Doc.BeginTaggedFigure(Root, 'Logo aziendale: freccia che punta a destra', [72, 600, 200, 720]); ... disegna il contenuto della figura ... Doc.EndTaggedFigure;` La figura fa parte della stessa struttura MCID / ParentTree di altri elementi, come introdotto in v2.90 BeginTaggedContent, ma con gli attributi /Alt e /BBox aggiunti automaticamente.
  • Questo risolve la sezione 7.3 relativa alla responsabilità del chiamante, come specificato in PDF/UA-1, come indicato nel rapporto di audit. La serie di strumenti semantici per PDF con tag ora copre tutti e quattro i tipi di struttura complessi: sezione 7.4 (intestazione, versione 2.96), sezione 7.6 (elenco, versione 2.97), sezione 7.5 (tabella, versione 2.98), sezione 7.3 (figura, versione 2.99). Insieme alle correzioni del livello di astrazione nelle versioni 2.94 e 2.95, la conformità di HotPDF allo standard PDF/UA-1 è ora rigorosa a livello di specifica E intuitiva a livello di API.
  • Compilazione pulita per Win32 e Win64; il test di base smoke_pdfua_table è stato ricompilato correttamente. Il nuovo test smoke smoke_pdfua_figure genera due elementi di struttura Figure (uno con /Alt + /BBox, uno con solo /Alt) e verifica anche i percorsi di eccezione per i casi di AltText vuoto e BBox malformati. Il verificatore Python asserisce entrambi i tipi di Figure /S, verifica che il contenuto del testo /Alt corrisponda e che i valori dell'array BBox siano [72, 600, 200, 720].

2026-05-19 Version 2.98.0

  • Sono stati aggiunti quattro helper per le tabelle con tag, conformi a PDF/UA-1 §7.5 (Tabelle), come terza parte della serie di helper semantici per PDF con tag. `BeginTaggedTable(Parent): TableElem` crea il contenitore della struttura della tabella; `AddTaggedTableRow(Table): TRElem` aggiunge una riga TR; `EmitTaggedTableHeader(TR, X, Y, Text, Scope): THElem` genera una cella TH con l'attributo obbligatorio /Scope; `EmitTaggedTableCell(TR, X, Y, Text): TDElem` genera una cella di dati TD. Tutti e cinque i tipi di tag (Table, TR, TH, TD e l'oggetto attributo) sono conformi alle specifiche.
  • L'attributo /Scope (ISO 32000-1 14.8.5.7 Tabella 350) è obbligatorio nell'elemento helper (senza valore predefinito), con valori validi `Row`, `Col` o `Both`. Stringhe /Scope non valide generano un errore, in conformità con le specifiche. PDF/UA-1 §7.5 è molto preciso: "Gli elementi strutturali di tipo TH devono avere un attributo /Scope. Se la struttura della tabella non può essere determinata tramite intestazioni e ID, allora gli elementi strutturali di tipo TH devono avere un attributo /Scope." Forzare l'attributo /Scope nella firma dell'elemento helper previene il mancato rispetto della conformità relativa all'attributo /Scope.
  • La serializzazione dello scope segue lo standard degli oggetti attributo: `/A << /O /Table /Scope / >>` (come definito in ISO 32000-1 14.7.5.3 Class Map), in modo che i lettori possano interpretarlo come un attributo nello spazio dei nomi Table. Questo segue lo stesso schema dell'attributo List introdotto nella versione v2.97: `/A << /O /List /ListNumbering ... >>`.
  • Le tabelle e i tag `TR` sono semplici contenitori strutturali (senza contenuto formattato nella pagina), ma i tag `TH` e `TD` contengono testo visibile, quindi entrambi vengono elaborati tramite `BeginTaggedContent + TextOut + EndTaggedContent`. Ogni cella `TH` e `TD` riceve il proprio MCID, l'operatore `BDC` nel flusso del contenuto della pagina e una voce `ParentTree`. Una funzione di supporto restituisce l'elemento `StructElem` della cella per i chiamanti che desiderano aggiungere ulteriori attributi (ad esempio, l'elenco `/Headers` per tabelle complesse, `/RowSpan`, `/ColSpan`).
  • Flusso di lavoro tipico: `T := Doc.BeginTaggedTable(Root); R := Doc.AddTaggedTableRow(T); Doc.EmitTaggedTableHeader(R, 72, 750, WideString('Name'), 'Col'); Doc.EmitTaggedTableHeader(R, 200, 750, WideString('Age'), 'Col'); R2 := Doc.AddTaggedTableRow(T); Doc.EmitTaggedTableCell(R2, 72, 730, WideString('Alice')); ...` Sostituisce la struttura a più passaggi della versione 2.90, oltre alla sequenza BDC/EMC per ogni cella.
  • Questo risolve la sezione 7.5 relativa alla responsabilità del chiamante, come specificato in PDF/UA-1, come indicato nel rapporto di audit. La serie di strumenti semantici per PDF con tag ora copre la sezione 7.4 (Intestazione, versione 2.96), la sezione 7.6 (Elenco, versione 2.97) e la sezione 7.5 (Tabella, versione 2.98). La parte rimanente (versione 2.99+): strumento per le figure per la sezione 7.3, con /BBox + /Alt + blocco di disegno fornito dal chiamante.
  • Compilazione pulita per Win32 e Win64; la build di base smoke_pdfua_list è stata ricompilata correttamente. Il nuovo test smoke smoke_pdfua_table crea una tabella di 3 righe (1 intestazione + 2 dati) con 3 celle TH (Scope=Col) + 6 celle TD e verifica l'eccezione "invalid-Scope". Il verificatore Python asserisce la struttura completa Table > TR > TH/TD con /Scope /Col su ogni TH.

2026-05-19 Version 2.97.0

  • Sono stati aggiunti due helper per le liste PDF/UA-1 §7.6 come parte della serie di helper semantici per PDF taggati: `BeginTaggedList(Parent, NumberingStyle): ListElem` crea l'elemento strutturale L con un oggetto attributo /A << /O /List /ListNumbering <