HotPDF Versionshinweise

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

  • Die Delphi-Demo PreflightReport wurde von einem console sample zu einem interaktiven VCL GUI tool für single-file preflight workflows ausgebaut.
  • Die GUI unterstützt jetzt standardmäßige Text-, JSON- und HTML-Berichte, optionale Passwörter, profile INI files, integrierte presets, single-file PDF/VT validation, embedded-report PDF output, report preview, status logging, automatic output naming und schnellen Zugriff auf erzeugte Dateien.
  • Das alte Startverhalten wurde entfernt: Ohne command-line arguments werden kein sample PDF und kein report mehr automatisch erzeugt.

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 verwendet für Unicode-Ausgaben aus den Ergänzungsebenen jetzt wieder die von RegisterUnicodeTTF erzeugte Type-0-Schriftressource, sodass Seitentext und AcroForm-Darstellungsstreams denselben internen CID-Codierungspfad nutzen.
  • Der gemeinsame Finalisierungslauf hält die SMP-Ausgabe auf Seitenebene nun über FUnicodeUsedCps, /CIDToGIDMap, die /W-Einträge der Descendant Font und /ToUnicode synchron und vermeidet die ältere seitenlokale SMP-Zuordnung.

2026-05-24 Version 2.121.2

  • THPDFPage.UnicodeTextOut leitet jetzt Unicode-Zeichen aus der erweiterten Zeichenebene über die im Seitenschriftfont registrierte cmap-Format-12-Glyph-Zuordnung, wenn RegisterUnicodeTTF die aktive Schriftart geladen hat. Emojis und andere U+10000+-Skalare werden als ein einzelnes CID-Glyph im Seitentext-Stream ausgegeben, anstatt als zwei Surrogate-Halb-CIDs.
  • Die Seitenschrift verwendet den `ToUnicode`-CMap, um diese SMP-Glyphen-CIDs wieder in das ursprüngliche UTF-16BE-Surrogatenpaar zurückzuverwandeln, wodurch die Textextraktion und Barrierefreiheit erhalten bleiben, während der bestehende Pfad für die Seitenschrift, nämlich `/CIDToGIDMap /Identity`, beibehalten wird.

2026-05-24 Version 2.121.1

  • Die mit RegisterUnicodeTTF erstellten AcroForm-Darstellungsstreams rendern jetzt Unicode-Zeichen aus dem erweiterten Zeichenbereich, wie z. B. Emojis, über ein einzelnes internes CID anstelle von zwei Identity-H-CIDs, die als UTF-16-Surrogatpaar geschrieben würden. Die generierten /CIDToGIDMap-Einträge verweisen dieses CID auf das tatsächliche Glyphe, und /ToUnicode ordnet es wieder dem ursprünglichen UTF-16BE-Surrogatpaar für die Textextraktion zu.
  • Der Unicode-Schriftarten-Finalisierungsschritt aktualisiert /CIDToGIDMap, /W und /ToUnicode, nachdem alle Darstellungsstreams ihre späten internen CID-Zuordnungen registriert haben, sodass TrueType-Subsetting und generierte Formulardarstellungen den endgültigen CID-Nutzungssatz verwenden.

2026-05-23 Version 2.121.0

  • PDF 1.7 §12.6.4.13–15: Multimedia-Aktionen (Wiedergabe / Ton / Video) erhalten drei neue Hilfsmethoden für Schaltflächen auf `THPDFPage`: `AddPushButtonWithRenditionAction` für §12.6.4.13 (verknüpft eine Bildschirm-Annotation mit einem MediaRendition + MediaClipData, die den Audio-/Video-Clip beschreiben, und einer /OP-Operation 0–4); `AddPushButtonWithSoundAction` für §12.6.4.14 mit zwei Varianten (Dateipfad oder rohe `TBytes`-Daten), einem vom Aufrufer bereitgestellten `THPDFSoundParams`-Datensatz (Abtastrate / Kanäle / Bits pro Sample / Kodierung) und optionalen Parametern für Lautstärke, Wiederholung und Synchronisation; `AddPushButtonWithMovieAction` für §12.6.4.15 (referenziert eine Video-Annotation über /Annotation und wählt die Operation "Wiedergabe", "Stopp", "Pause" oder "Fortsetzen").
  • `AddScreenAnnotation` und `AddMovieAnnotation` geben jetzt das erstellte Annotation-Dictionary zurück, sodass Aufrufer es in den entsprechenden Action-Helper integrieren können. Die Änderung von `procedure` zu `function` ist ABI-kompatibel für Delphi – bestehende Aufrufer, die diese Funktionen aufrufen und das Ergebnis verwerfen, können weiterhin kompiliert werden und erzeugen byte-identische PDFs.
  • Standardimplementierungstiefe: Jeder Helfer gibt die vom Standard geforderten Einträge sowie die häufig benötigten optionalen Felder aus (Sound/Lautstärke/Wiederholung/Synchron; Wiedergabe/JavaScript). Optionale MediaPlayParameters, MediaScreenParameters, SelectorRendition und Sound/Mix werden absichtlich weggelassen – die Standardeinstellungen des Leseprogramms decken 95 % der Anwendungsfälle ab, und die Helfer bleiben so minimal wie möglich.
  • PDF/A (alle Stufen) und PDF/X (alle Profile) lehnen alle drei Multimedia-Aktionen beim Zugriff des Hilfsprogramms ab und geben eine ISO-referenzierte Diagnose aus (ISO 19005-1 §6.6.1 / ISO 19005-2 §6.5.1 / ISO 19005-3 §6.5.1 / ISO 15930). Die bestehenden Annotationseinstellungen für `AddScreenAnnotation`, `AddSoundAnnotation` und `AddMovieAnnotation` bleiben unverändert.
  • Die Rendition-Aktion verknüpft die MediaClipData-Dateispezifikation mit den Medienberechtigungen (/P /TF (TEMPACCESS)) gemäß §13.2.6.1 Tabelle 280 – dem minimalen Berechtigungslevel, das es dem Leser ermöglicht, die Daten an die Audio-/Video-Codecs der Plattform weiterzuleiten.
  • Sound-Aktionen setzen standardmäßig optionale Felder auf die in der Spezifikation definierten Werte (Lautstärke=1.0, Wiederholung=false, Synchron=false) und geben sie nur dann aus, wenn der Aufrufer Nicht-Standardwerte übergibt, wodurch das Aktions-Dictionary für den häufigsten Fall so klein wie möglich gehalten wird.
  • 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.
  • Überprüft mit der neuen Win32 + Win64. Die Tests `smoke_multimedia_actions` (positive-path-Abdeckung aller vier Aktionen + Verkettung von Bildschirm-/Video-Annotationen) und `smoke_multimedia_actions_pdfa_pdfx` (8 Assertions, die 3 Aktionen × PDF/A + PDF/X abdecken) sind erfolgreich. Der Regressionstest `smoke_button_actions` läuft weiterhin problemlos, nachdem die Prozeduren `AddScreenAnnotation` und `AddMovieAnnotation` in Funktionen umgewandelt wurden.

2026-05-23 Version 2.120.15

  • Behebung: `EndDoc` serialisierte den PDF-Objektgraphen, bevor zwei Nachbearbeitungsschritte (der TrueType-Subsetter aus v2.84.0 und der PDF/UA-1 §7.18.3 /Tabs /S Auto-Stamper aus v2.94.0) ausgeführt wurden, sodass keine der Änderungen in der erstellten Datei wirksam wurde. Dokumente, die `RegisterUnicodeTTF + AddTextField` verwendeten, enthielten die vollständige Schriftdatei (~1 MB lateinisch / ~14 MB CJK) anstelle des Subsets (~150 KB / ~500 KB), der `/BaseFont` enthielt nicht das sechsstellige Subset-Präfix AAAAAA, der PDF/A `/CIDSet`-Stream im FontDescriptor fehlte (veraPDF meldete einen Fehler gemäß ISO 19005-1 §6.3.5 / -2 -3 §6.2.11), und PDF/UA-1-PDFs, denen der Schlüssel §7.18.3 /Tabs /S auf annotierten Seiten fehlte, führten zu einem Fehler in der Matterhorn-Prüfregel 21-001 und PAC 3 "Tabs".
  • Beide Mutatoren werden jetzt VOR dem Speichern in einen Stream oder einer Datei ausgeführt. Sie durchlaufen die Liste der indirekten Objekte und schreiben die PDF-Datei. Die Ausgabe ist byte-identisch zu v2.120.14 für Dokumente, die weder eine Unicode-TTF-Datei registrieren noch PDFUACompliance aktivieren; in diesen Fällen waren beide Mutatoren bereits inaktiv, so dass die Änderung der Reihenfolge nur Dokumente betrifft, deren Ausgabe in v2.120.14 stillschweigend fehlerhaft war.
  • Überprüft mit dem Win32 smoke_unicode_ttf_subset (der Subset umfasst 33,6 % der on-disk Arial-Datei – 676 KB wurden gespeichert – /BaseFont Präfix UYENHH+ArialMT, konsistent über Type 0 / CIDFontType2 / FontDescriptor.FontName) und dem Win32 smoke_pdfua_annot_structparents (/Tabs /S wurde auf der annotierten Seite im Dictionary gestempelt, alle fünf §7.18.3 + Annotation-Struktur-Verbindungsprüfungen sind grün).

2026-05-23 Version 2.120.14

  • PDF/UA-1 strikte Struktur- und Rollenprüfung (ISO 14289-1 §7.7 + ISO 32000-1 §14.7.3): Wenn PDFUACompliance aktiviert ist, verwirft AddStructureElement jetzt jede "/S"-Rolle, die weder einer der 41 Standardstrukturtypen gemäß PDF 1.7 §14.8.4 Tabelle 333 entspricht (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), noch eine benutzerdefinierte Rolle, die der Aufrufer zuvor über AddStructRoleMap registriert hat. Die diagnostische Ausnahme enthält die betreffende Rollenbezeichnung, verweist auf PDF/UA-1 §7.7 / Tabelle 333 und schlägt die Verwendung von AddStructRoleMap zur Behebung vor. Eine leere Rolle wird ebenfalls mit einer speziellen Meldung abgelehnt. Ohne diese Prüfung würden nicht konforme Rollen stillschweigend in den Strukturbaum gelangen und sich als "unbekannter Strukturtyp" in nachgelagerten veraPDF / PAC-Tools manifestieren.
  • Das neue Gate wird nur ausgelöst, wenn PDFUACompliance auf True gesetzt ist; Aufrufer, die nicht PDFUA verwenden, behalten das vorherige Verhalten für die Freiform-Rolle, byte für byte. Alle vier AddStructureElement-Überladungen (die 4-Argumente-AnsiString-Basis, die v2.88.0 6-Argumente-/Alt + /ActualText-Überladung, die v2.95.0 7-Argumente-/ID-Überladung und die v2.119.41 THPDFStandardStructureType-Enum-Überladung) konvergieren auf den gleichen Pfad, sodass ein einzelner Schutzmechanismus ausreicht. Die Enum-Überladung übergibt immer einen Namen aus Tabelle 333 und besteht daher immer die Prüfung – Aufrufer bevorzugen sie, um den Tippfehler oder die Gefahr von Groß-/Kleinschreibungsproblemen (z. B. 'Para' vs 'P', 'Lbody' vs 'LBody') zur Kompilierzeit zu vermeiden.
  • v2.119.41 hat bereits den THPDFStandardStructureType-Enum eingeführt (41 Spezifikationsnamen, gruppiert in 5 PDF-Rollenkategorien: §14.8.4.1 Gruppierung / §14.8.4.2 Blockebene / §14.8.4.3 Inlineebene / §14.8.4.4 Ruby+Warichu / §14.8.4.5 Illustration), StandardStructureTypeToName(T) für die Enum-zu-Name-Zuordnung und IsStandardStructureType(Name) für die Validierung durch den Aufrufer; v2.120.14 integriert diese Funktionen in den AddStructureElement-Einstiegspunkt, sodass die strenge Prüfung automatisch erfolgt. Ein neuer privater Helfer, _IsCustomRoleInRoleMap, durchläuft das dynamische Array FStructRoleMap mit einem byteweisen Vergleich (CompareMem) und findet benutzerdefinierte, nicht-ASCII-Rollennamen korrekt auf Hosts mit CP_ACP=65001.

2026-05-23 Version 2.120.13

  • Behebung: Die Quellcode-Datei von HotPDF v2.120.12 konnte in RAD Studio nicht kompiliert werden, da die beiden Überladungen von `EnableShapingFeatureForSubset` innerhalb des veröffentlichten Bereichs von `THotPDF` lagen, was von Delphi mit dem Fehler E2266 abgelehnt wurde ("nur eine der überladenen Methoden kann veröffentlicht werden"). In v2.120.13 werden die beiden Überladungen durch ein lokalisierte öffentliche Bereichspaar umschlossen, sodass derselbe öffentliche API sauber auf dcc32 / dcc64 kompiliert wird; die umgebenden Eigenschaften und Hilfsfunktionen bleiben unverändert. Es gibt keine Änderung des Laufzeitverhaltens.

2026-05-23 Version 2.120.12

  • EnableShapingFeatureForSubset (Abschluss von Phase 8f): THotPDF.EnableShapingFeatureForSubset (FeatureTag) / the Die THPDFShapingFeature-Enumeration überlädt die GSUB-Lookup-Verarbeitung, wobei jedes Lookup mit dem angeforderten Feature verknüpft ist (Version v2.119.49). SetGSUBScript / SetGSUBLanguage legt den Auswahlstatus fest und listet alle potenziellen Ersatz-GID-Werte für LookupType 1 (Single — Format 1, Delta über Coverage-Glyphen + Format 2, Array der substituteGlyphIDs), LookupType 2 (Multiple — Sequence.substituteGlyphIDs[]), LookupType 3 (Alternate — AlternateSet.alternateGlyphIDs[]), LookupType 4 (Ligature — Ligature.ligatureGlyph), LookupType 5 / 6 (Contextual / Chained Contextual — rekursive Verarbeitung von SequenceLookupRecord-Nested-Lookups mit einer Tiefenbegrenzung von 8), LookupType 7 (Extension — automatische Umwandlung in den effektiven Lookup-Typ) und LookupType 8 (Reverse Chained — substituteGlyphIDs[]). Die GID-Werte werden dann mit einem logischen ODER-Verknüpfung in FUnicodeExtraUsedGlyphs zusammengeführt, sodass der Subsetter von v2.84.0 alle Glyphen, die das Feature erzeugen kann, in den eingebetteten Schriftart-Subset einfügt. Phase 8f ergänzt v2.119.50 und ermöglicht eine feature-spezifische Batch-Option für Aufrufer, deren Produktionspipeline ein Feature universell aktiviert.
  • Die Enum-Überladung leitet jeden Wert von THPDFShapingFeature an den entsprechenden 4-Byte-OpenType-Feature-Tag-Satz weiter: 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. Die String-Tag-Überladung akzeptiert jeden 4-Byte-OpenType-Feature-Tag für eine präzise Ausrichtung, die über die enthaltenen Enum-Fälle hinausgeht. Warnung vor unnötigem Datenvolumen: Das Aktivieren umfassender Funktionen (z. B. aalt Access All Alternates, bei dem einige Schriftarten jedes Glyphe in einem Skript enthalten) kann einen großen Teil des Glyphen-Satzes der Schriftart in den Subset ziehen und so die Größenreduzierung in v2.84.0 zunichtemachen – Aufrufer sollten Phase 9 MarkUnicodeGlyphUsed bevorzugen, wenn sie die genauen GIDs kennen. Standardmäßig deaktiviert / explizite Opt-in. Schließt die letzte verbleibende Unterphase der GSUB Engine Roadmap Phase 8.
  • Die defensive Implementierung entspricht v2.119.50: keine Schriftart wird registriert, keine GSUB-Tabelle, kein 4-Byte-Tag, das Feature fehlt im (Skript-, Sprach-)Pfad, die Lookup-Kette ist leer – jede Bedingung, die "nichts zu tun" bedeutet, führt zu einer stillen, fehlerfreien Operation (keine Ausnahme). Wiederholte Aufrufe sind idempotent (das Bitmap wird logisch verknüpft). Die kontextuelle Subtabellen-Format 1 / 2-Rekursion wird für eine zukünftige Version aufgeschoben; Format 3 ist in realen Schriften vorherrschend und wird implementiert. Aufrufer, die eine präzise Format 1 / 2-kontextuelle Abdeckung benötigen, können auf die pro-Glyph-Methode MarkUnicodeGlyphUsed zurückgreifen.

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) speichert einen Eintrag (Substitut → Quellsequenz). Typische Anwendungsfälle: Nach Mehrfachsubstitution (1 GID → N GIDs) wird die Substitutionssequenz ausgegeben, die umgekehrte Zuordnung wird registriert, sodass das Kopieren/Einfügen durch den Konsumenten/Leser korrekt zum ursprünglichen Codepoint zurückgeführt wird; nach Ligatursubstitution (N GIDs → 1 Ligatur-GID) wird die Ligatur ausgegeben, und der Ligatur-Codepoint wird registriert, um zur N-elementigen Quellsequenz zurückzukehren (z. B. eine beliebige kontextuelle Ligatur, die auf ihre Bestandteile zurückgeführt wird). ClearToUnicodeReverseMappings löscht alle vom Aufrufer registrierten Einträge; ToUnicodeReverseMappingCount gibt die Anzahl der ausstehenden Einträge zurück.
  • EndDoc gibt Anmeldeinformationen aus, die vom Aufrufer registriert wurden, als zusätzliche bfchar-Blöcke nach dem eingebauten 35-Einträge-Block, automatisch in 100-Einträge-Unterblöcke pro Adobe CMap und CIDFont Files Specification (Technical Note #5014) §1.4.2 aufgeteilt, wobei die bfchar-Operatorgrenze eingehalten wird. BMP-Codepunkte geben 4 Hexadezimalziffern aus; SMP-Codepunkte geben ein UTF-16BE-Surrogatenpaar (8 Hexadezimalziffern) gemäß der Adobe CMap-Spezifikation aus. Die Registrierungsreihenfolge wird beibehalten, sodass die "last-write-wins"-Semantik von PDF-Readern es Aufrufern ermöglicht, ein deterministisches Überschreibungsverhalten bei Konflikten mit den eingebauten 35 Einträgen zu erzielen (ein Aufrufer, der eine benutzerdefinierte Zuordnung für <FB01> "fi" registriert, überschreibt die Standardeinstellung v2.119.65 im Reader). Aufrufer, die niemals RegisterToUnicodeReverseMapping aufrufen, behalten die ToUnicode-CMap byteidentisch zur Baseline v2.120.10. SetFormUnicodeFontDict ('', nil) setzt den Pfad zurück und löscht die Aufruferregistrierung, sodass die nächste Unicode-Schriftartregistrierung sauber beginnt.

2026-05-23 Version 2.120.10

  • Myanmar-Textformer (Phase 8f.10): registriert Myanmar (OpenType-Tag mymr) als das zehnte und letzte indische Schriftsystem in HotPDF und deckt sowohl den Myanmar-Kernbereich (U+1000-U+109F: Burmese, Mon, Sgaw Karen, Western Pwo, Shan, Rumai Palaung, Pa'O) als auch den erweiterten Bereich A (U+AA60-U+AA7F) ab. Eine neue Funktion ApplyMyanmarReorder führt eine Vorab-Neuordnung durch, und GetMyanmarCategory dient zur Codepoint-Suche und kann über den Dispatcher ApplyIndicReorder wiederverwendet werden.
  • Die komplexeste Silbenstruktur in der Charge: Kinzi 3-CP Das Präfix (U+1004 + U+103A + U+1039) am Anfang der Silbe wird erkannt, beiseitegelegt und gemäß R8 am allerersten Beginn der Ausgabe ausgegeben; der Vokal E (U+1031) wird gemäß R10 an den Anfang der Silbe verschoben; vier mediale Konsonanten Y / R / W / H (U+103B-U+103E) werden gesammelt und in fester Y → R → W → H Reihenfolge gemäß R9 ausgegeben, unabhängig von der ursprünglichen Reihenfolge.
  • ASAT (U+103A) und VIRAMA (U+1039) werden beide als Virama behandelt, für die Verarbeitung von Konsonantenkombinationen. DOT BELOW (U+1037) wird unterhalb der Basis dargestellt; andere diatonische Zeichen werden oberhalb angezeigt. ANUSVARA (Bindu) wird oberhalb platziert; VISARGA wird danach platziert. Keine Repha.
  • Zwei `IndicScripts`-Einträge (Hauptblock und Erweiterung-A) verwenden dieselben Myanmar-Sortierfunktionen, sodass Konsonanten der Erweiterung-A und Pa'o-Karen-Tonzeichen transparent über den Dispatcher verarbeitet werden.
  • **Vervollständigt den 11-Phasen-Batch für die nicht-devanagarische indische Schriftformatierung** (Phasen 8f.0-8f.10): Infrastruktur + 10 registrierte indische Schriften – Devanagari, Bengali, Gujarati, Tamil, Telugu, Kannada, Malayalam, Sinhala (Brahmic SIA-Familie), Khmer, Myanmar (südostasiatisch).
  • Gemäß Unicode 16.0 §16.3 (Myanmar) und der OpenType Myanmar-Formatierungsspezifikation.

2026-05-23 Version 2.120.9

  • Khmer-Textformer (Phase 8f.9): registriert Khmer (OpenType-Tag khmr, Unicode-Block U+1780-U+17FF) als das neunte indische Schriftsystem in HotPDF und das erste Schriftsystem in Südostasien. Eine neue Funktion, ApplyKhmerReorder, führt eine Vorverarbeitung zur Umstellung durch, und GetKhmerCategory dient zur Codepoint-Suche. Beide Funktionen sind wiederverwendbar über den Dispatcher ApplyIndicReorder.
  • Unabhängige Silbenstruktur (nicht das brahmische R1-R5-Muster, das in den Phasen 8f.1-8f.8 verwendet wird): Vokale vor der Grundform (E / AE / AI / OE / OO / AU) werden an den Anfang der Silbe verschoben; Registerverschiebungen (MUUSIKATOAN, TRIISAP) und andere Zeichen oberhalb der Grundform werden an den Puffer oberhalb der Grundform geleitet; Bindu (NIKAHIT) wird oberhalb gerendert; Visarga (REAHMUK, YUUKALEAPINTU) wird unterhalb gerendert.
  • COENG-Unterzeichenbehandlung: Jeder COENG-Buchstabe (U+17D2) zusammen mit einem Konsonanten bildet einen gestapelten Konsonantencluster, der in der ursprünglichen Reihenfolge im Basispuffer verbleibt, sodass die GSUB-Funktionen `pres` und `blws` der Schriftart die Positionierung der Unterzeichen übernehmen. Verschachtelte COENG-Zeichen werden unterstützt.
  • Keine Repha: Khmer-Schriften bilden keine visuelle Repha-Struktur, daher bleibt `Ra + COENG + Konsonant` in der ursprünglichen Reihenfolge, anstatt zum Syllabenende rotiert zu werden.
  • Gemäß Unicode 16.0 §16.4 (Khmer) und der OpenType Khmer-Formatierungsspezifikation.

2026-05-23 Version 2.120.8

  • PAdES adbe-revocationInfoArchival CMS signiertes Attribut (PAdES Phase 9): Gibt Adobes privates OID aus 1.2.840.113583.1.1.8, das CRL- und OCSP-Werte direkt in der CMS-Signatur enthält. Adobe Acrobat bevorzugt dieses Attribut für die Überprüfung der Signaturgültigkeit, vor DSS-Dictionary-Abfragen und Netzwerk-OCSP/CRL-Abrufen – entscheidend für offline überprüfbare PDFs und für die beste Interoperabilität mit Adobe Acrobat.
  • Neue Felder für `THPDFCMSSignOptions`:
    • AdobeCRLsDER: array of TBytes - jedes Element ist ein X.509 CertificateList (RFC 5280) im DER-Format, im gleichen Format wie die DSS /CRLs-Streams.
    • AdobeOCSPsDER: array of TBytes - jedes Element ist eine BasicOCSPResponse-SEQUENZ (RFC 6960 §4.2.1) im DER-Format. Beachten Sie: *nicht* die äußere OCSPResponse-Umhüllung - Aufrufer, die vollständige OCSP-Antworten verwenden, müssen zuerst den responseBytes.response-OKTETT-String entpacken, um die BasicOCSPResponse zu extrahieren.
  • Aktivierung: Dieses Attribut wird ausgegeben, wenn mindestens eines der beiden Arrays nicht leer ist. Der Standardwert "leer" (beide Arrays) sorgt für Byte-Level-Stabilität in Version v2.120.7.
  • ASN.1 DER gemäß der Adobe-Spezifikation: RevocationInfoArchival ::= SEQUENCE { crl [0] EXPLICIT SEQUENCE OF CRL OPTIONAL, ocsp [1] EXPLICIT SEQUENCE OF BasicOCSPResponse OPTIONAL, otherRevInfo [2] EXPLICIT SEQUENCE OF OtherRevInfo OPTIONAL }. HotPDF verwendet [0] und [1]; [2] (otherRevInfo für Nicht-X.509-Widerrufsysteme) bleibt außerhalb des Geltungsbereichs.
  • Form der Verbindung (beide Zweige befüllt): 30 A0 30 <...> A1 30 <...>
  • **Funktioniert zusammen mit dem DSS-Dictionary:** Dieses Attribut ist *ergänzend* (und kein Ersatz für) das PAdES-B-LT DSS-Dictionary (auf Katalogebene, `/DSS /Certs /OCSPs /CRLs /VRI`, eingeführt in v2.110.0). Strenge PAdES-Validierer (EU DSS, mTOM) respektieren in der Regel das DSS; Adobe Acrobat respektiert `adbe-revocationInfoArchival`. Für maximale Interoperabilität sollten beide Ebenen mit denselben CRL/OCSP-Daten über `AddPAdESDSSCRL / AddPAdESDSSOCSP sowie `AdobeCRLsDER / AdobeOCSPsDER` gefüllt werden.
  • Der 4-Argument-Wrapper `HPDFCMSBuildSignedData` setzt die neuen Felder auf Null, sodass ältere CMS-Pakete byte-identisch bleiben.
  • Für Adobe Acrobat PDF Reference + RFC 5280 (CRL) + RFC 6960 (OCSP).

2026-05-23 Version 2.120.7

  • PAdES content-time-stamp CMS signierte Attribut (PAdES Phase 8): emittiert 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), das ein Pre-Signing RFC 3161 TimeStampToken enthält, welches beweist, dass der Dokumentinhalt zum TSA-angegebenen Zeitpunkt vor der eigentlichen Signatur existierte. Unterscheidet sich von signature-time-stamp (Phase 4, unsigniertes Attribut, nach der Signatur).
  • Neues THPDFCMSSignOptions-Feld. GetContentTimeStamp: THPDFCMSTimestampCallback. Spiegelbildliche Implementierung von GetSignatureTimeStamp in v2.120.3: HotPDF ruft den Callback mit dem SHA-256-Hash des Dokuments auf (derselbe Hash, der im Attribut messageDigest verwendet wird) und bettet das zurückgegebene TimeStampToken im DER-Format als Wert des Attributs content-time-stamp innerhalb von SignedAttributes ein.
  • Standardmäßig wird `nil` verwendet, was bedeutet, dass kein Zeitstempel generiert wird. Aufrufer, die einen Zeitstempel benötigen, müssen eine Closure zuweisen, die einen RFC 3161 TSA über HTTP bereitstellt. Wenn ein leerer TBytes-Wert zurückgegeben wird, wird dieser stillschweigend übersprungen (elegante Fehlerbehandlung, wenn der TSA nicht erreichbar ist).
  • **Kostenlose TSA-Endpunkte** (keine Abonnement erforderlich) für nicht qualifizierte Anwendungsfälle: http://timestamp.digicert.com, http://timestamp.sectigo.com, http://timestamp.globalsign.com/tsa/r6advanced1, https://freetsa.org/tsr, http://timestamp.apple.com/ts01. Für Szenarien, die die eIDAS-Qualifizierung erfordern, ist ein kommerzieller QTSA erforderlich; die digitale Signierung für nicht-juristische Zwecke funktioniert mit den kostenlosen Endpunkten (die jedoch eine Ratenbegrenzung haben, aber für typische Arbeitsabläufe ausreichend sind).
  • Callback-Vertrag: Wird einmal pro Signieroperation aufgerufen, *vor*dem die `SignedAttributes` versiegelt werden. Die TST-Bytes werden Teil des signierten Inhalts, sodass die Signatur selbst den Zeitstempel des Inhalts abdeckt – deshalb ist es ein signiertes Attribut (im Gegensatz zum Signatur-Zeitstempel, der unsigniert ist und sich nach der Signatur in `unsignedAttrs` befindet).
  • Die 4-Argumente-Wrapper-Funktion `HPDFCMSBuildSignedData` setzt `GetContentTimeStamp` auf `nil`, sodass ältere CMS-Pakete byte-identisch bleiben.
  • Verantwortlichkeit des Aufrufers: PAdES-Platzhalter benötigen `ContentsBytes`, die für die Signatur sowie den Zeitstempel des Inhalts (TST) dimensioniert sind (typischerweise ~4-8 KB). Bei B-T-Workflows, die Zeitstempel des Inhalts und Zeitstempel der Signatur kombinieren, müssen beide TSTs berücksichtigt werden – `AddPAdESSignatureField(Profile='B-T')` hat standardmäßig 16 KB, was die meisten Kombinationen abdeckt.
  • Gemäß 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

2026-05-23 Version 2.120.5

2026-05-23 Version 2.120.4

  • PAdES signer-attributes-v2 CMS signiertes Attribut (PAdES Phase 5): emittiert id-aa-ets-signerAttrV2 (OID 0.4.0.19122.1.1, ETSI EN 319 122-1 §5.2.6), wodurch der Unterzeichner Rollen angeben kann (z. B. "Chief Financial Officer", "Authorisierter Vertreter") innerhalb des CMS-Bündels. Ersetzt die veraltete Version 1 signerAttr (RFC 5126 §5.10) für neue Signaturen.
  • Neuer THPDFClaimedRole-Eintrag: RoleOID (Attributtyp-OID in Punktnotation, typischerweise eine organisationsbezogene OID oder die 1.3.6.1.5.5.7.20.1 id-id-aa-PERMrole-ID) + RoleValue (UTF-8-Zeichenkette, die das für Menschen lesbare Rollenlabel enthält).
  • Neues THPDFCMSSignOptions-Feld: ClaimedRoles: array von THPDFClaimedRole. Mehrere Rollen werden unterstützt; jede wird zu einem Attribute innerhalb der claimedAttributes [0]-Sequenz. Ein leeres Array (Standard) unterdrückt das Attribut und behält die Byte-Level-Stabilität von Version 2.120.3 für Aufrufer, die sich nicht dafür entschieden haben.
  • ASN.1 DER gemäß ETSI EN 319 122-1 §5.2.6 + ANHANG A.1 (Modul DEFINITIONS EXPLICIT TAGS): SignerAttributeV2 SEQUENCE { [0] EXPLICIT ClaimedAttributes } wobei ClaimedAttributes ::= SEQUENCE OF Attribute. Jede Rolle wird als Attribute { type OID, values SET OF UTF8String } serialisiert. Der explizite Tag bedeutet, dass 0xA0 die innere SEQUENCE OF unverändert umschließt (der innere 0x30-Tag bleibt erhalten).
  • OID-Body manuell kodiert: 04 00 81 95 32 01 01 (arc 0.4.0.19122.1.1; Basis-128, Fortsetzung von 19122 → 0x81 0x95 0x32). Zukünftige, benutzerdefinierte Werte können die Funktion CMSEncodeOIDFromString ab Version v2.120.1 verwenden.
  • **Geltungsbereich:** Nur `claimedAttributes [0]` wird in dieser Phase implementiert. `certifiedAttributesV2 [1]` (X.509-Attribute gemäß RFC 5755) und `signedAssertions [2]` (Token im SAML-/JWT-Stil) erfordern zusätzliche Komponenten und werden erst implementiert, wenn ein konkreter Bedarf besteht.
  • Der 4-Argument-Wrapper `HPDFCMSBuildSignedData` setzt die Länge von `ClaimedRoles` auf Null, sodass ältere CMS-Pakete byte-identisch zu Version v2.119.27 bleiben.
  • Gemäß ETSI EN 319 122-1 V1.2.1 §5.2.6 + EN 319 142-1 V1.2.1, Tabelle 1, Zeile signer-attributes-v2 (optional, 0 oder 1).

2026-05-23 Version 2.120.3

  • PAdES signature-time-stamp CMS, unsigniertes Attribut (PAdES Phase 4): emittiert id-aa-signatureTimeStampToken (OID 1.2.840.113549.1.9.16.2.14, RFC 3161 §6 + ETSI EN 319 122-1 §5.3) innerhalb des SignerInfo's [1] IMPLICIT unsignedAttrs SET. Stellt den signature-time-stamp-Pfad für den PAdES-B-T vertrauenswürdigen Zeitdienst bereit (Tabelle 1: B-T muss über signature-time-stamp oder document-time-stamp bereitgestellt werden).
  • Neuer `THPDFCMSTimestampCallback`-Anonymus-Methoden-Typ: `reference to function(const SigValueSHA256: TBytes): TBytes`. HotPDF ruft den Callback mit dem SHA-256 von `SignerInfo.signatureValue` (dem RFC 3161 `messageImprint` gemäß §2.4.2) auf und bettet das zurückgegebene TimeStampToken im DER-Format als Attributwert ein.
  • Neues THPDFCMSSignOptions-Feld: GetSignatureTimeStamp. Standardmäßig nil, was bedeutet, dass kein Zeitstempel verwendet wird. PAdES-B-T-Aufrufer weisen eine Closure zu, die die HTTP/RFC 3161-Interaktion mit dem TSA steuert und die TST-Bytes zurückgibt. Wenn keine TBytes zurückgegeben werden, wird der Vorgang ohne Fehler übersprungen (z. B. wenn der TSA nicht erreichbar ist, die Signatur sollte aber trotzdem erstellt werden).
  • Die Netzwerk-/Authentifizierungs-/TSA-Kontoverwaltung bleibt im aufrufenden Code; HotPDF leitet lediglich das Ergebnis in das unsignedAttrs-Element weiter. Dies passt gut zum vorhandenen Platzhalter für die Größenanpassung von AddPAdESSignatureField(Profile='B-T', ContentsBytes >= 16384).
  • ASN.1 wire: Die SignerInfo-Sequenz enthält jetzt optional ein trailing [1] IMPLICIT SET OF Attribute (Tag 0xA1), das ein signature-time-stamp-Attribut enthält, dessen Wert die vom Aufrufer bereitgestellte TimeStampToken ContentInfo unverändert enthält.
  • Die 4-Argumente-Wrapper-Funktion `HPDFCMSBuildSignedData` setzt `GetSignatureTimeStamp:=nil`, sodass ältere CMS-Pakete byte-identisch bleiben.
  • Gemäß RFC 3161 §6 + ETSI EN 319 122-1 §5.3 + EN 319 142-1 V1.2.1 §6.3 Tabelle 1, Anmerkung q (B-T kann entweder eine Signatur-Zeitstempelung oder eine Dokument-Zeitstempelung für vertrauenswürdige Zeitangaben verwenden).

2026-05-23 Version 2.120.2

  • PAdES commitment-type-indication CMS Unterstützung für SignedAttribute (PAdES Phase 3): Es wird das id-aa-ets-commitmentType Attribut (OID 1.2.840.113549.1.9.16.2.16, ETSI EN 319 122-1 §5.2.3 + RFC 5126 §5.11) ausgegeben, das den Typ der Zusage angibt, die der Unterzeichner durch die Signatur macht (z.B. Nachweis der Herkunft / Empfang / Zustellung / Absender / Genehmigung / Erstellung).
  • Neues THPDFCommitmentType-Enum: ctNone (Standard, unterdrückt das Attribut), ctProofOfOrigin, ctProofOfReceipt, ctProofOfDelivery, ctProofOfSender, ctProofOfApproval, ctProofOfCreation (sechs Standard-id-cti-ets-*-OIDs aus RFC 5126 §5.11.1, Bereich 1.2.840.113549.1.9.16.6.{1..6}), und ctCustom (der Aufrufer liefert eine beliebige OID über das neue CommitmentTypeOID-Feld).
  • Aktivierung: Wird jedes Mal ausgelöst, wenn THPDFCMSSignOptions.CommitmentType nicht ctNone ist. Ein leerer Standardwert sorgt in Version v2.120.1 für Byte-Level-Stabilität für Aufrufer, die sich nicht dafür entschieden haben.
  • **Verantwortung des Aufrufers (PAdES Teil 1 §6.3 Tabelle 1, Anmerkung d):** Wenn ein Commitment-Type-Indikator ausgegeben wird, muss der Eintrag `Reason` im Signatur-Dictionary fehlen (gegenseitige Ausschlussbeziehung). HPDFCMS erkennt den Zustand des Signatur-Dictionaries nicht; der Aufrufer wählt entweder die eine oder die andere Option über `AddPAdESSignatureField(Reason='', ...)` plus `CommitmentType` oder indem er `CommitmentType=ctNone` lässt und `Reason` angibt.
  • ASN.1 DER-Struktur: CommitmentTypeIndication SEQUENCE { commitmentTypeId OBJECT IDENTIFIER }. Der CommitmentTypeQualifier (RFC 5126 §5.11.2) wird weggelassen, da die sechs Standard- id-cti-ets-* OIDs keine Qualifizierer definieren. Benutzerdefinierte Commitments, die Qualifizierer benötigen, können die Hilfsfunktion erweitern.
  • Der 4-Argument-Wrapper `HPDFCMSBuildSignedData` setzt das neue Feld `CommitmentType` auf Null, sodass ältere CMS-Pakete byte-identisch zu Version 2.119.27 bleiben.
  • Gemäß ETSI EN 319 122-1 §5.2.3 + RFC 5126 §5.11 + ETSI EN 319 142-1 V1.2.1 §6.3 Tabelle 1, Anmerkung d.

2026-05-23 Version 2.120.1

  • PAdES signature-policy-identifier CMS Unterstützung für SignedAttribute (PAdES Phase 2): gibt das Attribut 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) aus, das die Signaturrichtlinie angibt, unter der die Signatur erstellt wurde. Erforderlich für PAdES-E-EPES (Teil 2 V1.2.1 §5.4 Tabelle 2: muss vorhanden sein); kann in allen anderen PAdES-Ebenen vorhanden sein.
  • Neue Felder für den `THPDFCMSSignOptions`-Datensatz: `SignaturePolicyOID` (dotted-OID-String des Richtliniendokuments), `SignaturePolicyHash` (Hash des Richtliniendokuments), `SignaturePolicyHashAlgOID` (Hash-Algorithmus-OID, standardmäßig SHA-256, wenn leer) und `SignaturePolicyURI` (optionaler SPuri-Qualifizierer gemäß RFC 5126 §5.8.1, OID `1.2.840.113549.1.9.16.5.1`, der auf die URL des Richtliniendokuments verweist).
  • Aktivierung: Das Attribut "policy" wird nur dann ausgegeben, wenn sowohl `SignaturePolicyOID` als auch `SignaturePolicyHash` vom Aufrufer befüllt werden. Leere Standardwerte bedeuten, dass das Attribut unterdrückt wird – grundlegende Signierer bleiben mit der Version v2.120.0 in Bezug auf die Byte-Ebene stabil.
  • Die neue Hilfsfunktion `CMSEncodeOIDFromString` kodiert beliebige OIDs in Punktnotation in DER gemäß X.690 §8.19 (die ersten beiden Abschnitte werden kombiniert als `40*arc1 + arc2`, nachfolgende Abschnitte sind Basis-128 mit Fortsetzungsbits). Richtlinien-OIDs sind unternehmensspezifisch, sodass der Hersteller sie nicht als Byte-Literale fest codieren kann.
  • ASN.1 DER-Struktur: SignaturePolicyId SEQUENCE { sigPolicyId OBJECT IDENTIFIER, sigPolicyHash OtherHashAlgAndValue [, sigPolicyQualifiers SEQUENCE OF SigPolicyQualifierInfo] }. Der SPuri-Qualifier umschließt die URL als IA5String (Tag 0x16) innerhalb eines SigPolicyQualifierInfo.
  • Kompatibilität: Version 2.120.0: Aufrufer, die die neuen Policy-Felder nicht befüllt haben, erzeugen eine byte-identische Ausgabe. Der Wrapper `HPDFCMSBuildSignedData` mit 4 Argumenten setzt die neuen Felder auf Null, sodass bestehende CMS-Pakete unverändert bleiben.
  • Gemäß ETSI EN 319 122-1 §5.2.9 + ETSI EN 319 142-2 V1.2.1 §5.4 Tabelle 2 + RFC 5126 §5.8.

2026-05-23 Version 2.120.0

  • PAdES-Grundfunktionalität, Einhaltung der CMS-Attribute (PAdES Phase 1): `SignPDFWithPFX` gibt jetzt standardmäßig das **ESS-Signaturzertifikatsattribut der Version 2** (RFC 5035 / OID `1.2.840.113549.1.9.16.2.47`) aus, wodurch die Identität des Signaturzertifikats vor Austauschangriffen geschützt wird. ETSI EN 319 142-1 V1.2.1 §6.3 Tabelle 1 listet dies als *muss bereitgestellt werden* für alle Grundfunktionalitätsstufen (B-B / B-T / B-LT / B-LTA) auf.
  • Die PAdES-Basislinie lässt jetzt standardmäßig das Attribut `signing-time` des CMS aus. Tabelle 1 legt eine Kardinalität von 0 für Basisprofile fest (die angegebene Signaturzeit wird über den Eintrag `/M` im Signatur-Dictionary gemäß Anmerkung g in Tabelle 1 übertragen). Der vorherige Pfad v2.119.27 enthielt `signing-time` unabhängig vom Profil, was von strengen PAdES-Validatoren (EU DSS, Adobe Acrobat PAdES-Basislinienmodus) abgelehnt wird.
  • Neue öffentliche API: `THPDFPAdESLevel`-Enum (8 Werte, die die Basisebenen B-B / B-T / B-LT / B-LTA, die erweiterten Ebenen E-BES / E-EPES / E-LTV sowie die Legacy-Option `adbe.pkcs7`) abdecken, `THPDFCMSSignOptions`-Record (Ebene + Signaturzeit + Umschaltflächen für `signing-cert-v2` + UTC-Zeitstempel), `HPDFCMSDefaultOptions(Level)`-Hilfsfunktion, die spezifikonforme Standardwerte pro Ebene zurückgibt, und `HPDFCMSBuildSignedDataEx`, ein optionsgesteuerter CMS-Builder.
  • Abwärtskompatibilität: Die Signatur HPDFCMSBuildSignedData mit vier Argumenten der Version v2.119.27 wird als dünne Wrapper-Schicht beibehalten und erzeugt eine byte-identische Ausgabe (das Signing-Zertifikat v2 ist nicht vorhanden, die Signaturzeit wird wie angefordert angegeben). Aufrufer, die den CMS-Bundle der Version v2.119.27 in Tests gehasht haben, bleiben funktionsfähig.
  • Änderung des Verhaltens bei signierten PDF-Ausgaben: Jeder Aufruf von `THotPDF.SignPDFWithPFX` mit einem PAdES-Platzhalter (`AddPAdESSignatureField`, SubFilter `ETSI.CAdES.detached`) erzeugt jetzt Signaturen, die die strenge PAdES-Basisvalidierung bestehen. Aufrufer, die den Legacy-Attributsatz v2.119.27 wünschen, sollten `HPDFCMSBuildSignedDataEx` direkt mit `HPDFCMSDefaultOptions(palLegacy_adbePkcs7)` aufrufen.
  • ASN.1 DER-Struktur gemäß RFC 5035 §3: `SigningCertificateV2 SEQUENCE { certs SEQUENCE OF ESSCertIDv2 }` mit dem SHA-256 AlgorithmIdentifier, der weggelassen wurde (X.690 §11.5 DEFAULT-value DER-Regel), SHA-256-Zertifikathash und `IssuerSerial`, das die bestehende X.509-Extraktion von Herausgeber + Seriennummer aus `CMSExtractIssuerAndSerial` wiederverwendet.
  • Gemäß ETSI EN 319 142-1 V1.2.1 §6.3 Tabelle 1 sowie RFC 5035 §3.

2026-05-23 Version 2.119.77

  • Eine Sinhala-Formatierung wurde hinzugefügt (Phase 8f.8). Sinhala ('sinh', U+0D80-U+0DFF) ist die 8. registrierte indische Schrift. Neue Methoden `ApplySinhalaReorder` und `GetSinhalaCategory` für THotPDF.
  • Sinhala-Funktionen: Enthält Repha (Ra=U+0DBB + Halant=U+0DCA AL-LAKUNA); drei Präfix-Matras (E=U+0DD9, EE=U+0DDA, AI=U+0DDB) – einzigartig, da es drei Präfix-Matras gibt; 3 geteilte Matras (U+0DDC O, U+0DDD OO, U+0DDE AU) mit kanonischer Unicode-Zerlegung; U+0DDD OO ist ein 3-teiliges Zeichen (E + AA + AL-LAKUNA).
  • Der `ApplyIndicReorder`-Dispatcher verarbeitet jetzt Sinhala-Texte, und zwar transparent (das IndicScripts-Register ist jetzt ein Array mit den Indizes 0 bis 7).
  • 21 neue DUnitX-Tests wurden hinzugefügt. Insgesamt wurden 187 von 187 Tests auf Win32 und Win64 erfolgreich abgeschlossen.
  • Gemäß Unicode 16.0 §12.11 (Sinhala) und der OpenType Sinhala-Formatierungsspezifikation.

2026-05-23 Version 2.119.76

  • Es wurde ein Malayalam-Formatierer hinzugefügt (Phase 8f.7). Malayalam ('mlym', U+0D00-U+0D7F) ist die 7. registrierte indische Schrift. Neue Methoden `ApplyMalayalamReorder` und `GetMalayalamCategory` für THotPDF.
  • Malayalam-Funktionen: Enthält Repha (Ra=U+0D30 + Halant=U+0D4D, CHANDRAKKALA); I-matra (U+0D3F) ist wie im Tamilisch eine POST-Basis (eindeutig im Vergleich zu Devanagari/Bengali/Gujarati, wo sie eine PRE-Basis ist); E/EE/AI-Präfixe; 3 getrennte Matras (U+0D4A O / U+0D4B OO / U+0D4C AU) mit kanonischer Präfix-plus-Suffix-Zerlegung; Chillu-Buchstaben (U+0D54-U+0D56, U+0D7A-U+0D7F) und DOT REPH (U+0D4E) werden als Konsonanten klassifiziert.
  • Der `ApplyIndicReorder`-Dispatcher unterstützt jetzt Malayalam, und zwar transparent (das IndicScripts-Register ist jetzt ein Array mit den Indizes 0 bis 6).
  • 21 neue DUnitX-Tests, einschließlich der Abdeckung der Kategorie chillu/DOT-REPH. Insgesamt wurden 166 von 166 Tests auf Win32 und Win64 erfolgreich abgeschlossen.
  • Gemäß Unicode 16.0 §12.10 (Malayalam) und der OpenType-Spezifikation für die Malayalam-Formatierung.

2026-05-23 Version 2.119.75

  • Es wurde ein Kannada-Formgeber hinzugefügt (GSUB-Engine-Roadmap Phase 8f.6). Kannada ('knda', U+0C80-U+0CFF) ist das sechste registrierte indische Schriftsystem. Neue öffentliche Methoden `ApplyKannadaReorder` und `GetKannadaCategory` wurden für `THotPDF` hinzugefügt.
  • Kannada verwendet Repha (Ra=U+0CB0 + Halant=U+0CCD), ähnlich wie Devanagari, Bengalisch, Gujarati und Telugu. Wie Telugu hat Kannada keine Präfix-Basis-Matras; jede Kannada-Matra ist entweder oberhalb, unterhalb, hinter oder geteilt.
  • 5 Matras wurden mit der kanonischen Zerlegung gemäß Unicode 16.0 aufgeteilt: U+0CC0 II wird in U+0CBF (oben) + U+0CD5 (hinten) zerlegt; U+0CC7 EE wird in U+0CC6 (oben) + U+0CD5 (hinten) zerlegt; U+0CC8 AI wird in U+0CC6 + U+0CD6 (beide oben) zerlegt; U+0CCA O wird in U+0CC6 (oben) + U+0CC2 (hinten) zerlegt; **U+0CCB OO besteht aus drei Teilen:** U+0CC6 (oben) + U+0CC2 (hinten) + U+0CD5 (hinten) – die erste dreiteilige Aufteilung wird von der Shaper-Familie Phase 8f verarbeitet.
  • Über den Basislinien liegende Matras (R3): I (U+0CBF), E (U+0CC6), AU (U+0CCC), Längezeichen für AI (U+0CD6). Unterhalb der Basislinie liegende Matras (R4): Vokalische R/RR (U+0CC3-U+0CC4), Vokalische L/LL Matras (U+0CE2-U+0CE3). Unterhalb der Basislinie liegende Matras (R5): AA (U+0CBE), U/UU (U+0CC1-U+0CC2), Längezeichen unterhalb der Basislinie (U+0CD5).
  • Der `ApplyIndicReorder`-Dispatcher wählt Kannada nun transparent über die Registry aus (jetzt array[0..5]).
  • Tests: 21 neue DUnitX-Tests wurden hinzugefügt, einschließlich aller 5 Tests für getrennte Matras, sowie eine spezielle Überprüfung für dreiteilige OO-Zeichen. Insgesamt bestehen alle 145 von 145 Tests auf Win32 und Win64.
  • Gemäß Unicode 16.0 §12.9 (Kannada) und der OpenType Kannada-Formatierungsspezifikation.

2026-05-23 Version 2.119.74

  • Es wurde ein Telugu-Formgeber hinzugefügt (GSUB-Engine-Roadmap Phase 8f.5). Telugu ('telu', U+0C00-U+0C7F) ist das fünfte registrierte indische Schriftsystem. Neue öffentliche Methoden `ApplyTeluguReorder` und `GetTeluguCategory` wurden für `THotPDF` hinzugefügt.
  • Telugu verwendet Repha (Ra=U+0C30 + Halant=U+0C4D), ähnlich wie Devanagari, Bengalisch und Gujarati. Im Gegensatz zu allen vorherigen indischen Schriften gibt es keine Präfix-Basis-Matras; jede Telugu-Matra befindet sich entweder oberhalb, unterhalb oder mittig bezüglich der Basis.
  • Über den Basislinien liegende Matras (R3): AA/I/II/E/EE/O/OO/AU plus Längenzeichen. Unterhalb der Basislinie liegende Matras (R4): U/UU/Vokal-R/RR (U+0C41-U+0C44), AI-Längenzeichen (U+0C56), Vokal-L/LL-Matras (U+0C62-U+0C63).
  • 1. Die Matra U+0C48 AI wird während der Neuanordnung in U+0C46 (E über Basislinie) + U+0C56 (AI-Längenmark unterhalb der Basislinie) zerlegt.
  • Der `ApplyIndicReorder`-Dispatcher wählt nun transparent Telugu über die Registry aus (jetzt array[0..4]).
  • Tests: 17 neue DUnitX-Testfälle. Insgesamt werden 124 von 124 Tests auf Win32 und Win64 erfolgreich ausgeführt.
  • Gemäß Unicode 16.0 §12.8 (Telugu) und der OpenType-Spezifikation für die Telugu-Formatierung.

2026-05-23 Version 2.119.73

  • Tamil-Formatierung hinzugefügt (GSUB-Engine-Roadmap Phase 8f.4). Tamil ('taml', U+0B80-U+0BFF) wird das vierte registrierte indische Schriftsystem. Neue öffentliche Methoden `ApplyTamilReorder` und `GetTamilCategory` für `THotPDF`.
  • Tamil unterscheidet sich von anderen Brahmi-Schriften in folgenden Punkten: Es gibt kein Repha (im Tamilischen wird Repha traditionell nicht visuell dargestellt); I-matra (U+0BBF) ist eine POST-Basis-Diakritik, was unter den Brahmi-Schriften einzigartig ist; II (U+0BC0) ist eine obere Basis-Diakritik; E/EE/AI (U+0BC6-U+0BC8) sind Präfix-Basis-Diakritiken; es gibt 3 geteilte Matras (U+0BCA O = U+0BC6+U+0BBE, U+0BCB OO = U+0BC7+U+0BBE, U+0BCC AU = U+0BC6+U+0BD7).
  • Halant wird im Tamilischen als PULLI bei U+0BCD bezeichnet. `ApplyIndicReorder` Der Dispatcher wählt transparent Tamil über die Registry aus (jetzt array[0..3]).
  • Tests: 20 neue DUnitX-Testfälle hinzugefügt. Insgesamt bestehen 107 von 107 Tests auf Win32 und Win64.
  • Gemäß Unicode 16.0 §12.7 (Tamil) und der OpenType-Spezifikation für die Tamil-Formatierung.

2026-05-23 Version 2.119.72

  • Gujarati-Formatierung hinzugefügt (GSUB-Engine-Roadmap Phase 8f.3). Gujarati ('gujr', U+0A80-U+0AFF) wird die dritte registrierte indische Schrift nach Devanagari und Bengali. Neue öffentliche Methoden ApplyGujaratiReorder und GetGujaratiCategory auf THotPDF hinzugefügt.
  • Regeln für die Anordnung: R1 Repha (Ra=U+0AB0 + Halant=U+0ACD), R2 vor der Basis (U+0ABF I), R3 über der Basis (U+0AC5 CANDRA E, U+0AC7 E, U+0AC8 AI – beachten Sie, dass die Anordnung über der Basis im Gujarati ähnlich wie im Devanagari ist, im Gegensatz zur Anordnung vor der Basis wie im Bengalisch), R4 unterhalb der Basis (U+0AC1-U+0AC4, U+0AE2-U+0AE3), R5 nach der Basis (U+0ABE AA, U+0AC0 II, U+0AC9 CANDRA O, U+0ACB-U+0ACC O/AU). Keine getrennten diakritischen Zeichen.
  • Der `ApplyIndicReorder`-Dispatcher wählt Guarati transparent über das `IndicScripts`-Register (jetzt array[0..2]) aus. Die `BuildUnicode*FieldContent`-Integrationen verwenden `sfIndicShaping`, um Guarati ohne Änderungen zu integrieren.
  • Tests: 18 neue DUnitX-Tests, einschließlich einer erweiterten Abdeckung für R3, um die Behandlung von E/AI in Gujarati von der in Bengali zu unterscheiden. Insgesamt bestehen alle 87 von 87 Tests auf Win32 und Win64.
  • Gemäß Unicode 16.0 §12.6 (Gujarati) und der OpenType-Spezifikation für die gujaratische Schriftformung.

2026-05-23 Version 2.119.71

  • Ein Bengali-Formular wurde hinzugefügt (GSUB-Engine-Roadmap Phase 8f.2). Bengali ('beng', U+0980-U+09FF) ist das zweite registrierte indische Schriftsystem, nach Devanagari. Neue öffentliche Methoden, ApplyBengaliReorder und GetBengaliCategory, wurden in THotPDF hinzugefügt, und spiegeln die Phase 8e Devanagari-API wider.
  • Bengalischer Umlayout: R1 Repha (Ra=U+09B0 + Halant=U+09CD), R2 Präfix-Basis-Matras (I=U+09BF, E=U+09C7, AI=U+09C8 – beachten Sie, dass E/AI im Bengalischen im Gegensatz zu Devanagari unterhalb der Basis liegen), R4 unterhalb der Basis (U+09C1-U+09C4, U+09E2-U+09E3), R5 oberhalb der Basis (U+09BE, U+09C0, U+09D7). Es gibt keine Matras oberhalb der Basis im Hauptblock des Bengalischen.
  • Aufteilung von Matra-Komponenten: `U+09CB` Oo und `U+09CC` AU werden während der Neuanordnung in ihre visuellen Komponenten erweitert (U+09C7 + U+09BE / U+09C7 + U+09D7), sodass die GSUB-Pipeline sie in kanonischen Vor- und Nachpositionsstrukturen erkennt.
  • Der `ApplyIndicReorder`-Dispatcher leitet bengalische Codepunkte transparent an den entsprechenden Eintrag weiter; die `BuildUnicode*FieldContent`-Hilfsfunktionen, die `sfIndicShaping` verwenden, unterstützen jetzt neben Devanagari auch Bengalisch, ohne dass Änderungen an der Integration erforderlich sind.
  • Tests: 18 neue DUnitX-Tests, die Bengali R1/R2/R4/R5, Split-Zerlegung, Erhaltung von Ligaturen, Durchleitung von gemischten Skripten, Idempotenz und Dispatcher-Äquivalenz abdecken. Insgesamt wurden 69 von 69 Tests auf Win32 + Win64 erfolgreich abgeschlossen.
  • Gemäß Unicode 16.0 §12.2 (Bengali) und der OpenType-Spezifikation für die bengalische Schrift.

2026-05-23 Version 2.119.70

  • Devanagari-Vollständigkeits-Shaper-Update (GSUB-Engine-Roadmap Phase 8f.1): `ApplyDevanagariReorder` wendet jetzt die vollständige 5-Regeln-Reihenfolge an (R1 Repha + R2 Pre-Base + R3 Above-Base + R4 Below-Base + R5 Post-Base) anstelle der in v2.119.55 verwendeten Teilmenge, die nur R1 + R2 berücksichtigt. Die Cluster-Reihenfolge pro Silbe ist wie folgt: `[Pre-Matras] + [Base + Halant + Nukta + Bindu/Visarga/Modifier] + [Above-Matras] + [Below-Matras] + [Post-Matras] + [Repha]`.
  • Konsonanten-Halant-Konsonanten-Kombinationen bleiben im Basiblock zusammengefasst; die Umsortierung betrifft nur Matras und Repha. Einmalige Anwendung und idempotent.
  • Änderungen gegenüber v2.119.69: Für Silben, die obere/untere/nachgestellte diakritische Zeichen (oder Mehrfach-Diakritika-Cluster) enthalten, spiegelt der PDF-Byte-Stream jetzt das kanonische Anordnungslayout wider. Die visuelle Darstellung nach GSUB/GPOS bleibt unverändert. Eingaben, die nur R1 Repha oder R2 Pre-Base I-Matra (die v2.119.55-Untermenge) enthalten, erzeugen eine byte-identische Ausgabe.
  • Tests: 8 neue DUnitX-Tests, die R3, R4 und R5 einzeln abdecken, die Reihenfolge mehrerer Matras, die Erhaltung von Conjuncts unter Matras, die Kombination von Repha, obigen Zeichen und nachgestellten Zeichen sowie die Idempotenz mehrerer Matras. Insgesamt wurden alle 51 von 51 Tests auf Win32 und Win64 erfolgreich abgeschlossen.
  • Gemäß Unicode 16.0 §12.1 (Devanagari) und der OpenType-Spezifikation für die Devanagari-Formatierung.

2026-05-23 Version 2.119.69

  • Die Infrastruktur für die Formung indischer Schriftzeichen (GSUB-Engine-Roadmap Phase 8f.0) wurde überarbeitet: Der Devanagari-Reihenfolge-Vorprozess der Versionen v2.119.55 / v2.119.67 wurde in einen sprachunabhängigen Dispatch-Framework umgewandelt. Neue Typen `TIndicScriptInfo` / `TIndicCategoryFunc` / `TIndicFindSyllableFunc` / `TIndicReorderFunc` sowie ein neues `IndicScripts`-Register ermöglichen es, zukünftige indische Schriftzeichen über Funktionszeiger zu integrieren.
  • Die neue öffentliche Methode `ApplyIndicReorder(Wide)` leitet jeden Codepoint von `Wide` an das entsprechende registrierte Skript weiter und wendet die Syllaben- und Reorder-Callbacks dieses Skripts an. Nicht-indischer Inhalt wird unverändert weitergegeben.
  • Die drei Hilfsfunktionen `BuildUnicode*FieldContent` rufen jetzt `ApplyIndicReorder` auf (anstatt der Devanagari-spezifischen Wrapper-Funktion), wenn `sfIndicShaping` in `FShapingFeatures` enthalten ist. Phase 8f.0 enthält nur Devanagari; nachfolgende Phasen 8f.2 bis 8f.10 fügen Bengalisch, Gujarati, Tamil, Telugu, Kannada, Malayalam, Singhalesisch, Khmer und Myanmar hinzu, ohne diesen Integrationsbereich zu ändern.
  • Die bestehende Funktion `ApplyDevanagariReorder` wird beibehalten und dient als Wrapper, der nur Devanagari-Zeichen verarbeitet, um die Abwärtskompatibilität zu v2.119.55 zu gewährleisten. Die Ausgabe ist unverändert gegenüber v2.119.67.
  • Gemäß Unicode 16.0 §12 (Schriften Südasiens) und ISO 32000-1 §9.10.

2026-05-22 Version 2.119.68

  • Phase 8c.6 – Generierung von GID-Werten auf Produzenseite durch Zuordnung synthetischer Codepunkte aus dem Private Use Area: Zwei neue öffentliche Methoden in THotPDF ermöglichen es Aufrufern, Ersatz-GIDs zu generieren, die keinen natürlichen Unicode-Codepunkt haben, indem sie bei Bedarf synthetische PUA-Codepunkte (U+E000-U+F8FF) zuweisen. `AssignSyntheticCodepointForGID (GID; out SyntheticCP): Boolean` weist den nächsten verfügbaren PUA-Slot zu und spiegelt die Zuordnung in den Tabellen `FUnicodeCpToGid`, `FAcroFormUnicodeAdvances` und einer neuen `FUnicodeSyntheticCpForGID`-Nachschlagetabelle pro GID wider, sodass die bestehende Hex-Codierungs-Pipeline auf der Produzenseite den synthetischen Codepunkt als ein 4-stelligen Hex-Token ausgibt, das der Konsumenten-Reader über `/CIDToGIDMap` in das Ersatz-Glyph auflöst. `GetSyntheticCodepointForGID (GID): Word` fragt bestehende Zuordnungen ab (gibt 0 zurück, wenn kein synthetischer Codepunkt zugewiesen wurde). Beide Methoden sind idempotent – wiederholte Aufrufe mit derselben GID geben den gleichen synthetischen Codepunkt zurück.
  • Ermöglicht die serverseitige Generierung von GSUB-Ersetzungen für schriftspezifische Glyphen, die keine Unicode-Präsentationsform-Codepunkte haben: Devanagari-Clusterformen (Indic 'akhn' / 'rphf' / 'pres' / 'blws' / 'psts' / 'haln' führen typischerweise zu schriftspezifischen GIDs), stilistischen Alternativen ('salt' / 'ss01-20' ohne Codepunkte), diskretionären Ligaturen ('dlig' / 'hlig') und CJK-Ideogramm-Variationssequenz-Ersetzungen. In Kombination mit den GSUB-Engine-APIs der Version v2.119.43-50 und dem Subsetter-Closure v2.119.50 MarkUnicodeGlyphUsed, können Aufrufer jetzt vollständige serverseitige Formgebungs-Pipelines erstellen, die beliebige Ersetzungs-GIDs über die bestehende, codepunktbasierte Hex-Pipeline ausgeben.
  • Zustandslebensdauer: Synthetische Zuordnungen bleiben erhalten, bis RegisterUnicodeTTF erneut aufgerufen wird oder BeginDoc ausgelöst wird (beide setzen den gesamten pro-Schriftart-Zustand zurück, einschließlich der synthetischen Tabelle). Der PUA-Bereich U+E000-U+F8FF bietet 6400 Slots, was für jeden praktischen Schriftart-GSUB-Ersatzsatz ausreichend ist. Die umgekehrte Zuordnung der ToUnicode-CMap ist die Verantwortung des Aufrufers – synthetische PUA-Codepunkte haben keine Quell-Codepunkte, die umgekehrt zugeordnet werden können; Aufrufer, die sich Sorgen um die Textextraktion machen, sollten den in PDF-markierten Inhalten ausgegebenen Text mit der Eigenschaft /ActualText versehen, die die ursprünglichen Quell-Codepunkte angibt. PDFs, bei denen die Aufrufer AssignSyntheticCodepointForGID nicht aufrufen, sind byteidentisch mit der Ausgabe von v2.119.67 (die neuen Methoden sind zustandslose Abfrage-/explizite-Allokationshilfen; es gibt keine automatischen Nebenwirkungen). Dieses Commit schließt die GSUB-Engine-Roadmap-Phase 8-Fähigkeitsmatrix ab.

2026-05-22 Version 2.119.67

  • Devanagari-Neuanordnung: Die automatische Anwendung einer Vorab-Phase (Roadmap für den GSUB-Motor, Phase 8e): Die drei Hilfsfunktionen BuildUnicode*FieldContent rufen jetzt automatisch die Methode ApplyDevanagariReorder (Version 2.119.55) auf, wenn sfIndicShaping in FShapingFeatures enthalten ist. Diese Vorab-Phase durchläuft den Eingabestrom von links nach rechts und wendet die beiden Devanagari-spezifischen Neuanordnungen an (Verschiebung von Repha für Ra-Halant am Anfang der Silbe und Verschiebung von I-matra U+093F an den Anfang ihres Silbenclusters), sodass der ausgegebene Codepoint-Stream der visuellen Lesereihenfolge entspricht. Der GSUB-Motor des Lesegeräts wendet dann die Indic-Formketten ('nukt' / 'akhn' / 'rphf' / 'rkrf' / 'pref' / 'half' / 'vatu' / 'cjct' / 'pres' / 'blws' / 'abvs' / 'psts' / 'haln') auf die neu angeordneten Codepunkte an, um die endgültigen Cluster-Glyphen zu erzeugen.
  • Umfang: Phase 8e liefert nur die serverseitige Neuanordnung. Die serverseitige Anwendung von GSUB-Ketten (bei der der Server die Clusterformatierung zum Zeitpunkt der PDF-Generierung festlegt, anstatt sich auf den Reader zu verlassen) wird auf Phase 8c.6 verschoben, da die meisten Devanagari-GSUB-Ersetzungen auf schriftspezifische GIDs mit keinen Unicode-Präsentationsform-Codepunkten landen. Im Gegensatz zu Arabisch/Latein, wo die Blöcke Forms-A/Forms-B Codepunkte bereitstellen, die über Ersetzungen erreichbar sind, gibt es in Devanagari keinen äquivalenten Präsentationsform-Bereich in Unicode. Die PUA-synthetische Codepunkt-Zuordnung in Phase 8c.6 ermöglicht die serverseitige GSUB-Generierung für Devanagari und andere indische/südostasiatische Schriften, bei denen die Ersetzungs-GIDs schriftspezifisch sind.
  • Nicht-Devanagari-Inhalte werden unverändert durch `ApplyDevanagariReorder` übergeben (die Methode verarbeitet nur Devanagari-Silben; andere Codepoint-Bereiche werden unverändert ausgegeben). PDFs, bei denen die Aufrufer `sfIndicShaping` deaktiv lassen (die Standardeinstellung), erzeugen eine byte-identische Ausgabe wie die Version v2.119.66. In Kombination mit der Fähigkeits-Ebene v2.119.55 ( `GetDevanagariCategory` + `ApplyDevanagariReorder` als öffentliche Methoden) schließt dieser Commit die Devanagari-Integration für die Reorganisation auf Produzenseite ab: Aufrufer, die `sfIndicShaping` aktivieren, müssen den Text nicht mehr vorab neu ordnen oder `ApplyDevanagariReorder` manuell aufrufen, bevor `BuildUnicode*FieldContent` aufgerufen wird – HotPDF erledigt dies automatisch.

2026-05-22 Version 2.119.66

  • GSUB 'rclt' (Erforderliche kontextabhängige Alternativen): Automatische Integration durch die neue Methode THotPDF.ApplyArabicGSUBContextualRefinement (Wide). Diese Methode ähnelt v2.119.63 ApplyArabicGSUBRefinement, wendet jedoch kontextuelle Substitutionen (GSUB Typ 5 / 6) über die API v2.119.47 ApplyContextualSubst an, anstatt Ligatur-Substitutionen (Typ 4). 'rclt' kodiert erforderliche, kontextabhängige Substitutionen – typischerweise verwendet von arabischen Schriftarten für zusätzliche positionsabhängige Varianten, die über die statische Zuordnung Forms-B in v2.85.0 hinausgehen, und von Schriftarten aus Südostasien / Indien für clusterbasierte, neu angeordnete Formen, die von der Nachbarkontext abhängen.
  • Variable-length-Ausgabebehandlung: Im Gegensatz zu `ApplyLigatureSubstitution` (N Eingabe-GIDs -> 1 Ersatz-GID) kann `ApplyContextualSubst` M Ersatz-GIDs aus N Eingabe-GIDs erzeugen. Wenn eine kontextuelle Regel ausgelöst wird, müssen ALLE Ersatz-GIDs über Unicode-Präsentationsform-Codepunkte über eine umgekehrte cmap (FB00-FDFF + FE70-FEFF, ca. 770 Codepunkte) erreichbar sein, damit die Substitution durchgeführt wird; wenn eine Ersatz-GID keine umgekehrte Zuordnung hat, bleibt das Eingabefenster unverändert (eine teilweise Ausgabe würde die Sequenz beschädigen). Der Bereich der umgekehrten cmap wurde erweitert, um lateinische/armenische/hebräische Präsentationsformen (FB00-FB4F) sowie die vollständigen arabischen Bereiche abzudecken, sodass "rclt"-Ersatzzeichen aus jedem Skript ausgegeben werden können.
  • Neues THPDFShapingFeature-Enum-Element sfContextualAlternates (am Ende hinzugefügt, um die Abwärtskompatibilität zu gewährleisten – bestehende Aufrufer, die FShapingFeatures verwenden, bleiben unverändert, da sie mit dem 5-Element-Enum der Version 2.119.59 kompiliert werden). Integriert in die drei BuildUnicode*FieldContent-Hilfsfunktionen, die von sfContextualAlternates in FShapingFeatures gesteuert werden (optional, standardmäßig deaktiviert). Unabhängig von FAutoShapeArabic – 'rclt' kann auf nicht-arabische Skripte (Latein/Hebräisch/Indisch) angewendet werden. Ersetzende GIDs werden über MarkUnicodeGlyphUsed für den Subsetter in Version 2.84.0 weitergeleitet. Eine defensive No-Op-Operation, wenn die Schrift keine 'rclt'-Regeln hat oder die ersetzenden GIDs keine Presentation Form-Codepunkte enthalten. PDFs, bei denen die Aufrufer sfContextualAlternates deaktiv lassen, erzeugen eine byte-identische Ausgabe wie die Version 2.119.65.

2026-05-22 Version 2.119.65

  • Latin 'liga' Standard Ligaturen (Roadmap für den GSUB-Motor, Phase 8b): Die neue Methode THotPDF.ApplyLatinLigatureRefinement (Wide) ähnelt v2.119.63 ApplyArabicGSUBRefinement, zielt aber auf die lateinischen/armenischen/hebräischen alphabetischen Präsentationsformen in U+FB00-U+FB4F ab. Sie durchläuft die Eingabezeichenkette, erstellt ein paralleles GID-Array mithilfe von FUnicodeCpToGid und fragt die GSUB-'liga'-Funktion (Standardligaturen) der Schriftart an jeder Position über die API v2.119.43-50 ApplyLigatureSubstitution ab. Wenn eine Ligaturensubstitution erfolgt UND die ersetzende GID über einen Unicode-alphabetischen Präsentationsform-Codepunkt erreichbar ist, wird das Quellcodepunktfenster durch den Codepunkt des Ersatzes ersetzt. Diese Funktionalität ist in die drei Helferfunktionen BuildUnicode*FieldContent (einzeilig, mehrzeilig und Kombinations-AcroForm-/AP-Aussehen-Stream-Builder) integriert, die durch sfStandardLigatures in FShapingFeatures gesteuert werden (optional, byteweise stabil, wenn nicht gesetzt).
  • Optionaler zweiter Durchlauf für 'clig' (kontextuelle Ligaturen): Wenn auch `sfContextualLigatures` in `FShapingFeatures` enthalten ist, durchläuft die Methode das Ergebnis von 'liga' erneut und wendet 'clig' an, um schreiberspezifische kontextuelle Ligaturen zu berücksichtigen, die über den Standard-Satz fi / fl / ffi / ffl hinausgehen. Jede ausgegebene Ersatz-GID wird über `MarkUnicodeGlyphUsed` für den TTF-Subsetter in Version v2.84.0 geleitet. Die umgekehrte cmap wird linear über etwa 80 Codepunkte (FB00-FB4F) durchsucht; die Substitutionen sind spärlich und der Aufwand ist vernachlässigbar.
  • 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

  • Öffentliche API für die Abfrage von Codepoint-Fortschritten (Roadmap für den GSUB-Motor, Phase 8c.5): Die neue THotPDF.GetCodepointAdvance (CP: Cardinal) bietet eine einzelne Methode, die den v2.76.0 /W-Cache zugänglich macht, sodass Aufrufer, die benutzerdefinierte Wortumbruchberechnungen außerhalb der BuildUnicodeMultilineFieldContent-Hilfsfunktion erstellen, den tatsächlichen skalierten Em-Fortschritt für jeden Codepoint abfragen können. Dieser Wert wird aus der hmtx-Tabelle der Schriftart über die zwischengespeicherte cmap abgeleitet. Nach der v2.119.32 / v2.119.58 / v2.119.60 / v2.119.62 statischen Ligatur-Nachbearbeitungsschleife + der GID-Level-GSUB-Verfeinerung, die Ligatur-Codepoints erzeugt (LAM-ALEF FEF5-FEFC, YEH-HAMZA FBEA-FBFB, Allah FDF2, Bismillah FDFD und GSUB-substituierte Präsentationsformen in FB50-FDFF / FE70-FEFF), gibt die Methode den tatsächlichen hmtx-Fortschritt des Ligatur-Glyphs zurück – typischerweise schmaler als die Summe der Fortschritte der Quell-Codepoints –, sodass die Umbruchbudgets der Aufrufer mit der Wiedergabe auf der Client-Seite übereinstimmen.
  • Verbesserung der Heuristik für mehrzeilige Unicode-Felder: Der in v2.65 verwendete Ausweichpfad (der verwendet wird, wenn der Cache für "/W" nicht verfügbar ist, z. B. der Pfad "RegisterUnicodeFontDict" anstelle von "RegisterUnicodeTTF") behandelte zuvor alle Codepunkte >= U+2E80 als breit (1,0 em). Arabische Präsentationsformen (FB50-FBFF Forms-A-Buchstaben, FC00-FDFF Forms-A-Ligaturen + Quranic FDF0-FDFD, FE70-FEFF Forms-B-Grundformen + LAM-ALEF) sind tatsächlich schmal (~0,55 em im Durchschnitt bei gängigen arabischen Schriftarten) und nicht breit. v2.119.64 leitet diese drei Bereiche arabischer Präsentationsformen zum schmalen Pfad (0,5 em) in der Heuristik-Ausweichmethode, wodurch ein Sonderfall behoben wird, bei dem arabische Ligaturen, die von den v2.119.32 / v2.119.58 / v2.119.60 / v2.119.62 / v2.119.63-Überläufen erzeugt werden, andernfalls fälschlicherweise eine Breite von 1,0 em erhalten würden, wenn der Cache nicht gefüllt ist.
  • Gibt 0 für den typischen Pfad ohne Informationen zurück (keine Schriftart registriert, Cache noch nicht gefüllt, Codepoint über BMP, Codepoint hat kein Glyphe in der Schriftart-cmap). Rein funktional, keine Seiteneffekte, sicher aufrufbar aus jedem Kontext, nachdem RegisterUnicodeTTF erfolgreich war. PDFs, deren geladene Schriftart einen gefüllten /W-Cache hat und die die neue Abfragemethode nicht verwenden, erzeugen eine byte-identische Ausgabe wie v2.119.63. Phase 8c.5 schließt die GSUB-Engine-Roadmap §8c ab und implementiert eine producer-seitige automatische arabische GSUB-Formgebungspipeline auf Capability-Ebene – Phase 8c.1-8c.5 liefern zusammen statische Tabellen-Post-Passes (4 Ligaturfamilien) + ToUnicode-Reverse-Mapping + GSUB-Verfeinerung auf GID-Ebene + eine öffentliche Advance-Abfrage, die alle zusammenarbeiten, um eine byte-genaue arabische Ligaturdarstellung auf der Producer-Seite mit der Anzeige auf der Consumer-Seite zu ermöglichen.

2026-05-22 Version 2.119.63

  • Verbesserungen auf GID-Ebene für die GSUB-Funktion 'rlig' (Roadmap für den GSUB-Motor, Phase 8c.2): Die neue Methode THotPDF.ApplyArabicGSUBRefinement (Wide) durchläuft die Eingabezeichenkette von links nach rechts und erstellt ein paralleles GID-Array mithilfe des zwischengespeicherten cmap (FUnicodeCpToGid). An jeder Position mit einem nicht-Null-GID-Wert wird die GSUB-Funktion 'rlig' (erforderliche Ligaturen) der Schriftart über die API ApplyLigatureSubstitution (Version v2.119.43-50) abgefragt. Wenn eine Ligaturen-Substitution erfolgt UND der ersetzende GID über einen Unicode-Arabisch-Präsentationszeichen (rückwärtssuche im cmap über U+FB50-U+FDFF + U+FE70-U+FEFF, ca. 690 Zeichen) erreichbar ist, wird das Quellzeichenfenster durch das Zeichen des Ersatzes ersetzt. Die ersetzten Glyphen werden auch durch MarkUnicodeGlyphUsed für den TTF-Subsetter (Version v2.84.0) geleitet.
  • In die drei Helferfunktionen `BuildUnicode*FieldContent` wurde unmittelbar nach der statischen Kette für die Codepoint-Nachbearbeitung (LAM-ALEF / YEH-HAMZA / Allah / Bismillah) in den Versionen v2.85.0 / v2.119.32 / v2.119.58 / v2.119.60 / v2.119.62 integriert. Diese Funktion ergänzt die statische Tabelle, indem sie schriftspezifische 'rlig'-Regeln berücksichtigt, die in den vier fest codierten Schriftfamilien nicht enthalten sind – typische Beispiele sind kontextuelle Varianten in persischen / urduischen / sindhischen / kurdischen Schriften (Vazirmatn, Markazi Text, Lateef, Scheherazade, Amiri), die auf Unicode-Präsentationsformen abgebildet werden, die über den Satz LAM-ALEF / YEH-HAMZA / Allah / Bismillah hinausgehen. Diese Funktion wird nur ausgeführt, wenn `FAutoShapeArabic` auf `true` gesetzt ist UND `sfArabicGSUB` NICHT in `FShapingFeatures` enthalten ist (ein Mutex schützt den "vom Aufrufer gesteuerten" Pfad aus v2.119.59) UND die geladene Schrift eine GSUB-Tabelle enthält.
  • Umfangsbeschränkung: Nur solche Ersetzungen werden ausgegeben, deren GIDs über einen Präsentationsform-Codepunkt über die cmap erreichbar sind. Schriftenspezifische GSUB-Ersetzungen, die auf beliebige Glyphen-IDs landen (ohne umgekehrte Codepunkt-Zuordnung), können nicht über diesen Pfad ausgegeben werden – sie benötigen eine vollständige GID-basierte Ausgabe in der Produktionspipeline, die für Phase 8c.5+ reserviert ist. Die umgekehrte cmap ist ein linearer Scan über etwa 690 Codepunkte pro Ersetzungsversuch; Ersetzungen sind in der Praxis selten, sodass die Kosten vernachlässigbar sind. PDFs, deren geladene Schrift keine GSUB-'rlig'-Inhalte enthält oder deren Ersetzungen keine Präsentationsform-Codepunkte haben, erzeugen eine byte-identische Ausgabe wie v2.119.62 (in diesen Fällen ist die Methode eine defensive No-Op). Mit dieser Änderung erhält die automatische arabische Formgebungspipeline auf Produzentenseite im GSUB-Modul eine schriftdaten-basierte Ligatur-Faltung, die über die bisher verwendete, statische Tabelle hinausgeht.

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.
  • Die ToUnicode-CM-Tabelle wurde um einen 28. bfchar-Eintrag erweitert, der U+FDFD auf die ursprüngliche 22-Zeichen-Sequenz abbildet (BEH + SEEN + MEEM + SPACE + ALEF + LAM + LAM + HEH + SPACE + ALEF + LAM + REH + HAH + MEEM + NOON + SPACE + ALEF + LAM + REH + HAH + YEH + MEEM). Die Textextraktion auf der Client-Seite (Kopieren/Einfügen/Barrierefreiheit) stellt jetzt die ursprüngliche 22-Zeichen-Phrase wieder her, anstatt des einzelnen Ligatur-Zeichens, wodurch das Roundtrip-Verhalten für die vier statischen Ligatur-Familien (LAM-ALEF / YEH-HAMZA / Allah / Bismillah) vervollständigt wird.
  • 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.
  • Abdeckung: 8 LAM-ALEF-Einträge U+FEF5-U+FEFC (v2.119.32, obligatorische Ligatur, 4 ALEF-Varianten × 2 Formen) → LAM + ALEF / ALEF MADDA / ALEF HAMZA OBEN / ALEF HAMZA UNTEN Quellpaare; 18 YEH-HAMZA-Einträge U+FBEA-U+FBFB (v2.119.58, enthält die Anfangsformen FBF8 und FBFB, die der automatische Nachbearbeitungsschritt nicht erzeugt, aber von Aufrufen direkt verwendet werden können) → YEH-HAMZA + ALEF / AE / WAW / U / OE / YU / E / ALEF MAKSURA Quellpaare; 1 Allah-Eintrag U+FDF2 (v2.119.60) → ALEF + LAM + LAM + HEH, eine Vier-Codepoint-Quellsequenz. Mit diesem Abschnitt ist der Kopiervorgang / Einfügen / die Barrierefreiheit für die drei statischen Tabellen-Ligaturfamilien abgeschlossen.
  • Byte-stabil für Inhalte ohne arabische Schriftzeichen: Der bfchar-Block fügt etwa 700 Byte unkomprimierten PostScript-Text zum CMap-Stream hinzu, was FlateDecode typischerweise auf etwa 150-200 Byte reduziert. PDFs ohne arabische Inhalte verwenden weiterhin das gleiche Layout für den /ToUnicode-Stream – die Erweiterung ist additiv innerhalb desselben indirekten FlateDecode-Stream-Objekts. Alle Client-Reader (Adobe Reader, Foxit, PDF.js, Apple Preview usw.) respektieren die Priorität von bfchar gegenüber bfrange und wenden die umgekehrte Zuordnung korrekt an. Der 27-Einträge umfassende Block ist fest im CMap-Text codiert (keine PDF-spezifische Anpassung erforderlich); in einer zukünftigen Phase 8c.4 werden zusätzliche bfchar-Einträge für die U+FDFD-Bismillah-Ligatur hinzugefügt.

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

  • Der neue opt-in-Framework für die serverseitige Formatierung (GSUB-Engine-Roadmap Phase 8a) umfasst die neue Enumeration `THPDFShapingFeature` sowie den Typ `THPDFShapingFeatures`, die die geplanten Feature-Flags für die serverseitige Textformatierung in den Phasen 8a bis 8e definieren. Die fünf Enumerationsmitglieder sind `sfArabicGSUB` (in dieser Version implementiert), `sfStandardLigatures` (Phase 8b, zukünftig), `sfContextualLigatures` (Phase 8b, zukünftig), `sfStylisticAlternates` (Phase 8d, zukünftig) und `sfIndicShaping` (Phase 8e, zukünftig). `THotPDF` erhält eine Eigenschaft namens `ShapingFeatures` vom Typ `THPDFShapingFeatures` mit dem Standardwert `[]` (alle Features deaktiviert); Aufrufer in der Version v2.119.32-58 erhalten eine byte-identische Ausgabe, solange die Eigenschaft ihren Standardwert beibehält.
  • sfArabicGSUB fungiert als Sperre gegen die statische Tabelle für die arabische Formatierung in Version 2.85.0. Wenn sfArabicGSUB in ShapingFeatures enthalten ist, überspringen die drei Helferfunktionen BuildUnicode*FieldContent (für einzeilige, mehrzeilige und kombinierte AcroForm /AP-Darstellungsstreams) vollständig die Funktion _ApplyArabicShaping – es findet keine Umschreibung von vierstelligen Codepunkten in Version 2.85.0 statt, auch kein nachträglicher Verarbeitungsschritt für LAM-ALEF in Version 2.119.32 und kein nachträglicher Verarbeitungsschritt für YEH-HAMZA + Vokal in Version 2.119.58. Der Aufrufer ist dafür verantwortlich, die arabische Formatierung über die GSUB-Engine-APIs (SetGSUBScript ('arab') + GetSingleSubstituteGlyph für die Feature-Tags 'init' / 'medi' / 'fina' / 'isol' + MarkUnicodeGlyphUsed für den Subsetter in Version 2.84.0) auszuwählen. In Kombination mit sfArabicGSUB können Aufrufer, die Noto Sans Arabic / Amiri / Scheherazade / Markazi Text / ähnliche arabische Schriftarten verwenden, jetzt die vollständige GSUB-basierte arabische Formatierung auf Seitenebene während der Erstellung durchführen, anstatt sich auf die statische Tabellen-Fallback-Methode zu verlassen.
  • 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 + Vokalbuchstaben-Ligatur-Nachbearbeitung: Der arabische Formgeber auf Produzentenseite, Version v2.85.0, integriert nun die 8 Ligaturpaare, die im arabischen Präsentationsformen-A-Block bei U+FBEA-U+FBFB kodiert sind, und wandelt sie nach dem 4-Positionen-Algorithmus und dem LAM-ALEF-Nachbearbeitungsschritt in einzelne Ligatur-Codepunkte um. Das Modell und die Integration sind identisch mit LAM-ALEF (obligatorische statische Tabellensubstitution, 2-Formen-Ausgabe pro Ligatur). Abgedeckte Paare: YEH-HAMZA + ALEF -> FBEA/FBEB (Standard-Arabisch / Persisch / Urdu), YEH-HAMZA + AE U+06D5 -> FBEC/FBED (Kaschmirisch / Uigurisch), YEH-HAMZA + WAW -> FBEE/FBEF (Standard-Arabisch), YEH-HAMZA + U U+06C7 -> FBF0/FBF1 (Uigurisch / Kasachisch / Kirgisisch), YEH-HAMZA + OE U+06C6 -> FBF2/FBF3 (gleich), YEH-HAMZA + YU U+06C8 -> FBF4/FBF5 (gleich), YEH-HAMZA + E U+06D0 -> FBF6/FBF7 (gleich), YEH-HAMZA + ALEF MAKSURA -> FBF9/FBFA (Standard-Arabisch).
  • YEH-HAMZA wird entweder in seiner ursprünglichen Form (U+0626) oder in einer seiner in v2.85.0 definierten Varianten (FE89 isoliert, FE8A final, FE8B initial, FE8C medial) gefunden; der folgende Vokal wird entweder in seiner ursprünglichen Form oder in einer seiner in v2.119.57 definierten Varianten (FBD7-FBD8 für U, FBD9-FBDA für OE, FBDB-FBDC für YU, FBE4-FBE7 für E) oder in den in v2.85.0 definierten Varianten (FE8D-FE8E für ALEF, FEED-FEEE für WAW, FEEF-FEF0 für ALEF MAKSURA) gefunden. Die Auswahl der Endform (Basis + 1) folgt der LAM-ALEF-Regel: Wenn YEH-HAMZA in die Endform (FE8A) oder die Medialform (FE8C) umgewandelt wurde (d.h. es wird von einem Buchstaben mit doppelter Verbindung gefolgt), wird die Ligatur in ihrer Endform ausgegeben; andernfalls wird die isolierte Form verwendet.
  • Umfangsbegrenzungen: Nur die isolierten und endgültigen Formen (2-Form-Ausgabe) werden von dieser Nachverarbeitung erzeugt. Die vom Unicode definierten Anfangsformen FBF8 (YEH-HAMZA + E) und FBFB (UIGHUR YEH-HAMZA + ALEF MAKSURA) werden nicht erzeugt – Aufrufer, die diese dreiförmigen Varianten benötigen, verwenden die verketteten, kontextabhängigen GSUB-Lookups 'rlig' / 'clig' über ApplyContextualSubst. Andere arabische Ligaturregionen (Allah U+FDFA / FDFB, dekorative Ligaturen bei FC00-FDC7) erfordern GSUB 'rlig' / 'dlig' und liegen außerhalb des Geltungsbereichs des statischen Tabellen-Shapers. PDFs ohne YEH-HAMZA, gefolgt von einem der acht unterstützten Vokale, erzeugen eine byte-identische Ausgabe wie v2.119.57; die neue Nachverarbeitung wird nur für die spezifischen 2-Codepoint-Sequenzen ausgeführt.

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.
  • Von den neu klassifizierten Buchstaben haben 26 zusätzlich statische Presentation Forms-A-Einträge in U+FB52-U+FBFC und werden jetzt direkt vom statischen Tabellen-Shaper zugeordnet, ohne dass ein Font-GSUB-Shaper erforderlich ist: 15 D-verknüpfte 4-Form-Buchstaben (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, welches der Standard-Urdu-Buchstabe 'h' ist, und E U+06D0 → FBE4-FBE7 für arabische Buchstaben im Kazakh/Kyrgyz-Stil), sowie 11 R-verknüpfte 2-Form-Buchstaben (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, welches das Urdu-Wort-Ende 'yeh' ist, und YEH BARREE WITH HAMZA ABOVE U+06D3 → FBB0-FBB1).
  • Die beiden Zeichen HEH DOACHASHMEE und YEH BARREE verdienen eine besondere Erwähnung, da ihre Forms-A-Slots (FBAA-FBAD und FBAE-FBAF) fälschlicherweise von der v2.119.52-Version U+06C2 HEH GOAL WITH HAMZA ABOVE und U+06C3 TEH MARBUTA GOAL zugewiesen wurden. Mit v2.119.56 wurden diese falschen Zuordnungen rückgängig gemacht, und mit v2.119.57 wurden die Slots den korrekten Quellzeichen zugeordnet, wodurch der Audit-Trail sauber ist und die Verwechslung dauerhaft behoben wurde. Zeichen im Bereich U+0672-U+06D5, die keine Presentation Forms-A-Einträge in Unicode 16 haben (etwa 50 zusätzliche Codepunkte, hauptsächlich Varianten von REH / DAL / SEEN / SAD / TAH / AIN / FEH / QAF / KAF ohne vorab codierte Formen), nehmen weiterhin an der Joining-Class-Analyse teil, sodass benachbarte Zeichen korrekt geformt werden; die Zeichen selbst werden als rohe Codepunkte übergeben und verlassen sich auf die GSUB-Lookup-Tabellen der Schriftart unter dem GSUB-Engine v2.119.43-50 für ihre eigene Formauswahl. Kompiliert mit 78018 Zeilen; PDFs ohne diese neuen Codepunkte erzeugen Byte-identische Ergebnisse wie v2.119.56.

2026-05-22 Version 2.119.56

  • Fehlerbehebung für die arabische Schriftgestaltung: In v2.119.52 wurden falsche arabische Präsentationsformen-A-Zuordnungen für zwei Zeichen aus der Urdu/Sindh-Region eingeführt. U+06C2 HEH GOAL WITH HAMZA ABOVE wurde auf FBAA-FBAD abgebildet, was tatsächlich der Codepoint-Bereich für U+06BE HEH DOACHASHMEE ist; Client-Reader würden das Urdu-Zeichen "Goal-Heh-with-Hamza" als das Standard-Urdu-Zeichen "Heh-Doachashmee" darstellen. U+06C3 TEH MARBUTA GOAL wurde auf FBAE-FBAF abgebildet, was tatsächlich der Codepoint-Bereich für U+06D2 YEH BARREE ist; Reader würden "Teh-Marbuta-Goal" als das Urdu-Wort "Yeh-Barree" darstellen. Gemäß Unicode 16.0 haben weder U+06C2 noch U+06C3 vordefinierte Präsentationsformen-A-Einträge; beide müssen unverändert als Roh-Codepoints durchlaufen werden (Client-Reader zeigen sie korrekt über die cmap der Schriftart und jegliche GSUB-basierte Schriftgestaltung an).
  • Behebung: Die beiden fehlerhaften Einträge in der _ArabicShape Presentation Forms-A_-Nachschlagetabelle des arabischen Formatierungsprogramms auf Produzenseite in Version v2.85.0 wurden entfernt; U+06C2 und U+06C3 werden jetzt zum Durchgriffpfad weitergeleitet und ohne Änderung ausgegeben. Die Einträge für die Verbindungsklasse aus Version v2.119.52 (D für U+06C2, R für U+06C3) bleiben erhalten, sodass benachbarte Buchstaben weiterhin die korrekten Positionsformen verwenden, wenn diese Zeichen in einem Wort vorkommen. Diese Korrektur betrifft nur PDFs, die U+06C2 oder U+06C3 mit aktivierter AutoShapeArabic-Funktion enthalten; PDFs ohne diese beiden Codepunkte sind byteidentisch zur Ausgabe von v2.119.55. Die zugehörige Version v2.119.57 erweitert die Forms-A-Abdeckung auf zusätzliche persische/urdu/sindhi/kashmirische/uigurische/kasachische/kirgisische Buchstaben, einschließlich der tatsächlich als Forms-A-kodierten HEH DOACHASHMEE und YEH BARREE, die im Fehler von v2.119.52 fälschlicherweise miteinander verwechselt wurden.

2026-05-22 Version 2.119.55

  • Devanagari-Schriftsatzfunktionen: Zwei neue öffentliche Methoden in THotPDF decken das für indische Schriften spezifische Schriftsatzparadigma ab, das nicht mit dem für Arabisch/Syrisch/Mongolisch verwendeten 4-Positionen-Verbindungs-Klassen-Algorithmus kompatibel ist (v2.85.0 + v2.119.32-54). GetDevanagariCategory (CP) gibt die vereinfachte indische Silbenkategorie zurück (0 = Andere, 1 = Konsonant, 2 = Unabhängiger Vokal, 3 = Matra, 4 = Virama, 5 = Nukta, 6 = Bindu, 7 = Visarga, 8 = Danda, 9 = Ziffer, 10 = ZWJ, 11 = ZWNJ, 12 = Modifikator) gemäß Unicode 16.0 §12.1 + IndicSyllabicCategory.txt; die Tabelle deckt den gesamten Devanagari-Block U+0900-U+097F ab, einschließlich der Marwari-/Sindhi-/Vedischen-Erweiterungen in U+0978-U+097F.
  • ApplyDevanagariReorder (Wide) durchläuft die Eingabezeichenkette von links nach rechts und wendet den Devanagari-Umordnungs-Vorprozess auf jede gefundene Devanagari-Silbe an und gibt eine umordnete Unicode-Zeichenkette zurück, die für cmap- und GSUB-Verarbeitung bereit ist. Nicht-Devanagari-Inhalte (Latein, Ziffern, Interpunktion, andere Schriften) werden unverändert durchgegeben. Zwei Umordnungsalgorithmen werden implementiert (die beiden, die in der realen Devanagari-Formatierung dominieren): (1) Repha – wenn eine Silbe mit Ra (U+0930) + Halant (U+094D) + Konsonant beginnt, wird das Paar (Ra, Halant) an das ENDE der Silbe verschoben, sodass die GSUB-Funktion 'rphf' der Schriftart sie durch das Repha-Glyphe ersetzt, das visuell oberhalb und rechts der Basis der Silbe angebracht ist; (2) Vor-Basis I-matra – U+093F wird an den allerersten Anfang der Silbe verschoben (nachdem eventuell Repha entfernt wurde), sodass die GSUB-Verarbeitung von links nach rechts sie vor der Konsonantenkombination sieht, was der visuellen Reihenfolge entspricht.
  • Aufrufpipeline: Anwendung von ApplyDevanagariReorder auf den text in logischer Reihenfolge -> SetGSUBScript ('deva') -> Durchlaufen der neu angeordneten Codepunkte und Anwenden von GSUB-Funktionen ('nukt' / 'akhn' / 'rphf' / 'rkrf' / 'half' / 'vatu' / 'cjct' / 'pres' / 'blws' / 'abvs' / 'psts' / 'haln') über GetSingleSubstituteGlyph + ApplyLigatureSubstitution + ApplyContextualSubst -> Ausgeben der resultierenden GIDs in den PDF-Textstrom, wobei MarkUnicodeGlyphUsed (GID) für jede Ausgabe aufgerufen wird, für den v2.84.0-Subsetter. Mit Phase A (v2.119.52 Arabic Extended-A), Phase B (v2.119.53 Syriac), Phase C (v2.119.54 Mongolian) und Phase D (v2.119.55 Devanagari Indic), die alle implementiert sind, ist die Lücke "Mongolian / Syriac / Devanagari-Formatierung" vollständig geschlossen. Außerhalb des Geltungsbereichs: Nicht-Devanagari-Indic-Schriften (Bengali, Tamil, Telugu, Gujarati – jede hat ihre eigenen Kategoriedaten und Anordnungsregeln), Anordnungsregeln über Repha hinaus und automatische Devanagari-Formatierung auf Produzentenseite innerhalb von TextOut / BuildUnicode*FieldContent (für Phase 8 der GSUB-Engine-Roadmap reserviert).

2026-05-22 Version 2.119.54

  • Mongolische Formatierungsfunktionen: Zwei neue öffentliche Methoden in THotPDF ermöglichen die mongolische (U+1800-U+18AF) Zeichenverknüpfung und die kontextuelle Analyse in 4 Positionen, sodass Aufrufer die Formatierung des mongolischen Texts auf der Produktionsseite steuern können. GetMongolianJoiningClass (CP) gibt die mongolische Verknüpfungsklasse gemäß Unicode 16.0 §13.5 zurück (0 = nicht verknüpft, 2 = doppelt verknüpft, 4 = transparent / Variationsauswahl) für jeden Codepunkt; die Tabelle deckt das grundlegende Mongolisch sowie die Erweiterungen Todo, Sibe, Manchu und Ali Gali ab (U+1820-U+1878 + U+1887-U+18A8 + ALI GALI DAGALGA U+18A9 + MANCHU ALI GALI LHA U+18AA) und klassifiziert NIRUGU (U+180A) sowie die drei Free Variation Selectors FVS1-FVS3 (U+180B-U+180D) und die Ali Gali BALUDA / THREE BALUDA Vokalphoneme (U+1885-U+1886) als transparent. GetMongolianPosition (Wide, Index) durchläuft den umgebenden Text, überspringt transparente Zeichen und gibt 0 = isoliert, 1 = final, 2 = initial oder 3 = medial für den Buchstaben am 0-basierten Index zurück.
  • Wie Syrisch (v2.119.53) hat auch Mongolisch KEINE vorab codierten Präsentationsformen in Unicode – jede Schriftart, die Mongolisch unterstützt (Mongolian Baiti, Noto Sans Mongolian, Noto Serif Mongolian usw.), verwendet positionsabhängige Formatierung über OpenType GSUB-Lookups in ihren 'init'-/'medi'-/'fina'-/'isol'-Features unter dem Skript-Tag 'mong'. v2.119.54 folgt daher dem gleichen Funktionsmodell wie v2.119.53; Aufrufer kombinieren die Positionsausgabe mit den GSUB-Engine-APIs (SetGSUBScript ('mong'), GetSingleSubstituteGlyph für das entsprechende positionsabhängige Feature-Tag, MarkUnicodeGlyphUsed für den Subsetter v2.84.0), um formatierte GIDs zu erzeugen, die direkt in den PDF-Textstrom geschrieben werden.
  • Mongolisch wird in seiner ursprünglichen Schriftart vertikal von oben nach unten geschrieben; der Algorithmus verarbeitet die logische Codepoint-Reihenfolge (Vorheriger/Nächster im Codepoint-Stream), unabhängig von der visuellen Ausrichtung. Die tatsächliche vertikale Darstellung wird zur PDF-Generierungszeit über /WMode 1 (vertikale Schrift) oder eine Schriftmatrix-Rotation behandelt, nicht durch den Formgeber. Die Klassifizierung von Free Variation Selectors (FVS) als transparent bedeutet, dass der Algorithmus Positionierungsformen korrekt auflöst, auch wenn ein FVS auf einen Buchstaben folgt; die GSUB-Suche der Schrift unter den Features 'fina', 'medi', 'init' und 'isol' wählt automatisch die FVS-abhängige Variante aus, wenn ein FVS in der Eingabe vorhanden ist. Die Devanagari-Formatierung (indische Schrift) bleibt für zukünftige Versionen reserviert, da sie einen separaten Vorverarbeitungsschritt für die Reorganisation von Zeichen gemäß UAX #38 (virama / Konsonantencluster / Vorzeichen-Reihenfolge) erfordert, was nicht mit dem 4-Positionen-Algorithmus kompatibel ist, der für Arabisch, Syrisch und Mongolisch verwendet wird. Die automatische Mongolisch-Formatierung innerhalb von TextOut / BuildUnicode*FieldContent bleibt für Phase 8 der GSUB-Entwicklungsplanung reserviert.

2026-05-22 Version 2.119.53

  • Syrische Formatierungsfunktionen: Zwei neue öffentliche Methoden in THotPDF ermöglichen die syrische (U+0700-U+074F) Zeichenverknüpfung und eine kontextuelle Analyse mit 4 Positionen, sodass Aufrufer die Formatierung des syrischen Texts auf der Produktionsseite steuern können. GetSyriacJoiningClass (CP) gibt die Unicode 16.0 syrische Formatierungszeichenklasse (0 = Zeichen ohne Verknüpfung, 1 = rechtsseitige Verknüpfung, 2 = doppelte Verknüpfung, 4 = transparent / NSM) für jeden Codepunkt zurück; die Tabelle deckt alle 35 syrischen Buchstaben des Basissatzes sowie die persischen und sogdischen Erweiterungen ab (PERSISCHES BHETH / GHAMAL / DHALATH bei U+072D-U+072F, SOGDISCHES ZHAIN / KHAPH / FE bei U+074D-U+074F) und klassifiziert das OBERE ALAPH (U+0711) sowie die syrischen diakritischen Zeichen (U+0730-U+074A) als transparent. GetSyriacPosition (Wide, Index) durchläuft den umgebenden Text, überspringt transparente Zeichen und gibt 0 = isoliert, 1 = final, 2 = initial oder 3 = medial für den Buchstaben am 0-basierten Index zurück.
  • Im Gegensatz zum Arabischen (das über vorab kodierte Präsentationsformen B (U+FE70-U+FEFF) und Formen A (U+FB50-U+FBFF) verfügt, die es HotPDF ermöglichen, Codepunkte direkt in geformte Varianten umzuwandeln), verfügt der syrische Block NICHT über vorab kodierte Präsentationsformen in Unicode – jede syrisch-fähige Schrift (Estrangelo Edessa, Serto Jerusalem, East Syriac Adiabene, Noto Sans Syriac usw.) verwendet positionsabhängige Formatierung über OpenType GSUB-Lookups in ihren 'init'-/'medi'-/'fina'-/'isol'-Features. Daher enthält v2.119.53 nur die Fähigkeits-Ebene; der Aufrufer kombiniert die Positionsausgabe mit den GSUB-Engine-APIs von v2.119.43-50 (SetGSUBScript ('syrc'), GetSingleSubstituteGlyph für das entsprechende positionsabhängige Feature-Tag, MarkUnicodeGlyphUsed für den v2.84.0-Subsetter) um geformte GIDs zu erzeugen, die direkt in den PDF-Textstrom geschrieben werden.
  • Der Bereich für die Terminalform von Alaph: Unicode §9.3 beschreibt zwei kontextuelle Terminalfunktionen ('fin2', die nach DALATH / RISH angewendet wird, und 'fin3', die nach FINAL LAMADH angewendet wird), die syrische Schriftarten verwenden, um die finale Glyphe von Alaph auszutauschen. In v2.119.53 wird Alaph (U+0710) als grundlegende rechtsverknüpfende Schriftzeichen klassifiziert und gibt nur 0 (isoliert) oder 1 (final) zurück; Aufrufer, die eine Unterscheidung zwischen 'fin2' und 'fin3' benötigen, steuern die verketteten kontextuellen Nachschlagevorgänge der Schriftart über `ApplyContextualSubst` mit diesen Feature-Tags. Die Formatierung für Mongolisch und Devanagari (Indisch) ist für zukünftige Versionen reserviert: Mongolisch verwendet Free Variation Selectors plus Vokalharmonie, Devanagari erfordert einen separaten Vorverarbeitungsschritt gemäß UAX #38, und keines davon passt zum syrischen 4-Positionen-Algorithmus. Die automatische syrische Formatierung innerhalb von `TextOut` / `BuildUnicode*FieldContent` bleibt für Phase 8 der GSUB-Entwicklungsroadmap reserviert.

2026-05-22 Version 2.119.52

  • Arabische Schriftfamilien-Formatierungserweiterung: Die serverseitige, statische arabische Formatierungsfunktion der Version 2.85.0 deckt nun die verbleibenden Zeichen des Blocks Arabic Extended-A ab (ALEF WASLA U+0671, NOON GHUNNA U+06BA, HEH-Varianten U+06C0-U+06C3), den Block Arabic Supplement U+0750-U+077F (arabische Buchstaben, die in Hausa, Wolofal und anderen afrikanischen Sprachen verwendet werden) sowie die neue Region Arabic Extended-A U+08A0-U+08FF (koranisches Arabisch + erweiterte Buchstaben für Wolofal/Hausa + koranische Kombinationszeichen). Die Verbindungsregeln stammen aus der Datei ArabicShaping.txt in Unicode 16.0 und werden während der Vier-Positionen-Positionsanalyse in der Version 2.85.0 angewendet, sodass benachbarte Zeichen unabhängig davon, welche arabische Variante sie umgibt, die korrekte init-, medi-, fina- oder isol-Form auswählen.
  • Buchstaben, die in der Blockgruppe "Arabic Presentation Forms-A" (U+FB50-U+FBFF) vordefinierte statische Darstellungsformen haben, werden jetzt direkt auf diese Formen abgebildet, ohne dass eine OpenType-GSUB-Formatierung erforderlich ist: ALEF WASLA -> FB50/FB51 (rechtsverbindend, zwei Formen), NOON GHUNNA -> FB9E/FB9F (doppeltverbindend gemäß Unicode, aber nur zwei vordefinierte Formen; init/medi werden elegant zu isol reduziert), HEH MIT YEH OBEN -> FBA4/FBA5 (rechtsverbindend, zwei Formen), HEH GOAL -> FBA6/FBA7/FBA8/FBA9 (doppeltverbindend, alle vier Formen), HEH GOAL MIT HAMZA OBEN -> FBAA/FBAB/FBAC/FBAD (doppeltverbindend, alle vier Formen), TEH MARBUTA GOAL -> FBAE/FBAF (rechtsverbindend, zwei Formen). In Kombination mit der obligatorischen Nachbearbeitung für die Ligatur LAM-ALEF in Version 2.119.32 und dem Kern-Subset von 9 Buchstaben für Persisch/Urdu in Version 2.119.35 deckt die statische Formatierung nun praktisch alle modernen arabischen, persischen, urdu-, sindhi-, paschtu-, kurdischen, uigurischen, koranischen und afrikanischen arabischen (Hausa, Wolofal usw.) Texte ab, ohne auf die GSUB-Tabelle der Schriftart angewiesen zu sein.
  • Die Zeichen der arabischen Ergänzung (U+0750-U+077F) und der neueren arabischen erweiterten A-Buchstabenregion (U+08A0-U+08C7) haben keine vordefinierten statischen Darstellungsformen; ihre Verbindungs-Klassen ermöglichen es benachbarten Zeichen, korrekt geformt zu werden, aber die Buchstaben selbst bleiben als Roh-Codepunkte und benötigen eine GSUB-fähige Schriftart (oder die von der aufrufenden Anwendung gesteuerten GSUB-Engine-APIs der Version 2.119.43-50), um ihre eigene Positionierung zu bestimmen. Der Bereich der arabischen erweiterten A-Quran-Kombinationszeichen (U+08CA-U+08E1, U+08E3-U+08FF) wird als transparent (T-Verbindung) klassifiziert, sodass die Analyse der Position benachbarter Zeichen diese überspringt, was der bestehenden Behandlung von Harakat (U+064B-U+065F) entspricht. Text, der diese erweiterten Zeichen nicht enthält, bleibt byte-identisch zu den Ergebnissen von Version 2.119.51. Die Formgebung für Mongolisch/Syrisch/Devanagari (unterschiedliche Formgebungsmodelle im Vergleich zu Arabisch) ist für zukünftige Versionen reserviert.

2026-05-22 Version 2.119.51

  • XFA (XML Forms Architecture) bietet jetzt Unterstützung für Container auf der Produktionsseite: PDF 1.7 §12.7.6 + §12.7.8 ermöglicht es einem AcroForm, einen Eintrag /XFA zusammen mit (oder anstelle von) dem statischen Array /Fields zu enthalten. Die neue Funktion THotPDF.AddXFAPacket (PacketName, XMLBytes) registriert ein benanntes XFA-Paket – typische Namen sind 'template' (Formlayout + Skripte), 'datasets' (Datenbindung), 'config' (Viewer-Konfiguration), 'connectionSet', 'localeSet', 'stylesheet', 'xfdf', 'xmpmeta', 'signature' und 'sourceSet'. Jedes registrierte Paket wird zu einem indirekten, FlateDecode-komprimierten Stream am Ende des Dokuments, und das Array /XFA wechselt zwischen PDF-Strings für Paketnamen und Stream-Referenzen in der Registrierungsreihenfolge, sodass das Layout byteweise deterministisch ist. THotPDF.ClearXFAPackets und THotPDF.XFAPacketCount erweitern die API-Oberfläche.
  • Container-level-Unterstützung – HotPDF parst das XFA-XML nicht, implementiert keinen XFA-dynamischen Layout-Engine, führt keinen FormCalc oder JavaScript innerhalb der XFA-Vorlage aus und validiert die Template-Struktur nicht. Der Aufrufer erstellt das XFA-XML selbst (typischerweise mit Adobe LiveCycle Designer oder manuell anhand der XFA 3.3-Spezifikation), und HotPDF gibt die Bytes unverändert aus. Konsumenten-Reader mit einem XFA-Engine (ältere Acrobat-/Reader-Versionen, FormsCentral, einige Kiosk-Produkte) rendern das Formular; Reader ohne XFA-Engine (Adobe Reader DC ab 2017, die meisten Open-Source-Reader) zeigen die Fallback-AcroForm-Felder an, wenn das Dokument ein hybrider AcroForm- und XFA-Workflow ist.
  • PDF/A und PDF/X-Konformitätsprüfungen: ISO 19005-1 §6.4.2 / ISO 19005-2 §6.4.2 / ISO 19005-3 §6.4.2 schließen XFA-Formulare ausdrücklich aus (die dynamische Layout-Engine ist nicht deterministisch archivierbar). ISO 15930-Druckvorbereitungsworkflows lehnen interaktive Formulare vollständig ab. `AddXFAPacket` löst sofort einen Fehler aus, wenn `PDFACompliance` oder `PDFXCompliance` nicht leer sind, wobei die entsprechende Spezifikationsreferenz angegeben wird. Doppelte Paketnamen führen zu einem Fehler. Ein leerer `PacketName` oder leere `XMLBytes` führen ebenfalls zu einem Fehler. `RequirePDFVersion (pdf15)` erhöht automatisch die Dokumentversion. Das `AcroForm`-Dictionary wird jetzt ausgegeben, wenn entweder `/Fields` mindestens einen Eintrag enthält ODER mindestens ein XFA-Paket registriert wurde; ältere Aufrufer (vor v2.119.51), die keine Pakete registrieren, erhalten weiterhin eine `/AcroForm`-Ausgabe mit identischen Bytes.

2026-05-22 Version 2.119.50

  • TTF-Subsetter-Funktion für GSUB-Ersatzglyphen: Die neue Funktion `THotPDF.MarkUnicodeGlyphUsed (GID: Word)` wählt ein Glyphe für den v2.84.0 EndDoc-Subsetter aus, unabhängig davon, ob die cmap einen Codepoint für dieses Glyphe enthält. Die v2.84.0-Funktion leitet ihren Satz der verwendeten Glyphen aus `FUnicodeUsedCps` über die cmap ab, sodass alle durch GSUB eingeführten Ersatzglyphen – stilistische Alternativen, Ligaturen, kontextuelle Varianten, die gesamte Ausgabe der Phase 1-6-API-Abfragen – zuvor für den Subsetter unsichtbar waren und der lesende Client stattdessen `.notdef` darstellte. Nach der Ausgabe eines GID, der von `GetSingleSubstituteGlyph / GetMultipleSubstituteGlyphs / GetAlternateGlyph / ApplyLigatureSubstitution / ApplyContextualSubst / ApplyReverseChainedContextualSubst` zurückgegeben wird, ruft der Aufrufer jetzt einmal pro ausgegebenem GID `MarkUnicodeGlyphUsed (GID)` auf, um dieses in den eingebetteten Subset aufzunehmen.
  • Der Helfer ist idempotent (wiederholte Aufrufe mit derselben GID haben keine Auswirkung), robust (GID-Werte, die größer oder gleich FUnicodeNumGlyphs sind, werden stillschweigend verworfen, Aufrufe, die vor einem RegisterUnicodeTTF-Aufruf erfolgen, haben keine Auswirkung) und integriert sich in den v2.84.0-Komposit-Glyphen-Abschluss innerhalb von _BuildSubsetTTF. Aufrufer müssen nur die GID des obersten Substitutions-Glyphen markieren – die Komponentenglyphen werden automatisch von der vorhandenen _TTFWalkCompositeClosure-Funktion abgerufen. Der Satz wird bei der ersten Verwendung dynamisch zugewiesen und bei jedem RegisterUnicodeTTF-Aufruf (auf '') auf leer zurückgesetzt, zusammen mit dem restlichen Subset-Zustand. Mit der Implementierung von Phase 9 können alle GSUB-API-Abfragen der Phasen 1-7 sicher mit der Subset-Ausgabe kombiniert werden, ohne dass die Substitutions-Glyphen aus der eingebetteten Schriftart verloren gehen.

2026-05-22 Version 2.119.49

  • OpenType GSUB Skript-/Sprachsystemauswahl-API: Fünf neue öffentliche Methoden in THotPDF ermöglichen es Aufrufern, GSUB-Nachschlagetabellen an ein bestimmtes Skript und eine bestimmte Sprache zu binden, anstatt auf die historische DFLT-Skript-/Standard-Sprachsystem-Fallback-Methode zurückzugreifen. SetGSUBScript ('latn' / 'arab' / 'cyrl' / 'hani' / 'kana' / 'deva' / 'beng' / 'taml' / usw.) wählt einen OpenType-Skript-Tag aus; die Standardeinstellung (leerer String) behält die Baseline von v2.119.43-48 bei (bevorzugt 'DFLT', andernfalls das erste Skript). SetGSUBLanguage ('ENG ' / 'TUR ' / 'AZE ' / 'JAN ' / 'KOR ' / 'ARA ' / usw., mit Leerzeichen aufgefüllt, um 4 Bytes zu ergeben) wählt einen OpenType-Sprach-Tag aus; ein leerer String ist das Standardsprachsystem des Skripts. Beide Einstellungen bleiben bei GSUB-Abfragen erhalten und werden auf einen leeren String zurückgesetzt, wenn RegisterUnicodeTTF ('', nil) aufgerufen wird.
  • Drei neue Hilfsfunktionen geben Auskunft darüber, welche Eigenschaften die geladene Schriftart anbietet: `GetGSUBScripts`: `TGSUBStringArray` gibt jedes Skript-Tag in der Reihenfolge der `ScriptList` zurück; `GetGSUBLanguages (ScriptTag)` gibt jedes Sprach-Tag unter dem angegebenen Skript zurück (mit einem leeren Platzhalter an Index 0, wenn das Skript ein Standard-LangSys hat); `GetGSUBFeatures (ScriptTag, LangTag)` gibt jedes Feature-Tag (z. B. 'liga', 'salt', 'aalt', 'ss01' bis 'ss20') zurück, das von dem (Skript, Sprache)-Pfad im `LangSys` in der Reihenfolge der `featureIndices` angegeben wird. Leere `ScriptTag`- und `LangTag`-Werte verwenden die gleiche Standard-Fallback-Logik wie die Substitutions-APIs, sodass Aufrufer `GetGSUBFeatures ('', '')` aufrufen können, um die Standard-Pfade-Features aufzulisten, ohne zuerst die Skriptliste zu prüfen.
  • Strikte vs. Fallback-Auswahlsemantik: Wenn SetGSUBScript auf einen Tag gesetzt ist, den die geladene Schriftart nicht anbietet, geben nachfolgende GSUB-Abfragen leere Ergebnisse oder "no-op"-Ergebnisse zurück – die Engine greift NICHT stillschweigend auf DFLT zurück, sodass Aufrufer klar erkennen können, dass das ausgewählte Skript nicht verfügbar ist. Wenn SetGSUBLanguage auf einen nicht erkannten Tag gesetzt ist, greift es GEMÄSS der Empfehlung in der OpenType-Spezifikation auf die Standard-LangSys des Skripts zurück. Die sieben bestehenden GSUB-Ersetzungsmethoden (GetSingleSubstituteGlyph / GetMultipleSubstituteGlyphs / GetAlternateGlyphCount / GetAlternateGlyph / ApplyLigatureSubstitution / ApplyContextualSubst / ApplyReverseChainedContextualSubst) behalten ihre öffentlichen Signaturen byte-identisch; nur die interne Hilfsfunktion _GSUBFindFeatureLookups erhält zwei zusätzliche Parameter, die nun von allen sieben Aufrufstellen durchgeleitet werden. Mit der Script-/LangSys-API und der LookupType-Matrix 1-8 ist der GSUB-Motor für den reinen Funktionsumfang vollständig; die verbleibenden Planphasen (automatische Formgebungspipeline + TTF-Subsetter) zielen auf die Integration auf Produzenseite ab und nicht auf neue Abfrageoberflächen.

2026-05-22 Version 2.119.48

  • OpenType GSUB Reverse Chained Contextual Single Substitution (LookupType 8): Die neue Funktion `THotPDF.ApplyReverseChainedContextualSubst (const InputGIDs; StartIndex; FeatureTag; out OutGID): Boolean` ist der letzte GSUB-Lookup-Typ, der implementiert wurde. Dieser Typ 8 ermöglicht eine kontextabhängige, einfache 1:1-Substitution, bei der das zu ersetzende Glyphe anhand des Coverage-Index des Eingabeglyphen ausgewählt wird. Das Besondere an dieser Funktion ist, dass der Aufrufer sie in umgekehrter Scanreihenfolge über eine Zeichenkette mehrerer Glyphen anwenden muss (Ende → Anfang), da jede Substitution von einem zukünftigen Kontext abhängen kann, der noch nicht substituiert wurde. Diese Hilfsfunktion ist ein Single-Point-Applicator – der Aufrufer steuert die Schleife für das umgekehrte Scannen. Formate 1 und 2 für Coverage, die Berücksichtigung von LookupFlags (Eingabe + Rückverfolgung + Vorlauf, alle mit Skip-Bewusstsein) und die Unterstützung von Erweiterungen (LookupType 7) sind alle implementiert.
  • Typischer Anwendungsfall: Bestimmte arabische/syrische/N'Ko/indische kontextuelle Alternativen, deren endgültige Form von der Form des folgenden Glyphen abhängt. Einige Schriftarten verwenden dies auch zur Unterscheidung von lateinischen Zeichenfolgen. Im Gegensatz zu LookupType 5/6 verfügt Type 8 nicht über verschachtelte Suchmechanismen, da die Substitution intrinsisch 1:1 ist. Wenn keine Übereinstimmung gefunden wird, wird False zurückgegeben. OutGID = InputGIDs[StartIndex] (eine bestmögliche Durchleitung, die dem Vertrag von GetSingleSubstituteGlyph v2.119.43 entspricht).
  • Schließt die LookupType-Matrix: Ab Version v2.119.48 verfügt jeder OpenType GSUB LookupType (1 bis 8) über eine dedizierte öffentliche Funktion in THotPDF. Die API zur Auswahl von Skripten/Sprachsystemen, die automatische Formgebungspipeline-Integration und das automatische Einbinden von Ersatzglyphen durch den TTF-Subsetter bleiben für die Phasen 7-9 reserviert; Aufrufer sind weiterhin dafür verantwortlich, die ausgewählten Ersatzglyphen in den eingebetteten Schriftart-Subset einzufügen und den Reverse-Scan-Loop selbst zu steuern.

2026-05-22 Version 2.119.47

  • OpenType GSUB Kontextuelle und verkettete kontextuelle Substitution (LookupType 5 + 6): Die neue Funktion THotPDF.ApplyContextualSubst (const InputGIDs; StartIndex; FeatureTag; var OutGIDs; out ConsignedLen): Boolean ist ein einzelner Einstiegspunkt, der sowohl LookupType 5 (nur Eingabekontext) als auch LookupType 6 (Rückverfolgung / Eingabe / Vorausblick-Kontext) für alle drei Subtabellenformate abdeckt – Format 1 (Literal-Glyphen-ID-Sequenzen), Format 2 (ClassDef-Klassen-Sequenzen) und Format 3 (Coverage-Tabellen-Sequenzen, die kanonische Form, die von den meisten modernen Schriftarten verwendet wird). Die kanonischen Anwendungsfälle sind 'rclt' (Erforderliche kontextuelle Alternativen – arabische positionsbezogene Formen init/medi/fina/isol, wenn die Schriftart sie über GSUB steuert), 'clig' (Kontextuelle Ligaturen), 'calt' (Kontextuelle Alternativen) und die indischen Formatierungsfunktionen 'pres' / 'blws' / 'psts' / 'half' / 'pstf' / 'cjct'.
  • Verschachtelte Suchabfragen: Wenn eine kontextuelle Regel übereinstimmt, löst jeder Eintrag in der SequenceLookupRecord eine verschachtelte Suche an einer bestimmten Position innerhalb der übereinstimmenden Eingabesequenz aus. Der neue Helfer _GSUBApplyNestedLookup greift erneut auf die GSUB-Suchliste zu, löst Erweiterungen transparent auf und leitet die Verarbeitung an die entsprechenden Applikationen weiter: Einzeln (Typ 1) / Mehrfach (Typ 2) / Alternativ (Typ 3, erste Alternative) / Ligatur (Typ 4). Der Dispatcher verfolgt die aktuellen Indizes der MatchPositions[], sodass nachfolgende Einträge in der SequenceLookupRecord weiterhin die korrekten Arbeitsbereiche ansprechen, selbst wenn eine frühere Mehrfachsubstitution 1→N oder eine Ligatursubstitution N→1 Glyphen um sie herum zusammenführt. Verschachtelte Suchtypen 5 / 6 / 8 (rekursiv kontextuell) werden absichtlich verzögert; die meisten echten Schriftarten verwenden ohnehin verschachtelte Suchen für Typ 1 / 4.
  • Bei einem Treffer gibt die Methode `True` zusammen mit der Ausgabeglyphensequenz zurück, die `InputGIDs[StartIndex..StartIndex+ConsumedLen-1]` ersetzen soll. Die Länge von `OutGIDs` kann sich von `ConsumedLen` unterscheiden, wenn verschachtelte 1→N- oder N→1-Lookups ausgeführt werden. `ConsumedLen` ist immer die gesamte Eingabelänge, die die kontextuelle Regel erfasst (einschließlich der von `LookupFlag` übersprungenen Zeichen zwischen wichtigen Glyphen); ein typischer Aufrufer der Scan-Schleife erhöht den Wert um `ConsumedLen` und gibt `OutGIDs` aus. Wenn kein Treffer gefunden wird, gibt die Funktion `False` und eine leere `OutGIDs` zurück, wobei `ConsumedLen = 1` ist – dies entspricht dem gleichen sicheren "No-Op"-Verhalten wie bei den Hilfsfunktionen v2.119.43-46. Die `LookupFlag`-Einstellung (Phase 4) gilt während des gesamten kontextuellen Abgleichs: Rückwärtssuche, Eingabe und Vorabsuche überspringen alle Glyphen, die für die Ignorierung markiert sind. `Script` und `LangSys` bleiben für diesen Abschnitt auf den Standardwert `DFLT` festgelegt; die Auswahl-API ist im Geltungsbereich von Phase 7.

2026-05-22 Version 2.119.46

  • OpenType GSUB-Erweiterungs-Nachschlagetabellen (LookupType 7): Der GSUB-Motor entpackt jetzt transparent Erweiterungs-Ersetzungstabellen – eine reine Indirektionsebene, die in der OpenType-Spezifikation für so große Schriftarten definiert ist, deren tatsächliche Ersetzungstabelle außerhalb der 16-Bit-Reichweite des Offset16 in der LookupList liegt. Jede öffentliche API (GetSingleSubstituteGlyph / GetMultipleSubstituteGlyphs / GetAlternateGlyphCount / GetAlternateGlyph / ApplyLigatureSubstitution) der Version v2.119.43-45 verwendet automatisch die 32-Bit-Offset32-Indirektion, um auf die tatsächlichen LookupType 1 / 2 / 3 / 4-Tabellen zuzugreifen. Dies ist die binäre Layoutänderung, die den Einsatz von umfangreichen CJK-/Indik-OpenType-Schriftarten (Noto Sans CJK, Noto Sans Devanagari usw.) ermöglicht, deren GSUB-Tabellen 64 KB überschreiten und deren Nachschlagetabellen bisher hinter LookupType 7-Wrappern versteckt waren; zuvor erschienen solche Schriftarten in HotPDF als schreibgeschützt.
  • OpenType GDEF (Glyph Definition) Tabellen-Parsing: RegisterUnicodeTTF speichert jetzt auch die GDEF-Tabelle der Schriftart, falls vorhanden. Drei GDEF-Untertabellen steuern die LookupFlag-Logik – GlyphClassDef klassifiziert jede GID als Basis (1) / Ligatur (2) / Zeichen (3) / Komponente (4); MarkAttachClassDef kennzeichnet jedes Zeichen mit einer Anhangsklasse; MarkGlyphSetsDef (v1.2+) deklariert benannte Mengen von Zeichen. Sowohl das ClassDef-Format 1 (startGlyphID + classValueArray) als auch das Format 2 (sortierte classRangeRecords) sind implementiert; Alle GDEF-Versionen (v1.0 / v1.1 / v1.2) werden akzeptiert (das v1.3 itemVariationStore wird ignoriert). Wenn eine Schriftart keine GDEF-Tabelle enthält, wird auf das Standardverhalten von v2.119.43-45 zurückgegriffen ("kein Zeichen wird ignoriert"), sodass eine byte-identische Ausgabe für Aufrufer erhalten bleibt, die Schriftarten ohne GDEF verwenden.
  • OpenType GSUB LookupFlag wird berücksichtigt: Alle fünf öffentlichen GSUB-APIs lesen jetzt das LookupFlag jeder Lookup-Tabelle (und das optionale abschließende markFilteringSet uint16, wenn LookupFlag.useMarkFilteringSet gesetzt ist) und überspringen Eingabe-Glyphen, die als "ignorieren" markiert sind. Die in der Spezifikation definierten Flag-Bits werden berücksichtigt: 0x0002 ignoriert Basis-Glyphen (überspringt GDEF.GlyphClassDef Klasse 1), 0x0004 ignoriert Ligaturen (überspringt Klasse 2), 0x0008 ignoriert diakritische Zeichen (überspringt Klasse 3), 0x0010 verwendet markFilteringSet (nur diakritische Zeichen in dem benannten MarkGlyphSet werden berücksichtigt) und das hochrangige Byte markAttachmentType (nur diakritische Zeichen mit der angeforderten MarkAttachClassDef-Klasse werden berücksichtigt). Für die Ligaturen-Substitution (LookupType 4) ist dies am wichtigsten: Arabische 'rlig'- und indische 'akhn'-Ligaturen, deren Komponenten durch diakritische Zeichen getrennt sind (z. B. LAM + Fatha + ALEF), stimmen jetzt korrekt überein, wenn LookupFlag.ignoreMarks gesetzt ist, und die zurückgegebene ConsumedCount enthält die übersprungenen diakritischen Zeichen, sodass die Scan-Schleife des Aufrufers jeden absorbierten Eingabe-Glyphen überspringt. Bit 0x0001 (von rechts nach links) ist GPOS-spezifisch und wird weiterhin für GSUB-Lookups ignoriert.
  • Die gleichen Schutzmechanismen gelten weiterhin: Schriftarten ohne eine GSUB-Tabelle, Aufrufer, die ein Tag mit einer Länge von nicht genau 4 Byte übergeben, Funktionen, die das Standardskript der Schriftart nicht unterstützt, GIDs, für die keine Subtabelle vorhanden ist, und jetzt auch Eingabezeichen, für die das LookupFlag ignoriert wird, führen alle zum sicheren, unveränderten Ergebnis v2.119.43-45. Die fünf öffentlichen API-Schnittstellen sind byte-stabil; nur die interne Lookup-Verarbeitung berücksichtigt die Erweiterungsdispatchierung, die Beachtung des LookupFlag und die GDEF-Klassifizierung. Die API zur Skript-/Sprachsystemauswahl, die automatische Integration der Formgebungspipeline und die automatische Auswahl von Ersatzzeichen durch den TTF-Subsetter sind für zukünftige Versionen reserviert.

2026-05-22 Version 2.119.45

  • OpenType GSUB Ligature Substitution (LookupType 4): die neue Funktion `THotPDF.ApplyLigatureSubstitution (const InputGIDs: array of Word; StartIndex; FeatureTag; out OutGID; out ConsumedCount): Boolean` fasst eine Sequenz mehrerer Glyphen in einer einzigen Ligatur-Glyphe zusammen. Typische Anwendungsfälle sind 'liga' (Standard-Ligaturen – fi / fl / ffi / ffl), 'clig' (kontextuelle Ligaturen), 'dlig' (disjunktive Ligaturen), 'hlig' (historische Ligaturen), 'rlig' (erforderliche Ligaturen – z.B. das arabische LAM-ALEF, wenn die Schrift die Formatierung über GSUB steuert) und die Ligatur-Funktionen für indische Schriften ('akhn', 'pres', 'blws', 'psts'). Der Aufrufer übergibt eine Sequenz von Glyphen-IDs aus der cmap und eine Startposition (beginnend bei 0); bei einem vollständigen Treffer gibt die Hilfsfunktion `True` zurück, `OutGID` enthält die Glyphen-ID der Ligatur-Ersatzung und `ConsumedCount` enthält die Gesamtzahl der verbrauchten Eingabekomponenten (in der Praxis >= 2). Wenn kein Treffer gefunden wird, wird `False` zurückgegeben, `OutGID` ist 0 und `ConsumedCount` ist 1, sodass der Aufrufer einen Schritt vorwärts gehen und das Scannen fortsetzen kann. Die Implementierung berücksichtigt die OpenType-Konvention, dass LigatureSet-Einträge typischerweise von der längsten zur kürzesten aufgelistet werden, sodass Schriften mit überlappenden Präfixen (z.B. eine dreikomponentige 'ffi'-Ligatur neben einer zweikomponentigen 'ff'-Ligatur) zuerst die längere Übereinstimmung finden. Wie bei den Hilfsfunktionen in v2.119.43/.44 gelten folgende Schutzmaßnahmen: ein leerer oder nicht 4-Byte-Tag, kein GSUB, eine nicht angekündigte Funktion, eine Startposition außerhalb des gültigen Bereichs und das Fehlen einer passenden LookupType 4-Subtabelle an der angegebenen Position führen zu einer sicheren, ohne-Wirkung-Operation (False / OutGID = 0 / ConsumedCount = 1). Funktionen wie das Überspringen von LookupFlag-Markierungen, die Integration von GDEF GlyphClassDef und die automatische Anwendung während der Textausgabe sowie das automatische Einbinden von Ligatur-Glyphen durch den TTF-Subsetter sind für zukünftige Versionen reserviert.

2026-05-22 Version 2.119.44

  • OpenType GSUB Mehrfachsubstitution (LookupType 2): Die neue Funktion THotPDF.GetMultipleSubstituteGlyphs (InputGID, FeatureTag, var OutGIDs) gibt ein Eingabezeichen als eine Sequenz von Ersetzungszeichen zurück. Der typische Anwendungsfall ist das Glyph-Kompositions-/Zerlegungsfeature 'ccmp', das vorkomponierte lateinische Zeichen mit Akzenten in Basiszeichen plus diakritische Zeichen für die nachfolgende Positionierung der diakritischen Zeichen aufteilt. Die Hilfsfunktion durchläuft den gleichen Pfad für Skript, Standardsprache, Featureliste und Lookup-Liste wie GetSingleSubstituteGlyph in Version 2.119.43 und wendet jede LookupType 2-Subtabelle an, die mit dem angeforderten Feature und dem Eingabezeichen verbunden ist; die erste Übereinstimmung gewinnt. OutGIDs wird beim Eintritt zurückgesetzt, sodass Aufrufer keine Vorabinitialisierung durchführen müssen. Eine spec-konforme, leere Sequenz (glyphCount = 0, Unicode-kanonische Zeichenlöschung) wird als Result = True mit Length(OutGIDs) = 0 gemeldet, sodass der Aufrufer das Eingabezeichen aus der Zeichenkette entfernen kann.
  • OpenType GSUB-Alternative-Substitution (LookupType 3): Zwei neue Methoden ermöglichen den vollständigen Zugriff auf den alternativen Glyphenzyklus für stilistische Merkmale. THotPDF.GetAlternateGlyphCount (InputGID, FeatureTag) gibt die Anzahl der alternativen Formen zurück, die eine Schriftart für InputGID unter FeatureTag bietet, und THotPDF.GetAlternateGlyph (InputGID, FeatureTag, AlternateIndex) gibt die alternative Glyphe am angeforderten 0-basierten Index zurück. Die typischen Anwendungsfälle sind 'aalt' (Zugriff auf alle Alternativen), 'salt' (stilistische Alternativen), 'titl' (Titelsatz-Alternativen) und 'ss01' bis 'ss20' (stilistische Sätze 1-20), wenn sie mit LookupType 3 anstelle von LookupType 1 verwendet werden; in v2.119.43 hat GetSingleSubstituteGlyph diese Subtabellen stillschweigend übersprungen, sodass 'aalt'-Aufrufer zuvor nur die transitiven Ersetzungen von LookupType 1 gesehen haben. Diese Funktionen ermöglichen es Aufrufern, dekorative Glyphenzyklen (unterschiedliche Formen von 'a', 'g' und '7'), Titelsatzvarianten und stilistische Alternativen explizit abzufragen. Wenn AlternateIndex außerhalb des zulässigen Bereichs liegt oder negativ ist, wird InputGID unverändert zurückgegeben, sodass Aufrufer sicher prüfen können.
  • Beide Hilfsfunktionen respektieren den gleichen Sicherheitsmechanismus wie v2.119.43: Schriftarten ohne eine GSUB-Tabelle, Aufrufer, die ein nicht 4-Byte-Tag übergeben, Funktionen, für die das Standardskript der Schriftart keine Unterstützung anbietet, und GIDs, für die die LookupType 2 / 3-Untertabelle keine Abdeckung bietet, geben alle sicher den Nullwert zurück (False + leere OutGIDs für Multiple; 0 / InputGID für Alternate). LookupType 1 / 4-8-Untertabelle, die in der Lookup-Kette der Funktion gefunden werden, werden in diesem Bereich stillschweigend übersprungen. Funktionen wie LookupFlag-Filterung, GDEF-GlyphClassDef-Integration, API zur Skript-/LangSys-Auswahl, automatische Integration der Formgebungspipeline und automatisches Ziehen ausgewählter Ersatzglyphen durch den TTF-Subsetter sind für zukünftige Versionen reserviert; Aufrufer sind weiterhin dafür verantwortlich, die ausgewählten Glyphen in den eingebetteten Schriftart-Subset einzufügen.

2026-05-22 Version 2.119.43

  • OpenType GSUB-stilistische-Alternativen-Lookup: Die neue Funktion THotPDF.GetSingleSubstituteGlyph (InputGID, FeatureTag) durchläuft die GSUB-ScriptList-/FeatureList-/LookupList-Kette der Schriftart unter dem Standardskript DFLT und wendet jede LookupType-1-Untertabelle (einfache Substitution) an, die mit dem angeforderten Feature verknüpft ist, und gibt die substituierte Glyphen-ID zurück. Die häufigsten stilistischen-Alternativen-Feature-Tags sind 'salt' (stilistische Alternativen), 'ss01' bis 'ss20' (stilistische Sätze 1-20), 'aalt' (alle Alternativen verwenden), 'titl' (Titelsatz-Alternativen), 'subs' / 'sups' (Tiefgestellt / Hochgestellt), 'frac' (Brüche) und 'ordn' (Ordinalzahlen); alle 4-Byte-OpenType-Feature-Tags, deren Feature-Kette LookupType-1-Untertabelle enthält, werden unterstützt. Sowohl das Format 1 (sortiertes Glyphen-Array, binäre Suche) als auch das Format 2 (Bereichsdatensätze) werden berücksichtigt. Sowohl das Format 1 (Delta) als auch das Format 2 (Substitutions-Array) für die einfache Substitution werden implementiert. RegisterUnicodeTTF speichert jetzt den GSUB-Tabellen-Offset/die -Länge zusammen mit cmap, sodass GSUB-Durchläufe zur Abfragezeit das erneute Scannen des Tabellenverzeichnisses vermeiden. Wenn eine Schriftart keine GSUB-Tabelle enthält, wenn der Aufrufer ein 4-Byte-Tag übergibt, das das Standardskript der Schriftart nicht bewirbt, oder wenn die GID nicht in der Abdeckung des Lookups enthalten ist, wird die ursprüngliche InputGID unverändert zurückgegeben, sodass die API sicher aufgerufen werden kann, um eine bestmögliche Substitution oder Durchleitung zu erzielen. LookupType-2- bis 8-Untertabelle, die auf der Lookup-Kette des Features gefunden werden, werden in diesem ersten Schritt stillschweigend übersprungen – Mehrfachsubstitutionen/alternative Substitutionen/Ligaturen/kontextuelle Ketten sowie die automatische Formgebung sind für zukünftige Versionen reserviert.

2026-05-22 Version 2.119.42

  • AcroForm /DR-Ressourcen akzeptieren jetzt mehrere Unicode-Schriftarten. In v2.56.0 verfolgt SetFormUnicodeFontDict nur eine vom Aufrufer bereitgestellte Schriftart, die zur Standard-AcroForm-/DA-Schriftart wird; mehrsprachige Formulare, die für verschiedene Felder unterschiedliche Skripte benötigen (z. B. Arabisch + CJK + Latein in einem PDF), mussten das /DR-/Font-Dictionary manuell erstellen. Die neue Funktion THotPDF.RegisterAcroFormFont(LogicalName, FontDict) registriert eine zusätzliche Unicode-Schriftart unter einem beliebigen logischen Namen, macht sie für /DA-Strings pro Feld verfügbar (z. B. 12 Tf) und gibt sie in das AcroForm-/DR-/Font-Dictionary zusammen mit der Standard-Schriftart von v2.56.0 aus. Die Registrierungsreihenfolge wird beibehalten, sodass das ausgegebene /DR deterministisch ist. Namenskonflikte mit der Standard-Schriftart von SetFormUnicodeFontDict oder einer zuvor registrierten Schriftart führen zu einem Fehler mit dem betreffenden Namen. Leere logische Namen oder nil-FontDict führen ebenfalls zu einem Fehler. Der jetzt vorhandene Pfad zum Zurücksetzen von SetFormUnicodeFontDict ('', nil) löscht auch die zusätzliche Schriftartenregistrierung, sodass ein neuer Unicode-Workflow von einem bekannten, sauberen Zustand ausgeht. Erlaubt in allen PDF/A- und PDF/X-Ebenen – zusammengesetzte Unicode-Schriftarten sind strukturelle Formularmetadaten und keine interaktiven Skripte.

2026-05-22 Version 2.119.41

  • Eine Standard-Strukturtyp-Enumeration, die PDF 1.7 §14.8.4 Tabelle 333 abdeckt: Die neue THPDFStandardStructureType-Enumeration listet die ~40 spezifikationsdefinierten Strukturrollen, gruppiert nach ihrer PDF-Rolle (Gruppierung: Dokument / Teil / Artikel / Abschnitt / Div / Blockzitat / Bildunterschrift / Inhaltsverzeichnis / Inhaltsverzeichnis / Index / Nicht-strukturierte / Private; Block-Ebene: H / H1-H6 / P / L / LI / Lbl / LBody / Tabelle / TR / TH / TD / THead / TBody / TFoot; Inline-Ebene: Span / Zitat / Hinweis / Referenz / Bibliografieeintrag / Code / Link / Anmerkung; Ruby + Warichu: Ruby / RB / RT / RP / Warichu / WT / WP; Illustration: Abbildung / Formel / Formular). Zwei Hilfsfunktionen auf Einheitenebene wandeln die Enumeration in spezifikationsgenaue PDF-Namen um – StandardStructureTypeToName (T) gibt den groß-/kleinschreibungsabhängigen Namen zurück, der als Schlüssel für das Strukturelement verwendet wird, und IsStandardStructureType (Name) prüft eine beliebige AnsiString-Variable gegen den Standardsatz, sodass Aufrufer benutzerdefinierte Rollennamen vorab prüfen und diese bei Bedarf über AddStructRoleMap weiterleiten können. Eine neue Enum-Überladung von AddStructureElement akzeptiert THPDFStandardStructureType direkt, wodurch die Tippfehler-/Groß-/Kleinschreibungsfehler ('Para' vs 'P', 'Lbody' vs 'LBody') der Überladungen mit offenen Zeichenketten vermieden werden, während die gleiche Basisimplementierung verwendet wird. Die vorhandenen Überladungen, die auf AnsiString basieren, bleiben byteidentisch für Aufrufer, die benutzerdefinierte oder über RoleMap geleitete Namen verwenden.

2026-05-22 Version 2.119.40

  • Strukturelement-Attribut-Setter: Drei neue Hilfsfunktionen füllen die pro-Element-PDF-Text-String-Attribute aus, die mit v2.88.0 /Alt + /ActualText und v2.95.0 /ID zusammenhängen. THotPDF.SetStructureElementLanguage (Elem, BCP-47 Lang) schreibt PDF 1.7 §14.9.2 /Lang und überschreibt die Dokument-Standard-Sprache für den Inhalt unter diesem Element, bis eine andere /Lang-Überschreibung angewendet wird – eine typische Anwendung sind zitierte Passagen in einer anderen Sprache oder Abschnitte mit gemischten Schriftsystemen. THotPDF.SetStructureElementExpansionText (Elem, ExpansionText) schreibt §14.9.5 /E, die abgekürzte Erweiterung, die von Bildschirmleseprogrammen anstelle eines Akronyms gelesen wird (z. B. 'NASA' → 'National Aeronautics and Space Administration'), sowie den Wert, der von der Inhaltsausgabe extrahiert wird. THotPDF.SetStructureElementTitle (Elem, Title) schreibt §14.7.5.2 /T, den für Menschen lesbaren Titel, der das Element von Elementen mit der gleichen Rolle im Strukturbaum unterscheidet (das Tags-Panel von Acrobat zeigt /T neben dem Rollennamen an). Alle drei sind einfache Setter mit leerwertiger No-Op-Semantik, ein nil-Elem löst einen Fehler aus und sind in jeder PDF/A- und PDF/X-Version erlaubt, da die Schlüssel strukturelle Metadaten sind.

2026-05-22 Version 2.119.39

  • AcroForm-Formularfeld-Trigger-Familie: Drei neue Helfer ergänzen AttachFieldKeyStrokeAction (v2.119.37), um PDF 1.7 §12.7.5.3 Tabelle 246 zu schließen. THotPDF.AttachFieldFormatAction installiert /AA /F (Formatereignis, wird ausgelöst, wenn der angezeigte Wert des Felds nach einem Commit neu formatiert werden muss – typischerweise wird eine Währung-, Datums- oder Tausendertrennzeichenmaske über AFNumber_Format / AFDate_FormatEx angewendet). THotPDF.AttachFieldValidateAction installiert /AA /V (Validierungseereignis, wird ausgelöst, nachdem der Benutzer einen neuen Wert eingegeben hat – typischerweise wird eine Bereichsprüfung oder eine Regex-Validierung der Eingabe über event.rc := false durchgeführt). THotPDF.AttachFieldCalculateAction installiert /AA /C (Berechnungseereignis, wird ausgelöst, wenn sich ein abhängiges Feld ändert, gemäß der Reihenfolge der Berechnung in Catalog /AcroForm /CO – typischerweise werden Summen aufaddiert oder Steuern berechnet). Alle vier Wrapper verwenden die gleiche FFormFields /T-Suche, idempotente "letzte Aufruf gewinnt"-Ersetzungssemantik und PDF/A + PDF/X-JavaScript-Schutz. Andere Auslöser-Schlüssel im selben /AA-Dictionary (/E /X /D /U /Fo /Bl für Anmerkungs-Auslöser und die drei verwandten Formularfeld-Auslöser) bleiben unverändert. Interne Refaktorierung: AttachFieldKeyStrokeAction delegiert jetzt an einen gemeinsamen Helfer _InstallFieldTriggerJSAction; bestehende Aufrufer von v2.119.37 sehen byte-identische Fehlermeldungen.

2026-05-22 Version 2.119.38

  • RegisterUnicodeTTF erfasst jetzt Zuordnungen von Codepoints der Supplementary Multilingual Plane (SMP, U+10000-U+10FFFF) zu Glyphen aus der cmap-Format-12-Subtabelle der geladenen Schriftart. Frühere Versionen haben SMP-Einträge stillschweigend verworfen, da die Codepoint-zu-Glyphen-Suche ein Array in BMP-Größe war; v2.119.38 fügt eine parallele, spärliche Liste (FUnicodeCpToGidSMP) hinzu, die zusätzlich zum BMP-Array befüllt wird. Die neue öffentliche Methode GetUnicodeGlyphForCodepoint(Cp) gibt die Glyphen-ID für jeden Unicode-Codepoint bis U+10FFFF zurück (führt eine binäre Suche in der SMP-Liste für Codepoints über dem BMP durch) oder 0 (.notdef), wenn der Codepoint nicht in der cmap der geladenen Schriftart zugeordnet ist. Dies ist eine Funktion, die nur die Fähigkeit bereitstellt: die Hex-Kodierungs-Pipeline auf der Produktionsseite, der /CIDToGIDMap-Stream und die ToUnicode-CMap bleiben weiterhin an BMP-Werten ausgerichtet. Daher müssen Aufrufer weiterhin UTF-16BE-Surrogatpaare selbst in einen PDF-Textstream schreiben. Die vollständige, Surrogat-fähige Textstream-Ausgabe ist für eine zukünftige Version reserviert. Schriftarten, die nur Format 4 verwenden, erhalten wie erwartet eine leere SMP-Liste.

2026-05-22 Version 2.119.37

  • Neue Funktion zur Unterstützung von Tastatureingaben in AcroForm: `THotPDF.AttachFieldKeyStrokeAction(FieldName, JavaScriptBody)` sucht das angegebene Formularfeld anhand seines `/T`-Werts und installiert eine `/AA /K`-JavaScript-Aktion, sodass PDF-Reader das Skript bei jedem Tastendruck während der Texteingabe ausführen. Anwendungsfälle sind Echtzeit-Eingabevalidierung (numerisch/Datum/regulärer Ausdruck), Maskierung und Aktualisierung von berechneten Feldern, die durch Änderungen in einem anderen Feld ausgelöst werden. Die Funktion ist idempotent: wiederholte Aufrufe ersetzen den `/K`-Eintrag, wobei alle anderen bereits vorhandenen Auslöser (z. B. `/F`-Format, `/V`-Validierung, `/C`-NeuBerechnung, `/Bl`-Unschärfe, `/Fo`-Fokus) im selben `/AA`-Dictionary erhalten bleiben. PDF/A aller Stufen (ISO 19005-1 §6.6.1, -2/-3 §6.5.1) und PDF/X aller Stufen (ISO 15930 Vorstufe) verbieten JavaScript-Aktionen, daher löst die Funktion sofort einen Fehler aus und gibt die entsprechende Spezifikationsreferenz an, wenn eines der Compliance-Flags gesetzt ist. Diese Funktion basiert auf dem Trigger-Ereignis-Dictionary gemäß PDF 1.7 §12.6.3 und der Tabelle 246 für Formularfelder `/K` gemäß §12.7.5.3.

2026-05-22 Version 2.119.36

  • BeginTaggedContent akzeptiert jetzt vier optionale Eigenschaften für markierten Inhalt gemäß PDF 1.7 §14.8.4 Tabelle 322 (Lang / Alt / ActualText / ExpansionText) und gibt diese als ein einzelnes Inline-BDC-Eigenschafts-Dictionary zusammen mit dem vorhandenen MCID-Eintrag aus. Lang enthält den BCP-47-Sprachcode für den Textbereich (wird von Bildschirmleseprogrammen und sprachbewussten Textextraktionsprogrammen verwendet); Alt ist die alternative Beschreibung für nicht-textuelle oder dekorative Textbereiche; ActualText ist der Ersatztext, der von der Inhaltsextraktion und beim Kopieren und Einfügen anstelle der visuellen Glyphensequenz verwendet wird (wichtig für Ligaturen und stilisierte Glyphen, bei denen das sichtbare Zeichen von der zugrunde liegenden semantischen Text unterschiedlich ist); ExpansionText enthält den Schlüssel /E, der Abkürzungen erweitert. Leere Parameter überspringen den entsprechenden Eintrag, sodass das Inline-Dictionary nur Schlüssel enthält, die der Aufrufer explizit ausfüllt, und der bestehende Aufruf mit zwei Argumenten bleibt byteidentisch mit der Ausgabe von v2.119.35. Die automatische Maskierung von Literalzeichenketten (Klammern und Backslash) für PDF ist aktiviert; für nicht-ASCII-Daten (CJK ActualText, Indic Alt usw.) müssen die Aufrufer ihre Bytes vorab als UTF-16BE mit dem U+FEFF BOM kodieren und das Ergebnis in das Argument AnsiString packen. Die entsprechende Low-Level-API BeginMarkedContentMCIDProps für Seitendatenströme wird ebenfalls bereitgestellt, sodass Aufrufer eine direkte BDC-Steuerung ohne die High-Level-StructElem-Verkabelung erhalten.

2026-05-22 Version 2.119.35

  • Die Kern-Subset-Symbole für die persische/urdu-Schrift "Arabic Extended-A" mit 9 Buchstaben werden jetzt im v2.85.0-Shaper auf Produzenseite in vier Positionen integriert. Wenn "AutoShapeArabic" aktiviert ist, werden die folgenden Buchstaben auf ihre Glyphen "Arabic Presentation Forms-A" (U+FB50-U+FBFF) abgebildet, basierend auf demselben Algorithmus für den Kontext der Zeichenverknüpfung, der für den Basissatz "Arabic" verwendet wird: PEH (U+067E), TCHEH (U+0686), JEH (U+0698), KEHEH (U+06A9), GAF (U+06AF), FARSI YEH (U+06CC) (persischer Kern) sowie TTEH (U+0679), DDAL (U+0688), RREH (U+0691) (urdu-Kern für retroflexe Laute). Buchstaben mit doppelter Verknüpfung zeigen den vollständigen Satz für isolierte, finale, initiale und mediale Formen; Buchstaben, die nur nach rechts verknüpfen (JEH / DDAL / RREH), zeigen nur isolierte und finale Formen, wie im arabischen Formgebungsmodell. Andere Buchstaben "Arabic Extended-A" (ALEF WASLA U+0671, NOON GHUNNA U+06BA, HEH-Varianten U+06C0-U+06C3, vollständiges arabisches Supplement U+0750-U+077F) bleiben unverändert und werden in einer zukünftigen Version behandelt. Arabischer Text, der nicht persisch/urdu ist, bleibt byteidentisch mit der Ausgabe von v2.119.34.

2026-05-22 Version 2.119.34

  • Die PDF-Namensverarbeitung dekodiert jetzt ISO 32000-1 #XX-Escape-Sequenzen beim Importieren oder Kopieren von PDF-Objekten. Ressourcennamen, Spot-Color-Namen, Strukturrollennamen und andere Namensobjekte wie /PANTONE#20216#20CVC werden nun über HotPDF mit ihren beabsichtigten Byte-Werten verarbeitet, anstatt mit einem doppelt-escapierten Nummernzeichen zurückkopiert zu werden.

2026-05-22 Version 2.119.33

  • Die Behandlung von Datumsangaben in PDF-Dateien entspricht jetzt genauer den Regeln für Datumszeichenketten gemäß ISO 32000-1. Dokumentinformationen, aus XMP abgeleitete Datumsangaben und Signaturzeitstempel verwenden das vom Aufrufer bereitgestellte `TDateTime` anstelle der stillschweigenden Ersetzung durch die aktuelle Uhrzeit, während der Parser Standard-optionale Datumsfelder und Zeitzonen-Suffixe akzeptiert, ohne die lokalen Datums-/Zeitfelder zu beschädigen.
  • Der PDF-Importfilter unterstützt jetzt explizit die Helfer `ASCIIHexDecode`, `ASCII85Decode` und `RunLengthDecode`, und der Standardwert für `EarlyChange` für `LZWDecode` entspricht jetzt dem Standardwert von 1 in PDF. Dies verbessert die Kompatibilität mit importierten oder kopierten Seiten, die ältere PDF-Streamfilter verwenden.

2026-05-21 Version 2.119.32

  • Arabische LAM-ALEF-Ligaturen werden jetzt obligatorisch innerhalb des v2.85.0-Shapers auf Produzenseite angewendet. Wenn AutoShapeArabic aktiviert ist, kollabiert jede Sequenz aus U+0644 LAM (in roher Form oder einer seiner vier geformten Formen FEDD-FEE0), gefolgt von einer der vier ALEF-Varianten (MADDA U+0622, HAMZA-oben U+0623, HAMZA-unten U+0625, einfach U+0627; in roher oder nachgeformter Form), zu einem einzigen Ligaturzeichen aus dem Block U+FEF5-U+FEFC. Die Auswahl zwischen der verbundenen und der isolierten Ligaturform richtet sich danach, ob das LAM in eine finale (FEDE) oder mediale (FEE0) Form durch den Vier-Positionen-Walker umgewandelt wurde. Andere arabische obligatorische Ligaturen (Allah U+FDFB und dekorative Ehrentigaturen) erfordern weiterhin einen vollständigen GSUB-Engine und sind außerhalb des Geltungsbereichs des statischen Tabellenshaping-Modells. Text, der keine LAM-ALEF-Sequenzen enthält, und Aufrufe mit AutoShapeArabic deaktiviert, bleiben byteidentisch mit der Ausgabe von v2.119.31. Drei AcroForm Unicode-/AP-Helfer (einzeilig, mehrzeilig, Kombi) erben die Änderung automatisch über den gemeinsamen _ApplyArabicShaping-Einstiegspunkt.

2026-05-21 Version 2.119.31

  • Neuer DevExpress ExpressPrinting-System-Exportadapter: `dxHotPDFExportReportLinkToFile` / `dxHotPDFExportReportLinkToStream` akzeptieren jedes `TBasedxReportLink`-Objekt (die abstrakte Link-Familie, die cxGrid / cxRichEdit / cxScheduler / cxPivotGrid und ähnliche druckbare Komponenten mit dem `TdxComponentPrinter` verbindet) und leiten jede gerenderte Seite über HotPDF anstelle des eigenen `dxPSExportToPDF`-Generators von DevExpress weiter. Der Adapter spiegelt die interne Export-Schleife von DevExpress wider: Bericht neu erstellen → für jede Seite → Seite auf ein `TMetafileCanvas` zeichnen → erweitertes Metafile in HotPDF anzeigen. Die Optionsaufzeichnung legt Titel / Autor / Betreff / Stichwörter / PDF-Version / Komprimierung / Render-DPI fest. Gleiche Metafile-Brücken-Einschränkungen wie die Adapter für FastReport / QuickReport / ReportBuilder: keine AcroForm-Felder, keine Inhaltsverzeichnisse, keine PDF/A- / PDF/X-Optionen. Der Adapter befindet sich im Verzeichnis `Lib/Addons/DevExpress/` und ist nicht in der Hauptdatei `HotPDF*.dpk` enthalten.

2026-05-20 Version 2.119.30

  • Neue Geräteklasse für ReportBuilder: `TppHotPDFDevice` erbt von `TppGraphicsDevice` und wird somit in die Standard-Publisher-→-Geräte-Kette von ReportBuilder integriert, wenn sie `TppReport.PrinterDevice` oder `TppPublisher.Device` zugewiesen wird. Jede Seite wird auf ein temporäres `TMetafileCanvas` gerendert (erstellt in `BeforeRenderPage`, finalisiert in `AfterRenderPage`), als `TMetafile` gespeichert und über HotPDFs EMF-Importeur (`HPDFEmf.ShowEnhancedMetafile`) verarbeitet. Eigenschaften ermöglichen die Angabe von Titel, Autor, Thema, Schlüsselwörtern, PDF-Version, Komprimierungsstufe und ob komprimiert werden soll. `SetOutputStream` leitet die PDF-Bytes an einen vom Aufrufer bereitgestellten `TStream`. Dieselben Einschränkungen wie bei den Adaptern für FastReport/QuickReport: keine AcroForm-Felder, keine Inhaltsverzeichnisse, keine PDF/A- oder PDF/X-Funktionen. Der Adapter befindet sich im Verzeichnis `Lib/Addons/ReportBuilder/` und ist nicht in der Haupt-HotPDF*.dpk-Datei enthalten.

2026-05-20 Version 2.119.29

  • Neuer QuickReport-Exportfilter: `TQRHotPDFExportFilter` erbt von `TQRExportFilter` und lässt sich somit nahtlos in den regulären Workflow `MyReport.ExportToFilter(MyFilterInstance)` integrieren, ohne dass Änderungen am QuickReport-Kern erforderlich sind. Der Adapter verwendet die pro-Seite-Metafiles, die QuickReport bereits im `QRPrinter.PageList` speichert, und leitet diese über den EMF-Importeur von HotPDF (`HPDFEmf.ShowEnhancedMetafile`). Eigenschaften ermöglichen die Angabe von Titel, Autor, Thema, Schlüsselwörtern, PDF-Version, Komprimierungsstufe und ob komprimiert werden soll. `SetOutputStream` leitet die PDF-Bytes an einen vom Aufrufer bereitgestellten `TStream` anstelle einer Festplattenausgabe. Wie beim FastReport-Adapter gelten die gleichen Einschränkungen bezüglich Metafiles: keine AcroForm-Felder, keine Inhaltsverzeichnisse, keine PDF/A- oder PDF/X-Funktionen. Der Adapter befindet sich im Verzeichnis `Lib/Addons/QuickReport/` und ist nicht in der Haupt-`HotPDF*.dpk`-Datei enthalten.

2026-05-20 Version 2.119.28

  • Neuer FastReport 4 / FastReport VCL-Exportadapter: `TfrxHotPDFExport` erbt von `TfrxCustomExportFilter` und lässt sich somit nahtlos in den regulären Workflow `MyReport.Export(MyExportInstance)` integrieren, ohne dass Änderungen am FastReport-Kern erforderlich sind. Der Adapter leitet jede vorbereitete Seite über den EMF-Importeur von HotPDF (über `FastReport's TfrxPreviewPages.DrawPage → TMetafileCanvas → HotPDF.ShowEnhancedMetafile`), sodass vektor- und rasterbasierte Seiteninhalte, die von FastReports Standard-Layout-Engine gerendert werden, erhalten bleiben, ohne dass pro Objekt Code generiert werden muss. Eigenschaften ermöglichen die Steuerung von Aspekten wie Titel, Autor, Betreff, Schlüsselwörter, PDF-Version und Komprimierungsstufe sowie der Rendering-DPI für die resultierende PDF-Datei. Einschränkungen: Keine AcroForm-Felder, keine Inhaltsverzeichnisse, keine PDF/A- oder PDF/X-Funktionen (diese erfordern eine pro-Objekt-Code-Generierung, geplant für eine zukünftige Version). Der Adapter ist im Ordner `Lib/Addons/FastReport4/` enthalten und NICHT in der Haupt-HotPDF*.dpk-Datei; Benutzer fügen ihn ihrem eigenen Projekt zusammen mit dem entsprechenden FastReport-Paket hinzu.

2026-05-20 Version 2.119.27

  • Neue, umfassende PDF-Signaturfunktion basierend auf PFX: `THotPDF.SignPDFWithPFX(InputPDFPath, OutputPDFPath, PFXFilePath, Password)` lädt eine unsignierte PDF-Datei, die bereits einen Platzhalter für eine signierte Signatur enthält, parst die PFX/PKCS#12-Datei, erstellt ein vollständiges CMS SignedData (RFC 5652) für die durch den /ByteRange-Bereich abgedeckten Bytes und schreibt die signierte PDF-Datei in einem einzigen Aufruf. Eine TStream-basierte Variante wird ebenfalls für In-Memory-Workflows bereitgestellt. Der PDF-Inhaltsbereich muss groß genug sein, um die CMS DER-Hex-Daten zu speichern; standardmäßig sind 8192 Bytes ausreichend für RSA-Schlüssel mit 1024/2048 Bit. Nur PBES2 + AES-256-CBC PFX-Dateien werden unterstützt (die PKCS#12-Parser-Begrenzung in v2.119.26).
  • Neue HPDFCMS-Einheit: Builder für signierte Daten (CMS SignedData). HPDFCMSBuildSignedData kombiniert ContentInfo, SignedData und SignerInfo mit losen Daten, wobei signierte Attribute (contentType + messageDigest + signingTime, sortiert nach aufsteigender DER-Reihenfolge gemäß RFC 5652 §5.4) verwendet werden. Der Signer-Identifikator IssuerAndSerialNumber wird aus dem X.509-Zertifikat extrahiert, ein RSA-Signaturalgorithmus mit SHA-256 wird verwendet, und das X.509-Zertifikat ist in [0] impliziten Zertifikaten enthalten. Außerdem werden HPDFCMSSHA256ByteRanges für einen gestreamten Zwei-Fenster-Digest und HPDFCMSBytesToHex für die Einfügung von Platzhaltern in /Contents bereitgestellt. Dies schließt den internen Signing-Stack ab, der mit HPDFASN1 (v2.119.23) + HPDFRSA (v2.119.24) + HPDFCrypt-Erweiterungen (v2.119.25) + HPDFPFX (v2.119.26) begann.

2026-05-20 Version 2.119.26

  • Neue HPDFPFX-Einheit: Parser für PKCS#12 / PFX-Container. Liest .pfx / .p12-Dateien von OpenSSL ≥ 3.0, Windows 11+ certutil und macOS Keychain Access, entschlüsselt PBES2 (PBKDF2-HMAC-SHA-256 + AES-256-CBC) SafeBag-Payloads und extrahiert die X.509-Zertifikats-DER-Daten sowie die RSA-Private-Key-Parameter. Gibt einen THPDFPFXKeyMaterial-Datensatz mit CertDER, Modulus, PublicExponent und PrivateExponent zurück, den nachgelagerter CMS-/Signaturcode direkt verwenden kann. Ein falsches Passwort wird durch einen PKCS#7-Unpadding-Fehler erkannt, der auf einen ungültigen AES-Schlüssel folgt. Veraltete PBE-SHA1-3DES-Dateien führen zu einer Fehlermeldung mit einem klaren Hinweis, diese mit `-keypbe AES-256-CBC -certpbe AES-256-CBC` neu zu exportieren.

2026-05-20 Version 2.119.25

  • Neue kryptografische Funktionen: AES-256-Inverse-Chiffre mit AES256DecryptBlock + AES256CBCDecryptPKCS7 + AES256CBCDecryptNoPad (FIPS-197 §5.3, ergänzt die vorhandenen Verschlüsselungsfunktionen), HMAC-SHA-256 (RFC 2104) und PBKDF2-HMAC-SHA-256 (RFC 8018 §5.2). Überprüft anhand von RFC 4231 HMAC-Vektoren und Standard-PBKDF2-SHA-256-Referenzausgaben. Zusammen mit dem v2.119.23 ASN.1-Decoder und den v2.119.24 RSA-Funktionen bildet dies die kryptografische Grundlage für den PBES2-AES-256-SafeBag-Dekryptionspfad, der von modernen (OpenSSL ≥ 3.0 / Windows 11+) PKCS#12 / PFX-Dateien verwendet wird.

2026-05-20 Version 2.119.24

  • Neue HPDFRSA-Einheit: Mehrfachpräzisions-Integer-Arithmetik + RSA-Modularexponentiation + PKCS#1 v1.5 EMSA-Kodierung. Ausreichend groß, um mit realistischen 2048/4096-Bit-RSA-Schlüsseln zu signieren. Zusammen mit dem ASN.1-Decoder in v2.119.23 vervollständigt dies die kryptografischen Grundlagen, die für die bevorstehende, in der Bibliothek integrierte PFX-basierte PDF-Signaturpipeline benötigt werden. Bisher verwendet keine der Benutzeroberflächen-APIs diese Funktion – es handelt sich um eine interne Infrastruktur, die auf die PKCS#12- und CMS-Schichten wartet.

2026-05-20 Version 2.119.23

  • Neue HPDFASN1-Einheit: Ein kompakter BER/DER-Decoder für die ASN.1-Teilmenge, der benötigt wird, um PKCS#12-Schlüsselbehälter, X.509-Zertifikate und CMS/PKCS#7-Signaturdaten zu lesen. Bietet Zugriff auf THPDFASN1Node (beschriebener Tag-Länge-Wert), THPDFASN1ParseNode / ParseAt, Content / ToInteger / ToBigInt / ToOID / ToString-Zugriff sowie FirstChild / NextSibling / Children-Iteratoren. Lehnt explizit BER-Formate mit unbestimmter Länge und Kodierungen mit hohen Tag-Nummern (>= 31) ab, was dem strengen Subset von DER entspricht. Dies ist eine interne Infrastruktur für die in der Bibliothek integrierte PFX-Signaturpipeline, die in kommenden Versionen eingeführt wird – noch keine benutzerseitige API ist davon abhängig.

2026-05-20 Version 2.119.22

  • Neue PolyLine- und Polygon-Annotationen mit vollständigen Metadaten: THPDFPage.AddPolylineAnnotation und AddPolygonAnnotation erhalten zwei neue Varianten, die ein Array von THPDFCurrPoint-Punkten und einen optionalen THPDFPolyExtras-Datensatz akzeptieren. Der Extras-Datensatz stellt die optionalen Einträge gemäß ISO 32000-1 §12.5.6.9 bereit: /IC für die Innenfarbe, /BE für den bewölkten Rand (mit /besSolid /besCloudy und /I für die Intensität), /IT für den Zweck (PolyLineDimension / PolyLineFlight / PolygonCloud / PolygonDimension) und /LE für die Linienendstile für PolyLine. Verwenden Sie HPDFDefaultPolyExtras() für einen initialisierten Datensatz mit Nullwerten. Die neuen Varianten prüfen, ob mindestens zwei Punkte angegeben sind, und erhöhen automatisch die Dokumentversion (PDF 1.5 / 1.6 / 1.7, abhängig vom Zweck). Die vorherigen, verschachtelten Single-Varianten werden weiterhin unverändert kompiliert.

2026-05-20 Version 2.119.21

  • Neue Funktionen für Linienannotationen: Die Funktion `AddLineAnnotation` erhält eine dritte Überladung, die einen `THPDFLineExtras`-Datensatz akzeptiert, der optionale Einträge gemäß Tabelle 175 in PDF 1.6/1.7 §12.5.6.7 steuert – darunter `/IC` für die Innenfarbe (gefüllte Pfeilspitzen, Rauten usw.), `/LL` für die Länge der Führungslinie, `/LLE` für die Verlängerung der Führungslinie, `/LLO` für den Versatz der Führungslinie (PDF 1.7), ein Flag `/Cap` für die Beschriftung mit der Position `/CP` (/Inline oder /Top, PDF 1.7) sowie `/CO` für den Versatz der Beschriftung und `/IT` für den Zweck (Linie/Pfeil oder Linie/Dimension). Verwenden Sie `HPDFDefaultLineExtras()`, um mit einem auf Null initialisierten Datensatz zu beginnen. Die neue Überladung erhöht automatisch die Dokumentversion auf PDF 1.6 (oder 1.7, wenn `/LLO`, `/CP` oder `/CO` angefordert werden). Die beiden vorherigen Überladungen erzeugen weiterhin byte-identische Ausgaben, und es werden nur die Einträge geschrieben, die der Aufrufer tatsächlich anfordert.

2026-05-20 Version 2.119.20

  • Neue Aktionen für die Schaltflächen "baShow" und "baImportData": THPDFButtonAction enthält jetzt "baShow" (ein Gegenstück zu "baHide", das "/H false" ausgibt, um ein ausgeblendetes Widget wieder anzuzeigen) und "baImportData" (/S /ImportData /F Dateispezifikation, um FDF-Formular-Daten beim Klicken zu laden, ISO 32000-1 §12.7.5.4). "baShow" ist gemäß den Spezifikationen für PDF/A und PDF/X zulässig; "baImportData" ist sowohl gemäß ISO 19005-1 §6.6.1 als auch gemäß ISO 15930 für die Druckvorstufe nicht zulässig.
  • Neue Multi-Feld Hide/Show-Funktion: THPDFPage.AddPushButtonWithHideAction(FieldName, Caption, Targets, Hide, Rectangle, Flags) akzeptiert ein Array von Ziel-Feldnamen und einen expliziten Hide-Booleschen-Wert, sodass ein einzelner Button die Sichtbarkeit mehrerer Widgets mit einem Klick umschalten kann. Ein leeres Targets-Array führt zu einem Fehler. Sowohl PDF/A als auch PDF/X unterstützen diese Funktion (nur Widget-Sichtbarkeit).

2026-05-20 Version 2.119.19

  • Neues SubmitForm-Steuerelement /Flags: THPDFPage.AddPushButtonWithSubmitAction(FieldName, Caption, URL, Rectangle, SubmitFlags) ermöglicht die vollständige Nutzung des ISO 32000-1 §12.7.5.2 Tabelle 237 Flag-Sets über den neuen THPDFSubmitFormFlags-Datentyp. Aufrufer können jetzt verschiedene Optionen kombinieren, wie z.B. sffExportFormatHTML / sffXFDF / sffSubmitPDF (Übermittlungsformat), sffGetMethod (HTTP GET vs. POST), sffIncludeAnnotations, sffSubmitCoordinates, sffCanonicalFormat, sffIncludeNoValueFields, sffIncludeAppendSaves, sffExclNonUserAnnots, sffEmbedForm und andere, wodurch die bisher fest codierte /Flags 0 (FDF + POST) des alten baSubmitURL-Pfads ersetzt wird. Die bestehende Funktion AddPushButtonWithAction(.., baSubmitURL, ..) gibt weiterhin /Flags 0 für die Byte-Ebene aus, um die Abwärtskompatibilität zu gewährleisten. Die gleichen PDF/A- und PDF/X-Einschränkungen gelten wie bei baSubmitURL: unter PDF/A erlaubt, unter PDF/X gesperrt.

2026-05-20 Version 2.119.18

  • Erweiterte Push-Button-Aktionen: THPDFButtonAction enthält jetzt die Aktionen baNamed und baHide. baNamed erzeugt eine Aktion mit /S /Named /N (ISO 32000-1 §12.6.4.11), die für die vier Standard-Navigationsbefehle Nächste Seite / Vorherige Seite / Erste Seite / Letzte Seite geeignet ist (PDF/A erlaubt alle vier gemäß ISO 19005-1 §6.6.1) und für Acrobat-Erweiterungen wie Drucken und Speichern als. baHide erzeugt eine Aktion mit /S /Hide /T /H true (§12.6.4.10), die das benannte Formularfeld ausblendet, wenn der Button angeklickt wird. Beide Aktionstypen sind unter PDF/A und PDF/X zulässig; nur baJavaScript, baResetForm und baSubmitURL behalten ihre bestehenden Compliance-Einschränkungen.

2026-05-20 Version 2.119.17

  • Neues Namensregister für Ziele: `THotPDF.RegisterNamedDestination(Name, PageIndex, FitMode, ...)` registriert ein symbolisches Ziel im Katalog /Names /Dests (ISO 32000-1 §12.3.2.3). Aktionen "Gehe zu" / "Gehe zu (relativ)" und Einträge im Inhaltsverzeichnis können dann ein Ziel anhand des Namens referenzieren, anstatt Seitenzahlen fest zu codieren, wodurch Querverweise bei Einfügungen, Löschungen oder Umsortierungen von Seiten stabil bleiben. Das neue Enum `THPDFDestinationFitMode` deckt alle acht in der Spezifikation definierten Anpassungsmodi ab (XYZ, Fit, FitH, FitV, FitR, FitB, FitBH, FitBV). Die Methode löst eine Ausnahme aus, wenn der Name leer ist, der Seitenindex außerhalb des zulässigen Bereichs liegt oder der Name bereits vorhanden ist; sie erhöht außerdem automatisch die Dokumentversion auf PDF 1.2, wenn dies erforderlich ist. Es gibt keine Einschränkungen für PDF/A oder PDF/X – Navigationshilfen sind in allen Profilen zulässig.

2026-05-20 Version 2.119.16

  • Neue Zeilenannotationen /LE-Linienendstile: THPDFPage.AddLineAnnotation verfügt jetzt über eine überladene Funktion, die Anfangs- und Endlinienendstile akzeptiert. Der vollständige Satz von Stilen, definiert in ISO 32000-1 §12.5.6.7 Tabelle 176, wird über das neue THPDFLineEndingStyle-Enum verfügbar gemacht: None, Square, Circle, Diamond, OpenArrow, ClosedArrow, Butt, ROpenArrow, RClosedArrow, Slash. Zeilenannotationen können jetzt in Adobe Acrobat / Foxit korrekt als Pfeile, Dimensionsmarkierungen oder Zeiger dargestellt werden, ohne dass der Host manuell Pfeilspitzen auf der Seite zeichnen muss. Die ältere, vierparameter-Version funktioniert weiterhin bytegenau.

2026-05-20 Version 2.119.15

  • Neue Outline-Formatierung (Lesezeichen): THPDFDocOutlineObject bietet jetzt Farb-, Fett- und Kursiveigenschaften (ISO 32000-1 §12.3.3 Tabelle 153 /C und /F). Das Outline-Panel kann jetzt Lesezeichen in Farbe und mit fettgedruckter oder kursiver Schrift darstellen, was für die Gruppierung von Kapiteln, die Kennzeichnung von unvollständigen oder Aufmerksamkeit erfordern Abschnitten sowie für die Anpassung an die Markenrichtlinien nützlich ist. Die Farbe ist standardmäßig clNone (kein /C-Eintrag wird ausgegeben, byteweise identisch mit der vorherigen Ausgabe); Fett und Kursiv sind standardmäßig auf false eingestellt. Das Festlegen von Eigenschaften nach dem Hinzufügen eines Kindelements aktualisiert das aktive Outline-Dictionary direkt, und das Zurücksetzen der Farbe auf clNone oder sowohl Fett als auch Kursiv auf false entfernt die /C- und /F-Einträge.

2026-05-20 Version 2.119.14

  • Neue, dokumentweit definierte JavaScript-Registry: THotPDF bietet jetzt RegisterDocumentJavaScript(Name, Body) an. Jeder registrierte Eintrag wird in der Katalogstruktur unter /Names /JavaScript als indirektes /S /JavaScript /JS-Dictionary serialisiert (ISO 32000-1 §7.7.4.4 + §12.6.4.16). Aktionen von Formularfeldern und Dokumentöffnungsaktionen können die registrierte Funktion über die JavaScript-Engine des Viewers (Acrobat, Foxit) anhand ihres Namens aufrufen. Dies ist nützlich, um eine Bibliothek von Validierungs-, Formatierungs- oder Berechnungsfunktionen für viele Formularfelder freizugeben, ohne den JavaScript-Quellcode in jedem /A-Aktions-Dictionary zu duplizieren. Die Methode führt zu einem Fehler bei allen PDFA-Konformitätsstufen (ISO 19005-1 §6.6.1) und allen PDFX-Konformitätsstufen (ISO 15930-Arbeitsabläufe), und lehnt leere Name-/Body-Einträge sowie doppelte Namensregistrierungen ab.

2026-05-20 Version 2.119.13

  • Neue Unterstützung für Miniaturansichten von Seiten: THPDFPage bietet jetzt die Methoden SetPageThumbnail(ImageIndex) und ClearPageThumbnail. PDF-Viewer (Acrobat, Foxit, Browser-Viewer) verwenden den Eintrag /Thumb für jede Seite (ISO 32000-1 §12.3.4), um eine vordefinierte Vorschau im Navigationsbereich anzuzeigen, ohne die Seite zu rasterisieren. Dies ist besonders nützlich für Archive mit vielen Bildern, da der eigene Rasterisierer des Viewers sonst langsam wäre. Die Hilfsfunktion verwendet wiederverwendbare Bilder, die über AddImage / AddImageFromFile registriert wurden, sodass Aufrufer ein herunterskaliertes Vorschau-Bitmap vorbereiten und es mit einem einzigen Aufruf anhängen können. SetPageThumbnail(-1) oder ClearPageThumbnail entfernt eine zuvor angehängte Miniaturansicht. Ungültige Bildindizes führen zu einer aussagekräftigen Ausnahme.

2026-05-20 Version 2.119.12

  • PDF/A-Konformitätskorrektur: `AddPushButtonWithAction` löst jetzt eine Ausnahme aus, wenn die Aktionstypen `baJavaScript` oder `baResetForm` unter einer beliebigen PDFACompliance-Ebene (PDF/A-1/2/3) verwendet werden. ISO 19005-1 §6.6.1 / ISO 19005-2 §6.5.1 / ISO 19005-3 §6.5.1 verbieten JavaScript-, ResetForm- und ImportData-Aktionen für alle PDF/A-Ebenen. `baSubmitURL` (SubmitForm), `baURI` und `baNone` sind weiterhin unter PDF/A zulässig – SubmitForm steht in der Liste der in §6.6.1 zulässigen Aktionen. Zuvor konnten Schaltflächen verbotene Aktionen enthalten, selbst wenn PDFACompliance aktiviert war, da der Schutz in v2.119.5 nur die Pfade Catalog /AA und OpenAction auf Dokumentebene abdeckte.
  • PDF/X-Konformitätskorrektur: `AddPushButtonWithAction` löst jetzt eine Ausnahme aus, wenn die Aktionstypen `baJavaScript`, `baResetForm` oder `baSubmitURL` unter einer beliebigen PDF/X-Konformitätsebene verwendet werden. ISO 15930-Vorkonfigurationsworkflows schließen interaktive Skripte, Formänderungen und die Übermittlung von Formularen an externe Endpunkte aus.

2026-05-20 Version 2.119.11

  • PDF/A-Konformitätskorrektur: PDF/A-Annotationstypen verhindern die Vervollständigung. `AddScreenAnnotation`, `Add3DAnnotation` und `AddRichMediaAnnotation` lösen jetzt eine Ausnahme aus, wenn `PDFACompliance` auf einer beliebigen Ebene (PDF/A-1/2/3) aktiviert ist. ISO 19005-1 §6.5.2 / ISO 19005-2 §6.6.1 / ISO 19005-3 §6.6.1 verbieten Screen-, 3D- und RichMedia-Annotationstypen (Multimedia / Adobe Extension Level 3) in allen PDF/A-Ebenen. Die gleichen Einschränkungen gelten auch für `PDFXCompliance` – ISO 15930-Vorbereitungsprozesse lehnen Multimedia-Typen ab.
  • PDF/A-1-Konformitätskorrektur: `AddWatermarkAnnotation` und `AddRedactAnnotation` lösen jetzt eine Ausnahme aus, wenn `PDFACompliance` auf PDF/A-1 gesetzt ist. Watermark (PDF 1.6) und Redact (PDF 1.7) sind Untertypen von Annotationen, die nach PDF 1.4 eingeführt wurden und nicht mit der PDF/A-1-Basis (ISO 19005-1 §6.5.2) kompatibel sind. PDF/A-2 und PDF/A-3 (mit PDF 1.7 als Basis) erlauben weiterhin beide Annotationstypen.

2026-05-20 Version 2.119.10

  • PDF/A-Konformitätskorrektur: `AddImageWithSMask` und `AddImageWithSMask32` lösen jetzt eine Ausnahme aus, wenn `PDFACompliance` auf PDF/A-1 gesetzt ist. ISO 19005-1:2005 §6.4 verbietet alle Transparenzeffekte; ein Bild-`/SMask`-Stream aktiviert die transparente Komposition. Führen Sie eine Vorabkomposition des Bildes auf einer Hintergrundfarbe durch und übergeben Sie das Ergebnis an `AddImage()`, oder verwenden Sie PDF/A-2 oder eine neuere Version für die Unterstützung von Transparenz. PDF/A-2 und PDF/A-3 erlauben weiterhin die transparente Bildkomposition.

2026-05-20 Version 2.119.9

  • PDF/A-Konformitätskorrektur: `SetTransparencyGroup` und `SetTransparencyGroupICC` lösen jetzt eine Ausnahme aus, wenn `PDFACompliance` auf PDF/A-1 gesetzt ist. ISO 19005-1:2005 §6.4 verbietet alle Transparenzeffekte; Transparenzgruppen auf Seitenebene (Seite /Group /S /Transparency dict) aktivieren das Transparenz-Compositing-Modell für die gesamte Seite, was einen direkten Verstoß gegen §6.4 darstellt. PDF/A-2 und PDF/A-3 erlauben weiterhin Transparenzgruppen auf Seitenebene.

2026-05-20 Version 2.119.8

  • PDF/A-Konformitätskorrektur: `RegisterHalftoneState` löst jetzt eine Ausnahme aus, wenn `PDFACompliance` aktiviert ist und ein benutzerdefiniertes Halton-Dictionary angegeben wird (d.h. `HTDefaultName = false`). ISO 19005-1:2005 §6.2.9 und ISO 19005-2:2011 / ISO 19005-3:2012 §6.3.7 erlauben nur den Literal-Namen `/Default` für `ExtGState /HT`; benutzerdefinierte Halton-Dictionaries (Typ 1, 5, 6, 10, 16) sind nicht erlaubt. Das Setzen von `HTDefaultName=True`, um auf das Standard-Halton-Dictionary zurückzukehren, funktioniert weiterhin in allen PDF/A-Versionen.
  • PDF/A-Konformitätskorrektur: `RegisterSoftMaskState` löst jetzt eine Ausnahme aus, wenn `PDFACompliance` auf PDF/A-1 gesetzt ist und ein benutzerdefiniertes Soft-Masken-Dictionary angegeben wird (Parameter `SMaskDict`). ISO 19005-1:2005 §6.4 verbietet alle Transparenzeffekte; ein nicht-Null-Wert für `/SMask` aktiviert Soft-Masken-Transparenz. Das Übergeben von `SMaskNone=True` zum Zurücksetzen von Soft-Masken ist weiterhin zulässig. PDF/A-2 und PDF/A-3 erlauben weiterhin Soft-Masken-Transparenz.

2026-05-20 Version 2.119.7

  • PDF/A-Konformitätskorrektur: `AddDocumentAttachment` (Dokumenteinschluss auf Dateiebene über Catalog /Names /EmbeddedFiles) löst jetzt eine Ausnahme aus, wenn `PDFACompliance` für PDF/A-1 oder PDF/A-3 aktiviert ist. ISO 19005-1:2005 §6.1.11 verbietet explizit den Schlüssel `/EmbeddedFiles` im Dokument-Names-Dictionary unter PDF/A-1. Für PDF/A-3 müssen Dokumente über `AddPDFA3AssociatedFile()` registriert werden, um das erforderliche Catalog `/AF`-Array und den Schlüssel `/AFRelationship` gemäß ISO 19005-3:2012 Anhang E einzufügen. PDF/A-2 erlaubt weiterhin Dokumente, sofern die angehängten Dateien selbst PDF/A-konform sind.

2026-05-20 Version 2.119.6

  • PDF/A-Konformitätskorrektur: Die Verwendung von PDF-Standardschriften (Arial, Helvetica, Times New Roman, Courier New, Symbol, ZapfDingbats) mit aktivierter StandardFontEmulation löst jetzt eine aussagekräftige Ausnahme aus, wenn PDFACompliance aktiviert ist. ISO 19005-1:2005 §6.3 und ISO 19005-2:2011 / ISO 19005-3:2012 §6.3 erfordern, dass alle Schriften in konformen Dateien eingebettet sind; der Pfad für die Standardschriftemulation erzeugt eine Referenz auf eine nicht eingebettete Schrift, was einen direkten Verstoß gegen §6.3 darstellt. Benutzer sollten StandardFontEmulation auf false setzen oder für die PDF/A-Ausgabe zu RegisterUnicodeTTF() mit den entsprechenden Schriftdateien wechseln.
  • PDF/A-Konformitätskorrektur: Nicht-standardmäßige Schriftarten werden jetzt immer eingebettet, wenn PDFACompliance aktiviert ist, unabhängig von der Einstellung der FontEmbedding-Eigenschaft. Die FontEmbedding = false-Optimierung wird im PDF/A-Modus stillschweigend überschrieben, um die Anforderung aus §6.3, dass alle Schriftarten eingebettet sein müssen, zu erfüllen.

2026-05-20 Version 2.119.5

  • PDF/A-Konformitätskorrektur: JavaScript-Aktionen und Katalog-Ebene /AA (zusätzliche Aktionen) werden jetzt blockiert, wenn PDFACompliance aktiviert ist. ISO 19005-1:2005 §6.6.1/§6.6.2 und ISO 19005-2:2011 / ISO 19005-3:2012 §6.5.1/§6.6.2 verbieten alle JavaScript-Aktionstypen und untersagen den Schlüssel /AA im Katalog-Dictionary. Der Aufruf von SetActionScript mit einem beliebigen PDFACompliance-Wert löst jetzt eine aussagekräftige Ausnahme aus. Als zusätzliche Sicherheitsmaßnahme werden die JavaScript-Pfade für OpenAction und Katalog-/AA im EndDoc ebenfalls so gesteuert, dass die Ausgabe stillschweigend übersprungen wird, wenn PDFACompliance aktiviert ist, um sicherzustellen, dass auch über interne Pfade keine nicht konformen Schlüssel geschrieben werden.

2026-05-20 Version 2.119.4

  • PDF/A-Konformitätskorrektur: Das Attribut /NeedAppearances in AcroForm wird jetzt bei aktivierter PDFACompliance zwangsweise auf false gesetzt, unabhängig von der Einstellung von AutoFormAppearances. ISO 19005-1:2005 §6.9 und ISO 19005-2:2011 / ISO 19005-3:2012 §6.4 fordern, dass dieser Schlüssel in konformen Dateien entweder nicht vorhanden ist oder auf false gesetzt ist. Zuvor wurde, wenn AutoFormAppearances deaktiviert war, während PDFACompliance aktiv war, /NeedAppearances auf true gesetzt, was zu einer nicht konformen Datei führte.

2026-05-20 Version 2.119.3

  • PDF/A-Konformitätskorrektur: Eingebettete CIDFont-Teilmengen enthalten jetzt einen /CIDSet-Datenstrom in ihrem FontDescriptor, wenn PDFACompliance aktiviert ist. ISO 19005-1:2005 §6.3.5 und ISO 19005-2:2011 / ISO 19005-3:2012 §6.2.11 erfordern, dass CIDFont-Teilmengen einen /CIDSet-Bitstrom enthalten, der angibt, welche CID-Werte im eingebetteten Schriftprogramm vorhanden sind. HotPDF verwendet die Identity-H-Kodierung, bei der CID gleich dem Unicode-Codepunkt ist, sodass der CIDSet-Bitstrom direkt aus der Menge der im Dokument verwendeten Codepunkte erstellt wird. Der Bitstrom wird mit FlateDecode komprimiert und als indirektes Stream-Objekt an den vorhandenen FontDescriptor angehängt. Dies behebt eine zuvor unentdeckte Lücke in allen PDF/A-Ebenen (die vorherige Konformitätsprüfung gab fälschlicherweise an, dass dies bereits vorhanden sei).

2026-05-20 Version 2.119.2

  • PDF/A-2 und PDF/A-3-Konformitätskorrektur: Das Erscheinungsbild-Dictionary für Annotationen (/AP /N) wird jetzt automatisch für Annotationstypen, die keine Links und keine Popups sind (Textnotizen, Freitext, Linie, Quadrat, Kreis, Stempel, Dateianhang), generiert, wenn PDFACompliance auf eine PDF/A-2- oder PDF/A-3-Ebene eingestellt ist. ISO 19005-2:2011 §6.3.3 und ISO 19005-3:2012 §6.3.3 fordern, dass jede solche Annotation mindestens ein Erscheinungsbild-Dictionary (mit dem Eintrag "N" für XObject) hat. Ein minimales, leeres Formular-XObject wird generiert, um die strukturelle Anforderung zu erfüllen; die meisten PDF-Betrachter verwenden ihre eigene integrierte Darstellung für Standard-Annotationstypen, unabhängig vom Inhalt des /AP-Streams. Link- und Popup-Annotationen sind ausdrücklich von dieser Anforderung ausgenommen und bleiben unverändert. Diese Anforderung gilt nicht für PDF/A-1 (ISO 19005-1 §6.5.3 beschränkt nur das Format von /AP, wenn es vorhanden ist, nicht seine Existenz).

2026-05-20 Version 2.119.1

  • PDF/A-Konformitätskorrektur: Alle Annotationstypen, die keine Widgets sind (Textnotizen, Stempel, Linien, Formen, Hyperlinks, GoTo-Links, GoToR-Links, URI-Links), setzen jetzt automatisch das Flag /F (Bit 3 = 1, Wert 4), wenn PDFACompliance aktiviert ist. ISO 19005-1:2005 §6.5.3 und ISO 19005-2:2011 / ISO 19005-3:2012 §6.3.2 schreiben vor, dass jedes Annotations-Dictionary einen Schlüssel /F enthalten muss, wobei das Print-Bit gesetzt ist. Zuvor hatten nur Widget-Annotationen (Formularfelder) dieses Flag; alle anderen Annotationstypen enthielten es nicht, was dazu führte, dass die erstellten Dateien nicht den Spezifikationen entsprachen.
  • PDF/A-1-Konformitätskorrektur: optionale Inhaltsgruppen (Ebenen) werden jetzt blockiert, wenn PDFACompliance auf eine PDF/A-1-Ebene ('A' oder 'B') gesetzt ist. ISO 19005-1:2005 §6.1.13 verbietet den Schlüssel /OCProperties im Katalog-Dictionary; der Aufruf von RegisterOptionalContentGroup unter PDF/A-1 löst jetzt eine aussagekräftige Ausnahme aus, die Aufrufer dazu auffordert, PDF/A-2 oder höher zu verwenden, wenn optionale Inhalte erforderlich sind. Die Ausgabe von /OCProperties am Ende des Dokuments wird ebenfalls unterbunden, um eine stille Nichtkonformität zu verhindern, selbst wenn optionale Inhaltsgruppen irgendwie registriert wurden.

2026-05-20 Version 2.119.0

  • Unterstützung für XAdES-in-PDF-Container gemäß ETSI EN 319 142-2 V1.2.0 §6.2 (Abschluss der B/C/D-Serie, Teil 3). Betten Sie von der aufrufenden Anwendung bereitgestellte, XAdES-signierte XML-Daten als PDF-EmbeddedFile ein, registrieren Sie die Dateispezifikation im Katalog /AF-Array und legen Sie /AFRelationship gemäß der von der aufrufenden Anwendung angegebenen PDF 2.0-Aufzählung fest. Dies ist nur eine Wrapper-Funktion auf der Produktionsseite – die eigentliche XAdES-Signaturerstellung (XML-DSig + ETSI EN 319 132-1 QualifyingProperties + RFC 3161-Zeitstempel, eingebettet in xades:UnsignedSignatureProperties) liegt in der Verantwortung der kryptografischen XML-Bibliothek der aufrufenden Anwendung (z. B. Apache Santuario, .NET SignedXml, libxmlsec, Saxon mit XAdES-Erweiterungen).
  • Neue Methode `THotPDF.AddXAdESAssociatedFile(FileName, XMLBytes, Description, MimeType, Relationship)`. Standardwerte: MimeType `'application/xml'` (häufig auch `'application/vnd.etsi.asic-e+zip'` für ASiC-E-Archive), Relationship `'Source'` (die mit XAdES signierte XML-Datei ist der Hauptinhalt des Dokuments). Gibt das indirekte Filespec-Dictionary zurück, sodass Aufrufer zusätzliche Metadaten oder Querverweise aus benutzerdefinierten Katalogeinträgen hinzufügen können.
  • Unabhängig von PDF/A: Im Gegensatz zu `AddPDFA3AssociatedFile` in Version v2.108 (das PDFACompliance='3*' erfordert), hat diese Hilfsfunktion keine PDF/A-Beschränkung – XAdES-in-PDF ist eine eigene Profilfamilie gemäß PAdES Teil 2 V1.2.0 §6.
  • Wichtige Fehlerbehebung in `_EscapePDFNameBytes` (PDF 1.7 ISO 32000-1 §7.3.5 + Tabelle 2). Die vorherige Maskierung konvertierte nur Bytes außerhalb des Bereichs [0x21..0x7E] und das '#' Zeichen; PDF-Begrenzer (`/ ( ) < > [ ] { } %`) müssen laut Spezifikation als '#XX' innerhalb von Namen maskiert werden, wurden aber bisher unverändert belassen. Namen wie `/Subtype /application/xml` wurden daher von strengen Readern als zwei separate Namens-Token geparst (/application gefolgt von /xml), was die Erkennung von EmbeddedFile /Subtype beeinträchtigte. In Version 2.119 werden alle 10 Begrenzer gemäß der Spezifikation maskiert; Namen, die keine Begrenzer enthalten (die überwiegende Mehrheit der HotPDF-Ausgaben), bleiben byteidentisch. MIME-Typen für PDF/A-3 Anhang E (Version 2.108) werden jetzt korrekt ausgegeben (`/application#2Fxml` anstelle des fehlerhaften `/application/xml`).
  • Die PAdES B/C/D-Reihe wurde mit 3 Commits abgeschlossen: v2.117 (Erweiterte Profile E-BES / E-EPES / E-LTV gemäß Teil 2 §5) + v2.118 (Seed-Werte gemäß ISO 32000-1 §12.7.5.5 + Teil 2 §4.2.6) + v2.119 (XAdES-in-PDF + Korrektur der Escape-Sequenz gemäß Teil 2 §6.2). In Kombination mit v2.109 - v2.116 deckt HotPDF nun den gesamten PAdES-Herstellerbereich ab, einschließlich Basisprofilen, erweiterten Profilen, Dokumentenzeitenstempel, DSS-Validierungsinformationen, ESIC-Erweiterungen, Signierungsbeschränkungen über Seed-Werte und dem XAdES-in-PDF-Container.
  • Win32 + Win64: saubere Kompilierung; die Baselines v2.108 - v2.118 wurden komplett neu kompiliert, ohne Änderungen. Neue Tests für `smoke_pades_xades` mit 2 positiven Pfaden (XAdES-signierte XML-Dateien als `/AFRelationship /Source` und ASiC-E-Archive als `/Data`) und 4 negativen Pfaden (leere Dateinamen, leere XML-Bytes, leerer MIME-Typ, ungültige Beziehung). Der Python-Verifizierer durchläuft beide Dateispezifikationen vollständig, einschließlich der Escape-Formen `/Subtype /application#2Fxml` und `/Subtype /application#2Fvnd.etsi.asic-e+zip`. Die Tests für PDF/A-3 / PAdES / PDF/X in `v2.108` wurden erneut ausgeführt und sind sauber.

2026-05-20 Version 2.118.0

  • PAdES Seed Values gemäß 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 (Schritt 2 von 3 der B/C/D-Serie). Ein Seed Value (SV)-Dictionary, das einem Signaturfeld beigefügt ist, schränkt ein, welche Optionen das Signaturwerkzeug des Lesegeräts für dieses spezifische Feld auswählen darf – welcher Handler, welcher SubFilter, welche Digestmethode, ob Informationen zur Widerrufspflicht erforderlich sind und welche Mindest-PDF-Version erforderlich ist.
  • Neue `THotPDF.AttachPAdESSeedValue(FieldName, SubFilters, DigestMethods, ForceSubFilter, ForceDigestMethod, AddRevInfo, MinPDFVersion, ForceMinPDFVersion)`-Methode. Sucht das benannte Signaturfeld in der Liste der AcroForm-Felder (das muss bereits durch einen vorherigen Aufruf von `AddPAdESSignatureField` oder `AddDocumentTimestampSignature` erstellt worden sein) und fügt ein Unter-Dictionary `/SV` mit den vom Aufrufer angegebenen Einschränkungen hinzu.
  • Seed Value-Einträge werden (gemäß Tabelle 234) ausgegeben:
    • `/Type /SV`
    • `/SubFilter` ein Array von Namen – z.B. [/ETSI.CAdES.detached]
    • `/DigestMethod` ein Array von Namen – z.B. [/SHA256 /SHA384 /SHA512]
    • `/AddRevInfo` ein boolescher Wert – das Signaturwerkzeug muss OCSP/CRL in CMS enthalten
    • `/V` eine Zahl – die minimale PDF-Version (z.B. 1.7)
    • `/Ff` Integer-Bitflags (Tabelle 235) – jeder Parameter `Force*` setzt das entsprechende Bit, sodass das Signaturwerkzeug die Einschränkung BEACHTEN MUSS (Bit 2 = erzwinge `SubFilter`, Bit 3 = erzwinge `V`, Bit 6 = erzwinge `AddRevInfo`, Bit 7 = erzwinge `DigestMethod`)
  • Sicherheitsmechanismen zur Einhaltung von Standards: PAdES Teil 2 V1.2.0 §4.2.6 verbietet Seed-Werte, die dazu führen würden, dass Signaturtools gegen das PAdES-Profil verstoßen (z. B. die Angabe eines PKCS#1 SubFilters). HotPDF erzwingt dies nicht auf der Produktionsseite – der Aufrufer ist dafür verantwortlich, nur Werte zu übergeben, die den Spezifikationen entsprechen (`'adbe.pkcs7.detached'` oder `'ETSI.CAdES.detached'` für SubFilter, SHA-256+ für DigestMethod). Der Hilfekommentar macht explizit auf diese Einschränkung aufmerksam.
  • Saubere Kompilierung für Win32 und Win64; die Baselines v2.108 bis v2.117 wurden komplett neu kompiliert, ohne Änderungen. Das neue Modul `smoke_pades_seedvalue` erstellt ein PAdES-B-T-Feld und fügt eine vollständige Menge von Seed-Value-Einschränkungen hinzu (SubFilter ist auf ETSI.CAdES.detached beschränkt, DigestMethod ist auf SHA256/384/512 beschränkt, AddRevInfo ist aktiviert, MinPDFVersion ist 1.7, alle Zwangseinstellungen sind gesetzt). Der Python-Verifizierer durchläuft das Unter-Dictionary `/SV` und überprüft die Form jedes Eintrags; er testet auch den Pfad zur Ablehnung von "unbekannten FieldName"-Einträgen.
  • Serie Schritt 3 (v2.119): Der XAdES-in-PDF-Container gemäß Teil 2 V1.2.0 §6 schließt die B/C/D-Serie ab. Auf der Produzenseite handelt es sich um eine dünne Wrapper-Schicht um die bestehende EmbeddedFile-/Catalog-/AF-Infrastruktur von HotPDF (v1.08 PDF/A-3-Hilfsmittel) sowie um die /AFRelationship-Semantik, die PAdES Teil 2 V1.2.0 §6.2.2 für XAdES-signierte XML-Daten erwartet.

2026-05-20 Version 2.117.0

  • PAdES erweiterte Profile gemäß ETSI EN 319 142-2 V1.2.0 §5 (B/C/D-Reihe, Schritt 1 von 3). Der Teil 1 legt die grundlegenden (festen) Kombinationen von CMS-Attributen fest (V1.2.1 §6 B-B / B-T / B-LT / B-LTA); Teil 2 §5 definiert eine parallele Familie von "erweiterten" Profilen (E-BES / E-EPES / E-LTV) mit größerer Flexibilität bei den optionalen CMS-Attributen für Anwender, die mehr Flexibilität benötigen als die Basis bietet (z. B. unternehmensweite Bereitstellungen mit mehreren Richtlinien, benutzerdefinierte CAdES-Profile innerhalb der PAdES-Umgebung).
  • `AddPAdESSignatureField`: Der Profilparameter akzeptiert jetzt drei zusätzliche Werte zusätzlich zu den vier Basismusternamen:
    • `'E-BES'` — grundlegende + eindeutige Bindung des Signaturzertifikats über das Attribut ESS (CAdES-BES-Äquivalent innerhalb der PAdES-Umschlag). Standardmäßig 16 KB Speicherplatz für den Inhalt.
    • `'E-EPES'` — E-BES + explizites signiertes Attribut für die Signaturrichtungs-ID. Standardmäßig 16 KB Speicherplatz; der Aufrufer übergibt typischerweise 18-20 KB, um die Bytes für die Richtungs-OID und die Qualifizierungsdaten zu berücksichtigen.
    • `'E-LTV'` — Langzeitvalidierung mit flexibler Zertifikatskette und eingebetteter Widerrufsinformation. Wird automatisch auf mindestens 20 KB erhöht (entspricht B-LT).
  • Das interne Format auf Produzenseite ist für die Basis- und erweiterte Profile identisch – alle sieben verwenden den Subfilter `ETSI.CAdES.detached`, das gleiche Muster für `/ByteRange` und `/Contents` sowie die gleiche DSS- und ESIC-Implementierung (Version 2.110 / Version 2.116). Die Unterscheidung zwischen den Levels liegt ausschließlich in der Zusammensetzung der signierten Attribute im CMS, die von der kryptografischen Bibliothek des Aufrufers erzeugt werden. Der Profilstring variiert nur in Bezug auf die Validierungsdiagnose und das Standardbudget für `/Contents`; HotPDF kodiert keine Unterschiede zwischen CAdES-BES, CAdES-EPES und CAdES-T im PDF-Dictionary selbst.
  • Aktualisierte die Hilfedokumentation für PAdES, um die Verantwortlichkeiten des Aufrufers hervorzuheben, die in Teil 2, Version 1.2.0, §4.2 beschrieben sind: Auswahl des SHA-256+-Hash (Einstellung von SHA-1), ein einzelnes SignerInfo pro Sig-Feld, keine RFC 5755-Attributzertifikate und die Anforderung von E-EPES, das signierte Attribut "signature-policy-identifier" einzuschließen. Elemente, die dem Aufrufer zugewiesen sind, bleiben außerhalb des Verantwortungsbereichs des Herstellers, aber der Vertrag ist jetzt explizit in der API-Schnittstelle definiert.
  • Win32 + Win64: saubere Kompilierung; die Baselines v2.108 bis v2.116 wurden komplett neu kompiliert, ohne Änderungen. `smoke_pades_signature` wurde um 3 neue Felder erweitert (SigEBES / SigEEPES / SigELTV), wobei jeder neue Profilwert über die Pfade "automatische Größenanpassung", "explizites Budget" und "Standard-Budget" getestet wurde. Der Python-Verifizierer wurde erweitert, um alle 7 Felder zu durchlaufen und die Catalog ESIC-Erweiterung zu überprüfen (Funktionalität von v2.116 wurde übernommen).
  • Schritt 2 der B/C/D-Reihe: v2.118 fügt Seed-Werte hinzu (PDF 1.7 §12.7.5.5 + ETSI EN 319 142-1 V1.2.1 §5.5 + Teil 2 V1.2.0 §4.2.6), sodass PAdES-Signaturfelder Handler-/SubFilter-/Digest-Methoden-Einschränkungen definieren können, die der empfangende Reader während der Signierung einhalten muss. Schritt 3: v2.119 fügt Unterstützung für XAdES-Container in PDF gemäß Teil 2 V1.2.0 §6 hinzu (XAdES-signierte XML-Dateien werden als EmbeddedFile eingebettet und mit dem Katalog /AF verknüpft).

2026-05-20 Version 2.116.0

  • Aktualisierung von PAdES gemäß den neuesten normativen Versionen von ETSI und der Durchführungsentscheidung von eIDAS: ETSI EN 319 142-1 V1.2.1 (2024-01, veröffentlicht) + ETSI EN 319 142-2 V1.2.0 (2025-03, Entwurf zusätzlicher Profile + erweiterter Profilfamilie + XAdES-in-PDF) + ETSI TS 119 142-3 V1.1.1 (2016-12, PAdES-DTS Dokument-Zeitstempel) + EU 2015/1506 (Anerkennung im öffentlichen Sektor). Die Baselines von HotPDF v2.109 - v2.111 (B-B / B-T / B-LT / B-LTA + unabhängiger Zeitstempel) erfüllen weiterhin das gleiche Datenformat; diese Version behebt zwei Probleme, die die neuen Spezifikationsversionen aufgeworfen haben.
  • Der Eintrag `/Type "DSS"` im DSS-Dictionary (EN 319 142-1 V1.2.1 §5.4.2.2). Der Eintrag `/Type` ist optional, muss aber, falls vorhanden, den Namen `/DSS` haben. HotPDF gibt ihn jetzt sofort aus, sodass strenge Validierer, die `/Type` überprüfen, bevor sie den Rest des Dictionarys durchlaufen, die Struktur sofort erkennen.
  • ESIC-Erweiterungs-Dictionary (TS 119 142-3 §5.1, empfohlen). Die neue Methode `EnsurePAdESESICExtensions` schreibt idempotent folgende Einträge in den Katalog, wann immer ein PAdES-Helfer aufgerufen wird: `<< /Extensions << /ESIC << /BaseVersion /1.7 /ExtensionLevel 1 >> >> >>`. Validierer (Adobe Acrobat Preflight, EU DSS, callas pdfaPilot) verwenden diesen Eintrag, um das Dokument als einen PAdES-Container zu identifizieren, der PDF 1.7 und ESIC-Erweiterungsebene 1 deklariert.
  • Kritischer Fehler in der `EnsurePAdESDSS`-Rückgabepfadfunktion behoben. Vor der Version v2.116 hat die Hilfsfunktion das DSS-Dictionary bei jedem Aufruf erneut aufgelöst, und zwar über `Catalog.GetIndexedItem(FindValue('DSS'))`, was einen indirekten Link vom Typ `THPDFLink` zurückgab, der im Katalog gespeichert ist, anstatt des eigentlichen DSS-Dictionaries. Die implizite Umwandlung in `THPDFDictionaryObject` führte zu einer falschen Typisierung des Zeigers, wodurch jeder nachfolgende Aufruf von `AddPAdESDSSCertificate` / `AddPAdESDSSOCSP` / `AddPAdESDSSCRL` / `AddPAdESDSSVRI` nach dem ersten Aufruf dazu führte, dass das Element nicht in das Array eingefügt wurde (die Array-Referenz wurde zu nil, `FindValue` gab -1 zurück, und die frühzeitige Beendigung der `if-Idx-less-than-zero`-Bedingung wurde ausgelöst). Die Korrektur in v2.116 speichert eine Referenz auf das tatsächliche Dictionary in einem Feld namens `FPAdESDSSDict`, sodass nachfolgende Aufrufe direkt auf diesen Cache zugreifen. Der Test `smoke_pades_dss` gibt jetzt korrekt 2 Zertifikate + 1 OCSP + 1 CRL + 1 VRI-Eintrag aus (zuvor wurde nur das erste Zertifikat in `/DSS` eingefügt, während `/OCSPs` und `/CRLs` leere Arrays waren).
  • Änderungen an den Dokumentationskommentaren für die PAdES-Hilfsfunktionen, die die Verantwortlichkeiten des Aufrufers abdecken und in Abschnitt 4.2 von Teil 2, Version 1.2.0, beschrieben sind: Ausphasung von SHA-1 (Aufrufer sollten SHA-256+ für CMS verwenden), nur ein SignerInfo pro PDF-Signatur (Teil 2, Abschnitt 4.2.1 h / Teil 1, Abschnitt 4.1 a), RFC 5755-Attributzertifikate sollten nicht verwendet werden (Teil 2, Abschnitt 4.2 g) und PAdES-DTS-Dokumente sollten keine VRI-Dictionaries enthalten (TS 119 142-3, Abschnitt 6.3 h – DSS ist ausreichend). Das interne Format von HotPDF erfüllt bereits alle vier Einschränkungen. Der Kommentar informiert die Aufrufer darüber, was ihre CMS-Konstruktionsbibliotheken tun müssen.
  • Win32 + Win64: saubere Kompilierung; die Tests `smoke_pades_signature`, `smoke_pades_dss` und `smoke_pades_doctimestamp` sowie deren Verifizierer sind erfolgreich. Verifizierungs-Erweiterungen: `smoke_pades_dss` setzt jetzt `/Type /DSS` und `Catalog /Extensions /ESIC /BaseVersion /1.7 /ExtensionLevel 1` durch; `smoke_pades_doctimestamp` setzt dieselbe ESIC-Erweiterung durch und akzeptiert eine um 180 Grad gedrehte, nullflächige `/Rect` (`[0 H 0 H]`, wobei H die Seitenhöhe ist). Die Audit-Dokumente und technischen Notizen wurden aktualisiert, um auf EN 319 142-1 V1.2.1 / Teil 2 V1.2.0 / TS 119 142-3 / EU 2015/1506 zu verweisen.

2026-05-20 Version 2.115.0

  • PDF/X (ISO 15930) Produktionsreihen-Abschluss (4/4): Verbotene Anmerkungs- und Aktionsarten gemäß ISO 15930-1:2001 / ISO 15930-3:2002 / ISO 15930-7:2010 + ISO 32000-1 §12.5.6 / §12.6.4. PDF/X-Druckworkflows verarbeiten nur den sichtbaren, druckbaren Inhalt – Multimedia-Anmerkungen, eingebettete Dateien und interaktive Aktionen spielen keine Rolle im Druckprozess, daher lehnen Vorabprüfungstools (Adobe Acrobat, Enfocus PitStop, callas pdfaPilot) Dokumente ab, die diese enthalten.
  • Verbotene Annotationstypen (werden unter allen PDF/X-Konformitätsstufen ∈ {X-1a, X-3, X-4} abgelehnt):
    • FileAttachment – Druckereien verarbeiten keine eingebetteten Dateien.
    • Sound – Multimedia hat in Druckworkflows keinen Platz.
    • Movie – Gleiche Argumentation wie bei Multimedia.
    Jeder Einstiegspunkt (AddFileAttachmentAnnotation, AddSoundAnnotation, AddMovieAnnotation) löst jetzt eine Diagnose gemäß der Spezifikation und den Wert der PDF/X-Konformität aus, wenn er unter einem PDF/X-Profil aufgerufen wird.
  • Verbotene Aktionsarten (werden unter allen PDF/X-Konformitätsprüfungen abgelehnt): Launch, JavaScript, SubmitForm, ImportData, Movie, Sound, ResetForm. Druckvorstufearbeitsabläufe dürfen keine externen Programme starten – die PDF-Datei wird nur vom Drucksystem/RIP verarbeitet und niemals ausgeführt. Die Funktion AddLaunchLink löst jetzt unter allen PDF/X-Profilen einen Fehler aus (andere Aktionen, die HotPDF nicht als öffentliche API-Schnittstellen bereitstellt, werden automatisch erfüllt).
  • Die PDF/X-Reihe ist jetzt funktional vollständig: v2.112 (optional + XMP-Identität + Trapped/Name) + v2.113 (OutputIntent + ICC GTS_PDFX) + v2.114 (Transparenzprüfung + Durchsetzung der Seitengröße) + v2.115 (verbotene Anmerkungen/Aktionen). Alle drei Industriestandardprofile (X-1a:2001, X-3:2002, X-4:2010) werden unterstützt. Der Aufrufer erstellt weiterhin inhalt für die Vorstufe auf Seitenebene (korrekte CMYK-Werte, Schrifteinbettung über den TTF-Subsetter v2.84, TrimBox-Dimensionen, die mit dem Design übereinstimmen, BleedBox, wenn ein Beschnitt erforderlich ist), aber alle strukturellen Konformitätsprüfungen sind implementiert.
  • Win32 + Win64: saubere Kompilierung; die Baselines v2.108 - v2.114 wurden vollständig neu kompiliert, ohne Änderungen. `smoke_pdfx_optin` wurde um 4 neue Ablehnungstests erweitert (TestRejectFileAttachmentAnnot, TestRejectSoundAnnot, TestRejectMovieAnnot, TestRejectLaunchAction) – jeder Test erzeugt den verbotenen Typ innerhalb eines der drei PDF/X-Profile und bestätigt eine saubere Ablehnung. Insgesamt deckt der gesamte Testlauf jetzt 11 Szenarien ab: 3 positive Ergebnisse + 8 Ablehnungspfade.
  • In dieser Gruppe wurden zwei parallele, mehrversionierte Serien zusammengefasst: PAdES (ETSI EN 319 142, v2.109 - v2.111, 3 Commits, B-B / B-T / B-LT / B-LTA + unabhängiger Zeitstempel, alle unterstützt) und PDF/X (ISO 15930, v2.112 - v2.115, 4 Commits, X-1a / X-3 / X-4, alle strukturellen Konformitätsprüfungen auf Produzenseite implementiert).

2026-05-20 Version 2.114.0

  • PDF/X (ISO 15930) Produktreihe, Sektion 3/4: Transparenzprüfung und Durchsetzung des PageBox-Formats gemäß ISO 15930-1:2001 / ISO 15930-3:2002 / ISO 15930-7:2010 + ISO 32000-1 §14.11.2. Diese Sektion umfasst zwei unabhängige Einschränkungen, die beide pro Seite gelten; die Struktur der Prüfung spiegelt das Muster für Transparenz und Seiteneigenschaften von PDF/A-1 in Version 2.103 wider.
  • Transparenzprüfung (§7.5): RegisterExtGState lehnt Füllalphawerte kleiner 1 (/ca), Strichalphawerte kleiner 1 (/CA) oder Mischmodi außerhalb von {Normal, Kompatibel} ab, wenn PDFXCompliance auf 'X-1a' oder 'X-3' eingestellt ist. PDF/X-1a (ISO 15930-1:2001) und PDF/X-3 (ISO 15930-3:2002) erfordern eine Basisversion von PDF 1.3, die vor PDF 1.4-Transparenz eingeführt wurde. PDF/X-4 (ISO 15930-7:2010, Basisversion PDF 1.6) erlaubt explizit Transparenz, sodass die Prüfung unter X-4 nicht ausgelöst wird. Die Diagnose erklärt die Ursache und schlägt vor, auf X-4 zu aktualisieren, wenn Transparenz erforderlich ist.
  • Durchsetzung von PageBoxen (§14.11.2): Die neue Methode `EnsurePDFXPageBoxes` durchläuft jede Seite und erfordert mindestens eines von /TrimBox oder /ArtBox. Allein die MediaBox ist nicht ausreichend, da sie die Designfläche darstellt und nicht die Abmessungen der fertigen Seite, die die Druckerei benötigt, um zu wissen, wo sie schneiden muss. Fehlende PageBoxen führen zu einer Fehlermeldung, die die 1-basierte Seitenzahl, den Abschnitt der Spezifikation und den empfohlenen Aufruf von SetTrimBox enthält. Das EndDoc PDFXCompliance-Gate ruft automatisch EnsurePDFXPageBoxes nach der OutputIntent-Prüfung auf.
  • Typisches Aufrufverhalten: Nachdem PDFXCompliance, Trapped und AddPDFXOutputIntent eingestellt wurden, muss jede Seite im Dokument `CurrentPage.SetTrimBox(Left, Bottom, Right, Top)` enthalten, wobei die Abmessungen dem Endprodukt entsprechen (z. B. 0 0 612 792 für US Letter oder 0 0 595 842 für A4). Ein BleedBox wird empfohlen, ist aber nicht zwingend erforderlich.
  • Win32 + Win64: saubere Kompilierung; die Baselines v2.108 bis v2.113 wurden vollständig neu kompiliert, ohne Änderungen. `smoke_pdfx_optin` wurde erweitert um: einen positiven Aufruf von `SetTrimBox` in jedem der 3 Profile, einen Pfad zur Ablehnung fehlender `TrimBox`-Werte, einen Pfad zur Ablehnung von Transparenz vom Typ X-1a (der Aufruf `RegisterExtGState` mit `ca=0.5` führt zu einem Fehler), einen positiven Pfad für Transparenz vom Typ X-4 (derselbe Aufruf ist erfolgreich und `ExtGState` wird registriert). Der Python-Verifizierer durchläuft jedes `/Type /Page`-Dictionary und stellt sicher, dass mindestens eines von `/TrimBox` oder `/ArtBox` für jede Seite vorhanden ist.
  • Bleibt noch der PDF/X-Bereich: Version 2.115 schließt die Reihe ab und verbietet bestimmte Aktionstypen (JavaScript / Launch / SubmitForm / ImportData / Movie / Sound), bestimmte Annotationstypen (Movie / Sound / FileAttachment / Screen) sowie die Verwendung von AcroForm/XFA. Druckworkflows haben keinen Platz für diese Funktionen; Tools zur Vorabprüfung weisen auf diese als schwerwiegende Fehler hin.

2026-05-19 Version 2.113.0

  • PDF/X (ISO 15930) Produktreihe, Teil 2/4: Durchsetzung von OutputIntent und ICC-Profilen gemäß ISO 15930-1:2001 §6.2.2 / ISO 15930-3:2002 §6.2.2 / ISO 15930-7:2010 §6.2 sowie ISO 32000-1 §14.11.5. Jedes PDF/X-Profil erfordert mindestens einen Eintrag vom Typ /Type /OutputIntent /S /GTS_PDFX, der die Ziel-Druckbedingungen benennt und den zugehörigen /DestOutputProfile ICC-Profil-Datenstrom bereitstellt – Druckereien verwenden dies, um die Farbe des PDF an ihre jeweilige Druckmaschine, das Papier oder die Tinte anzupassen.
  • Die neue Hilfsfunktion `AddPDFXOutputIntent(OutputConditionIdentifier, Info, ICCProfileStream, NumComponents, AlternateCS)` ähnelt dem v2.102 PDF/A-Wrapper, erzeugt aber den GTS_PDFX-Subtyp anstelle von GTS_PDFA1. Sie prüft, ob `ICCProfileStream` nicht null ist und `OutputConditionIdentifier` nicht leer ist; sie ruft `RegisterICCProfile` auf, um das Profil einzubetten (und behandelt automatisch die Zuordnung des alternativen Farbraums zu `NumComponents`), und `AddOutputIntent`, um das `OutputIntent`-Dictionary zu erstellen.
  • Erzwingung von EndDoc: Wenn PDFXCompliance aktiviert ist, überprüft EnsurePDFXOutputIntent das Array der OutputIntents und stellt sicher, dass mindestens ein Eintrag mit /S /GTS_PDFX + /DestOutputProfile vorhanden ist. Fehlt ein solcher Eintrag, wird ein Fehler ausgelöst, wobei eine entsprechende Empfehlung für die Kennung angezeigt wird (FOGRA39 für Offsetdruck, CGATS TR 001 SWOP für den nordamerikanischen Markt, Japan Color 2001 Coated für asiatische Märkte).
  • Typischer PDF/X-Workflow: 1) `Doc.PDFXCompliance := 'X-4'`, 2) `Doc.Trapped := 'False'`, 3) Laden eines CMYK-ICC-Profil-Streams (FOGRA39 / SWOP / usw.) in einen `TStream`, 4) `Doc.AddPDFXOutputIntent('FOGRA39 (ISO 12647-2:2004)', '', ICCStream, 4, 'DeviceCMYK')`, 5) Inhalt gestalten, 6) `Doc.EndDoc` erzeugt den OutputIntent, der mit dem Array /OutputIntents im Katalog verknüpft ist; Tools zur Vorabprüfung (Adobe Acrobat, Enfocus PitStop, callas pdfaPilot) validieren die Farbmanagement-Einstellungen.
  • Win32 + Win64: Saubere Kompilierung; die Baselines v2.108, v2.109, v2.110, v2.111 und v2.112 wurden komplett neu kompiliert, ohne Änderungen. `smoke_pdfx_optin` (ursprünglich v2.112) wurde erweitert, um ein gefälschtes ICC-Profil zu registrieren und `AddPDFXOutputIntent` in jeder der drei Profilausgaben hinzuzufügen (X-1a → FOGRA39 CMYK, X-3 → SWOP CMYK, X-4 → sRGB RGB), sowie einen Ablehnungspfad, der sicherstellt, dass das Fehlen eines `OutputIntent` zu einem Fehler führt. Der Python-Verifizierer wurde erweitert, um jedes Dictionary zu durchlaufen und den Eintrag `/Type /OutputIntent /S /GTS_PDFX` mit `/DestOutputProfile` zu überprüfen.
  • Verbleibende PDF/X-Funktionen: v2.114 fügt die Transparenzprüfung hinzu (X-1a / X-3 lehnen ExtGState-Füllung/Kontur mit Alpha-Wert < 1 und BM-Normal ab; X-4 erlaubt Transparenz) + erzwingt die Seitengrößen (jede Seite benötigt einen TrimBox- oder ArtBox-Bereich gemäß §14.11.2); v2.115 schließt die Reihe mit verbotenen Aktionen für die Bereiche /annot /XFA (Filme, Audio, Dateianhänge, Bildschirme, JavaScript, Starten, Formularübermittlung, Datenimport und XFA werden alle abgelehnt, da Druckworkflows keinen Platz dafür haben).

2026-05-19 Version 2.112.0

  • Gestartet der PDF/X (ISO 15930) Druck-Vorkonvertierungsproduktsreihe. PDF/X ist die ISO-Familie für das Senden von druckfertigen PDFs an Druckereien; die Profile X-1a (striktes CMYK + Spotfarben), X-3 (ICC-verwaltete Farben) und X-4 (PDF 1.6 Transparenz + ICCN) sind die drei, die in der Industrie weit verbreitet sind. v2.112 ist Teil 1/4: Optionale Eigenschaft + Identitätsmetadaten. Eine vollständige Prüfung sowie eine 4-Versions-Roadmap sind unter .superpowers/specs/2026-05-19-pdfx-compliance-audit.md archiviert.
  • Die neue `PDFXCompliance: AnsiString`-Eigenschaft von THotPDF akzeptiert `''` (deaktiviert, Standard), `'X-1a'` (ISO 15930-1:2001), `'X-3'` (ISO 15930-3:2002) oder `'X-4'` (ISO 15930-7:2010). Wenn ein nicht leerer Wert eingestellt wird, werden automatisch alle anfordernden Bedingungen aktiviert, die HotPDF für dieses Profil strukturell erfüllen kann.
  • Neue `Trapped: AnsiString`-Eigenschaft (obligatorisch unter PDFXCompliance), akzeptiert `'True'`, `'False'` oder `'Unknown'`. Die PDF/X-Familie erfordert diesen DocInfo-Eintrag, damit die Druckerei weiß, ob die PDF-Datei bereits getrennt wurde oder ob eine Trennung in der Vorstufe erforderlich ist. Wird als PDF-Objektname (nicht als Zeichenkette) gemäß ISO 32000-1 §14.11.6.1 ausgegeben; z.B. `<< /Trapped /False >>`.
  • XMP-Metadatenidentifizierung: Das Paket gibt jetzt `xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/"` aus, wobei `` auf die exakte Zeichenkette (z. B. `PDF/X-1:2001`, `PDF/X-3:2002` oder `PDF/X-4`) gesetzt ist, und (für X-1a + X-4) `` auf den vollständigen Profilnamen (z. B. `PDF/X-1a:2001` oder `PDF/X-4:2010`) gesetzt ist. Adobe Acrobat, Enfocus PitStop und callas pdfaPilot erkennen das Dokument als ein PDF/X-Kandidaten.
  • EndDoc-Validierung: verwirft unbekannte Profilwerte, verwirft leere/unerkannte "Trapped"-Werte, erfordert einen Titel und erhöht automatisch die PDF-Version auf die obligatorische Mindestversion des Profils (X-1a/X-3 → PDF 1.3, X-4 → PDF 1.6). Verschlüsselung und PDFXCompliance sind inkompatibel; der Aufruf von EnableEncrypt (oder `ActivateProtection := True`) führt zu einem Fehler mit einer klaren Diagnose, die erklärt, dass PDF/X-Workflows jedes Objekt ohne Passwortverarbeitung prüfen müssen.
  • Der Aufrufer muss weiterhin das OutputIntent, das ICC-Profil, das TrimBox/ArtBox, die gültigen Vorstufefarbräume und die korrekte Schrifteinbettung definieren (und Transparenz für X-1a/X-3 vermeiden), um die vollständige PDF/X-Konformität zu gewährleisten. Die Versionen v2.113 bis v2.115 schließen diese Lücken: v2.113 fügt `AddPDFXOutputIntent` hinzu (obligatorisches /GTS_PDFX-Intent), v2.114 fügt eine Transparenzprüfung und eine Durchsetzung der PageBox hinzu, und v2.115 schließt die Reihe mit Sperren für unerlaubte Aktionen, Annotationen und XFA ab.
  • Win32 + Win64: Saubere Kompilierung; die Baselines v2.108, v2.109, v2.110 und v2.111 wurden komplett neu kompiliert, ohne Änderungen. Das neue Testprogramm "smoke_pdfx_optin" erzeugt drei PDFs (eines pro Profil) und überprüft den XMP-Namespace sowie die Werte GTS_PDFXVersion und GTS_PDFXConformance, zusätzlich zu DocInfo /Trapped /Name. Es werden auch ungültige Profile, leere "Trapped"-Einträge, unbekannte "Trapped"-Einträge sowie Fälle von Konflikten bei der Verschlüsselung abgefangen.
  • Die PAdES-Reihe (Versionen v2.109 / v2.110 / v2.111) deckt die Anwendungsfälle B-B / B-T / B-LT / B-LTA sowie die Verwendung von unabhängigen Zeitstempeln ab. Die ursprünglich geplante Version v2.112 (ein PDF mit ausschließlich einem unabhängigen ETSI.RFC3161-Zeitstempel) ist faktisch implizit – die Funktion `AddDocumentTimestampSignature` aus Version v2.111 funktioniert mit einem neuen Dokument ohne eine interne Signatur. Daher wird die PAdES-Reihe mit 3 Commits abgeschlossen, und Version v2.112 wird für PDF/X umgewidmet. Alle Baseline-Profile gemäß ETSI EN 319 142-1 werden unterstützt.

2026-05-19 Version 2.111.0

  • PAdES-Produzentenreihe, Teil 3/4: Unterstützung für Dokumentzeitstempel-Signaturen gemäß ISO 32000-1 §12.8.5 + ETSI EN 319 142-1 §5.7. Der Dokumentzeitstempel ist eine zweite Signatur, die NACH Abschluss der Langzeitvalidierungs-Signatur angewendet wird; er umfasst die gesamte LT-Statusdatei (Originalsignatur + DSS) und beweist, dass das LT-Material zu einem notariell beglaubigten Zeitpunkt existierte. Dies ist das Archivprofil, das für die in der EU vorgeschriebene Langzeitarchivierung über die Lebensdauer des ursprünglichen CA-Zertifikats hinaus erforderlich ist.
  • Neue `THPDFPage.AddDocumentTimestampSignature(FieldName, ContentsBytes)`-Hilfsfunktion. Im Gegensatz zu einer normalen PAdES-Signatur hat ein Dokumentzeitstempel:
    • SubFilter `/ETSI.RFC3161` (ein RFC 3161 TimeStampToken, nicht CAdES).
    • Ein Widget-Rechteck mit Nullfläche (ein Zeitstempel hat keine sichtbare Darstellung – nur kryptografische Metadaten).
    • Keine `/Reason`, `/Location` oder `/ContactName` (diese befinden sich in den signierten Attributen des TST, nicht im Signatur-Dictionary).
    • Standardmäßig ein `/Contents`-Byte-Budget von 16 KB (der Aufrufer kann einen kleineren Wert angeben, mindestens 1 KB; ein vollständiger RFC 3161 TST mit Zertifikatskette beträgt typischerweise 4-8 KB).
  • Der Gültigkeitsbereich des Producers endet beim Drahtformat: Der Helfer erstellt das Platzhalter-Dictionary /Type /Sig mit dem zeitstempel-spezifischen SubFilter und einem /ByteRange + /Contents-Sentinel für nachträgliche Anpassungen über PreparePDFForSigning + InsertSignatureHex. Der Aufrufer erhält die tatsächlichen RFC 3161 TST-Bytes von einer vertrauenswürdigen Zeitstempelbehörde (TSA, z. B. DigiCert / GlobalSign / FreeTSA HTTP POST) und fügt sie ein. Der typische PAdES-B-LTA-Archivierungsablauf umfasst: 1) Erstellung der PAdES-B-LT-Basis-Signatur (v2.109), 2) Befüllung des Katalogs /DSS mit der Zertifikatskette + OCSP/CRL (v2.110), 3) Speichern als inkrementelles Update, 4) Hinzufügen eines Dokument-Zeitstempel-Felds zu den LT-Status-Bytes (v2.111), 5) Anfordern des TST von der TSA für den Byte-Bereich, 6) Einfügen der TST-Bytes.
  • Win32 + Win64: saubere Kompilierung; die Baselines v2.108, v2.109 und v2.110 wurden vollständig neu kompiliert, ohne Änderungen. Der neue Smoke-Test `smoke_pades_doctimestamp` erzeugt ein PAdES-B-LT 'SigInner'-Feld sowie ein 'DocTS'-Dokumentzeitstempel-Feld mithilfe eines neuen Hilfsmoduls. Der Python-Verifizierer stellt sicher, dass die innere Signatur `/SubFilter /ETSI.CAdES.detached` enthält, das Zeitstempel-Widget `/Rect` eine Fläche von Null hat, das Zeitstempel-`/V`-Dictionary `/SubFilter /ETSI.RFC3161` enthält und keine `/Reason`, `/Location` oder `/ContactName`-Einträge hat, und dass `/Contents` ein Platzhalter von 16 KB (32768 hexadezimale Zeichen) ist.
  • Verbleibender PAdES-Bereich: v2.112 (optional) fügt eigenständige ETSI.RFC3161-Zeitstempel-PDFs hinzu (ohne CAdES-Innersignatur – ein reines Zeitstempel-Dokumentcontainer).

2026-05-19 Version 2.110.0

2026-05-19 Version 2.109.0

  • Gestartet Arbeiten an einem PAdES (ETSI EN 319 142) digitalen Signatur-Generator. Die Version v2.109 fügt eine High-Level-Schnittstelle zu der bestehenden ISO 32000-1 §12.8 Signaturinfrastruktur hinzu (Version 2 des AddSignedSignatureField-Hilfsprogramms), die den für PAdES erforderlichen SubFilter festlegt und die Konformität validiert. Eine vollständige Prüfung sowie ein 4-Versions-Roadmap sind unter .superpowers/specs/2026-05-19-pades-compliance-audit.md archiviert.
  • Neue `THPDFPage.AddPAdESSignatureField(FieldName, Rect, Profile, Reason, Location, ContactName, ContentsBytes, Flags)` Hilfsfunktion. Das Profil wählt die ETSI EN 319 142-1 Basisebene aus: 'B-B' (grundlegende CAdES, ohne Zeitstempel), 'B-T' (mit RFC 3161 vertrauenswürdigem Zeitstempel, Minimum für rechtliche Verwendung in der EU), 'B-LT' (mit DSS-Validierungsinformationen für die langfristige Überprüfung) oder 'B-LTA' (mit Dokument-Zeitstempel-Signatur für die Archivierung). Alle vier verwenden den SubFilter 'ETSI.CAdES.detached'; der Profilparameter variiert die Diagnose und das Standard-Byte-Budget für /Contents. Andere Profilstrings führen zu einer Ausnahme gemäß der aufgeführten ETSI-Aufzählung.
  • Automatisch angepasste Inhaltsgröße: Für PAdES-B-B + B-T ist der Standardwert 16 KB (der Aufrufer kann einen kleineren Wert angeben; wir erzwingen einen Mindestwert von 64 Byte, der von v2.108 übernommen wurde). Für PAdES-B-LT wird die Größe automatisch auf mindestens 20 KB angepasst (CAdES + Zertifikatskette + OCSP/CRL-Daten). Für PAdES-B-LTA wird die Größe automatisch auf mindestens 24 KB angepasst (B-LT + Dokumentzeitstempel). Größere Werte, die vom Aufrufer angegeben werden, werden übernommen; der Helfer erhöht lediglich den Mindestwert.
  • Producer scope: Der Wrapper erstellt das Dictionary mit den Platzhaltern /Type /Sig und /SubFilter /ETSI.CAdES.detached, sowie /Reason, /Location, /ContactName und /M (Signaturdatum), und fügt das /ByteRange und /Contents-Sentinel für nachträgliche Anpassungen über PreparePDFForSigning und InsertSignatureHex hinzu. Die eigentliche Verarbeitung der CMS-/CAdES-Daten, der Abruf des RFC 3161-Zeitstempels, das Sammeln von OCSP/CRL-Informationen und die Erstellung des DSS-Dictionaries liegen in der Verantwortung des Aufrufers – dafür ist eine externe kryptografische Bibliothek (OpenSSL, Bouncy Castle, Windows CAPI usw.) erforderlich, die außerhalb des PDF-Produzenten liegt.
  • Saubere Kompilierung für Win32 und Win64. Der neue Smoke-Test `smoke_pades_signature` erzeugt vier PAdES-Signaturfelder (B-B / B-T / B-LT / B-LTA) und bestätigt, dass ungültige Profilwerte zu Fehlern führen. Der Python-Verifizierer prüft, ob `AcroForm /SigFlags` den Wert 3 hat, ob jedes Widget `/FT /Sig` und eine indirekte Referenz auf ein `/Type /Sig`-Dictionary mit `/SubFilter /ETSI.CAdES.detached` enthält, und ob die Länge des Platzhalters für `/Contents` mit dem erwarteten (automatisch angepassten) Byte-Budget übereinstimmt.
  • Restliche geplante Funktionen für PAdES: In Version 2.110 wird der Builder für das Dictionary /DSS (Document Security Store) hinzugefügt, um Validierungsinformationen für PAdES-B-LT (Zertifikatskette + OCSP/CRL) zu erstellen; in Version 2.111 wird ein unabhängiges Zeitstempel-Signaturfeld für die Archivierung PAdES-B-LTA hinzugefügt; in Version 2.112 (optional) werden PDFs mit nur Zeitstempel gemäß ETSI.RFC3161 hinzugefügt.

2026-05-19 Version 2.108.0

  • PDF/A-2 + PDF/A-3 Hersteller-Reihe, Abschluss (4/4): ISO 19005-3 Anhang E, zugehörige Dateien. Eine neue, hochrangige Hilfsfunktion, `AddPDFA3AssociatedFile(FileName, MimeType, Description, Relationship, FileBytes)`, ermöglicht das Anhängen einer beliebigen Datei (z. B. XML-Rechnungen, Quelldatenblätter, JSON-Metadaten) an einen PDF/A-3-Hybrid-Container und registriert diese im `/AF`-Array des Katalogs unter Verwendung der Semantik von §E.4 `/AFRelationship`.
  • Hybrid-Container-Workflow: Ein typischer Anwendungsfall ist die ZUGFeRD-konforme PDF/A-3-Rechnungsstellung, bei der die für Menschen lesbare Rechnungsdarstellung im PDF-Seitenstrom enthalten ist und die maschinenlesbare XML-Quelldatei als zugehörige Datei mitgeliefert wird. Der Schlüssel `/AFRelationship` gibt den Konsumenten an, wie die angehängte Datei mit dem sichtbaren Inhalt zusammenhängt: `'Source'` (Originaldaten), `'Data'` (Rohdaten, die im PDF visualisiert werden), `'Alternative'` (alternative Darstellung), `'Supplement'` (ergänzendes Material), `'Unspecified'` (keine der oben genannten).
  • Spezifische Einschränkungen: `AddPDFA3AssociatedFile` löst einen Fehler aus, wenn der Wert für `PDFACompliance` nicht `PDF/A-3` ist (Anhang E ist spezifisch für Teil 3), wobei eine Diagnose angezeigt wird, die `AddFileAttachmentAnnotation` für `PDF/A-2` vorschlägt und darauf hinweist, dass `PDF/A-1 §6.1.11` Anhänge vollständig verbietet. Ein leerer `FileName` oder `MimeType` führt zu einem Fehler; ein ungültiger `Relationship`-Wert löst einen Fehler aus, wobei auf die Aufzählung in Abschnitt §E.4 der Spezifikation verwiesen wird.
  • Emissionsstruktur: Ein indirekter EmbeddedFile-Stream enthält /Type /EmbeddedFile sowie /Subtype , /Params <> und die Dateibytes. Das indirekte Filespec-Dictionary enthält /Type /Filespec, /F, /UF (beide = Dateiname), optional /Desc, /EF <> und /AFRelationship (Annex E-Schlüssel). Das Catalog-/AF-Array wird bei der ersten Anfügung erstellt und bei nachfolgenden Aufrufen erweitert. Das zurückgegebene Filespec-Dictionary ermöglicht es Aufrufern, bei Bedarf zusätzliche optionale Schlüssel (z. B. /CI-Checksumme/Informationen) hinzuzufügen.
  • Saubere Kompilierung für Win32 und Win64. Das neue Testprogramm "smoke_pdfa3_associated" erstellt eine PDF/A-3B-Hybrid-Rechnung mit einer echten XML-Rechnung, die als `/AFRelationship Source` angehängt ist, und testet anschließend drei Ablehnungsszenarien: PDF/A-1 wird abgelehnt, PDF/A-2 wird abgelehnt, eine ungültige `/AFRelationship` wird abgelehnt. Der Python-Verifizierer überprüft die Dictionary-Struktur "Filespec / EmbeddedFile" (Typ / F / UF / Desc / AFRelationship / EF F UF / EmbeddedFile Type / Subtype #2F escape / Params Size).
  • Die Oberfläche für PDF/A-2 + PDF/A-3-Ersteller ist jetzt vollständig revisionssicher (v2.105: optionale Wrapper-Funktion + XMP, v2.106: Verhinderung von Annotationen/Aktionen, v2.107: Implementierungsgrenzen gemäß §6.1.13, v2.108: Anhang E: zugehörige Dateien). Da HotPDF bereits bei PDF/A-1 (v2.101-104) und PDF/UA-1 (v2.94-v2.100) eine strikte Konformität gewährleistet, deckt HotPDF jetzt die gesamte Matrix für die Archivierung/Barrierefreiheit von PDF/A-1/2/3 + PDF/UA-1 vollständig ab.

2026-05-19 Version 2.107.0

  • PDF/A-2 + PDF/A-3 producer series, slice 3/4: Implementierungseinschränkungen für ISO 19005-2 §6.1.13 + ISO 19005-3 §6.1.13 werden durchgesetzt. PDF/A-1 §6.1.13 ist deutlich weniger restriktiv (keine strikte Begrenzung der String-Länge), sodass die neue Prüfung nur dann aktiv wird, wenn PDFACompliance auf PDF/A-2 oder höher ('2*' / '3*') eingestellt ist.
  • Die neue öffentliche Methode EnsurePDFAImplementationLimits validiert die vom Aufrufer gesteuerten Werte des Dokuments anhand der in der Spezifikation festgelegten Grenzen: Die Zeichenketten Doc.Title / Author / Subject / Keywords / Lang müssen ≤ 32767 Bytes lang sein; die Abmessungen des MediaBox jeder Seite müssen im Bereich [3..14400] Einheiten liegen. EndDoc ruft den Validator automatisch auf, wenn PDFACompliance auf PDF/A-2/3 eingestellt ist; Aufrufer können ihn auch direkt während des Build-Prozesses für frühe Diagnosezwecke aufrufen.
  • Die in dem Prüfbericht dokumentierten, automatisch eingehaltenen Grenzen sind: Ganzzahlbereich (-2³¹..2³¹-1), Realbereich (±3,403×10³⁸, nahezu Null ≥1,175×10⁻³⁸), Namenslänge ≤127 Bytes, Anzahl indirekter Objekte ≤8388607, Verschachtelung von q/Q ≤28, Anzahl der DeviceN-Farbstoffe ≤32, CID ≤65535. Die Emissionspfade von HotPDF überschreiten diese Grenzen niemals, da sie an Datenstrukturen gekoppelt sind, die von HotPDF kontrolliert werden. Der Validator konzentriert sich auf vom Aufrufer bereitgestellte Zeichenketten und Seitenränder, da dies die einzigen Grenzen sind, die ein realer Aufrufer potenziell überschreiten kann.
  • XFA-Formulare (§6.4.2): HotPDF gibt keine AcroForm-/XFA- oder Catalog-/NeedsRendering-Elemente aus. Beide werden automatisch erfüllt, was für PDF/A-1/2/3 gilt – dies ist in dem Prüfbericht dokumentiert, um sicherzustellen, dass zukünftige Erweiterungen von Softwareherstellern diese Elemente nicht erneut einführen.
  • .notdef Glyphe (§6.2.11.8 in PDF/A-2): Die Spezifikation verbietet es, dass Textanzeigeoperatoren auf das .notdef-Glyphe verweisen. Die Schriftverarbeitung von HotPDF vermeidet dies, wenn Aufrufer registrierte Unicode-TTF-Schriften verwenden (Version v2.74-v2.86), da der Ersteller jeden Codepunkt auf ein echtes Glyphe abbildet oder die Registrierung ablehnt. Der Aufrufer ist für die Ausgabe von rohem Text verantwortlich; dies ist im Prüfbericht dokumentiert.
  • XMP-Namensraum (§6.6.2): Die Spezifikation verbietet das Attribut "bytes" oder "encoding" im XMP-Paket-Header. `BuildXMPPacket` erzeugt einen minimalen Header (id="W5M0MpCehiHzreSzNTczkc9d"), der keines dieser Attribute enthält – was in allen PDF/A-Teilen problemlos erfüllt wird.
  • Win32 + Win64: Saubere Kompilierung. Neue Tests für `smoke_pdfa2_limits` mit drei Pfaden: PDF/A-2 innerhalb der Grenzen besteht; PDF/A-1 mit einem 32768-Byte-Titel besteht ebenfalls (keine Prüfung gemäß §6.1.13); PDF/A-2 mit einem 32768-Byte-Titel wird mit einer Diagnose gemäß der Spezifikation abgelehnt. Die vorherigen PDF/A-2/3-Basislinien wurden alle neu kompiliert, ohne Änderungen.
  • Verbleibende PDF/A-2/3 Producer-Funktionalität: Version 2.108 implementiert PDF/A-3 Annex E für zugehörige Dateien (die PDF/A-3-spezifische Hybrid-Container-Funktion: Catalog /AF-Array von Dateispezifikationen mit dem Schlüssel /AFRelationship + EmbeddedFile /Params /CheckSum + /ModDate).

2026-05-19 Version 2.106.0

  • PDF/A-2 + PDF/A-3 producer series, version 2/4: Abdeckung von PDF/A-2 §6.3.1 + §6.5.1 (und identisch PDF/A-3 §6.3.1 + §6.5.1). Die in Version 2.104 eingeführten, PDF/A-1-spezifischen Einschränkungen für Annotationen und Aktionen werden weiterhin aktiviert, wenn ein nicht-leeres PDFACompliance-Feld vorhanden ist. Version 2.106 bestätigt dieses Verhalten, aktualisiert die Diagnosemeldungen, um auf die einheitlichen Spezifikationsabschnitte in allen PDF/A-Teilen zu verweisen, und dokumentiert die zusätzlichen, in PDF/A-2 eingeführten, verbotenen Subtypen, die HotPDF standardmäßig erfüllt (es gibt keinen öffentlichen Pfad, um diese zu erzeugen).
  • Verbotene Aktionen-Matrix: PDF/A-1 verbietet 6 Aktionen (Starten / Ton / Film / Formular zurücksetzen / Daten importieren / JavaScript). PDF/A-2 + PDF/A-3 erweitern diesen Satz auf 13, indem sie Hide / SetOCGState / Rendition / Trans / GoTo3DView sowie die veralteten Untertypen / no-op hinzufügen. AddLaunchLink löst weiterhin einen Fehler aus; HotPDF hat keinen öffentlichen Eintrag, der die anderen 12 Aktionen auslöst, sodass diese automatisch als erfüllt gelten.
  • Verbotene Annotationstypen-Matrix: PDF/A-1 verbietet Dateianhänge / Audio / Video. PDF/A-2 / PDF/A-3 lockern das Verbot für Dateianhänge (seit v2.105), fügen aber 3D-Objekte / Bildschirme zur Liste der verbotenen Elemente hinzu. Die Funktionen AddSoundAnnotation + AddMovieAnnotation führen weiterhin zu Fehlern in allen PDF/A-Komponenten; HotPDF hat keinen Mechanismus zum Erzeugen von 3D-Objekten / Bildschirmen, sodass diese Einschränkungen automatisch erfüllt werden.
  • Wichtige Aktualisierung der Diagnosemeldungen: Die drei Funktionen v2.104 (AddSoundAnnotation, AddMovieAnnotation, AddLaunchLink) verweisen jetzt in ihren Fehlermeldungen auf alle drei relevanten Spezifikationsabschnitte (z. B. "PDF/A-1 §6.5.2 / PDF/A-2 §6.3.1 / PDF/A-3 §6.3.1"), sodass Entwickler die einheitliche Einschränkung erkennen. Die Meldung für AddLaunchLink listet zusätzlich die erweiterten, in PDF/A-2/3 verbotenen Aktionen auf.
  • Win32 + Win64: Saubere Kompilierung. Der neue Test "smoke_pdfa2_annot_action" prüft die drei Funktionen für alle sechs PDF/A-2/3-Ebenen (2B, 2U, 2A, 3B, 3U, 3A); jeder Aufruf überprüft die erwartete Ausnahme und gibt eine Diagnose gemäß §6.3.1 / §6.5.1 aus. Die vorherigen PDF/A-1-Basislinien (smoke_pdfa1_compliance / smoke_pdfa1_forbidden / smoke_pdfa1_annot_action) und der Test v2.105 "smoke_pdfa2_compliance" wurden ebenfalls ohne Änderungen neu kompiliert.
  • Verbleibende PDF/A-2/3-Produzenten-Implementierungen: v2.107 erzwingt die in ISO 19005-2 §6.1.13 definierten Implementierungsgrenzen (Integer-/Real-/String-/Namensbytebereiche, q/Q-Verschachtelung, DeviceN-Farbstoffe, CID, Seitenränder) sowie §6.4.2 XFA und §6.2.11 für strikte Type 3-/ .notdef-Implementierungen; v2.108 implementiert PDF/A-3 Anhang E für zugehörige Dateien (hybride Container-PDFs mit beliebigen eingebetteten Dateitypen).

2026-05-19 Version 2.105.0

  • Gestartet eine Reihe von vier Versionen zur Einhaltung der Standards PDF/A-2 (ISO 19005-2:2011) und PDF/A-3 (ISO 19005-3:2012). Die Prüfung und die Roadmap sind unter .superpowers/specs/2026-05-19-pdfa2-pdfa3-compliance-audit.md archiviert. Version 2.105 führt die optionale Wrapper-Schicht ein, erweitert den XMP pdfaid-Namensraum, erhöht die Basis-PDF-Version automatisch auf 1.7 und lockert selektiv die strengen Einschränkungen von PDF/A-1, die in den Spezifikationen für PDF/A-2 und PDF/A-3 explizit erlaubt sind.
  • Die Eigenschaft PDFACompliance akzeptiert jetzt sechs neue Werte zusätzlich zu den bereits vorhandenen '' / 'A' / 'B': '2A' / '2B' / '2U' (PDF/A-2 Level A / B / U) und '3A' / '3B' / '3U' (PDF/A-3 Level A / B / U). Level U ist die neue Ebene "nur Unicode-Erhaltung", die in PDF/A-2 eingeführt wurde (visueller Text + Unicode-extrahierbarer Text, keine Anforderung für Tagged PDF).
  • BuildXMPPacket wurde erweitert: das ``-Element spiegelt nun die geparste Teilnummer (1 / 2 / 3) wider, und `` spiegelt den geparsten Level-Buchstaben (A / B / U) wider. veraPDF und ähnliche Validierer identifizieren den PDF/A-Teil des Dokuments anhand dieses Paares. Gemäß ISO 19005-2 §6.6.4 + ISO 19005-3 §6.6.4 Tabelle 8.
  • Auto-bump: PDFACompliance '2*' / '3*' erhöht automatisch die Dokumentversion auf PDF 1.7, da sowohl PDF/A-2 als auch PDF/A-3 auf ISO 32000-1 (PDF 1.7) basieren. PDF/A-1 bleibt an PDF 1.4 gebunden.
  • v2.103: Die Transparenzprüfung wurde gelockert: `RegisterExtGState` löst jetzt nur dann einen Fehler aus, wenn ein transparenter Alpha-Wert oder ein nicht-normaler Mischmodus verwendet wird, wenn `PDFACompliance` auf PDF/A-1 (mit den Optionen 'A' oder 'B') eingestellt ist. PDF/A-2 / PDF/A-3 §6.4 erlauben explizit Transparenz (mit separaten Anforderungen wie der Anwesenheit von `OutputIntent` und den vollständigen PDF 1.4-Mischmodi), sodass `PDFACompliance` mit den Optionen '2*' / '3*' den Aufruf zulässt.
  • v2.104: Die Einschränkung für `FileAttachment` wurde aufgehoben. `AddFileAttachmentAnnotation` löst jetzt nur noch bei strikter PDF/A-1-Konformität einen Fehler aus. PDF/A-2 §6.3.1 verbietet nur 3D-, Audio-, Bildschirm- und Video-Annotationen; `FileAttachment` ist erlaubt und bildet die Grundlage für den hybriden Workflow von PDF/A-3, Anhang E (Associated Files). Die übrigen Einschränkungen für Annotationen/Aktionen (Audio-, Video-Annotationen; "Launch"-Aktion) gelten weiterhin für alle PDF/A-Profile gemäß den gemeinsamen Verbotsregelungen in §6.3.1 und §6.5.1.
  • Neue Hilfsmethoden für THotPDF, nämlich PDFAPart, PDFAConformanceLevel, IsPDFA1Strict und IsPDFA2OrLater, erleichtern die bedingte Verarbeitung von Werten. Vorhandene PDF/A-Funktionen in den Versionen v2.101-104 verwenden jetzt diese Hilfsmittel für saubereren Code und klarere Fehlermeldungen, die den Wechsel zu PDF/A-2 oder PDF/A-3 empfehlen, wenn dies angemessen ist.
  • Win32 + Win64: saubere Kompilierung; die Baselines v2.101-104 (smoke_pdfa1_compliance / smoke_pdfa1_forbidden / smoke_pdfa1_annot_action) wurden neu kompiliert, ohne Änderungen. Der neue Test smoke_pdfa2_compliance erzeugt vier PDFs (Levels 2B / 2U / 2A / 3U) und testet die Transparenz-Entspannung von v2.103, die Dateianhang-Entspannung von v2.104 sowie zwei Validierungspfade (ungültiges Level '4Q' wird abgelehnt; das PDF/A-1-Transparenz-Gate funktioniert weiterhin). Der Python-Verifizierer stellt sicher, dass XMP pdfaid:part und die Konformität für jedes Level übereinstimmen, und Level 2A hat eine Tagged-PDF-Vererbung.
  • Restliche PDF/A-2/3 Producer-Änderungen: v2.106 erweitert den Satz der verbotenen Aktionen von 6 auf 13 (Hinzugefügt: Hide, SetOCGState, Rendition, Trans, GoTo3DView; veraltete Set-Zustands-Funktion / No-Op), passt außerdem die Beschränkungen für Anmerkungstypen an (Hinzugefügt: 3D, Screen; entfernt: FileAttachment); v2.107 erzwingt die Implementierungsgrenzen gemäß ISO 19005-2 §6.1.13 sowie XFA-Beschränkungen; v2.108 implementiert PDF/A-3 Anhang E für zugehörige Dateien (Hybrid-Container-PDFs).

2026-05-19 Version 2.104.0

  • PDF/A-1 producer series: (Slice 4/4) geschlossen. Folgende Punkte wurden geschlossen: §6.5.2 verbotene Annotationstypen (FileAttachment, Sound, Movie) und §6.6.1 Launch action subtype. Mit der Version v2.104 wurden alle 17 Lücken im Bereich des Producers, die bei der PDF/A-1-Prüfung vom 19.05.2026 (.superpowers/specs/2026-05-19-pdfa1-compliance-audit.md) identifiziert wurden, geschlossen: die vier wichtigsten Punkte (§5, §6.7.11 Identifizierung, §6.1.3 Verschlüsselungsverbot, §6.2.2 OutputIntent, §6.4 Transparenz) sowie die verschiedenen Sperren für bestimmte Funktionen.
  • §6.5.2 verbotene Annotationstypen: `AddFileAttachmentAnnotation`, `AddSoundAnnotation` und `AddMovieAnnotation` lösen jetzt unter `PDFACompliance` einen Fehler mit einer eindeutigen Diagnose aus, die auf den entsprechenden Abschnitt der Spezifikation verweist. Gemäß der Spezifikation "die Annotationstypen 'FileAttachment', 'Sound' und 'Movie' dürfen nicht zulässig sein", um externe Inhaltsabhängigkeiten und Multimedia in Archivdateien zu vermeiden.
  • §6.6.1 Aktion "Start": `AddLaunchLink` löst jetzt einen Fehler im Kontext von `PDFACompliance` aus, wobei eine Diagnose den Start-Zielwert angibt. Gemäß der Spezifikation sind die Aktionen "Start", "Sound", "Film", "Formular zurücksetzen", "Daten importieren" und "JavaScript" nicht zulässig. Die anderen fünf verbotenen Aktionsuntertypen (Sound/Film/Formular zurücksetzen/Daten importieren/JavaScript) haben keinen öffentlichen `HotPDF`-Einstiegspunkt, der sie ausführt, sodass sie ohne explizite Einschränkungen automatisch erfüllt sind.
  • PDFUACompliance und PDFACompliance funktionieren jetzt korrekt in allen vier PDF/A-Varianten. Die beiden Optionen werden übereinandergelegt: Level A erbt die automatische Aktivierung von PDFUACompliance für getaggte PDFs; beide Wrapper wenden ihre eigenen, abschnittsspezifischen Sicherheitsvorkehrungen an (für PDF/UA: Verdächtige/Registerkarten/Sprache; für PDF/A: Verschlüsselung/Transparenz/Annotationen/Aktionen), ohne dass es zu Interferenzen kommt.
  • Zusammenfassung der Überprüfungen: Alle strukturellen Anforderungen des PDF/A-1-Dateiformats, die HotPDF erfüllen kann, wurden als abgeschlossen markiert. Die verbleibenden Verantwortlichkeiten des Aufrufers (Abschnitt 6.1.5, Info-XMP-Äquivalenz, Abschnitt 6.2.3.3, Farbraum ↔ OutputIntent-Abgleich, Abschnitt 6.3, Schriftarten, wobei die Arbeiten zu PDF/UA in den Versionen 2.74 bis 2.86 bereits die meisten Aspekte abgedeckt haben) entsprechen den entsprechenden Verantwortlichkeiten des Aufrufers in PDF/UA-1.
  • Win32 + Win64: saubere Kompilierung; v2.103: "smoke_pdfa1_forbidden" wird sauber neu kompiliert. Der neue Test "smoke_pdfa1_annot_action" testet alle vier verzweigten Pfade (AddFileAttachmentAnnotation, AddSoundAnnotation, AddMovieAnnotation, AddLaunchLink) unter PDFACompliance und stellt sicher, dass jeder Aufruf mit einer Diagnose gemäß §6.5.2 oder §6.6.1 fehlschlägt.
  • Die PDF/A-1-Produzentenoberfläche ist jetzt vollständig auditgeschützt. Zukünftige Erweiterungen wie PDF/A-2 (basierend auf ISO 19005-2:2011 und PDF 1.7, ermöglicht Transparenz und Ebenen) und PDF/A-3 (ISO 19005-3:2012, ermöglicht eingebettete Dateien für hybride Workflows) sind weiterhin potenzielle Kandidaten, abhängig von der Nachfrage der Benutzer.

2026-05-19 Version 2.103.0

  • PDF/A-1 producer series slice 3/4: geschlossen §6.4 Transparenz (KRITISCHE Lücke #15) + §6.2.8 ExtGState /TR Transferfunktion (Lücke #14). Zwei Abschnitte in §6, die sich auf bestehende HotPDF-Producer-Pfade beziehen, werden automatisch erfüllt, ohne dass Codeänderungen erforderlich sind: §6.1.10 LZW-Filter (HotPDF gibt in seinem Writer-Pfad nur FlateDecode aus) und §6.2.4 Bild-/Interpolate (HotPDF gibt niemals /Interpolate aus). Diese werden jetzt als automatisch im Prüfbericht dokumentiert.
  • §6.4 Die Transparenz verbietet Alpha-Werte, die nicht 1,0 sind, sowie Mischmodi, die nicht "Normal" oder "Kompatibel" sind. `RegisterExtGState` wird jetzt unter Berücksichtigung von `PDFACompliance` ausgeführt: ein Alpha-Wert für Füllungen kleiner als 1 führt zu einem Fehler (PDF/A-1 erfordert `/ca = 1.0`); ein Alpha-Wert für Konturen kleiner als 1 führt zu einem Fehler (`/CA = 1.0`); ein Mischmodus, der nicht "Normal" oder "Kompatibel" ist, führt zu einem Fehler. Alle drei Prüfungen geben den entsprechenden Abschnitt der Spezifikation und den fehlerhaften Wert an. Der Standard-ExtGState (ohne Alpha-Schlüssel, ohne Mischmodus) und die explizit erlaubten Werte (Alpha-Werte von 1,0, Mischmodi "Normal" / "Kompatibel") bleiben unverändert.
  • §6.2.8 ExtGState verbietet den Schlüssel /TR für die Transferfunktion (veraltet; PDF/A-1 erlaubt nur /TR2 mit dem Wert /Default, und selbst das sollte möglichst vermieden werden). RegisterTransferFunctionState löst jetzt einen Fehler unter PDFACompliance mit einer eindeutigen Diagnose aus. Aufrufer, die Transferfunktionen für PDF/X-Workflows benötigen, können diese weiterhin außerhalb des PDFACompliance-Modus verwenden.
  • §6.1.10 LZW + §6.2.4 Interpolate: Die Einhaltung wird wie von Natur aus durch die bestehenden Produktionspfade von HotPDF gewährleistet (nur FlateDecode-Writer, keine Emission von "/Interpolate"). Es sind keine Codeänderungen erforderlich; dies wurde im Kommentar des Prüfberichts vermerkt, damit zukünftige Aufrufer diese Funktionalitäten nicht erneut einführen.
  • Win32 + Win64: Saubere Kompilierung; v2.102: Die smoke_pdfa1_compliance-Tests wurden sauber neu kompiliert. Die neuen smoke smoke_pdfa1_forbidden-Tests decken alle drei eingeschalteten Pfade ab (ca<1, CA<1, BM=Multiply, /TR-Registrierung) und stellen außerdem sicher, dass die erlaubten Pfade (ca=1.0, CA=1.0, BM=Normal/Kompatibel, ohne Alpha) weiterhin funktionieren. Es gibt keinen Verifier – der Smoke-Test selbst prüft über try/except, ob jeder eingeschaltete Aufruf eine Ausnahme auslöst.
  • Verbleibende PDF/A-1-Produzenten-Änderungen: v2.104 behebt §6.5.2, die verbotenen Annotationstypen (FileAttachment, Sound, Movie), sowie §6.5.3, die Regeln für Annotationen /F /AP, und §6.6.1, die verbotenen Aktionstypen (Launch, Sound, Movie, ResetForm, ImportData, JavaScript). Außerdem werden §6.9 Formularfelder /A /AA und /NeedAppearances behandelt. Nach der Implementierung von v2.104 ist die PDF/A-1-Produzenten-Oberfläche vollständig abgeschlossen und geprüft.

2026-05-19 Version 2.102.0

  • PDF/A-1 (ISO 19005-1:2005) producer series slice 2/4: behebt §6.2.2 OutputIntent + ICC-Profil-Lücke. Eine neue, hochrangige Hilfsfunktion `AddPDFAOutputIntent(OutputConditionIdentifier, Info, ICCProfileStream, NumComponents, AlternateCS)` vereinfacht die v2.51 RegisterICCProfile + AddOutputIntent('GTS_PDFA1', ...) Sequenz in einen einzigen Aufruf. PDF/A-1 erfordert strikt einen Eintrag mit `/Type /OutputIntent /S /GTS_PDFA1` und einen gültigen `/DestOutputProfile`-ICC-Stream; ohne diesen können konforme Dateien Farben nicht korrekt auf verschiedenen Plattformen wiedergeben.
  • Die Änderung `PDFACompliance gate` fügt eine Prüfung `EnsurePDFAOutputIntent` hinzu: Sie durchläuft die registrierte Liste von `OutputIntent`-Einträgen, sucht nach mindestens einem Eintrag mit `/S /GTS_PDFA1` und `/DestOutputProfile`. Wenn ein solcher Eintrag fehlt, wird eine eindeutige Diagnose ausgegeben, die auf den entsprechenden Abschnitt der Spezifikation verweist und die Aufrufer an `AddPDFAOutputIntent` verweist. Gemäß §6.2.2 + Anhang A.
  • Typischer Archivierungs-Workflow: Übergeben Sie einen sRGB IEC61966-2.1 ICC-Profil-Stream für PDF/A-Dokumente, die für Bildschirmanzeige optimiert sind, FOGRA39 / GRACoL für den Druck oder das entsprechende registrierte CMYK-Profil für die Vorstufe. `NumComponents` muss 1 (Graustufen), 3 (RGB / Lab) oder 4 (CMYK) sein, gemäß PDF 1.7 Abschnitt 8.6.5.5, Tabelle 66; die Hilfsfunktion leitet die Validierung an `RegisterICCProfile` weiter.
  • Der Helper validiert: Ein leerer OutputConditionIdentifier führt zu einem Fehler (gemäß §6.2.2, der den Identifier erfordert); ein nil ICCProfileStream führt zu einem Fehler (DestOutputProfile ist obligatorisch). Die Funktion gibt keinen Wert zurück – das OutputIntent wird automatisch in FOutputIntents registriert und über den bestehenden Serialisierungspfad für den Katalog /OutputIntents bereitgestellt.
  • Win32 + Win64: saubere Kompilierung; `v2.101 smoke_pdfa1_compliance` wurde aktualisiert, um `AddPDFAOutputIntent` aufzurufen (mit einem simulierten 192-Byte-ICC-Objekt; echte Aufrufer verwenden ein echtes ICC-Binärformat). Ein neuer Validierungstest prüft, ob das Fehlen von `OutputIntent` unter `PDFACompliance` einen Fehler gemäß Abschnitt 6.2.2 auslöst. Der Python-Verifizierer wurde erweitert, um das Array `Catalog /OutputIntents` zu prüfen und Einträge zu finden, die `/S /GTS_PDFA1` mit einer indirekten Referenz zu `/DestOutputProfile` enthalten.
  • Verbleibende PDF/A-1 Producer-Bereiche: v2.103 behebt #15 Transparenz (KRITISCH) + #5 LZW-Filter + #10 Bildinterpolation + #14 ExtGState /TR; v2.104 behebt #16 Dateianhänge/Audio/Video-Annotationen + #17 Annotationsregeln für /F /AP + #18 Aktionen zum Starten/Abspielen von Audio/Video/Zurücksetzen des Formulars/Importieren von Daten/JavaScript + #20 Formularfelder /A /AA + /NeedAppearances.

2026-05-19 Version 2.101.0

  • Eine vierteilige Reihe von PDF/A-1 (ISO 19005-1:2005)-Konformitätsprüfungen wurde gestartet, wobei die Wrapper-Ebene optional aktiviert werden kann. Der vollständige Prüfbericht mit 17 Punkten ist unter `.superpowers/specs/2026-05-19-pdfa1-compliance-audit.md` archiviert; Version 2.101 enthält die grundlegenden Komponenten (Eigenschaft PDFACompliance, XMP pdfaid-Identifizierung, strikte Titel-/Sprache-Regeln, Schutz vor Konflikten bei der Verschlüsselung). Version 2.102 bis 2.104 schließen die verbleibenden Lücken in Bezug auf Farbmanagement, Transparenz, Schriftarten sowie Anmerkungen/Aktionen.
  • Neue `PDFACompliance: AnsiString`-Eigenschaft, die entweder "" (deaktiviert, Standard), 'A' (Level A: visuell + getaggte PDF + Barrierefreiheit) oder 'B' (Level B: nur visuelle Darstellung) akzeptiert. Ungültige Werte führen zu einem Fehler am Ende des Dokuments. Entspricht den Konformitätsstufen gemäß ISO 19005-1:2005 §5.
  • Die Einstellung von `PDFACompliance` auf 'A' aktiviert automatisch `PDFUACompliance` (Level A erbt die Anforderungen für strukturierte PDFs aus §6.8, die mit den logischen Strukturanforderungen von PDF/UA-1 in §7 übereinstimmen). Beide Funktionen können problemlos kombiniert werden; die v2.94 PDF/UA-1 Sprach-/Titel-/Verdachts-Steuerungsebene wird zusätzlich zu den v2.101 PDF/A-Sicherheitsvorkehrungen hinzugefügt.
  • Das Aktivieren einer dieser Optionen aktiviert automatisch FEnableXMPMetadata, sodass das Dokument den erforderlichen /Metadata XMP-Datenstrom enthält. Gemäß §6.7.2 sind Metadaten im Katalog obligatorisch.
  • BuildXMPPacket wurde erweitert: Wenn PDFACompliance nicht leer ist, deklariert das XMP-Paket `xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/"` sowie `1` und `A` (oder `B`). VeraPDF und ähnliche Validierer verlassen sich auf dieses exakte Tripel, um das Dokument als PDF/A-1A- oder 1B-Kandidat zu klassifizieren. Gemäß §6.7.11 Tabelle 6 PDF/A-Identifikationsschema.
  • Titel / Sprachrichtigkeit: Wenn PDFACompliance aktiviert ist und Doc.Title='' ist, wird ein Fehler ausgelöst (PDF/A-1 §6.7.3 erfordert dc:title im XMP-Äquivalent zu Info /Title). Die Sprachrichtigkeit entspricht dem Verhalten von v2.94 PDFUACompliance (§6.8.4 für Level A), sodass Autoren eine gültige BCP-47-Kennzeichnung auswählen müssen, anstatt einen stillen Standardwert 'en' zu erhalten.
  • Kryptografie-Konfliktprüfung: Gemäß §6.1.3 darf der Dateitrailer nicht das Element "/Encrypt" enthalten. Die Funktion "EnableEncrypt" (die interne Funktion, die aufgerufen wird, wenn die Optionen "OwnerPassword", "UserPassword" oder "Protection" aktiviert werden) löst jetzt eine klare Fehlermeldung aus, wenn "PDFACompliance" nicht leer ist. "EndDoc" meldet den Konflikt auf dem gleichen Weg, sodass Aufrufer den Fehler sehen, bevor die Serialisierung erfolgt.
  • Die Verantwortung des Aufrufers umfasst weiterhin: das Erzeugen eines gültigen PDF/A-1 OutputIntent mit ICC-Profil (Fortsetzung von v2.102), das Vermeiden von Transparenz (v2.103), das Vermeiden von verbotenen Annotationen/Aktionen (v2.104) und das Erstellen einer semantisch korrekten Struktur für Level A (abgedeckt durch die Tagged PDF-Hilfsfunktionen v2.96-v2.99).
  • Win32 + Win64: Saubere Kompilierung; v2.100: Die Basiskompilierung smoke_pdfua_link_contents wurde erfolgreich neu kompiliert. Der neue Test smoke_pdfa1_compliance erzeugt sowohl PDFs der Stufe A als auch der Stufe B und testet drei Validierungspfade (ungültige Stufe Z, leerer Titel, Verschlüsselung + Konflikt mit PDFACompliance). Der Python-Verifizierer prüft xmlns:pdfaid + pdfaid:part=1 + übereinstimmende pdfaid:conformance, dc:title, und zusätzlich hat die Stufe A /MarkInfo /Marked true + Catalog /Lang + /StructTreeRoot + xmlns:pdfuaid (automatische Vererbung).

2026-05-19 Version 2.100.0

  • Behebung der verbleibenden Lücke in der Abdeckung von PDF/UA-1 §7.18.5 für Link-Annotationen /Contents, basierend auf der Prüfung vom 2026-05-19. In v2.95 wurde die Eigenschaft "Description" zu AddURILink hinzugefügt; v2.100 erweitert diese Unterstützung für alternative Beschreibungen auf die drei verbleibenden Link-Einstiegspunkte: AddGoToLink (Sprung innerhalb des Dokuments), AddGoToRLink (Sprung zwischen Dateien) und AddLaunchLink (Starten einer externen Datei).
  • Jeder Helfer erhält einen optionalen finalen Parameter `const Description: AnsiString = ''`. Wenn dieser nicht leer ist, enthält das Anmerkungs-Dictionary einen Eintrag `/Contents (Description)`; unter `PDFUACompliance` führt ein leerer Eintrag zu einer Fehlermeldung, die den betreffenden Link-Ziel eindeutig benennt, sodass eine fehlende alternative Beschreibung nicht unbemerkt bleibt. Ein leerer Standardwert gewährleistet die Abwärtskompatibilität außerhalb des `PDFUACompliance`-Modus.
  • Gemäß PDF/UA-1 §7.18.5, strikt: "Links müssen eine alternative Beschreibung über ihren 'Contents'-Schlüssel enthalten, wie in ISO 32000-1:2008, 14.9.3 beschrieben." Diese Spezifikation gilt für alle Arten von Link-Annotationen, nicht nur für URI-Links – die Helfer-Signaturen sorgen jetzt für eine einheitliche Anwendung.
  • Typischer Workflow: `Page.AddGoToLink(R, 1, 700, 'Springe zu Seite 2: Methodik'); Page.AddGoToRLink(R, 'companion.pdf', 0, -1, false, 'Öffne das Begleitdokument für vollständige Datentabellen'); Page.AddLaunchLink(R, 'readme.txt', false, 'Öffne die README-Datei im Standard-Texteditor');`
  • Win32 + Win64: Saubere Kompilierung; v2.99 baseline smoke_pdfua_figure wird sauber neu kompiliert. Der neue Test smoke_pdfua_link_contents erstellt ein 2-seitiges Dokument mit drei Link-Annotationen auf Seite 0 (GoTo zur Seite 1, GoToR zu "companion.pdf", Launch zu "readme.txt") und testet zusätzlich den Sonderfall der leeren Beschreibung für die PDFUACompliance-Ausnahme für alle drei. Der Python-Verifizierer stellt sicher, dass jede Link-Annotation das Attribut /Subtype /Link, den passenden Aktions-Typ /S /GoTo (oder /GoToR oder /Launch) und einen /Contents-Wert enthält, der mit der angegebenen Beschreibung übereinstimmt.
  • Zusammenfassung der PDF/UA-1-Produzentenabdeckung: Mit Version 2.100 erfüllen alle vier Link-Annotationseinstiegspunkte nun §7.18.5. In Kombination mit der in Version 2.94 abgeschlossenen Prüfung (Verdachtsfälle, Registerkarten, Sprache), Version 2.95 (URI-Inhalte, Bit 10, ID) und der in den Versionen 2.96 bis 2.99 veröffentlichten Reihe von semantischen Hilfsmitteln für strukturierte PDFs (Überschrift, Liste, Tabelle, Abbildung) ist die PDF/UA-1-Produzentenseite von HotPDF nun vollständig geprüft und abgeschlossen, sowohl in der strikten Spezifikationsschicht als auch in der benutzerfreundlichen API-Schicht.

2026-05-19 Version 2.99.0

  • Es wurden `BeginTaggedFigure(Parent, AltText, BBox): FigureElem` und `EndTaggedFigure` als vierter und letzter Teil der Reihe von semantischen Hilfsmitteln für Tagged PDF gemäß PDF/UA-1 §7.3 (Grafiken) hinzugefügt. Diese ermöglichen es dem Aufrufer, Zeichenoperationen (Bild-XObject, Vektorpfad, gefülltes Rechteck) innerhalb eines Figure-Elementes zu definieren, wobei das Attribut /Alt obligatorisch und das Attribut /BBox optional ist.
  • /Alt ist obligatorisch (es gibt keinen Standardwert). Gemäß PDF/UA-1 §7.3: "Figure-Tags müssen eine alternative Darstellung oder einen Ersatztext enthalten, der den Inhalt repräsentiert, der mit dem Figure-Tag markiert ist." Ein leerer AltText führt zu einer Fehlermeldung, die den Aufrufer auf die AddStructureElement-Überladung mit 6 Argumenten verweist, falls /ActualText (und nicht /Alt) der geeignete Mechanismus für alternativen Text ist.
  • Optional BBox ist ein 4-Elemente umfassendes Array [llx, lly, urx, ury], das die Begrenzungsbox der Grafik im Standard-Benutzerraum beschreibt und gemäß ISO 32000-1 14.8.5.4.5 als /A << /O /Layout /BBox [...] >> angehängt wird. Übergeben Sie ein leeres Array, um das BBox-Attribut vollständig zu überspringen. Eine BBox mit falscher Länge (1/2/3/5+ Elemente) führt zu einem Fehler, wobei das Spezifikations-Rechtecklayout als Richtlinie dient.
  • Typischer Workflow: `Fig := Doc.BeginTaggedFigure(Root, 'Firmenlogo: Pfeil nach rechts', [72, 600, 200, 720]); ... Inhalt der Figur zeichnen ... Doc.EndTaggedFigure;` Die Figur verwendet die gleiche MCID / ParentTree-Verkabelung wie andere v2.90 BeginTaggedContent-Pfade, wobei die Attribute /Alt und /BBox automatisch hinzugefügt werden.
  • Dies behebt die in Abschnitt PDF/UA-1 §7.3 beschriebene Problemstellung bezüglich der Verantwortlichkeit des Aufrufers, wie sie im Audit-Bericht aufgeführt ist. Die Reihe von semantischen Hilfsmitteln für Tagged PDF deckt nun alle vier Hauptstrukturtypen ab: §7.4 (Überschrift, v2.96), §7.6 (Liste, v2.97), §7.5 (Tabelle, v2.98) und §7.3 (Abbildung, v2.99). Zusammen mit den Korrekturen der Wrapper-Schicht in den Versionen v2.94 und v2.95 erfüllt HotPDFs PDF/UA-1-Produzentenoberfläche nun sowohl die Spezifikationen streng und ist gleichzeitig benutzerfreundlich auf API-Ebene.
  • Saubere Kompilierung für Win32 und Win64; die Basis-Smoke-Tests für `smoke_pdfua_table` wurden erfolgreich neu kompiliert. Der neue Smoke-Test `smoke_pdfua_figure` erzeugt zwei Figure-Strukturelemente (eines mit `/Alt` und `/BBox`, eines nur mit `/Alt`) und testet gleichzeitig die Ausnahmen für leeren Alternativtext und fehlerhafte BBox-Werte. Der Python-Verifizierer überprüft sowohl die `/S`-Typen der Figure-Elemente, stellt sicher, dass der Alternativtextinhalt übereinstimmt und dass die Werte des BBox-Arrays [72, 600, 200, 720] sind.

2026-05-19 Version 2.98.0

  • Es wurden vier Helfer für markierte Tabellen hinzugefügt, gemäß PDF/UA-1 §7.5 (Tabellen), als dritte Komponente der Reihe von semantischen Helfern für markierte PDFs. `BeginTaggedTable(Parent): TableElem` erstellt den Tabellenstruktur-Container; `AddTaggedTableRow(Table): TRElem` fügt eine TR-Zeile hinzu; `EmitTaggedTableHeader(TR, X, Y, Text, Scope): THElem` erzeugt eine TH-Zelle mit dem obligatorischen Attribut /Scope; `EmitTaggedTableCell(TR, X, Y, Text): TDElem` erzeugt eine TD-Datenzelle. Alle fünf Tag-Typen (Table, TR, TH, TD sowie das Attribut-Objekt) entsprechen der Spezifikation.
  • Das Attribut "/Scope" (ISO 32000-1 14.8.5.7 Tabelle 350) ist für das Hilfselement obligatorisch (kein Standardwert) und muss einen gültigen Wert von `Row`, `Col` oder `Both` haben. Ungültige Scope-Strings führen zu einem Fehler, wobei die Spezifikation als Richtlinie dient. PDF/UA-1 §7.5 ist streng: "Strukturelemente vom Typ TH müssen ein Scope-Attribut haben. Wenn die Struktur der Tabelle nicht über Überschriften und IDs bestimmt werden kann, müssen Strukturelemente vom Typ TH ein Scope-Attribut haben." Das Erzwingen des Scope im Signatur des Hilfselements verhindert den Fehler, wenn das Scope-Attribut fehlt.
  • Die Serialisierung des Bereichs folgt dem Standardformat für Attributobjekte: `/A << /O /Table /Scope / >>` (gemäß ISO 32000-1 14.7.5.3 Class Map), sodass lesende Anwendungen es als Attribut des Table-Namensraums interpretieren. Dies entspricht dem Muster des Attributs `/A << /O /List /ListNumbering ... >>` in Version 2.97.
  • Tabellen und TR-Elemente sind reine Strukturcontainer (ohne markierten Inhalt auf der Seite), aber TH- und TD-Elemente enthalten sichtbaren Text, sodass beide den Prozess BeginTaggedContent + TextOut + EndTaggedContent durchlaufen. Jede TH- und TD-Zelle erhält ihre eigene MCID, einen BDC-Operator im Seiteninhaltsstrom und einen Eintrag im ParentTree. Eine Hilfsfunktion gibt das StructElem der Zelle zurück, sodass Aufrufer zusätzliche Attribute hinzufügen können (z. B. die Liste "/Headers" für komplexe Tabellen, "/RowSpan", "/ColSpan").
  • Typischer Workflow: `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')); ...` Ersetzt die mehrstufige Struktur der Version 2.90 sowie die BDC/EMC-Sequenz für jede Zelle.
  • Dies behebt den Bereich der Anwenderverantwortung gemäß PDF/UA-1 §7.5, der im Prüfbericht aufgeführt ist. Die Reihe von semantischen Hilfefunktionen für Tagged PDF deckt nun §7.4 (Überschrift, v2.96), §7.6 (Liste, v2.97) und §7.5 (Tabelle, v2.98) ab. Der verbleibende Teil (v2.99+): Hilfefunktion für Abbildungen gemäß §7.3 mit /BBox + /Alt + vom Aufrufer bereitgestelltem Zeichenblock.
  • Win32 + Win64: saubere Kompilierung; die Basisversion v2.97 und die smoke_pdfua_list wurden erfolgreich neu kompiliert. Das neue smoke smoke_pdfua_table erstellt eine 3-zeilige Tabelle (1 Kopfzeile + 2 Datenzeilen) mit 3 TH-Zellen (Scope=Col) + 6 TD-Zellen und testet die Ausnahme für ungültige Scope-Werte. Der Python-Verifizierer überprüft die vollständige Tabellenstruktur > TR > TH/TD mit /Scope /Col für jede TH-Zelle.

2026-05-19 Version 2.97.0

  • Es wurden zwei PDF/UA-1 §7.6 Listen-Helfer hinzugefügt, als Teil der Reihe von semantischen Helfern für strukturierte PDFs: `BeginTaggedList(Parent, NumberingStyle): ListElem` erstellt das L-Strukturelement mit einem /A-Attributobjekt der Form << /O /List /ListNumbering /<Style> >> gemäß ISO 32000-1 14.8.5.5; `EmitTaggedListItem(ListElem, LblX, LblY, LabelText, BodyX, BodyY, BodyText): LIElem` erzeugt eine vollständige LI-Substruktur > {Lbl, LBody} mit markiertem Inhalt sowohl für den sichtbaren Label- als auch für den Textkörper.
  • Der Parameter `NumberingStyle` akzeptiert die 8 in der PDF/UA-1 / ISO 32000-1 Spezifikation genannten Namen: `None`, `Decimal`, `UpperRoman`, `LowerRoman`, `UpperAlpha`, `LowerAlpha`, `Circle`, `Disc`. Ungültige Stilnamen führen zu einer Ausnahme, wobei der ungültige Wert und der vollständige Spezifikationssatz als Hinweis angegeben werden. Eine leere Zeichenkette lässt die gesamte `/ListNumbering`-Funktionalität aus, sodass Aufrufer ein benutzerdefiniertes Attributobjekt hinzufügen können, bevor sie die Änderungen speichern.
  • Gemäß PDF/UA-1 §7.6: nummerierte Listen erfordern ein explizites Attribut "/ListNumbering"; ungeordnete Listen können `None` oder eines der Aufzählungszeichen verwenden. Die Hilfsfunktion erzwingt keines davon – es liegt in der Verantwortung des Aufrufers, den Stil auszuwählen, der dem sichtbaren Inhalt entspricht.
  • Typischer Workflow: `Lst := Doc.BeginTaggedList(Root, 'Decimal'); Doc.EmitTaggedListItem(Lst, 72, 750, WideString('1.'), 96, 750, WideString('First item')); ...` Jeder Listeneintrag entspricht einem Aufruf, der die vorherige v2.90-Implementierung ersetzt, wobei diese aus sechs Zeilen besteht, bestehend aus LI + Lbl-BDC-TextOut-EMC + LBody-BDC-TextOut-EMC.
  • Die untergeordneten Elemente "Lbl" und "LBody" durchlaufen beide den Vorgang "BeginTaggedContent" (so dass jedes sein eigenes MCID und ParentTree-Eintrag erhält), und die Hilfsfunktion "EmitTaggedListItem" gibt das LIs-Strukturelement für Aufrufer zurück, die verschachtelte LI-Elemente, "/Alt" oder "/Lang" hinzufügen möchten.
  • Dies behebt die in Abschnitt 7.6 von PDF/UA-1 beschriebene Problemstellung bezüglich der Verantwortung des Aufrufers, wie sie im Prüfbericht aufgeführt ist. Die verbleibenden semantischen Hilfefunktionen für Tagged PDFs (Version 2.98+): Eine Tabellen-Hilfefunktion, die Abschnitt 7.5 abdeckt (Tabelle / TR / TH / TD mit /Scope), und eine Figuren-Hilfefunktion, die Abschnitt 7.3 abdeckt (Figur + /Alt + /BBox-Attribut).
  • Win32 + Win64: saubere Kompilierung; v2.96: die Basis-Smoke-Tests für `smoke_pdfua_heading` wurden erfolgreich neu kompiliert. Der neue Smoke-Test `smoke_pdfua_list` erstellt eine nummerierte Liste mit 3 Elementen und eine nicht-nummerierte Liste mit 2 Elementen und testet den Pfad für ungültige Formatierungen. Der Python-Verifizierer überprüft zwei `/S /L` StructElems mit unterschiedlichen Attributwerten für `/ListNumbering`, 3 bzw. 2 Kindelemente für `LI` und Kindelemente für `Lbl` und `LBody` im ersten `LI`-Element der nummerierten Liste.

2026-05-19 Version 2.96.0

  • Es wurde eine High-Level-Hilfsfunktion `EmitTaggedHeading(Level, Parent, X, Y, Text)` für PDF/UA-1 §7.4 hinzugefügt. Ein Aufruf erzeugt ein vollständiges `/H1` bis `/H6` Strukturelement zusammen mit dem sichtbaren Text auf der aktuellen Seite: die Hilfsfunktion weist einen MCID pro Seite zu, führt den BDC-Operator aus, führt `TextOut` aus, dann `EMC`, erstellt das `StructElem` mit der entsprechenden `/H<Level>`-Rolle und verbindet es mit `/ParentTree`. Dies ersetzt die v2.90-Methode mit drei Zeilen (`BeginTaggedContent + TextOut + EndTaggedContent`) für den häufigsten Fall von Überschriften.
  • Der Parameter "Level" akzeptiert Werte von 1 bis 6 (die Standard-Überschriften). Wenn der Wert außerhalb des zulässigen Bereichs liegt, wird eine Ausnahme ausgelöst, die eine klare Diagnose liefert. PDF/UA-1 §7.4.3 erlaubt benutzerdefinierte H7+-Tags, diese sind jedoch selten; Aufrufer, die diese benötigen, können stattdessen die explizite Sequenz BeginTaggedContent('H7', ...) verwenden.
  • Gibt das StructElem-Element zurück, sodass Aufrufer Attribute hinzufügen können (z. B. /Lang, /Alt für dekorative Überschriften), nachdem die Hilfsfunktion zurückgegeben wurde.
  • Typischer Workflow: `Doc.EmitTaggedHeading(1, RootElem, 72, 750, WideString('Chapter 1'));` ersetzt jetzt die bisherige, komplexe Abfolge von BDC + TextOut + EMC + AddStructureElement vollständig.
  • Dies ist der erste Teil einer geplanten Reihe von "semantischen Hilfsmitteln für taggebasierte PDFs", die auf der Schließung des PDF/UA-1-Wrappers in Version v2.95 folgt. Zukünftige Teile (v2.97+) umfassen Hilfsmittel für Listen (L / LI / Lbl / LBody) und Tabellen (Table / TR / TH / TD mit /Scope), um die Verantwortlichkeiten des Aufrufers in den Abschnitten §7.5 und §7.6 des Prüfberichts abzudecken.
  • Win32 + Win64: saubere Kompilierung; die Baselines v2.95 wurden sauber neu kompiliert. Der neue Test "smoke_pdfua_heading" erzeugt drei Überschriften (H1/H2/H3) und testet den Bereichsüberprüfung-Ausnahmepfad für Level=7; der Python-Verifizierer überprüft drei /S /H StructElems und die entsprechenden /H BDC-Operatoren im dekomprimierten Seiteninhaltsstrom.

2026-05-19 Version 2.95.0

2026-05-19 Version 2.94.0

  • PDF/UA-1 (ISO 14289-1:2014) Überprüfung der Herstellerkonformität: Es wurden drei tatsächliche Konformitätslücken geschlossen, die in der v2.87-Version mit der erweiterten Option nicht abgedeckt waren. Bei der Überprüfung wurden die Ausgaben von HotPDF v2.93 mit jeder Anforderung des Dateiformats gemäß §7 verglichen, und es wurden sechs Lücken beim Hersteller festgestellt; diese Version behebt drei Probleme, die im Enddokumentschritt auftreten (Schlüssel für verdächtige Elemente, Registerkarten für annotierte Seiten, strikte Sprachauswahl). Die verbleibenden drei Lücken (Inhalte von Links, Verschlüsselungs-Bit 10, StructElem-ID) werden in den Versionen v2.95-v2.97 behoben.
  • §7.1 Verdächtige (Hohe Priorität): Das Catalog-Dictionary gibt jetzt `/Suspects false` aus, wenn `PDFUACompliance` auf True gesetzt ist. Gemäß der Spezifikation „Dateien, die die Konformität mit dieser internationalen Norm beanspruchen, müssen einen `Suspects`-Wert von `false` haben“ – veraPDF und ähnliche Validierer prüfen auf das explizite Vorhandensein des Schlüssels, nicht nur auf dessen Fehlen. In Version 2.93 wurde der Schlüssel vollständig entfernt, was bei einer strengen Spezifikationsprüfung zu dem Fehler „Catalog MarkInfo enthält keinen `Suspects`-Eintrag“ führte.
  • §7.18.3 Tabs (MED-Schweregrad): `EndDoc` durchläuft jetzt jede Seite und fügt `/Tabs /S` auf jeder Seite hinzu, die ein nicht leeres `/Annots`-Array enthält und `/Tabs` noch nicht deklariert hat. Gemäß der Spezifikation: "Jede Seite, auf der eine Anmerkung vorhanden ist, muss im Seitendictionary den Schlüssel `Tabs` ... und den Wert `S` enthalten." Dies wird nur ausgeführt, wenn `PDFUACompliance` aktiviert ist; Aufrufer, die `/Tabs` explizit festlegen (über `THPDFPage.SetTabsOrder`), behalten ihre Einstellung.
  • §7.2 Sprache (MED-Schweregrad): Wenn `PDFUACompliance=True` gesetzt ist und `Doc.Lang` leer ist, wird jetzt eine Ausnahme ausgelöst, die eine klare Diagnose liefert, anstatt stillschweigend auf `'en'` zu setzen. In älteren Versionen (vor v2.94) wurden nicht-englische Dokumente fälschlicherweise gekennzeichnet (jeder chinesische/arabische/japanische usw. Inhalt würde stillschweigend ein falsches BCP-47-Tag ausgeben, das von Bildschirmleseprogrammen verwendet wird, um die Aussprache zu ändern). Aufrufer müssen jetzt die Dokumentensprache explizit angeben – typische Verwendung: `Doc.Lang := 'en-US'`, `'zh-CN'`, `'ar-SA'`, usw.
  • Wichtiger Hinweis zur Abwärtskompatibilität: Bestehende Aufrufer von `PDFUACompliance` müssen `Doc.Lang := '...'` vor `BeginDoc` / `EndDoc` hinzufügen. Die vier Beispieltests (smoke_pdfua_compliance, smoke_pdfua_alt_actualtext, smoke_pdfua_annot_structparents, smoke_pdfua_tagged_content) wurden aktualisiert, um `Doc.Lang := 'en-US'` entsprechend zu setzen. Aufrufer, die `PDFUACompliance` nicht verwenden, sind nicht betroffen.
  • `smoke_pdfua_compliance_verify.py` überprüft jetzt, ob `/Suspects false` im Dictionary `MarkInfo` des Katalogs vorhanden ist; `smoke_pdfua_annot_structparents_verify.py` überprüft, ob `/Tabs /S` auf der annotierten Seite vorhanden ist. Beide Tests werden vollständig gegen die resultierende PDF-Datei ausgeführt.
  • Berichtsüberprüfung: Ein umfassender PDF/UA-1-Compliance-Bericht, der alle 21 Paragraphen der Dateiformatspezifikationen abdeckt, ist unter `.superpowers/specs/2026-05-19-pdfua-compliance-audit.md` archiviert (projektlokal, nicht committet). Der Bericht klassifiziert jeden Abschnitt als "von HotPDF automatisch erfüllt", "Verantwortung des Aufrufers mit Hilfs-API" oder "echte Lücke des Herstellers" und bewertet die verbleibenden Lücken nach Schweregrad für die Roadmap v2.95+.

2026-05-19 Version 2.93.0

  • Es wurde `RegisterColorConversionLUT3D(GridR, GridG, GridB, OutputComponents, Samples, BitsPerSample=8, Order=1): THPDFStreamObject` hinzugefügt, eine High-Level-Wrapper-Funktion für den v2.52 Function Type 0-Primitive, der für den häufigen Anwendungsfall der Farbmanagement-LUT mit 3 Eingängen verwendet wird. Intern werden die Standard-Arrays `/Domain=[0,1]*3`, `/Range=[0,1]*OutputComponents` und `/Size=[GridR, GridG, GridB]` erstellt und an `RegisterSampledFunction` übergeben.
  • Typischer Workflow: ICC-Profil-gesteuerte Umwandlung von sRGB in Lab, von sRGB in CMYK oder von RGB in RGB (Geräteverknüpfung), wobei dies als eine 3D-LUT ausgedrückt wird. Die Wrapper-Funktion validiert die Größe der Raster für jede Achse und den Bereich von OutputComponents; die zugrunde liegende Funktion RegisterSampledFunction validiert BitsPerSample / Order / die Gesamtanzahl der Bytes im Vergleich zur erwarteten Größe des Sample-Payloads. Inkompatible Puffer führen zu einer Ausnahme mit einer klaren Diagnosemeldung.
  • Beispiel für die Byte-Anordnung: Zeilenweise über das 3D-Gitter, wobei R am schnellsten, dann G und dann B angeordnet sind. Anzahl der Bytes pro Zelle für `OutputComponents` bei `BitsPerSample=8`. Gesamt: `GridR * GridG * GridB * OutputComponents` Bytes. Höhere Bittiefen (12, 16) erfordern, dass der Aufrufer Datenpakete erstellt, die den Spezifikationen entsprechen und die Byte-Reihenfolge mit dem höchstwertigen Bit zuerst verwenden.
  • Sichtbare Auswirkungen für den Benutzer: Ein Farbmanagement-Workflow kann jetzt eine 17x17x17 RGB-zu-CMYK ICC-Simulation in einer einzigen Zeile mit einem vorab berechneten Beispiel-Array darstellen, anstatt die Bereiche und Größen manuell zu definieren. Das zurückgegebene indirekte THPDFStreamObject kann in jeder API verwendet werden, die Funktionen verarbeitet: Muster vom Typ 2 für axiale/radiale Schattierungen, Farbseparationstransformationen über RegisterSeparationLUT, Übertragungsfunktionen in ExtGState /TR, Schwarzgenerierung in ExtGState /BG.
  • Abwärtskompatibilität: Die bestehende RegisterSampledFunction-Funktion bleibt unverändert; der neue Wrapper ist eine einfache Erweiterung. Aufrufer, die keine Standardwerte für /Domain benötigen (z. B. Lab L* in [0..100], a* / b* in [-128..127]) oder keine rechteckigen Bereiche verwenden möchten, können weiterhin RegisterSampledFunction direkt verwenden.
  • Kandidat #4: Dies ist der einzige Eintrag für den Matrix-Kandidaten "3D Function Type 0". Die hochrangige Wrapper-Funktion macht die vorhandene primitive Funktion mit N=3 für den typischen Farbraum-Anwendungsfall benutzerfreundlicher; Kandidat #4 wird geschlossen.

2026-05-19 Version 2.92.0

  • Es wurde `RegisterHalftoneType5(ColorantNames, Halftones, DefaultHalftone, HalftoneName)` hinzugefügt, um die Familie von Halbtönen des Typs `/HT` in ExtGState abzuschließen. Typ 5 ist ein mehrkomponentiges Dictionary, das nach Farbnamen indiziert ist (z. B. /Cyan, /Magenta, /Yellow, /Black, /Red, /Green, /Blue, /Gray sowie alle registrierten Separation/DeviceN-Farbwerte), wobei die Werte indirekte Halbtontypen sind, die auf Sub-Halbtöne der Typen 1/6/10/16 verweisen. CMYK-Druckvorstufen können jetzt jedem Farbton in einem einzigen ExtGState-Eintrag eine eigene Rasterfrequenz/Winkel/Punktform zuweisen.
  • Parallele-Array-Signatur: `ColorantNames` und `Halftones` werden paarweise abgeglichen und auf gleiche Länge überprüft. Leere Farbnamen oder fehlende Halbtöne führen zu einem Fehler mit dem entsprechenden Index. Das optionale `DefaultHalftone` wird zum Dictionary-Eintrag `/Default`, den lesende Anwendungen als Standard für alle Farbnamen verwenden, die nicht in der expliziten Liste enthalten sind (typisch für Dokumente, die unerwartete Sonderfarben enthalten).
  • Die Ausgabe erfolgt in Form einer Dictionary-Struktur (PDF 1.7, ISO 32000-1, 10.5.5.2): /Type /Halftone + /HalftoneType 5 + optional /HalftoneName + ein /ColorantName-Eintrag pro Paar + optional /Default. Es wird das indirekte THPDFDictionaryObject zurückgegeben, sodass der Aufrufer es wie jedes andere Halftone-Objekt an `RegisterHalftoneState` (Version 2.64) übergeben kann.
  • Validierung: mindestens eine Komponente oder ein `DefaultHalftone` ist erforderlich (ein leerer Typ 5 ohne `/Default` ist semantisch bedeutungslos). Die Hilfsfunktion validiert NICHT, ob die bereitgestellten Sub-Halbtöne keine Typ-5-Objekte sind (die Spezifikation verbietet die Verschachtelung von Typ 5), da der Aufrufer aktiv einen selbstreferenzierten Graphen erstellen müsste, und reale Vorbereitungsprozesse lösen dies normalerweise nicht aus.
  • Sichtbare Auswirkungen für den Benutzer: Ein Vorstufen-Ingenieur, der eine Vierfarben-Broschüre erstellt, kann jetzt vier unabhängige Raster einrichten (Cyan bei 105° / 75 lpi, Magenta bei 75° / 75 lpi, Gelb bei 90° / 75 lpi, Schwarz bei 45° / 75 lpi über Type 1-Farbwerte oder durch Ersetzen mit Type 6-Schwellwertrastern für FM-Rasterung) und diese in einem einzigen ExtGState zusammenfassen. Derselbe ExtGState wird dann von jedem Zeichenbefehl aktiviert, der die kanalbezogenen Raster benötigt.
  • Kandidat #3: Dies ist der zweite und letzte Teil der Haltonierungsfamilie `/HT` in `ExtGState`. Der vollständige Funktionsumfang (Type 1 Spotfunktion in v2.64, Type 5 Mehrkomponenten in v2.92, Type 6/10/16 Schwellenwert-Stream in v2.91) ist jetzt gemäß der PDF 1.7-Spezifikation vollständig implementiert. Kandidat #3 wird geschlossen.

2026-05-19 Version 2.91.0

  • Es wurden drei neue Halbtontöne-Stream-Builder hinzugefügt, um die Familie von Halbtönen mit dem ExtGState `/HT` zu vervollständigen, die in v2.64 eingeführt wurde: `RegisterHalftoneType6` (8-Bit-Schwellenwert-Raster, Breite/Höhe-abhängig), `RegisterHalftoneType10` (8-Bit-Schwellenwert-Raster mit Parallelogramm-Zellen über Xsquare/Ysquare für schräge Raster) und `RegisterHalftoneType16` (16-Bit-Schwellenwert-Raster, 65536-stufige Präzision für hochwertige Druckvorstufe).
  • Jeder Builder gibt ein indirektes /Type /Halftone Stream-Objekt zurück, das Aufrufer an `RegisterHalftoneState` v2.64 übergeben können, um es in einen ExtGState /HT-Eintrag zu verpacken, genau wie Type 1 Spot-Funktions-Halbtöne. Optionale /HalftoneName-, /TransferFunction- oder /TransferFunction /Identity-Einträge entsprechen dem Type 1-Muster.
  • Größenvalidierung: Typ 6 erfordert, dass `len(ThresholdBytes) = Width * Height` ist; Typ 10 erfordert `Xsquare^2 + Ysquare^2` (PDF 1.7 §10.5.5.4, gestapelte Quadrate); Typ 16 erfordert `Width * Height * 2` (Paare von Big-Endian-uint16-Werten, vom Aufrufer bereitgestellt). Inkompatible Puffer führen zu einer Ausnahme, die sowohl die tatsächliche als auch die erwartete Byte-Anzahl angibt.
  • Die interne Hilfsfunktion `_HotPDFCreateHalftoneStream` vermeidet unnötige Wiederholungen bei der Erstellung von Halbtönen: Sie kümmert sich um die indirekte Stream-Allokation, den Header (/Type /Halftone + /HalftoneType N), optionale Namens- und Transferfunktionseinträge, das Schreiben der Daten und den /Length-Stempel. Jede öffentliche Funktion validiert nur die typenspezifischen Größen und leitet die Verarbeitung weiter.
  • Sichtbare Auswirkungen für den Benutzer: Vorbereitungsprozesse, die benutzerdefinierte Bildschirmmuster benötigen (benutzerdefinierte Punktformen, frequenzmodulierte Raster, geneigte Zellen), haben jetzt einen HotPDF-Einstiegspunkt. Der Aufrufer liefert das Schwellenwert-Raster (das er normalerweise offline aus einem Rastermustergenerator erstellt), HotPDF erzeugt das spezifikationskonforme /Type /Halftone-Stream-Objekt und verbindet es mit der ExtGState-Ressourcenkette.
  • Abdeckung der Spezifikationen: PDF 1.7 ISO 32000-1 10.5.5.3 (Typ 6) + 10.5.5.4 (Typ 10) + 10.5.5.5 (Typ 16). Wird automatisch auf PDF 1.2 aktualisiert (entspricht der Mindestanforderung für Typ 1, da Halbtöne zusammengefasst wurden).
  • Kandidat #3: Dies ist der erste Teil der Matrix für "ExtGState /HT Halftöne, verbleibende Typen". Der Typ-5-Mehrkomponenten-Halbton (ein Dictionary, das nach Farbkomponenten benannt ist und an Typ-1/6/10/16-Unter-Dictionaries für Kanal-spezifische Raster delegiert, für CMYK-Vordruck) ist der zweite und letzte Teil und wird in v2.92 eingeführt.

2026-05-19 Version 2.90.0

  • Es wurde ein Helfer für Markierungsinhaltssequenzen auf hoher Ebene hinzugefügt: `THotPDF.BeginTaggedContent(Role, Parent): THPDFDictionaryObject` + `THotPDF.EndTaggedContent`. Dieser Helfer weist automatisch eine MCID pro Seite zu, gibt den BDC-Operator im aktuellen Seiteninhaltsstrom aus, erstellt das StructElem unter Parent und verbindet es in einem Aufruf mit /ParentTree. Das Ergebnis ist, dass Anwender von PDF/UA-1 sichtbare Inhaltsabsätze markieren können, ohne MCID-Zähler manuell verwalten zu müssen.
  • Typische Verwendung: `Para := Doc.BeginTaggedContent('P', Root); Doc.CurrentPage.TextOut(...); Doc.EndTaggedContent;` Das zurückgegebene StructElem kann in AddStructureElement('Span', Para, ...) für Unterstrukturen integriert werden oder `/Alt` und `/ActualText` über den Attributpfad v2.88 enthalten.
  • Neues Feld THPDFPage.FNextMCID verfolgt die pro-Seite zugeordnete MCID-Zuweisung; wird pro Seite zurückgesetzt (wird bei der Initialisierung von BeginDoc lazy initialisiert auf 0). Die Low-Level-Operatoren BeginMarkedContentMCID / EndMarkedContent (seit v2.11 in HotPDF verfügbar) bleiben für Aufrufer verfügbar, die eine explizite MCID-Steuerung wünschen.
  • Pipeline-Integration: `BeginTaggedContent` gibt "/Role <> BDC" im aktuellen Seiteninhaltsstrom aus und ruft dann `AddStructureElement(Role, Parent, PageIdx, MCID)` auf, wodurch das `StructElem` erstellt und `RegisterMCIDForPage` ausgeführt wird (der Pfad v2.11, der lazyweise `/StructParents` im Seitendiktat setzt und das pro-Seite-Array in `/ParentTree` erweitert). `EndTaggedContent` gibt "EMC" im aktuellen Seiteninhalt aus. Verschachtelung funktioniert, weil BDC/EMC-Paare implizit über die lineare Reihenfolge des Seiteninhaltsstroms verschachtelt werden.
  • Sichtbare Auswirkungen für den Benutzer: Ein PDF/UA-1-kompatibles Dokument kann jetzt jeden sichtbaren Absatz, jede Überschrift, jeden Bereich oder jede Bildunterschrift mit semantischer Struktur versehen, wobei zwei Zeilen vor und nach dem Zeichenbefehl platziert werden. veraPDF akzeptiert die resultierenden Seiteninhalte mit den markierten Inhalten und der Verknüpfung zum Strukturbaum; assistive Technologien folgen der Dokumentstruktur zu den markierten Inhalten und geben die Rolle und den Text aus.
  • Kandidat #1: vierte und letzte Phase. Die PDF/UA-1-Funktionalität wurde jetzt erweitert, um die Option für Wrapper (v2.87) sowie die Attribute /Alt und /ActualText (v2.88) zu unterstützen. Außerdem wurden die Verbindungen für Annotationen und die Struktur (StructParent) sowie die umgekehrte Verkabelung von OBJR (v2.89) verbessert. Die automatische Umbruchfunktion für BDC/EMC im Seiteninhalt wurde ebenfalls hinzugefügt (v2.90). Aufrufer behalten weiterhin die Kontrolle über die Struktur des Strukturbaums (z. B. Überschriftenhierarchie, Listen, Tabellenüberschriften), aber die technische Umsetzung ist vollständig automatisiert. Kandidat #1 abgeschlossen.

2026-05-19 Version 2.89.0

  • Hinzugefügte Verbindungen zwischen Annotationen und Strukturen gemäß PDF 1.7 14.7.4.4. Die neue Hilfsfunktion `THotPDF.RegisterAnnotForStructure(AnnotDict, StructElem)` weist einen neuen Schlüssel für /ParentTree zu, setzt /StructParent in der Annotation, speichert das StructElem bei /ParentTree[Schlüssel] (eine einzelne Referenz für Annotationen, im Gegensatz zur Array-von-Referenzen-Form, die von Seiteneinträgen verwendet wird) und fügt <</Type /OBJR /Obj <annotRef>>> zum /K-Array des StructElem hinzu. Bildschirmleseprogramme können jetzt von jeder markierten Annotation zu ihrem übergeordneten Strukturelement navigieren und umgekehrt.
  • Es wurde `THPDFPage.AddURILink(Rect, URL): THPDFDictionaryObject` hinzugefügt, sodass Anwender von PDF/UA-1 eine Möglichkeit zur Erstellung von URI-Annotationen mit Rückgabewert erhalten. Die bestehenden Methoden `AddGoToLink`, `AddGoToRLink` und `AddLaunchLink` geben ihre Annotations-Dictionaries nicht zurück (eine Einschränkung der API aus früheren Versionen); die neue Methode `AddURILink` gibt das indirekte Annotations-Dictionary zurück, sodass es direkt an `RegisterAnnotForStructure` übergeben werden kann.
  • Sichtbare Auswirkungen für den Benutzer: Ein PDF/UA-1-konformes Dokument kann jetzt einen Hyperlink mit seiner semantischen Struktur in drei Zeilen versehen: `LinkAnnot := Doc.CurrentPage.AddURILink(R, 'https://example.org/'); LinkElem := Doc.AddStructureElement('Link', RootElem, -1, -1); Doc.RegisterAnnotForStructure(LinkAnnot, LinkElem);`. Hilfstechnologien, die der Dokumentstruktur folgen, können nun auf den Link zugreifen, seinen Zweck bekannt geben und ihn als aktivierbar darstellen.
  • Implementierungsnotiz: Die Schleife v2.11 "EmitTaggedPDFRoot", die die Einträge "/ParentTree" und "/Nums" ausgibt, verwendete einen harten Cast `THPDFArrayObject(FParentTree.Items[I])`. In v2.89 wurde der Cast auf THPDFObject erweitert, da Annotationseinträge ein einzelnes Dictionary und kein Array enthalten; THPDFArrayObject.AddObject verwendet bereits zur Laufzeit die IsIndirect-Prüfung, sodass der Cast immer nur eine formale Angabe war. In v2.11+ wurde sichergestellt, dass die Arrays in FParentTree weiterhin byte-stabil bleiben.
  • Spezifische Anmerkung: PDF 1.7, Abschnitt 14.7.4, erlaubt, dass die Werte von `/ParentTree` entweder ein Array (für markierte Inhalte, die durch MCID indiziert sind) oder eine direkte Referenz zu einem `StructElem` sein können (für Anmerkungen, "Beads" und andere nicht-MCID-Strukturelemente). v2.89 ist die erste Version, die die Form mit einer einzelnen Referenz verwendet; die Array-Form funktioniert weiterhin über den Pfad `AddStructureElement` mit MCID in Version v2.11.
  • Kandidat #1: Dies ist der dritte Teil der PDF/UA-Implementierung auf der Produktionsseite. Es verbleibt noch ein Teil: Die automatische Zeilenumbruchfunktion für BDC/EMC-Inhalte, sodass `AddTextField` und `CurrentPage.TextOut` markierte Inhalte ohne manuelle Operatoraufrufe ausgeben können. Danach erreicht die PDF/UA-Produktionsoberfläche ein zufriedenstellendes Basisniveau.

2026-05-19 Version 2.88.0

  • Es wurde eine überladene `AddStructureElement`-Signatur hinzugefügt, die optionale Attribute `/Alt` und `/ActualText` als Zeichenketten akzeptiert. PDF/UA-1 (ISO 14289-1) erfordert, dass nicht-textuelle Inhalte (Bilder, Formeln, dekorative Glyphen) alternative, für Bildschirmleseprogramme geeignete Darstellungen bereitstellen; die neue Überladung ermöglicht es, diese problemlos in einem einzigen Aufruf an ein StructElem anzuhängen.
  • `/Alt` (alternative Beschreibung) ist der Text, den assistive Technologien laut vorlesen, um nicht-textliche Inhalte zu beschreiben – typische Anwendung: Strukturelemente, die Bilder oder Diagramme umschließen. `/ActualText` ist der Text, der beim Kopieren und Einfügen zurückgegeben wird, wenn die sichtbaren Glyphen von den beabsichtigten Unicode-Zeichen abweichen – typische Anwendung: dekorative Ligaturen, Initialen, schwer zu extrahierende Kalligraphie.
  • Beide Attribute sind PDF-Textzeichenketten, die über den standardmäßigen, byteweisen SaveStringObject-Ausgabepfad erzeugt werden. Leere Zeichenketten überspringen den entsprechenden Eintrag, sodass bestehende Aufrufe mit vier Argumenten weiterhin eine byteweise identische Ausgabe erzeugen. Die ursprüngliche Signatur `AddStructureElement(Role, Parent, PageIndex, MCID)` mit vier Argumenten wird über die Pascal-`overload`-Direktive beibehalten.
  • Sichtbare Auswirkungen: Ein PDF/UA-1-kompatibles Dokument kann jetzt ein Logo mit `AddStructureElement('Figure', Root, 0, 0, 'Company logo', '')` und eine Ligatur mit `AddStructureElement('Span', Root, 0, 1, '', 'A bus stop')` versehen; veraPDF und assistive Technologien verarbeiten die resultierenden /Alt- und /ActualText-Einträge ohne zusätzliche Konfiguration.
  • Pipeline-Platzierung: Die in v2.88 eingeführte Erweiterung leitet die Verarbeitung an die Basisimplementierung in v2.11 weiter (so dass die Verkabelung von StructTreeRoot, das Anhängen des /K-Arrays, der Back-Link zu /Pg sowie die Registrierung von MCID/ParentTree unverändert bleiben) und fügt erst danach die beiden Attributeinträge hinzu. Es erfolgt keine Änderung der bestehenden Aufrufstellen; die Byte-Stabilität von v2.74 bis v2.87 bleibt erhalten.
  • Kandidat #1 Status: Dies ist der zweite Teil der PDF/UA-Implementierung auf der Produzenseite. Folgende Punkte werden bearbeitet: Automatische Zeilenumbrüche für Seitenelemente (so dass `AddTextField` und `CurrentPage.TextOut` markierte Inhalte ohne manuelle Operatoraufrufe erzeugen können); Verbindungen für `/StructParents` für Annotationen (so dass die Navigation für Bildschirmlesegeräte auch Links und Formularelemente erreicht).

2026-05-19 Version 2.87.0

  • Es wurde eine High-Level-Opt-in-Funktion für PDF/UA-1 (ISO 14289-1) über die neue Eigenschaft `PDFUACompliance` hinzugefügt. Durch das Setzen von "True" vor "BeginDoc" / "EndDoc" werden automatisch alle PDF/UA-1-Anforderungen aktiviert, die HotPDF erfüllen kann, ohne die Zusammenarbeit des Aufrufers: `/MarkInfo /Marked = true`, ein Platzhalter für `/StructTreeRoot`, `/Lang` (Standardwert 'en', wenn leer), `/ViewerPreferences /DisplayDocTitle = true`, ein XMP-Stream für `/Metadata` und der im XMP-Paket registrierte AIIM-Identifier `pdfuaid:part = 1`.
  • Anstelle von sechs Optionen: Zuvor musste ein Aufrufer, der die PDF/UA-1-Konformität erreichen wollte, die Optionen EnableTaggedPDF, EnableXMPMetadata, Lang, ViewerPreferences := [vpDisplayDocTitle] und Title einzeln festlegen und dann ein benutzerdefiniertes XMP-Paket erstellen, um den Namespace pdfuaid hinzuzufügen. In Version 2.87 werden all diese Optionen zu PDFUACompliance:=True zusammengefasst; die einzelnen Optionen bleiben weiterhin verfügbar und werden berücksichtigt, wenn der Aufrufer sie explizit festlegt.
  • Aktualisierung des XMP-Pakets: Die Funktion `BuildXMPPacket` gibt jetzt `xmlns:pdfuaid="http://www.aiim.org/pdfua/ns/id/"` sowie `1` aus, wenn `PDFUACompliance` auf `True` gesetzt ist. `veraPDF` und andere PDF/UA-1-Validierer erkennen Dokumente anhand dieser exakten Namensraum- und Identifikator-Kombination als potenzielle PDF/UA-1-Kandidaten.
  • Sichtbare Auswirkungen für den Benutzer: Ein PDF, das mit `Doc.Title := '...'; Doc.PDFUACompliance := True; Doc.BeginDoc; ...; Doc.EndDoc;` erstellt wurde, wird in veraPDF als PDF/UA-1-Kandidat validiert, ohne dass zusätzliche Konfigurationen erforderlich sind, vorausgesetzt, der Autor des Dokumentinhalts erstellt eine echte Struktur durch die Verwendung von `AddStructureElement` und Markierungssequenzen. Regierungs-, Bildungs- und barrierefreie Publikationsworkflows haben jetzt eine einzige Umschaltoption.
  • Verantwortung des Aufrufers: PDF/UA-1 erfordert auch die Integrität des Strukturbaums (jedes Glyphe gehört zu einem strukturierten Element), sowie `/Alt` oder `/ActualText` für Abbildungen/Formeln, eine sinnvolle Tab-Reihenfolge, eine gültige Überschriftenhierarchie usw. Die Option umfasst die Katalog-/Metadaten-Wrapper, die von automatisierten Validatoren zuerst geprüft werden; die vollständige semantische Konformität hängt weiterhin davon ab, dass der Aufrufer den Strukturbaum ehrlich über die Funktionen `AddStructureElement` und die Operatoren `BDC`/`EMC` für markierten Inhalt erstellt.
  • Abwärtskompatibilität: Standardmäßig ist PDFUACompliance auf False eingestellt, sodass Aufrufer von v2.74 bis v2.86 eine byte-identische Ausgabe erhalten. Bestehende Flags für EnableTaggedPDF und EnableXMPMetadata funktionieren weiterhin unabhängig voneinander, wenn die neue Option deaktiviert ist.
  • Dies ist der erste Teil der Matrix für Kandidat #1 (Tagged PDF / PDF/UA, Implementierung auf Produzenseite). Folgende Verbesserungen (v2.88+): Unterstützung für "/Alt" und "/ActualText" in AddStructureElement, Hilfsfunktionen für BDC / EMC im Zusammenhang mit AddTextField und CurrentPage.TextOut, sowie die Verknüpfung von "/StructParents" für Annotationen.

2026-05-19 Version 2.86.0

  • Der Parser von `RegisterUnicodeTTF` wurde erweitert, um das OpenType-Format 12 zu verarbeiten (segmentierte, vollständige Unicode-Abdeckung). In den Versionen v2.75 bis v2.85 wurde nur Format 4 (Legacy-BMP-Segmentzuordnung) geparst; moderne Schriftarten, die sowohl Format 12 als auch Format 4 enthalten, verwenden jetzt die umfassendere Tabelle. Die Auswahl der Subtabelle bevorzugt Format 12 gegenüber Format 4, da Format 12 für den gesamten Codepoint-Bereich maßgeblich ist.
  • Neuer `_TTFParseCmapFormat12`-Parser: liest den 16-Byte-Header (Format/Reserviert/Länge/Sprache/AnzahlGruppen) und iteriert dann über die AnzahlGruppen 12-Byte-Gruppen (startCharCode/endCharCode/startGlyphID). Für jeden Codepunkt C im Bereich [startCharCode..endCharCode] ist die Glyphen-ID gleich startGlyphID + (C - startCharCode). Bei jedem mehrByte-Lesevorgang werden die Grenzen überprüft; beschädigte oder fehlerhafte Gruppen werden stillschweigend übersprungen.
  • Die Bewertung der Subtabellen wurde aktualisiert:
    • Plattform 3 (Microsoft) + Kodierung 10 (vollständiges Unicode) + Format 12: 120 (am besten)
    • Plattform 0 (Unicode) + Kodierung 4 oder 6 + Format 12: 110
    • Alle anderen Formate 12: 105
    • Plattform 3 + Kodierung 1 (Unicode BMP) + Format 4: 100 (Legacy-BMP-Fallback)
    • Plattform 0 + Kodierung 3..4 + Format 4: 80
    • Plattform 3 + Kodierung 10 + Format 4: 70
    • Alle anderen Formate 4: 50
  • SMP-Bereich: Das Ausgabearray von CpToGid behält die Größe des Basic Multilingual Plane (BMP) bei (10000 Einträge × 2 Bytes = 128 KB), da unsere Identity-H-Kodierung 2-Byte-CIDs (0..65535) verwendet. 12 Format-SMP-Einträge (U+10000+) werden geparst, aber nicht gespeichert; der Format-12-Parser begrenzt den Wert von endCharCode auf $FFFF, bevor er iteriert. Eine vollständige SMP-Abdeckung in /CIDToGIDMap würde eine andere Kodierung erfordern (Identity-V mit Surrogate-Pair-CMap oder Adobe-Japan1) und liegt außerhalb des Geltungsbereichs.
  • Sichtbare Auswirkungen: Schriftarten, die nur im Format 12 ausgeliefert werden (einige moderne CJK-Schriftarten, Segoe UI Emoji / Symbol), füllen jetzt korrekt die Felder /W, /CIDToGIDMap, /FontFile2 aus und werden vom v2.84-Subsetter verarbeitet. Vor der Version v2.86 führten diese Schriftarten zu einem stillen Fallback beim cmap-Parsing, wodurch alle vier Stream-Ausgaben übersprungen wurden und stattdessen das Ergebnis von v2.74 mit nur Metadaten verwendet wurde.
  • Byte-Stabilität: Schriftarten mit Format 4 (nur Arial und Tahoma) durchlaufen weiterhin den gleichen Code-Pfad und erzeugen die gleiche CpToGid-Ausgabe. Schriftarten, die sowohl Format 4 als auch Format 12 haben, verwenden jetzt Format 12 für BMP, was typischerweise die gleiche BMP-Zuordnung ergibt (Format 12 ist eine strikte Erweiterung). Die vorhandenen Tests für diese Schriftarten in den Versionen v2.74 bis v2.85 bleiben byte-stabil.
  • Dies schließt die Phase der vollständigen Implementierung der dichten PDF-Spezifikation von v2.4.0 bis v2.86.0 ab. Die verbleibenden Arbeiten ab v2.86 (SMP-Kodierung über Surrogate-Pair-CMaps, schriftspezifische GSUB-stilistische Alternativen, fortgeschrittenere Typografie) liegen außerhalb des Bereichs von ""grundlegender Typ 0 / Identity-H + AcroForm Unicode"" und werden auf unbestimmte Zeit verschoben, bis eine tatsächliche Benutzeranforderung vorliegt.

2026-05-19 Version 2.85.0

  • Es wurde eine optionale arabische Präsentationsform-B-Kontextualisierung über die neue Eigenschaft `AutoShapeArabic` hinzugefügt. Wenn diese auf True gesetzt ist, ersetzen die drei Helferfunktionen `BuildUnicode*FieldContent` grundlegende arabische Buchstaben (U+0621..U+064A) durch ihre positionsgerechte Präsentationsform (U+FE70..U+FEFF), *bevor* die bidirektionale Umkehrung erfolgt. PDF-Reader müssen nun keinen Text-Shaper (HarfBuzz / FreeType / GSUB-Binärsuche) im Prozess verwenden, um die korrekte positionsgerechte Form zur Renderzeit auszuwählen.
  • Algorithmus zur Zeichenanpassung: Scannt den UTF-16-Puffer in logischer Reihenfolge; für jeden arabischen Buchstaben werden der vorherige und der nächste nicht-transparente Buchstabe gefunden (NSMs / diakritische Zeichen U+064B..U+065F + Alef Khanjareeya U+0670, transparent). Die Position wird anhand des Verbindungs-Kontexts bestimmt: D (doppelte Verbindung: BEH, TEH, SEEN, LAM, MEEM, NOON usw.) unterstützt isolierte, initiale, mediale und finale Formen, abhängig davon, ob die umgebenden starken Buchstaben eine Verbindung auf ihren jeweiligen Seiten zulassen; R (rechte Verbindung: ALEF, DAL, ZAL, REH, ZAIN, WAW usw.) unterstützt nur isolierte und finale Formen.
  • Direkter Einfluss auf den Benutzer (bei AutoShapeArabic=True): Die Eingabe von "بسم" (BEH + SEEN + MEEM) erzeugt einen Tj-Befehl mit den Präsentationsformen FE91 (BEH initial), FEB4 (SEEN medial) und FEE2 (MEEM final). Nach der RTL-Umkehrung ist das Tj-Operand FEE2 FEB4 FE91, was jeder PDF-Reader als zusammenhängende arabische Schrift ausgibt, auch ohne eine integrierte Formgebung.
  • Abdeckung: 35 grundlegende arabische Buchstaben (Varianten von HAMZA, Varianten von ALEF, das 28-Buchstaben-Arabische-Alphabet, YEH MAKSURA). Eine statische Unicode-Standard-Suche ersetzt die font-spezifische GSUB-Binäranalyse, sodass die Formatierung mit jeder Schriftart funktioniert, die Glyphen im Bereich U+FE70..U+FEFF enthält (Arial, Tahoma, Segoe UI Arabic, Noto Sans Arabic, Amiri usw.).
  • Nicht abgedeckt in dieser Version: Erweiterte persische/urduische Buchstaben (U+0671..U+06D3); LAM-ALEF Ligaturen (FEFB / FEFC); Mongolisch/Syrisch (unterschiedliche Formgebung); schriftsatzspezifische GSUB-Stilvarianten über das grundlegende 4-Positionen-Modell hinaus.
  • Byte-Stabilität: Standardmäßig ist `AutoShapeArabic` auf `False` eingestellt, sodass alle Aufrufer in den Versionen v2.74 bis v2.84 eine byte-identische `/AP`-Ausgabe erhalten. Aufrufer, die bereits eine Vorab-Formatierung im Upstream-Bereich durchführen (oder einen Shaper auf Konsumentenseite verwenden), sind nicht betroffen.
  • Pipeline-Platzierung: Die Formatierungsoperationen werden in jedem Build*UnicodeFieldContent-Helfer NACH der UTF-8-Dekodierung, aber VOR der bidirektionalen Umkehrung durchgeführt, sodass die formatierten Anzeigeelemente korrekt in RTL-Reihenfolge umgekehrt werden, wenn auch AutoDetectFormBidi / FormUnicodeRTL aktiviert ist.
  • Noch ausstehende Arbeiten im Zusammenhang mit UAX #9: Das SMP-cmap-Format 12 (Abdeckung von Codepoints ab U+10000 in RegisterUnicodeTTF) muss noch implementiert werden.

2026-05-18 Version 2.84.0

  • Ein dateibasierter TrueType-Subsetter wurde hinzugefügt, der zum Zeitpunkt von EndDoc ausgeführt wird. Nach RegisterUnicodeTTF + AddTextField sammelt das Dokument für jeden Codepunkt eine Nutzungsmengenangabe während der Erstellung des Unicode-Feldinhalts; EndDoc wandelt die verwendeten Codepunkte in Glyphen-IDs um, durchläuft die Glyphen-Kompositstruktur und erstellt das eingebettete Schriftprogramm nur mit diesen Glyphen neu. Das rohe v2.82-Embedding wurde ersetzt; die verbleibende Tabellenstruktur bleibt gültig, da der Subsetter die Glyphen-IDs unverändert lässt (nur Komprimierung von glyf/loca).
  • Direkter Einfluss auf den Benutzer: PDFs mit eingebetteten Unicode-TTFs werden drastisch kleiner. Ein "Hello World"-Dokument mit eingebetteter Arial-Schriftart wurde in Version 2.82 etwa 350 KB groß; in Version 2.84 reduziert sich die Größe auf etwa 10-15 KB. CJK-Schriftarten mit den typischen 1000-3000 Glyphen werden von etwa 14 MB auf etwa 500 KB-2 MB komprimiert.
  • Subsetter-Algorithmus: Die Glyphen-IDs bleiben unverändert, sodass cmap, hmtx, /CIDToGIDMap und /W gültig bleiben. Für jeden Glyphenindex von 0 bis numGlyphs-1 kopiert die neue glyf-Tabelle entweder die ursprünglichen Bytes (falls verwendet) oder gibt einen leeren Eintrag über loca[i+1] = loca[i] aus (falls nicht verwendet). Das loca-Format (kurz/lang, abhängig von head.indexToLocFormat) bleibt erhalten. Die Prüfsummen pro Tabelle und head.checksumAdjustment werden für eine streng konforme TTF-Validierung neu berechnet.
  • Verbesserte Behandlung von zusammengesetzten Glyphen: Wenn ein verwendetes Glyphe `numContours == -1` (zusammengesetzt) hat, durchläuft der Subsetter die Liste seiner Komponenten (parst die Flags, den `glyphIndex` und optionale Argumente/Transformationen jeder Komponente), markiert die verwendeten Komponenten und iteriert, bis keine neuen Glyphen hinzugefügt werden. Eine Überprüfung der Grenzen stellt sicher, dass fehlerhafte Ketten von zusammengesetzten Glyphen keine Endlosschleifen verursachen.
  • Konformität mit den Spezifikationen: Der Eintrag "/BaseFont" im Type 0-Dictionary, der descendente "CIDFontType2" und der Eintrag "/FontName" im FontDescriptor erhalten alle ein 6-Buchstaben-Präfix "AAAAAA+", das aus einem deterministischen FNV-1a-Hash des verwendeten Glyphen-Satzes abgeleitet wird. Gemäß Spezifikation 9.6.4 gibt das Präfix an, dass das Schriftprogramm reduziert wurde; ohne dieses Präfix warnen spezifikationskonforme Leser vor Änderungen an eingebetteten Schriftarten.
  • Infrastruktur zur Nutzungserfassung: Ein Array vom Typ `FUnicodeUsedCps[]` mit 65536 Einträgen, das als Boolescher Wert gespeichert wird, wird bei der ersten Ausführung von `RegisterUnicodeTTF` initialisiert. Jeder der drei Helfer (`BuildUnicode*FieldContent` für einzeilige, mehrzeilige und kombinierte Inhalte) markiert Codeeinheiten, während UTF-16BE-Hex-Operanden mit `Tj` ausgegeben werden. `SetFormUnicodeFontDict('', nil)` und ein zukünftiges `BeginDoc`-Reset löschen den Zustand.
  • Fehlersichere Ausfallsicherheit: Jeder Subsetting-Schritt, der nicht abgeschlossen werden kann (fehlende Tabellen, fehlerhafte Lokalisierungsdaten, Fehler bei der Komposit-Verschlüsselung, Komprimierungsfehler), lässt die unbearbeitete Einbettung von v2.82 unverändert. Die PDF-Datei bleibt gültig; nur die Dateigröße wird beeinträchtigt. Dies bewahrt die Zuverlässigkeitsgarantie von v2.82 und bietet gleichzeitig den Vorteil des Subsettings im Erfolgsfall.
  • Was in diesem Abschnitt NICHT enthalten ist: OpenType GSUB für arabische/syrische/devanagari Schriftarten mit kontextabhängigem Zusammenschluss; SMP cmap-Format 12 (immer noch nur BMP). Beides wird für Version v2.85+ bereitgestellt.

2026-05-18 Version 2.83.0

  • Zu PDF 1.7 ISO 32000-1 9.10.3 wurde eine /ToUnicode CMap zu RegisterUnicodeTTF hinzugefügt. Das Font-Dictionary vom Typ 0 enthält jetzt einen indirekten Verweis auf einen Adobe-Identity-UCS CMap-Stream, sodass PDF-Reader Unicode-Text aus der PDF-Datei extrahieren können. Ohne /ToUnicode würden PDF-Dateien in den Versionen 2.74 bis 2.82 beim Kopieren rohe CID-Indizes anstelle von Unicode-Codepunkten liefern; Bildschirmleseprogramme konnten den Inhalt nicht vorlesen; die PDF/A-Konformität schlug fehl.
  • CMap-Struktur: Minimale Adobe-Identity-UCS-CMap mit /CIDSystemInfo (Adobe / UCS / 0), /CMapName /Adobe-Identity-UCS, /CMapType 2, einem einzigen Codespace-Bereich, der <0000>..<FFFF> abdeckt, und einem einzigen bfrange, der <0000> <FFFF> auf <0000> (Identität) abbildet. Der PostScript-CMap-Text wird durch FlateDecode auf etwa 150 Bytes komprimiert, sodass der Einbettungs-Overhead vernachlässigbar ist.
  • Die Begründung für die Identitätszuordnung: Unsere Konfiguration von v2.74 bis v2.82 verwendet Identity-H + Adobe-Identity-0 + CID = Unicode-Codepunkt, sodass die umgekehrte Zuordnung ToUnicode tatsächlich eine Identitätszuordnung für den gesamten BMP ist. Ein einzelner `bfrange`-Eintrag erfasst die gesamte Zuordnung; es ist keine `bfchar`-Liste für jeden einzelnen Codepunkt erforderlich.
  • Sichtbare Auswirkungen für den Benutzer: Die Textauswahl und das Kopieren/Einfügen aus PDF-Readern (Adobe, Foxit, Chrome PDF-Viewer) erzeugen jetzt die ursprünglichen Unicode-Codepunkte anstelle von CID-Müll. Bildschirmleseprogramme (NVDA, JAWS, VoiceOver) können den Textinhalt von AcroFormen für Barrierefreiheit vorlesen. Die Einhaltung der PDF/A-1/2/3-Standards wird möglich (PDF/A erfordert "/ToUnicode" für alle Type 0-Schriftarten).
  • Pipeline-Platzierung: Die Generierung von "/ToUnicode" erfolgt AUSSERHALB des `try/except`-Blocks für `WArrayValid`, da die Identitätszuordnung nicht davon abhängt, ob das Parsen der cmap erfolgreich ist. Selbst wenn "/W", "/CIDToGIDMap" und "/FontFile2" aufgrund beschädigter Schriftentabellen stillschweigend übersprungen würden, würde die ToUnicode-cmap weiterhin generiert und ist semantisch korrekt.
  • Stream-Objekt: indirektes THPDFStreamObject + /Filter /FlateDecode (kein /Length1, da ToUnicode ein Text-Stream und kein Schriftprogramm ist). An das Type 0 Wrapper-Dictionary über Result.AddValue('ToUnicode', ...) angehängt. Verwendet das gleiche zlib-Komprimierungsmuster wie v2.77 /CIDToGIDMap und v2.82 /FontFile2.
  • Was in diesem Bereich NICHT enthalten ist: Einträge für einzelne Codepunkte (bfchar), die eine Zuordnung von nicht-identischen CIDs zu mehrteiligen Unicode-Sequenzen ermöglichen würden (z. B. fi -> f+i), aber unsere Identity-Konfiguration benötigt dies nicht; SMP-Abdeckung über den BMP-Bereich hinaus (immer noch der Bereich 0x0000..0xFFFF). Beides wird für v2.84+ verschoben.

2026-05-18 Version 2.82.0

  • Zu RegisterUnicodeTTF wurde die Möglichkeit hinzugefügt, eine rohe Schriftart gemäß PDF 1.7 ISO 32000-1 9.6.4 + 9.9 als /FontFile2 einzubetten. Das eigentliche Schriftartprogramm (die binären TTF-/OTF-Bytes) wird nun innerhalb der PDF-Datei als /FontFile2-Stream an den FontDescriptor angehängt, sodass Leseprogramme den Namen /BaseFont nicht mehr über den OS-/App-Schriftart-Cache auflösen müssen. Ergebnis: Eine eigenständige PDF-Datei, die auf Systemen ohne die angegebene Schriftart korrekt dargestellt wird.
  • Stream-Struktur: indirektes THPDFStreamObject mit /Filter /FlateDecode und /Length1 = unkomprimierte Schriftdateigröße (gemäß Spezifikation Tabelle 124). Die Komprimierung verwendet TZCompressionStream (zcDefault, windowBits 15) und folgt dem Muster v2.77 /CIDToGIDMap. Typische lateinische TTF-Schriftarten werden 30-50 % komprimiert (z. B. 700 KB Arial -> 350 KB komprimiert eingebettet).
  • Pipeline-Integration: Die Ausgabe erfolgt im selben WArrayValid-Zweig wie die Arrays /W (Version 2.75) und /CIDToGIDMap (Version 2.77). Wenn die cmap-Analyse fehlschlägt (beschädigte Untertabelle / nicht unterstütztes Format), werden alle drei Feature-Streams gemeinsam übersprungen, um einen reibungslosen Übergang zu den Metrik-basierten Ergebnissen von Version 2.74 zu ermöglichen.
  • Sichtbare Auswirkungen: PDFs in den Versionen v2.74 bis v2.81 waren technisch gesehen zusammengesetzte Schriftarten vom Typ 0 / CIDFontType2, aber das Schriftartprogramm fehlte. Lesegeräte mussten den /BaseFont (PostScript-Name) mit ihrem eigenen Schriftartcache abgleichen. Auf Systemen, auf denen die exakt benannte Schriftart installiert war, funktionierte die Darstellung; auf Systemen ohne diese Schriftart ersetzte der Lesegerät entweder eine andere Schriftart (was zu falschen Glyphen / Metriken führte) oder zeigte Platzhalterfelder an. Version 2.82 enthält das Schriftartprogramm direkt in der PDF-Datei – das gleiche Schriftartprogramm, das der Ersteller in RegisterUnicodeTTF verarbeitet hat – sodass die Darstellung durch den Lesegerät deterministisch ist, unabhängig von der Verfügbarkeit von Schriftarten im Betriebssystem.
  • Kompromiss: PDFs werden pro eingebetteter Schriftart um etwa 150–500 KB größer (komprimierte Größe); CJK-Schriften fügen 2–20 MB (komprimiert) hinzu. Dies vermeidet die gleiche Speicherplatzverschwendung durch Schriftartsubstitution auf der Client-Seite, allerdings auf Kosten einer nicht deterministischen Darstellung. Das Extrahieren von Teilmengen (ab Version v2.83) reduziert diesen Speicherplatzbedarf, indem ungenutzte Glyphen aus dem eingebetteten Programm entfernt werden.
  • Spezifische Anmerkungen: In unserer Version 2.82 behält der Eintrag "/BaseFont" den ursprünglichen PostScript-Namen bei (kein "AAAAAA+"-Teilzeichenpräfix), da wir die vollständige Schriftart einbetten. Das 6-Buchstaben-Präfix gemäß Spezifikation 9.6.4 gilt nur, wenn das Schriftartprogramm reduziert wurde; in Version 2.83 und höher wird das Präfix als Teil der Integration des Reduzierers hinzugefügt.
  • Was in dieser Version NICHT enthalten ist: Schriftart-Subsetting (d.h. eine einzelne eingebettete Schriftart fügt die vollständige Dateigröße zur PDF-Datei hinzu). ToUnicode-CMaps (für PDF/A-Kopieren und -Einfügen). SMP-CMaps im Format 12 (Codepunkte ab U+10000 sind weiterhin nicht zugeordnet). All dies wird für v2.83+ bereitgestellt.

2026-05-18 Version 2.81.0

  • Die UAX #9 W4 (Trennzeichen zwischen Ziffern) und W5 (Terminator neben Ziffer) wurden in den LTR-Absatz-Umordnungs-Pfad integriert. Zuvor war dies nur für RTL-Texte verfügbar (seit v2.72.0 / v2.73.0); in v2.81 wurden beide Durchgänge in die gemeinsamen Hilfsfunktionen `_ApplyUAX9W4Rules` und `_ApplyUAX9W5Rules` extrahiert, sodass beide Absatzrichtungen die gleichen schwachen Transformationsregeln anwenden.
  • Refaktorierung: Der RTL-Pfad, Schritt 1b (W4) und Schritt 1c (W5), wurde umstrukturiert, wobei der Inline-Code durch einzelne Hilfsfunktionen ersetzt wurde. Diese Funktionen nehmen den Wide-String und das Klassen-Array entgegen und modifizieren das Klassen-Array direkt; die Logik ist identisch mit den Inline-Implementierungen in den Versionen v2.72/v2.73, sodass die RTL-Ausgabe während der Refaktorierung byte-stabil bleibt.
  • Der LTR-Pfad fügt Schritt 1c (W4) und Schritt 1c.2 (W5) zwischen der W1-NSM-Vererbung (Schritt 1b) und W7 EN-preceded-by-L (Schritt 1d) ein. Nachfolgende N-Regeln (Schritt 1e) und die I-Regel (Schritt 1f) wurden neu nummeriert, um die Reihenfolge der Verarbeitung explizit zu halten.
  • Sichtbare Auswirkungen von LTR: In gemischten LTR-Kontexten, in denen ein RTL-Starkelement einem Ziffern-/ET-Ausdruck vorausgeht, platziert W5 jetzt das ET vor dem N1, wodurch dieses nicht mehr in den R-Run aufgenommen wird. Beispiel: "Hi shin $1" (LTR-Absatz mit einem eingebetteten hebräischen "shin"-Buchstaben, gefolgt von "$1") erzeugte zuvor "Hi $ shin 1", wobei das "$" in den R-Run gezogen und mit "shin" vertauscht wurde. In v2.81 wird "Hi shin $1" erzeugt, wobei "$" direkt neben der Ziffer bleibt. Das Gleiche gilt für W4: "Hi shin $1,2 widgets" behält "$1,2" als logische Einheit bei, anstatt sie um das Komma herum aufzuteilen.
  • In LTR-Pfaden wurden byteweise Stabilitätsverbesserungen vorgenommen: Reine LTR-Eingaben ohne vorhergehende R-Elemente (z. B. "12.345 Widgets") zeigen keine sichtbaren Änderungen, da W7 sor=L bereits alle EN-Elemente in L konvertiert; LTR-Eingaben, die nur L- und RTL-Elemente enthalten, ohne Ziffern oder ET-Elemente, sind ebenfalls unbeeinflusst. Bestehende LTR-Tests (smoke_bidi_n_rules_ltr, smoke_bidi_ltr_reorder) in Version 2.79 bestehen weiterhin byteweise.
  • Die Pipeline-Reihenfolge (RTL-Pfad unverändert): W1 -> W4 -> W5 -> W7 -> N0 -> N1 -> N2 -> I2 -> L2. Der LTR-Pfad ist jetzt: W1 -> W4 -> W5 -> W7 -> N0 -> N1 -> N2 -> I-Regel -> L2. Beide Pfade verwenden die gleichen Helfer für W4/W5/W7/N; nur die Klassifizierung (Schritt 1a) und die abschließende L2-Verarbeitung unterscheiden sich zwischen RTL und LTR.
  • Weitere Arbeiten an UAX #9 sind noch ausstehend: Dazu gehören die OpenType GSUB-Funktionen für arabische, syrische und Devanagari-Schriften sowie die Implementierung von RegisterUnicodeTTF (einschließlich ToUnicode CMap, SMP cmap im Format 12 und /FontFile2 mit Subsetting).

2026-05-18 Version 2.80.0

  • Es wurde die Unicode UAX #9 W7 European Number Bridging-Funktion hinzugefügt: Eine Zahl, bei der die Rückwärtssuche ein starkes L (oder sor=L, wenn die Suche den Anfang des Absatzpuffers erreicht) findet, wird zu L. Diese Transformation wird nach W4 (Trennzeichen zwischen Ziffern) und W5 (Terminator neben Ziffer) sowohl auf RTL- als auch auf LTR-Absatzpfaden ausgeführt, sodass jedes Trennzeichen, das von W4 zu einer EN befördert wurde, ebenfalls der L-Bridging-Funktion unterliegt.
  • Sichtbare Auswirkungen von RTL: Eine Eingabe wie ""Hello 123 Arabic"" in einem RTL-Absatz erzeugte zuvor die visuelle Anordnung ""Arabic SP 123 SP Hello"", da der EN-Textblock zwischen L (Hello) und AL (Arabic) lag und die N-Regeln den LTR-Textblock in zwei unabhängige Textblöcke aufteilten (mit einem Leerzeichen auf der Einfügungsebene zwischen ihnen). In Version 2.80 konvertiert W7 den EN-Textblock in L (da L vorher steht), und N1 nimmt das führende Leerzeichen zwischen Hello und 123 in den L-Textblock auf; der gesamte Text ""Hello 123"" wird zu einer Ebene-2-Teilzeichenkette, die als Einheit umgekehrt wird. Die endgültige visuelle Anordnung wird zu ""Arabic SP Hello SP 123"", was dem strikten UAX #9-Verhalten entspricht.
  • W7 wird nicht ausgelöst, wenn: die dem EN am nächsten stehenden starken Zeichen R oder AL sind (arabische Buchstaben stehen vor den Ziffern); das EN am Anfang des Puffers in einem RTL-Absatz steht (sor=R); oder es nirgendwo vor dem EN ein L vorhanden ist. Das Verhalten vor Version 2.80 wird in diesen Fällen beibehalten – die Baseline-Offsets W4/W5 der Versionen 2.72/2.73 bleiben byte-stabil.
  • LTR-Absatz-Effekt: W7 funktioniert auch auf dem LTR-Pfad (für Speicherkonsistenz), wobei sor=L ist, wenn der Scan den Pufferstart erreicht. Unter HotPDFs vereinfachter LTR-Regel für Single-Embedding landen sowohl L als auch EN auf Level 0, sodass die Transformation von EN zu L die Levels[]-Array nicht direkt ändert, aber sie ändert das N1-Absorptionsmuster: Ein Leerzeichen zwischen L und einem L-verknüpften EN erfüllt nun N1s Bedingung für die gleiche Richtung und wird dem Lauf hinzugefügt. Für reine LTR-Eingaben ohne interne RTL-Elemente ist die Änderung eine byte-stabile, keine Operation; für LTR-Eingaben, die abschließende RTL-Elemente enthalten (z. B. "Hello 123 shalom"), verschiebt sich die Position des Leerzeichens relativ zum RTL-Block um eine Position.
  • W6 (residual ES/CS/ET -> ON gemäß strenger UAX #9) ist in der vereinfachten Klassen[]-Tabelle von HotPDF implizit: ES, CS, ET, WS und ON teilen sich alle Klasse 0 (bcOther), und die N-Regeln behandeln Klasse 0 einheitlich. Die Umwandlung von W6 in ON ist in unserem Modell eine No-Op-Operation, da N1/N2 keine Unterscheidung zwischen ON und WS treffen. Dies ist in dem Code-Kommentar neben der W7-Hilfsfunktion dokumentiert.
  • Pipeline-Reihenfolge (von rechts nach links): W1 NSM-Vererbung -> W4 ES/CS zwischen Ziffern -> W5 ET neben Ziffern -> W7 EN, vorangestellt von L -> N0 gepaarte Klammern -> N1 Absorption in die gleiche Richtung -> N2 Standard-zu-Einbettung -> I2 Level-Zuweisung -> L2 Umkehrung der Umkehrung. Die gleiche Reihenfolge gilt für den von links nach rechts gerichteten Pfad, wobei W4/W5 fehlen (diese bleiben in diesem Bereich nur für von rechts nach links gerichtete Texte; die von links nach rechts gerichtete Version von W4/W5 ist der nächste Kandidat).
  • Die neue gemeinsame Hilfsfunktion `_ApplyUAX9W7Rules(Classes, ParaIsRTL)` arbeitet direkt auf dem Array `Classes[]`. Die Rückwärtssuche überspringt schwache/NSM/EN/AN-Positionen; nur L/R/AL werden als starke Typen berücksichtigt. Wenn die Suche keine starke Position findet, wird die Absatzrichtung (sor) als impliziter starker Typ verwendet. Der RTL-Pfad übergibt `ParaIsRTL=True`, der LTR-Pfad übergibt `False`.
  • Weitere Arbeiten an UAX #9 sind noch ausstehend: Portierung des LTR-Pfads für W4/W5 (derzeit nur RTL), OpenType GSUB für arabische/syrische/devanagari-kontextuelle Verbindungen und weitere Arbeiten im Zusammenhang mit RegisterUnicodeTTF (ToUnicode CMap, SMP cmap Format 12, /FontFile2 + Subsetting).

2026-05-18 Version 2.79.0

  • Die Regeln von v2.78.0 für N0/N1/N2 wurden in den Pfad zur Umordnung von Absätzen von links nach rechts (LTR) übernommen. Dies behebt einen Fehler, bei dem eine mehrteilige RTL-Phrase, die in einem LTR-Absatz eingebettet ist (z. B. ein englischer Satz, der mehrere hebräische oder arabische Wörter enthält, die durch Leerzeichen getrennt sind), für einen RTL-Leser optisch vertauschte Wörter aufwies, da der Abstand zwischen den Wörtern auf Ebene 0 blieb und die RTL-Phrase in unabhängige R-Blöcke aufteilte. Mit v2.79 N1 wird der Abstand in den umgebenden R-Block aufgenommen; die gesamte Phrase wird zu einer Substring-Ebene 1, und die umgekehrte Ebene 2 behält die Wörter in logischer Reihenfolge.
  • Der Pfad für Absätze von links nach rechts (LTR) (`_ApplyUAX9L2ReversalLTRPara`) wurde umstrukturiert, um die Anordnung des Pfads von rechts nach links (RTL) widerzuspiegeln: Jeder UTF-16-Codeeinheit wird in ein Byte-Array namens `Classes[]` klassifiziert, dann wird die Vererbung von W1 NSM auf `Classes[]` angewendet (vor v2.79 wurde `Levels[]` verwendet), und anschließend wird eine gemeinsame Hilfsfunktion `_ApplyUAX9NRules` aufgerufen, die `Classes[]` unter Verwendung eines Parameters für die Einbettungsrichtung verarbeitet (1 = L für LTR, 2 = R für RTL). Die Regel I leitet dann `Levels[]` aus `Classes[]` ab. Sowohl der RTL- als auch der LTR-Pfad verwenden jetzt eine einzige Implementierung der N-Regeln.
  • Die Hilfsfunktion `_ApplyUAX9NRules(Wide, Classes, EmbedDirCls)` akzeptiert die Einbettungsrichtung als einen Klassenwert (1 oder 2) und wendet die N0-Paarungsregeln für eckige Klammern, die N1-Regel für die Absorption von Zeichen in die gleiche Richtung und die N2-Regel für die einheitliche Standardeinstellung zur Einbettung an. Der RTL-Pfad verwendet den Wert 2 (R); der LTR-Pfad verwendet den Wert 1 (L). Das Verhalten auf der RTL-Seite von Version 2.78 wird bytegenau beibehalten.
  • Sichtbare Auswirkungen auf die linke Seite (LTR): "Hi shalom olam World" wurde zuvor mit den beiden hebräischen Wörtern in umgekehrter Reihenfolge ausgegeben (jedes Wort einzeln korrekt, aber ihre RELATIVEN Positionen vertauscht). In Version 2.79 wird die logische Wortreihenfolge beibehalten, sodass ein Leser von rechts nach links (RTL) "Hi shalom olam World" mit dem hebräischen Abschnitt in der erwarteten Reihenfolge sieht. Die gleiche Korrektur gilt für mehrteilige RTL-Phrasen, die in Klammern eingeschlossen sind, dank der Zusammenarbeit von N0 und N1.
  • Die Reihenfolge der Verarbeitung im LTR-Pfad (Spiegelung des RTL-Pfads): Klassifizierung in Klassen[] -> Vererbung von W1 NSM -> N0 gepaarte Klammern -> N1 Absorption in derselben Richtung -> N2 Standard-zu-Embedding -> I-Regel (Ableitung von Levels[]) -> L2 Umkehrung der Level-1-Läufe. Die W4/W5-Ziffernverarbeitungsschritte sind noch nicht in den LTR-Pfad portiert; LTR-Absätze mit Ziffern-plus-Trennzeichen-Kombinationen werden weiterhin unverändert über die N-Regeln verarbeitet.
  • In bestehenden LTR-Tests bleiben die Byte-Werte stabil: reiner LTR-ASCII-Text, einzelne RTL-Wörter in LTR-Absätzen sowie die Mischung aus RTL und LTR ohne Leerzeichen zwischen RTL-Wörtern erzeugen alle identische Levels[]-Arrays nach der Refaktorierung (der W1 NSM-Vererbungs-Schritt ist beobachtbar äquivalent, unabhängig davon, ob er auf Levels[] oder Classes[] angewendet wird). Die LTR-Tests v2.67, v2.69 und v2.71 bestehen weiterhin byteidentisch.
  • Weitere ausstehende Arbeiten im Zusammenhang mit UAX #9: Abschließende kleinere Bereinigungen für W6/W7, Behandlung von Ziffern in W4/W5 auf dem LTR-Pfad (derzeit nur RTL), OpenType GSUB für arabische/syrische/devanagarische kontextuelle Verbindungen und weitere Arbeiten im Zusammenhang mit RegisterUnicodeTTF (ToUnicode CMap, SMP cmap im Format 12, /FontFile2 + Subsetting) sind noch erforderlich.

2026-05-18 Version 2.78.0

  • In der RTL-Absatzreihenfolge-Pipeline wurden die Unicode UAX #9-Vereinfachungen für die Paarenthesenauflösung sowie die N1-Neutralisierungs- und N2-Standard-Einfüge-Regeln hinzugefügt. Dies behebt einen sichtbaren Fehler, bei dem eine mehrteilige LTR-Phrase, die in einem RTL-Absatz eingebettet ist (z. B. Hebräisch oder Arabisch, das englischen Text mit Leerzeichen umschließt), mit umgekehrten Wörtern ausgegeben wurde, da der Abstand zwischen den L-Läufen auf der Einbettungsebene verblieb und die LTR-Phrase in unabhängige Unterläufe aufteilte. Mit N1 wird der Abstand in den umgebenden L-Lauf aufgenommen, sodass die gesamte Phrase zu einer Ebene-2-Unterkette wird, und L2-Umkehrung behält sie in logischer Reihenfolge.
  • Keine Klammern: 22 BMP-Klammerpaare werden abgedeckt, von ASCII-Klammern (runde, eckige, geschweifte) bis hin zu mathematischen/typografischen Symbolen (Deckelung, Fuß, Winkel, weiße Quadratklammer, geschweifte Klammer) und CJK-Satzzeichenklammern (Winkel, Doppelwinkel, Ecke, weiße Ecke, schwarze Linse, Schildpatt, weiße Schildpatt, weiße Quadratklammer) bis hin zu Vollbreitformen. BD16 verwendet eine stapelbasierte Paarklammererkennung (maximal 63 Einträge pro Spezifikation); die Paarlösung scannt innerhalb, um die erste starke Richtung (L, R, AL, EN, AN) zu finden (wobei EN/AN gemäß Spezifikation als R zählen), wobei ein Rückfallmechanismus zum Vorabprüfen vor der öffnenden Klammer verwendet wird, falls sich die innere Richtung von der Einbettungsrichtung unterscheidet.
  • N1-Absorption: Durchsucht Klassenarrays, um die längstmöglichen Sequenzen von `bcOther` (neutral) zu finden, identifiziert linke und rechte starke Typen, die keine NSM-Typen sind, und wenn beide Seiten die gleiche Richtung aufweisen (entweder beide links oder beide rechts – wobei EN/AN als rechts gezählt werden), wird die gesamte Sequenz in diese Richtung eingeordnet. Auswirkungen in der Praxis: Leerzeichen, Kommas, Punkte und Doppelpunkte innerhalb englischer Phrasen, die in arabischen oder hebräischen Absätzen eingebettet sind, werden jetzt mit der Phrase selbst gruppiert, anstatt sie aufzuteilen.
  • N2 standard: Die verbleibenden bcOther-Positionen (ohne umgebende starke Formatierung oder nicht übereinstimmende linke/rechte Formatierung) übernehmen die Einbettungsrichtung. Für Textabsätze in RTL-Ausrichtung ist dies R; Klasse 2. Nach N2 befindet sich jeder Eintrag in dem Array Classes[] im aufgelösten Satz {1..6}, sodass die Zuweisung der I2-Ebene nicht mehr davon abhängt, dass bcOther standardmäßig auf Ebene 1 gesetzt ist.
  • Sichtbare Auswirkungen: Zuvor gab HotPDF die Zeichenkette ""aleph aleph SP a b c SP d e f SP aleph aleph"" aus (logische Eingabe mit dem englischen Ausdruck ""abc def"" in einem rechts-nach-links-Absatz) als ""aleph aleph SP d e f SP a b c SP aleph aleph"", wobei die Wörter vertauscht waren, weil der Abstand zwischen den Wörtern auf Ebene 1 (= Einbettung von RTL) lag. In Version 2.78 wird die Zeichenkette ""aleph aleph SP a b c SP d e f SP aleph aleph"" mit dem intakten Ausdruck ausgegeben. Klammern um den eingebetteten Ausdruck werden jetzt korrekt über N0 + L4-Spiegelung beim Konsumenten aufgelöst.
  • Pipeline-Reihenfolge: W1 NSM-Vererbung -> W2/I2 (EN/AN-Klassenzuweisung in der BIDI-Tabelle, nicht in diesem Durchlauf) -> W4 ES/CS zwischen Ziffern -> W5 ET neben Ziffern -> N0 gepaarte Klammern -> N1 Absorption in gleicher Richtung -> N2 Standard-Einbettung -> I2 Level-Zuweisung -> L2 Umkehrung der Umkehrung. Die N-Regeln werden zwischen den W- und I-Regeln platziert; die Ausgaben der vorhandenen W-Regeln dienen als Eingabe für die N-Regeln.
  • Für bestehende Schriftarten, die keine mehrteiligen Links-nach-Rechts-Phrasen innerhalb von Rechts-nach-Links-Text enthalten, ist die Byte-Stabilität gewährleistet: reiner Rechts-nach-Links-Text, reiner Links-nach-Rechts-Text (die Funktion gibt die Eingabe zurück), einzelnes Links-nach-Rechts-Wort in Rechts-nach-Links-Text (keine internen Neutralzeichen, die absorbiert werden), Arabisch + formatierte Ziffern mit Leerzeichen + Komma (Leerzeichen wechseln von bcOther zu einem Rechts-nach-Links-Äquivalent, bleiben aber auf derselben Ebene, sodass die umgekehrte Ausgabe von L2 unverändert bleibt). Die Basis-Schriftarten v2.66, v2.67, v2.68, v2.71, v2.72 und v2.73 bestehen weiterhin die Byte-Identitätsprüfung.
  • Weitere Arbeiten an UAX #9: Abschließende kleinere Bereinigungen für W6/W7, Spiegelung von N-Regeln für LTR-Absätze (mehrteilige RTL-Phrase in einem LTR-Absatz), OpenType GSUB für kontextuelle Verbindungen für Arabisch/Syrisch/Devanagari und weitere Arbeiten im Zusammenhang mit RegisterUnicodeTTF (ToUnicode CMap, SMP cmap Format 12, /FontFile2 + Subsetting) sind noch ausstehend.

2026-05-18 Version 2.77.0

  • In RegisterUnicodeTTF wurde der PDF 1.7 ISO 32000-1 9.7.4.2 /CIDToGIDMap-Stream hinzugefügt. Jeder Unicode-Codepunkt (CID) im BMP wird jetzt auf den tatsächlichen Glyphenindex innerhalb des eingebetteten Schriftprogramms abgebildet. Vor Version v2.77 führte die Konfiguration von HotPDFs Typ 0 / CIDFontType2 + Identity-H dazu, dass der /CIDToGIDMap-Eintrag nicht angegeben wurde, was standardmäßig zu /Identity gemäß der Spezifikation führt. Der lesende Client indizierte dann die Glypentabelle der Schriftart direkt anhand des CID, was für fast jedes Zeichen die falsche Glyphe auswählte, da die tatsächlichen Glypentabellen der Schriftart selten den Glyphenindex N mit dem Unicode-Codepunkt N in Einklang bringen.
  • Die Implementierung verwendet die bereits für das /W-Array in Version 2.75 durchgeführte cmap-Analyse. Die CpToGid[0..$FFFF]-In-Memory-Tabelle wird als ein 131072-Byte-Stream serialisiert (2 Bytes Big-Endian pro CID) und mit FlateDecode komprimiert; die typische Reduzierung der Dateigröße für echte Schriftarten beträgt 80-95 %, da die überwiegende Mehrheit der BMP-Codepunkte keine Glyphe hat und als 0x0000 serialisiert wird. Der komprimierte Stream wird als indirekter /CIDToGIDMap-Eintrag im abgeleiteten CIDFontType2-Dictionary angehängt.
  • Sichtbare Auswirkungen: Eine PDF-Datei, die mit RegisterUnicodeTTF + SetFormUnicodeFontDict + AcroForm-Textfeldern generiert wurde, zeigt jetzt die gleichen Glyphen im Wiedergabegerät wie die ursprüngliche Schriftart. PDF-Dateien vor der Version v2.77, die auf das /Identity-Standardverfahren angewiesen sind, zeigten bei streng standardkonformen Wiedergabegeräten eine deutlich falsche Darstellung (zufällige Glyphen anstelle der beabsichtigten lateinischen Zeichen, Ziffern oder Satzzeichen). Wiedergabegeräte, die stattdessen auf die Interpretation der cmap-Datei anhand von Unicode zurückgreifen, zeigten zwar korrekt, taten dies aber durch ein nicht standardmäßiges Verhalten.
  • Pipeline-Platzierung: Die Erstellung von /CIDToGIDMap erfolgt innerhalb des gleichen WArrayValid-Zweigs, der /W erstellt, sodass die beiden Elemente die gleiche cmap-Verarbeitung nutzen und nur der zweite Komprimierungsschritt neu ist. Wenn die Parsierung von cmap, hmtx oder maxp fehlschlägt, wird ein stiller Fallback verwendet, der sowohl /W als auch /CIDToGIDMap überspringt; der aufrufende Reader sieht dann das Dictionary vor v2.77 und greift auf seine Standard-cmap-Interpretation zurück.
  • Was in dieser Version NICHT enthalten ist (wird für v2.78+ verschoben): SMP cmap-Format 12 (Codepunkte ab U+10000 werden weiterhin auf GID 0 in der Tabelle abgebildet), Einbettung des `/FontFile2`-Streams (der Leseprogramm löst weiterhin den `/BaseFont`-Namen über seine eigene Schriftartzuordnung), Schriftart-Subsetbildung (die rohe 128-KB-Zuordnung ist eine vollständige Zuordnung) und eine ToUnicode-Zuordnung für das Kopieren/Einfügen und die Barrierefreiheit.

2026-05-18 Version 2.76.0

  • Die v2.75.0 TTF-Breiteninformationen wurden in den eigenen Multiline-Textumbruchalgorithmus von HotPDF integriert. Der Helfer v2.65.0 BuildUnicodeMultilineFieldContent.CodeUnitAdvance verwendet jetzt einen Cache für die Breitenwerte pro Codepunkt, der von RegisterUnicodeTTF gefüllt wird, und ersetzt die bisherige Heuristik für schmale/breite Zeichen durch die tatsächlichen Glyphenmetriken. Zeilenumbrüche, die auf der Produzenseite erfolgen, stimmen jetzt mit der Darstellung auf der Konsumentenseite überein: Der Umbruchpunkt, den HotPDF auswählt, entspricht dem Punkt, an dem der Konsument den Text tatsächlich umbricht, wenn der /Tj-Operator verwendet wird.
  • Neue private Felder: `FAcroFormUnicodeAdvances` (ein dynamisches Array von `Word`, mit einer Größe von 65536 oder leer), das die Advance-Breiten pro Codepoint in PDF-Designeinheiten (1000 pro em) speichert. Das Flag `FAcroFormUnicodeAdvancesActive` unterscheidet zwischen einem "durch `RegisterUnicodeTTF` befüllten Cache" und einem "nicht geladenen Font (Heuristik wird verwendet)". `RegisterUnicodeTTF` füllt diese Felder während des gleichen hmtx + cmap-Durchlaufs aus, der das `/W`-Array erstellt, sodass kein zusätzlicher Parsing-Durchlauf erforderlich ist.
  • CodeUnitAdvance-Lookup-Reihenfolge: Wenn FAcroFormUnicodeAdvancesActive aktiviert ist und der Cache einen nicht-null-Wert für die Codeeinheit enthält, teilen Sie die skalierte Breite durch 1000,0 und geben Sie das Ergebnis als em-Bruch zurück; andernfalls wird die Heuristik von v2.65 angewendet (schmal für ASCII / Latin-1, breit für CJK / Hangul / Hiragana / Katakana / Breitformat). Die Hälften von Surrogate-Paaren werden weiterhin über die Heuristik verarbeitet, da der Cache nur BMP-Zeichen unterstützt.
  • Cache-Lebenszyklus: Wird bei THotPDF.Create gelöscht (standardmäßig leer/inaktiv), wird bei SetFormUnicodeFontDict('', nil) gelöscht, wenn der Aufrufer die Unicode-Schriftartregistrierung explizit zurücksetzt, und wird bei jedem nachfolgenden Aufruf von RegisterUnicodeTTF neu befüllt. Belegt 128 KB (64.000 Codepunkte * 2 Bytes), nur wenn mindestens eine TTF-Datei geladen wurde; Instanzen, die niemals Unicode-Schriftarten verwenden, verursachen keine Speicherbelastung.
  • RegisterUnicodeFontDict (Version 2.70.0) und RegisterUnicodeTTF (Version 2.74.0) ohne ein /W-Array (z. B. fehlende maxp-, cmap- oder hmtx-Tabellen) lassen den Cache leer/inaktiv, sodass die mehrzeilige Textumbruchfunktion auf die Heuristik von Version 2.65 zurückgreift – die Ausgabe ist byteidentisch zu Version 2.65 für diese Pfade.
  • Sichtbare Auswirkungen: Ein mehrzeiliges AcroForm-Textfeld mit einer typischen lateinischen Schriftart (Arial, Segoe UI, Times) wird jetzt an Zeichengrenzen umbrochen, die mit dem tatsächlichen Layout des verwendeten Leseprogramms übereinstimmen. Ohne die Version 2.76 behandelte die in Version 2.65 verwendete Heuristik jedes ASCII-Zeichen als 0,5 em breit; bei einer echten Schriftart, bei der "M" etwa 0,8 em und "i" etwa 0,3 em breit ist, überschätzt oder unterschätzt die Heuristik um 30-60 %, was dazu führt, dass das Leseprogramm anders umbricht als von HotPDF geplant, was zu Textüberläufen oder zu kurzen Zeilen führt.
  • Die Funktionen `BuildUnicodeTextFieldContent` und `BuildUnicodeCombFieldContent` verwenden weiterhin nicht `CodeUnitAdvance` und sind davon nicht betroffen (bei einzeiligen Textfeldern erfolgt keine Umbruch; bei Kombinationszeichen werden Zellen gleicher Breite verwendet).
  • Was in diesem Abschnitt NICHT enthalten ist: SMP cmap-Format 12 (Codepunkte ab U+10000 werden weiterhin über eine heuristische Methode für die Surrogate-Hälfte verarbeitet), ToUnicode CMap, Einbettung des /FontFile2-Streams, Schrift-Subsetbildung. Diese Funktionen sind in den Versionen v2.77 und höher enthalten.

2026-05-18 Version 2.75.0

  • Aktualisierte Version v2.74.0 von THotPDF.RegisterUnicodeTTF mit Parsing von hmtx, maxp und cmap, sodass die resultierende CIDFontType2-Abkömmlingsschrifttyp ein echtes Array für die Zeichen-spezifische Vorwärtsbreite (/W) enthält. Konsumierende Leser verwenden jetzt echte Schriftmetriken für die Textbreitenberechnung anstelle des Rückfalls auf /DW = 1000 für jedes Glyphe – Text innerhalb eines AcroForm-/AP-Darstellungsstroms nimmt nun die gleiche Breite ein, wie sie von der ursprünglichen Schriftart gerendert würde.
  • Neue Hilfsfunktionen auf Einheitenebene parsen die drei zusätzlichen SFNT-Tabellen: `_TTFParseMaxpNumGlyphs` (liest `numGlyphs` aus `maxp`), `_TTFParseHmtxAdvances` (liest das Array der Zeichen-spezifischen Anstiege aus `hmtx`, dessen Größe durch `numberOfHMetrics` aus `hhea` bestimmt wird) und `_TTFFindAndParseCmap + _TTFParseCmapFormat4` (ermittelt die Zuordnung zwischen Unicode-Codepunkten und Glyphen-IDs über die Subtabelle im Format 4 für den BMP-Bereich). `_TTFBuildWArray` erstellt das spärliche /W-Array im Format 1 gemäß PDF 1.7 Abschnitt 9.7.4.3, wobei aufeinanderfolgende Codepunkte mit nicht-Standardbreite in Gruppen `[startCID [w1 w2 w3 ...]]` zusammengefasst werden, und Codepunkte, deren Breite gleich /DW = 1000 ist, werden übersprungen, um die Größe des Arrays zu reduzieren.
  • Die Auswahl der Cmap-Untertabelle bevorzugt Microsoft Unicode BMP (Plattform 3, Kodierung 1, Format 4) – das universelle Windows-Schriftsatz-Cmap-Layout. Bei plattformübergreifenden OpenType-Schriftsätzen wird auf Unicode-Plattform (0, Kodierung 3 oder 4) zurückgegriffen, dann auf Plattform 3, Kodierung 10 (nur Unicode, Format 4), und schließlich auf jedes andere Format 4. Nicht-Format-4-Untertabelle (Format 0, 2, 6, 8, 12, 13, 14) werden in diesem Bereich ignoriert – die SMP-Abdeckung über Format 12 wird in v2.76+ hinzugefügt.
  • Im Array /W wird über eine direkte Suche dem Dictionary des CIDFontType2-Nachfahren hinzugefügt: Type0 -> /DescendantFonts -> [0] -> AddValue('W', WArray). Die Signatur von RegisterUnicodeFontDict wurde in v2.70 nicht geändert; das Nachfahrdictionary wird nach der Zusammenstellung direkt verändert.
  • Die FUnit-Breiten aus der hmtx-Datei werden unter Verwendung des Werts "unitsPerEm" der Kopfzeile auf PDF-Designeinheiten (1000 pro em) skaliert. Codepoints ohne Glyphenzuordnung (cmap gibt 0 / .notdef zurück) werden als DW = 1000 behandelt und aus dem /W-Array entfernt. Für eine typische lateinische Schriftart (Arial, Segoe UI, Times) enthält das resultierende /W-Array typischerweise 500 bis 1500 Codepoint-Einträge; bei Schriftarten für Chinesisch, Japanisch und Koreanisch kann das Array auf 10.000 oder mehr Einträge anwachsen.
  • Was in dieser Version NICHT enthalten ist (verschoben auf v2.76+): Die Daten für die Breite (/W) werden noch nicht von HotPDFs eigenem Algorithmus für mehrzeilige Textumbruchverarbeitung verwendet – die Funktion `BuildUnicodeMultilineFieldContent` in v2.65 verwendet weiterhin die Heuristik von 0,5/1,0 für die Berechnung von Zeilenumbrüchen; das Array /W dient ausschließlich der Genauigkeit der Darstellung auf der Client-Seite. Die vollständige, perfekte Textumbruchfunktion (die /W zur Berechnung des Umbruchs verwendet) wird in v2.76+ implementiert. Ebenfalls verschoben: Die Umwandlung von cmap-Reverse-Mappings in ToUnicode-CMaps, das Einbetten von Schriftdateien im Stream /FontFile2, das Erstellen von Schriftteilmengen und das SMP-cmap-Format 12.
  • Beim Parsen von `/W` wird ein Try/Except-Fallback verwendet – falls `maxp`, `cmap` oder `hmtx` fehlen oder eine Untertabelle fehlerhaft ist, setzt `RegisterUnicodeTTF` die Verarbeitung stumm mit dem Ergebnis der Metrikversion 2.74 fort; der aufrufende Reader verwendet für jeden Codepunkt den Wert `/DW = 1000`. Es kommt zu keiner stillen Beschädigung: Tabellen werden bei jedem mehrByte-Lesevorgang auf Gültigkeit geprüft.

2026-05-18 Version 2.74.0

  • Es wurde THotPDF.RegisterUnicodeTTF hinzugefügt, eine dateibasierte Wrapper-Funktion für v2.70.0 RegisterUnicodeFontDict, die eine TTF-/OTF-Schriftart lädt, die Header-, hhea-, OS/2-, Post- und Namens-Tabellen analysiert, die FUnit-Metriken in PDF-Designeinheiten (1000 pro em) umrechnet und die Werte an RegisterUnicodeFontDict übergibt, um das vollständige Type 0 / CIDFontType2 + Identity-H-Komposit-Schriftart-Dictionary zu erstellen. Das zurückgegebene Dictionary ist bereit für SetFormUnicodeFontDict – Aufrufer müssen weder die genauen Metrikwerte der Schriftart noch das SFNT-Binärformat kennen.
  • API: RegisterUnicodeTTF(FontPath, LogicalName=""). FontPath ist ein absoluter oder relativer Pfad zu einer .ttf- oder .otf-Datei. LogicalName ist für Version 2.75 und höher reserviert (und kann dort Schriftarten unterscheiden, die denselben PostScript-Namen haben).
  • Analysierte Tabellen: head (unitsPerEm, FontBBox xMin/yMin/xMax/yMax in FUnits), hhea (ascender, descender in FUnits), OS/2 (usWeightClass zur Schätzung von /StemV, sCapHeight, fsSelection für das Kursiv-Bit), post (italicAngle in FIXED 16.16 -> Grad, isFixedPitch -> /Flags Bit 1), name (PostScript-Name mit nameID 6 von Windows oder Mac-Plattform, falls nicht verfügbar, wird der vollständige Name mit nameID 4 verwendet). Überprüfung der Grenzen für jeden Tabellen-Offset/jede Länge sowie für jeden mehrbyte-Lesevorgang, sodass eine fehlerhafte Schriftart als eindeutige Ausnahme angezeigt wird und nicht zu einem Speicherfehler führt.
  • Automatisch abgeleitete Metriken: `/FontBBox L/B/R/T` wird auf PDF-Designeinheiten skaliert, `/Ascent` und `/Descent` werden skaliert, `/CapHeight` wird aus `OS/2 sCapHeight` übernommen (fällt auf `ascent` zurück, wenn die `OS/2`-Tabellen vor Version 2 verwendet werden), `/ItalicAngle` wird aus `post.italicAngle` übernommen, `/StemV` wird geschätzt als 50 + (`usWeightClass` - 400) / 5, begrenzt auf [50, 250], `/Flags` = `Symbolic` + `FixedPitch` (wenn dies in den PostScript-Daten angegeben ist) + `Italic` (wenn das Bit 0 in `fsSelection` gesetzt ist oder `italicAngle` ungleich 0 ist). `/BaseFont` verwendet den geparsten PostScript-Namen; falls der Namensbereich keine brauchbaren Informationen liefert, wird auf `"UnnamedTTF"` zurückgegriffen.
  • Es werden deskriptive Ausnahmen ausgelöst: fehlende Datei, ungültige Größe (kleiner als 12 Bytes oder größer als 64 MB), nicht erkannte sfntVersion (muss 0x00010000 / 'OTTO' / 'true' / 'typ1' sein), fehlende erforderliche Tabellen (head / hhea / OS/2 / post / name), Tabelle zu klein für die benötigten Felder.
  • Diese Version enthält NICHT (wird für v2.75+ verschoben): das Array für die Vorwärtsbreite (/W) aus der hmtx-Datei (benötigt maxp für die Anzahl der Glyphen + cmap für die Unicode-zu-Glyphen-Zuordnung; derzeit verwendet die mehrzeilige Textumbruchfunktion v2.65 ihre Heuristik von 0,5/1,0), eine ToUnicode-CMap aus cmap (derzeit nimmt die Identity-H-Zuordnung ab v2.56 an, dass CID gleich dem Unicode-Codepunkt ist), das Einbetten der rohen Schriftdateibytes als Stream /FontFile2 und das Erstellen von Schriftteilmengen. Mit v2.74.0 muss der aufrufende Reader den Namen /BaseFont weiterhin über seine eigene Schriftzuordnungsmechanik auflösen.
  • Smoke smoke_unicode_ttf.dpr lädt eine Windows-Systemschriftart (durchsucht %SystemRoot%\Fonts nach arial.ttf / segoeui.ttf / times.ttf / verdana.ttf in dieser Reihenfolge) und überprüft, ob RegisterUnicodeTTF ein Dictionary vom Typ 0 zurückgibt, das dateigeprägte Metriken enthält. Der Verifier prüft, ob die resultierende /BaseFont kein Platzhalter ist, und ob FontBBox, Ascent, Descent und ItalicAngle innerhalb plausibler Bereiche für eine echte Schriftart liegen.

2026-05-18 Version 2.73.0

  • Added Unicode UAX #9 simplified W5 (European Terminator adjacent to European Number) for RTL paragraphs. Fixes the visible bug where Arabic text with currency / percent symbols — "$12.50", "50%", "€100", "شار 12.50$ ريال" — left the currency or percent glyph stranded at the boundary between the digit substring and the surrounding RTL text. With v2.73 W5, ETs adjacent to digits join the digit run and reverse with the digits, preserving the currency-and-number unit as one LTR substring inside the RTL paragraph.
  • W5 ETs wurden erkannt (Codepoint-Menge): U+0023 # (Nummernsymbol), U+0024 $ (Dollar), U+0025 % (Prozent), U+00A2..U+00A5 (¢ £ ¤ ¥), U+00B0 ° (Grad), U+00B1 ± (Plus-Minus), U+066A ٪ (Arabisches Prozent), U+2030..U+2031 (‰ ‱ pro Tausend / pro Hunderttausend), U+20A0..U+20CF (Währungssymbolblock, einschließlich € ₹ ₽ ₩ usw.). Eine maximale Folge von ETs, die sich an einer EN auf beiden Seiten befinden (wobei nur NSMs übersprungen werden), wird in EN umgewandelt.
  • Erweiterung für HotPDF: Die vereinfachte W5-Funktion konvertiert zusätzlich zur Standardregel, die nur lateinische Zeichen berücksichtigt, auch ET-Zeichen (Extended Text), die sich neben AN-Ziffern (arabisch-indische Ziffern) befinden, in AN-Ziffern. Dies sorgt für eine symmetrische Behandlung von ASCII- und arabisch-indischen Ziffern, sodass beispielsweise ""٥٠٪"" (arabisch-indische 50 + arabischer Prozent) den Prozentwert genauso behandelt wie ""50%"" den ASCII-Prozentwert.
  • Concrete fix: "شار $12.50 ريال" (logical UTF-16 0634 0627 0631 0020 0024 0031 0032 002E 0035 0030 0020 0631 064A 0627 0644). v2.72 output: 0644 0627 064A 0631 0020 0031 0032 002E 0035 0030 0024 0020 0631 0627 0634 — the $ glyph stranded at memory position 11, between the digit substring and the trailing space, reading awkwardly. v2.73 output: 0644 0627 064A 0631 0020 0024 0031 0032 002E 0035 0030 0020 0631 0627 0634 — "$12.50" intact as one LTR substring inside the RTL flow.
  • BIDI_Class-Tabelle korrigiert: Das Zeichen U+066A ARABIC PERCENT SIGN wurde von bcAL nach bcOther verschoben (damit der W5 ET-Durchlauf es erkennen und transformieren kann). Die arabische Block-Suche enthält jetzt Ausnahmen für die Ziffernbereiche (bcAN), den Harakat-/Shadda-Block (bcNSM), das Alef-Kanjareeya (bcNSM), die Dezimal-/Tausendertrennzeichen (bcAN) UND das Prozentzeichen (bcOther + ET über W5).
  • Pipeline-Reihenfolge: W1 NSM-Vererbung (LTR-Pfad explizit, RTL implizit) -> W4 ES/CS zwischen Ziffern -> W5 ET neben Ziffern -> I2-Level-Zuweisung. W5 wird nach W4 ausgeführt, sodass ein von W4 transformierter Trenner, der zu EN wurde, korrekt von W5 als "EN neben" identifiziert wird, um in den nächsten Durchlauf zu gehen; Mehrfachregelinteraktionen innerhalb komplexer Ausdrücke mit Ziffern, Trennzeichen und Währung werden in einem einzigen Pipeline-Durchlauf aufgelöst.
  • Der reine Text, ohne benachbarte Zahlen, ist byte-identisch zur Ausgabe von v2.72. Alle bestehenden Funktionen von v2.59 bis v2.72 (RTL-Arabisch/Hebräisch/SMP-RTL/NSM-Positionierung/LTR-Absatzreihenfolge/Ziffernverarbeitung/W4) bleiben byte-stabil.
  • Die verbleibenden Arbeiten gemäß UAX #9 (Bereinigung von W6/W7, Behandlung von N0-Klammerpaaren durch UAX #9 BD16-Stack-Scan, neutrale Auflösung für N1/N2, OpenType GSUB für arabische/syrische Kontextverknüpfung, RegisterUnicodeTTF basierend auf Dateien) sind noch ausstehend.

2026-05-18 Version 2.72.0

  • Added Unicode UAX #9 simplified W4 (ES / CS between same-typed digits) for RTL paragraphs. Fixes the visible bug where Arabic text with formatted numbers — "السعر 12,345 ريال" (price with thousands comma), "12.50" (decimal point), "12:30" (time colon) — split the digit run at the separator in the reversed /Tj output, producing visually-broken numbers that read backwards within the RTL flow. With v2.72 W4 the separator joins the digit run, both reverse together once and then reverse together again at the whole-string pass, preserving the digit + separator logical order inside the RTL paragraph.
  • W4-Trennzeichen werden erkannt: Europäischer Trenner U+002B (+) / U+002D (-), Gemeinsamer Trenner U+002C (,) / U+002E (.) / U+002F (/) / U+003A (:) / U+00A0 (NBSP) und Arabischer Gemeinsamer Trenner U+060C (arabisches Komma). Jeder wird in EN umgewandelt, wenn er zwischen zwei ENs steht, oder in AN, wenn er zwischen zwei ANs steht. Bei gemischten Nachbarn (EN + AN oder Ziffer + Nicht-Ziffer) bleibt der Trenner im bcOther-/level-1-/surrounding-RTL-Stream unverändert, wie zuvor. Vereinfacht vs. vollständig UAX #9 W4: Die Überprüfung über NSMs wird berücksichtigt (NSMs in der Nähe des Trennzeichens beeinträchtigen die W4-Suche nicht), aber Mehrfach-Trennzeichenketten unterliegen einer Transformation pro Position anstatt der in der Spezifikation definierten Einschränkung auf ein einzelnes Trennzeichen (geringe praktische Auswirkungen, da reale Zahlen selten benachbarte Trennzeichen haben).
  • Concrete fix: "شار 12,345 ريال" (logical UTF-16 starts with Arabic letters, then space, "1" "2" "," "3" "4" "5", then space, then Arabic letters). v2.71 previous output: 0644 0627 064A 0631 0020 0035 0034 0033 002C 0031 0032 0020 0631 0627 0634 — digits split at the comma, reversed within each fragment ("345" before "12"), reads as "345,12" inside the LTR substring user perception. v2.72 fixed output: 0644 0627 064A 0631 0020 0031 0032 002C 0033 0034 0035 0020 0631 0627 0634 — "12,345" intact as one LTR substring, user reads it naturally in numeric order.
  • BIDI_Class-Tabelle korrigiert (v2.72.0): U+066B ARABIC DECIMAL SEPARATOR und U+066C ARABIC THOUSANDS SEPARATOR werden jetzt gemäß der Unicode-Spezifikation als bcAN (Rückgabewert 5) und nicht mehr als bcAL klassifiziert. Diese Trennzeichen sind Teil der arabischen numerischen Formatierung und werden daher automatisch in die arabisch-indische Ziffernfolge für die L2-Reihenfolge aufgenommen, ohne dass der W4-Durchlauf erforderlich ist. U+066A ARABIC PERCENT SIGN wird jetzt als bcAL klassifiziert (Platzhalter; die Spezifikationsbehandlung für europäische Zahlentrennzeichen wird auf W5 verschoben).
  • Interne Refaktorierung: Im Schritt zur Level-Zuweisung in _ApplyUAX9L2Reversal wird jetzt ein explizites paralleles Array von Klassen (ein Byte pro UTF-16-Code-Einheitsposition) erstellt, sodass der W4-Durchlauf die Klassen der benachbarten Zeichen ohne erneutes Dekodieren der Code-Punkte überprüfen kann. Surrogate-Paar-Code-Punkte teilen sich sowohl das Klassen-Array als auch das Level-Array zwischen den oberen und unteren Hälften. Eine entsprechende Refaktorierung für _ApplyUAX9L2ReversalLTRPara wurde verschoben (W4 hat keine sichtbaren Auswirkungen in Links-nach-Rechts-Absätzen, da EN/AN bereits auf dem Basisebene 0 im vereinfachten Modell mit einer einzigen Einbettungsebene bleiben).
  • Reiner RTL/LTR/gemischter Text ohne W4-Trennzeichen zwischen gleichen Ziffern ist byte-identisch zur Ausgabe von v2.66 bis v2.71. Alle bestehenden v2.59-v2.71-Tests (RTL-Arabisch/Hebräisch/SMP-RTL/NSM-Positionierung/LTR-Absatzreihenfolge/Ziffernverarbeitung/Detektor) bleiben byte-stabil.
  • Noch ausstehende Arbeiten zu UAX #9 (W5: ET-Element neben EN, W6/W7-Bereinigung, N0: Klammerpaar über UAX #9 BD16-Stack-Scan, N1/N2: vereinfachte neutrale Auflösung, OpenType GSUB: arabische/syrische kontextuelle Verbindungen, RegisterUnicodeTTF basierend auf Dateien).

2026-05-18 Version 2.71.0

  • Behoben wurde ein Fehler bei der Positionierung von NSM-Zeichen (Non-Spacing Marks) in der Textreihenfolge für Arabisch/Hebräisch. Zuvor führte eine einfache Umkehrung der gesamten Zeichenkette dazu, dass diakritische Zeichen (arabische Harakat wie Fatha, Kasra, Damma, Schadda; hebräische Niqqud wie Sheva, Kamatz, Patah; lateinische kombinierte Diakritika im Bereich U+0300..U+036F) auf die falsche Seite ihres Basiskarakters in der umgekehrten Zeichenkette verschoben wurden. Die Rendering-Komponenten für diakritische Zeichen in PDF-Readern fügten dann das NSM an dem vorhergehenden Glyphe in der Anzeigereihenfolge an – also am falschen Basiskarakter. Das sichtbare Problem: "ALEF + FATHA + BA" (Arabisch) wurde so dargestellt, dass die Fatha auf dem Glyphe "BA" und nicht auf dem Glyphe "ALEF" angezeigt wurde.
  • Es wurde die UAX #9 W1 vereinfachte NSM-Vererbung hinzugefügt, sowie ein gruppenorientierter Rücklauf, der von allen drei L2-Reihenfolgealgorithmen verwendet wird (RTL-Absatz Schritt 2 + Schritt 3, LTR-Absatz Einzelpass). Der Rücklauf behandelt jetzt [Basis, NSM*] als Einheit: beim Rechts-nach-links-Durchlauf werden NSMs in einen Stapel gepuffert und unmittelbar nach der nächsten nicht-NSM-Basis im Ausgabestrom geleert. Surrogate-Paar-Codepunkte bleiben weiterhin während des gleichen Rücklaufs intakt, und SMP-Bereich-NSMs (selten) werden symmetrisch behandelt.
  • Konkrete Korrektur: Die Zeichenkette ""ALEF + FATHA + BA"" (logische UTF-16-Darstellung: 0623 064E 0628) wurde zuvor als 0628 064E 0623 ausgegeben (umgekehrte Reihenfolge, wobei FATHA zwischen BA und ALEF platziert wurde). Mit v2.71.0 stellt die NSM-unterstützte Umkehrung die gleiche Eingabe korrekt als 0628 0623 064E dar – BA links, ALEF in der Mitte und FATHA nach ALEF, sodass der Renderer sie an das korrekte Basiselement anhängt.
  • Die interne BIDI_Class-Tabelle wurde um die Klasse bcNSM (Rückgabewert 6) für die wichtigsten Kombinationszeichenblöcke erweitert: Allgemeine diakritische Kombinationszeichen U+0300..U+036F (lateinische/allgemeine Akzente), Hebräische Niqqud U+0591..U+05BD sowie die verstreuten U+05BF / U+05C1..U+05C2 / U+05C4..U+05C5 / U+05C7-Einträge (aus dem Hebräischen R-Bereich), Arabische Harakat U+064B..U+065F und Alef Khanjareeya U+0670 (aus dem Arabischen AL-Bereich). NSMs werden weiterhin während des ersten, starken Scans in Absatzrichtung P2/P3 übersprungen.
  • Für Textabsätze in Linkslaufrichtung (LTR) wird ein expliziter W1-Durchlauf zur Vererbung auf NSM-Ebene ausgeführt, nachdem die anfängliche Ebene zugewiesen wurde: Jeder NSM übernimmt die Ebene des vorhergehenden Nicht-NSM-Zeichens, sodass ein arabisches NSM, das auf eine AL-Basis folgt, dieser Basis-Ebene-1-Sequenz für den einmaligen L2-Umkehrdurchlauf zugeordnet wird. Bei Textabsätzen in Rechtslaufrichtung (RTL) wird die Ebene implizit vererbt (sowohl NSM als auch R/AL werden im vereinfachten Modell mit einer einzigen Einbettungsebene als Ebene 1 interpretiert), sodass kein separater W1-Durchlauf erforderlich ist.
  • Reine RTL-/LTR-/gemischte Eingaben ohne NSMs sind byte-identisch mit den Ausgaben von v2.66 / v2.67 / v2.68 / v2.69 / v2.70 (kein NSM bedeutet keine Verhaltensänderung). Bestehende v2.59 RTL-Arabisch-, v2.66 LTR-in-RTL-, v2.67 LTR-Absatz-, v2.68 EN-AN- und v2.69 SMP-RTL-Tests bleiben byte-stabil.
  • Noch sind Arbeiten gemäß UAX #9 ausstehend (detaillierte Implementierung von schwachen Typübergängen für W3-W7, neutrale Elemente N0-N2 und Auflösung von Klammerpaaren, kontextuelle Verknüpfung für OpenType GSUB Arabic/Syriac sowie RegisterUnicodeTTF basierend auf Dateien).

2026-05-18 Version 2.70.0

  • Es wurde ein Helfer `THotPDF.RegisterUnicodeFontDict` hinzugefügt, der ein vollständiges PDF 1.7 ISO 32000-1 9.7 / 9.7.6 Type 0 / CIDFontType2 + Identity-H zusammengesetztes Schriftdatenbank-Dictionary in einem Aufruf erstellt. Benutzer, die den Pfad `v2.56.0 SetFormUnicodeFontDict AcroForm /AP` verwenden, müssen jetzt nicht mehr manuell etwa 30 Zeilen Code für die Erstellung der Sub-Dictionaries `CIDSystemInfo / FontDescriptor / CIDFontType2 / Type 0 / Identity-H` schreiben. Gibt ein indirektes `THPDFDictionaryObject` zurück, das an `SetFormUnicodeFontDict` übergeben werden kann.
  • API: RegisterUnicodeFontDict(BaseFont, FontBBoxL/B/R/T, Ascent, Descent, CapHeight, ItalicAngle, StemV, Flags, DefaultWidth). Alle Metrikparameter haben sinnvolle Standardwerte (CJK/Arabisch eingebettete Schriftgeometrie: FontBBox [-1000 -300 2000 1300], Ascent 1000, Descent -300, CapHeight 750, StemV 100, Flags 4 = Symbolisch, DW 1000). Überschreiben Sie diese Werte einzeln für lateinische/hebräische/kyrillische Schriftarten mit kleineren Bounding Boxes und nicht-symbolischen Flags = 32.
  • Die erstellte Dictionary-Struktur entspricht dem spezifikationskonformen Typ 0 + CIDFontType2-Layout, das in smoke_acroform_cid_rtl / smoke_bidi_* in den Versionen v2.59-v2.69 verwendet wird: Adobe / Identity / Supplement 0 CIDSystemInfo, FontDescriptor mit allen in 9.8.2 definierten obligatorischen Einträgen, Identity-H-Kodierung, CIDFontType2 als Kind in der DescendantFonts-Array, /DW für die Standardzeichenbreite. Wenn kein Wert angegeben ist, ist /CIDToGIDMap standardmäßig auf /Identity gesetzt (CID == GID), was die Identity-H + Adobe-Identity-0-Reihenfolge impliziert.
  • In der kommenden Version v2.71+ wird eine dateibasierte `RegisterUnicodeTTF`-Funktion hinzugefügt, die eine .ttf- oder .otf-Datei analysiert, tatsächliche Metriken sowie die horizontalen Ausdehnungen (hmtx /W) für präzise Zeilenumbruchberechnungen extrahiert, die Schriftart als `/FontFile2` einbettet, eine ToUnicode-CMAP aus der cmap generiert und intern `RegisterUnicodeFontDict` für die strukturellen Elemente aufruft.

2026-05-18 Version 2.69.0

  • Die interne Unicode BIDI-Klassentabelle wurde erweitert, um die Rechts-nach-links-Schriftsystemblöcke der Supplementary Multilingual Plane (SMP) im Bereich U+10800..U+10FFF abzudecken. Die Erkennung der Absatzrichtung und die L1-L2-Reihenfolge erkennen jetzt korrekt Phönizisch, Imperial Aramaisch, Palmyrenisch, Nabataisch, Hatranisch, Lydisch, meroitische Hieroglyphen/Kursiv, Kharoshthi, Altsüdarabisch, Altnordarabisch, Manichäisch, Awastanisch, Inschriftparthisch/Pahlavi, Psalter-Pahlavi, Alttürkisch, Ungarisch, Hanifi Rohingya (AL, das heute verwendete Schriftsystem für die Rohingya-Sprache in Burma), Garay, Jesidisch, Arabisch erweitert-C (AL), Altsogdisch, Sogdisch, Altuygurisch, Chorasmisch und Elymaisch.
  • SMP RTL-Absätze werden jetzt automatisch als RTL erkannt, und zwar durch DetectBidiParagraphDirection (der erste starke Zeichenscan durchläuft Ersatzpaare und findet die entsprechende R/AL-Klasse), und es wird die v2.66 RTL L1-L2-Reihenfolge für die visuelle UTF-16BE Tj-Ausgabe angewendet. LTR-Absätze, die eingebettete SMP RTL-Teilstrings enthalten, werden zusätzlich umgekehrt, wenn EnableLTRParaReorder aktiviert ist (v2.67, optionale Funktion); andernfalls werden sie in logischer Reihenfolge ausgegeben und verlassen sich auf die inhärente BIDI-Funktionalität des Leseprogramms.
  • Die korrekte Behandlung von Surrogate-Paaren bleibt in allen L2-Umkehrvorgängen erhalten: SMP-RTL-Codepunkte bleiben als unveränderte High- und Low-Paare im Hex-Stream von `/Tj`, während der umgebende Absatz korrekt neu angeordnet wird.
  • v2.67: Der Smoke-Test (smoke_bidi_ltr_reorder), Assertion #7, verwendete zuvor U+10840 IMPERIAL ARAMAIC LETTER ALEPH, um zu demonstrieren, dass ""SMP-Codepunkte als bcOther in LTR-Absätzen behandelt werden"". Diese Assertion wurde im Rahmen dieser Version aktualisiert, um die jetzt korrekte bcR-Klassifizierung widerzuspiegeln: U+10840 in einem LTR-Absatz wird Teil der R/AL-Laufstufe 1 und wird visuell neben benachbarten hebräischen/arabischen Teilstrings neu angeordnet.
  • Noch sind Arbeiten gemäß UAX #9 ausstehend (W1 NSM-Vererbung + W3-W7 schwache Typübergänge + N0-N2 neutral + Auflösung von Klammerpaaren + I1 explizite Level-Auflösung + OpenType GSUB arabische/syrische kontextuelle Verbindungen). Mit der SMP RTL-Abdeckung sind alle standardisierten Unicode RTL-Schriften jetzt korrekt für die Absatzrichtung und die grundlegende L1-L2-Reihenfolge klassifiziert.

2026-05-18 Version 2.68.0

  • Fixed visible direction bug for digits embedded in Arabic / Hebrew paragraphs. Added Unicode UAX #9 weak-class BIDI_Class entries for European digits (EN, U+0030..U+0039) and Arabic-Indic digit ranges (AN, U+0660..U+0669 + U+06F0..U+06F9), with simplified UAX #9 I2 + L2 level assignment: in an RTL paragraph these digit codepoints now get resolved level 2 (same as embedded LTR runs) rather than level 1 alongside the surrounding RTL text. The two-pass L2 reorder then preserves their logical order inside the visual RTL flow, matching the spec-correct "شارع 12345" user reading even when the paragraph is rendered LTR for the PDF /Tj stream.
  • Concrete fix: an input "شار 12345" (logical UTF-16 0634 0627 0631 0020 0031 0032 0033 0034 0035) previously emitted as the Tj operand 0035 0034 0033 0032 0031 0020 0631 0627 0634 (whole-string reverse - digits inverted, the visible bug). With the v2.68 fix the same input emits 0031 0032 0033 0034 0035 0020 0631 0627 0634 - digits stay 1-2-3-4-5 in reading order while the Arabic word still renders in visual RTL.
  • DetectBidiParagraphDirection behandelt EN und AN jetzt als schwach gemäß UAX #9 P2: Absätze, die nur aus Ziffern bestehen oder mit Ziffern beginnen, verankern RTL nicht mehr an den Ziffern; das erste STARKE Zeichen (L / R / AL) hat weiterhin Vorrang. Leere Eingaben oder Eingaben, die nur schwache Zeichen enthalten, fallen weiterhin auf LTR zurück, wie in P3 beschrieben. Der Smoke-Test für Batterien überprüft, dass reine Ziffern LTR zurückgeben, während Ziffern gefolgt von arabischen Zeichen RTL zurückgeben (arabisches AL ist das erste starke Zeichen), und Ziffern gefolgt von lateinischen Zeichen LTR zurückgeben (lateinisches L ist das erste starke Zeichen).
  • Der arabische Zeichenbereich U+0600..U+06FF wurde in der Nachschlagetabelle aufgeteilt, um die beiden zweistelligen Bereiche als bcAN auszuweisen; die umliegenden Bereiche U+0600..U+065F + U+066A..U+06EF + U+06FA..U+06FF bleiben bcAL. Andere arabische Zeichen (Interpunktion, Prozent-/Promilleteile, Währung usw.) behalten vorerst die bcAL-Klassifizierung; eine feinere Aufteilung der Zeichenklassen (ET / CS / ON / NSM) wird in einer zukünftigen Version zusammen mit dem Rest der W1-W7 / N0-N2-Pipeline eingeführt.
  • Die reine RTL-Eingabe ohne Ziffern ist byteidentisch zur Ausgabe von v2.66 / v2.67 (es werden keine Übergänge der Klasse W ausgelöst). LTR-Absätze sind nicht betroffen (Ziffern werden bereits aufgrund der Absatzrichtung in LTR gerendert). Die Korrektur wird automatisch für alle bestehenden Aufrufer aktiviert, die AutoDetectFormBidi oder FormUnicodeRTL mit UseUAX9LevelReversal=True verwenden (Standardeinstellungen).
  • Noch immer sind die verbleibenden UAX #9- und GSUB-Bereiche (W1 NSM-Vererbung + vollständige W3/W4/W5/W6/W7 + N0-N2-Eckklammern + explizite Level-Auflösung für I1 + OpenType GSUB für arabische/syrische Kontextverknüpfungen + SMP RTL-Skripte mit BIDI_Class) ausstehend.

2026-05-18 Version 2.67.0

  • Es wurde eine Unicode UAX #9 L2 Neuordnung auf Serverseite für linksläufige Absätze hinzugefügt, die eingebettete rechtsläufige Teilstrings enthalten. Die neue Eigenschaft `THotPDF.EnableLTRParaReorder` (Standardwert: False) ermöglicht es Aufrufern, die strikte Einhaltung der Spezifikation und eine reader-unabhängige `/AP`-Ausgabe zu aktivieren: Ein linksläufiger Absatz mit eingebetteten hebräischen/arabischen Texten wird während der `/AP`-Generierung neu angeordnet, sodass Client-Reader keinen eigenen BIDI-Durchlauf für die logisch geordneten rechtsläufigen Teilstrings durchführen müssen.
  • Einphasiger Algorithmus, symmetrisch zu v2.66.0s RTL-Absatz L1-L2: LTR-Absatz, Basisebene 0; jeder starke-R / starke-AL-Codepunkt wird auf Ebene 1 aufgelöst; alles andere bleibt auf Ebene 0. UAX #9 L2, die niedrigste ungerade Ebene ist 1, daher hat die Schleife nur einen Durchlauf: kehre jede maximale Ebene-1-Substring (zusammenhängende R/AL-Sequenz) um. LTR-Zeichen und schwache / neutrale Zeichen werden unverändert kopiert. Stellvertreterpaare bleiben während der Umkehrung erhalten.
  • Die öffentliche Methode THotPDF.ApplyUAX9L2ReversalLTRPara stellt den neuen Algorithmus als eigenständige Funktion bereit (UTF-8 als Eingabe, UTF-8 als Ausgabe). Sie unterscheidet sich von ApplyUAX9L2Reversal in v2.66.0: Der Pfad ParagraphRTL=False dieser Methode bleibt wie in v2.66, sodass Aufrufer, die von der v2.66-Schnittstelle abhängig sind, eine byte-identische Ausgabe erhalten; verwenden Sie die neue Methode für die Umordnung in LTR-Richtung.
  • `EnableLTRParaReorder` standardmäßig auf `False`, wodurch die byte-identische `/AP`-Ausgabe von v2.59-v2.66 für LTR-Absatzaufrufe erhalten bleibt. Der Umschalter hat keine Auswirkung, wenn `UseUAX9LevelReversal=False` (die einfache Umkehrung von v2.59 ordnet LTR-Absätze niemals neu); die beiden Umschalter sind ansonsten unabhängig.
  • Vollständige UAX #9 W1-W7 schwache Typ-Übergänge + N0-N2 neutrale Elemente + Klammerpaar-Auflösung + I1-I2 explizite Level-Auflösung + OpenType GSUB Formatierung bleiben im Umfang von v2.68+.

2026-05-18 Version 2.66.0

  • Für AcroForm-Unicode-Darstellungsstreams wurde eine Unicode-UAX #9-basierte, kontextsensitive Umkehrung für L1- und L2-Ebenen hinzugefügt. Die neue Eigenschaft `THotPDF.UseUAX9LevelReversal` (Standardwert: True) ersetzt die einfache, globale Umkehrung ganzer Zeichenketten für RTL-Absätze der Version 2.59.0 durch eine spezifikationskonforme, zweipassige L2-Neuanordnung, die die interne logische Reihenfolge von LTR-Teilzeichenketten innerhalb von RTL-Absätzen beibehält.
  • Concrete fix: an input "<Hebrew>AB" (logical UTF-16 05D0 05D0 0041 0042) previously emitted as the Tj operand hex 0042 0041 05D0 05D0 ("BAאא"), which inverts the embedded LTR "AB" - wrong per UAX #9. With L1-L2 active the same input now emits 0041 0042 05D0 05D0 ("ABאא"). Pure-RTL input with no L runs (e.g. the v2.59.0 pre-shaped Arabic smoke) remains byte-identical to the legacy naive reverse.
  • Die öffentliche Methode THotPDF.ApplyUAX9L2Reversal stellt den neuen Algorithmus als eigenständige Hilfsfunktion bereit (UTF-8 als Eingabe, UTF-8 als Ausgabe) für Aufrufer, die ihre eigenen Anzeigeströme erstellen oder die Umordnung vor der /AP-Generierung anzeigen möchten.
  • Vereinfachte, einstufige Teilmengen von UAX #9 I1 + L2, die in diesem Bereich verwendet werden: In einem Textabschnitt mit Textrichtung von rechts nach links (RTL) erhält jeder starke-L-Codepunkt die Ebene 2; alles andere (R, AL, schwach, neutral, Stellvertreter) bleibt auf Ebene 1. Anschließend kehrt Ebene 2 zuerst die Ebenen-2-Sequenzen um (wodurch die logische Reihenfolge von eingebetteten LTR-Teilstrings wiederhergestellt wird) und kehrt schließlich das gesamte Zeichenkettensegment der Ebene 1 um (wodurch das visuelle RTL-Layout erzeugt wird). Stellvertreterpaare werden während beider Durchläufe beibehalten.
  • Die vollständige Implementierung von UAX #9 W1-W7 (Übergänge zu schwachen Typen) + N0-N2 (Neutrale Zeichen + Klammerpaare) + I1-I2 (explizite Auflösung auf Seitenebene) sowie die Neuanordnung für Links-nach-Rechts-Absätze mit eingebetteten Rechts-nach-Links-Textblöcken bleiben im Umfang von Version 2.67+. Version 2.66.0 behebt den häufigsten beobachteten Fehler: Rechts-nach-Links-Absätze mit mehrteiligen Links-nach-Rechts-Teilstrings.
  • UseUAX9LevelReversal standardmäßig auf True gesetzt. Setzen Sie es auf False, um zur einfachen, zeichenbasierten Umkehrung der gesamten Zeichenkette von v2.59.0 zurückzukehren, um eine byte-identische, ältere Ausgabe zu erzielen. Beide Methoden lesen weiterhin FormUnicodeRTL und AutoDetectFormBidi auf die gleiche Weise.

2026-05-18 Version 2.65.0

  • Es wurde eine automatische Erkennung der Absatzrichtung gemäß Unicode Standard Annex #9 für Unicode-AP-Darstellungsströme in AcroForm hinzugefügt. Eine neue Eigenschaft, `THotPDF.AutoDetectFormBidi`, ersetzt die manuelle FormUnicodeRTL-Umschaltung in den Versionen v2.59.0 für die Helferfunktionen `BuildUnicode*FieldContent` (einzeilig, mehrzeilig, Kombi) durch eine Erkennung der Absatzrichtung für jeden Aufruf. Dadurch kann dieselbe Sequenz von Set-Befehlen eine Mischung aus LTR- und RTL-Feldern in einem Dokument verarbeiten, ohne dass eine manuelle Umschaltung erforderlich ist.
  • Die Richtung wird ermittelt, indem die Eingabe nach dem ersten starken Zeichen (UAX #9-Regeln P2 + P3) durchsucht wird, und dieses Zeichen anhand der BIDI-Klasse L (links), R (rechtsläufig) oder AL (arabischer Buchstabe) klassifiziert wird. Ein starkes R- oder AL-Zeichen fixiert den Absatz als RTL (rechtsläufig); ein starkes L-Zeichen fixiert ihn als LTR (linksläufig); ein Absatz ohne starkes Zeichen ist standardmäßig LTR (linksläufig) gemäß P3.
  • Erkannt: BIDI_Class: Stark L - ASCII, Latin, Latin Extended, Griechisch, Koptisch, Kyrillisch, Armenisch, CJK Unified Ideographs, Hangul, Hiragana, Katakana, Yi. Stark R - Hebräischer Block (U+0590..U+05FF), Hebräische Präsentationsformen (U+FB1D..U+FB4F), N'Ko, Samariter, Mandäisch. Stark AL - Arabischer Block, Arabisches Supplement, Arabisch Extended-A, Syrisch, Thaana, Arabische Präsentationsformen A + B (U+FB50..U+FDFF + U+FE70..U+FEFF). Während der Suche werden Surrogate-Paare sowie schwache/neutrale Zeichen (Ziffern, Interpunktion, Leerzeichen) übersprungen.
  • Die öffentliche Methode THotPDF.DetectBidiParagraphDirection stellt den Detektor für Aufrufer bereit, die die Richtung im Voraus berechnen möchten (z. B. für die /Lang-Kennzeichnung, gespiegelte neutrale Ausgabe oder benutzerdefinierte Feldweiterleitung). Sie akzeptiert eine UTF-8-kodierte AnsiString und gibt einen Booleschen Wert zurück (True = RTL). Eine leere Eingabe gibt gemäß P3 False zurück.
  • AutoDetectFormBidi ist standardmäßig auf False eingestellt; das bisherige Verhalten von v2.59.0-v2.64.0 bleibt unverändert. Wenn AutoDetectFormBidi auf True gesetzt ist, werden die Hilfsfunktionen FormUnicodeRTL für jeden einzelnen Aufruf ignoriert. Setzen Sie AutoDetectFormBidi auf False, um die manuelle Steuerung wiederherzustellen.
  • Vollständige UAX #9 implizite Level- und schwache Typ- sowie neutrale Klammerauflösung (Regeln W1-W7, N0-N2, I1-I2, L1-L4) sowie automatische arabische/syrische OpenType GSUB-Kontextverknüpfung sind weiterhin für v2.66+ geplant. Für mehrsprachige Absätze ist weiterhin eine manuelle Eingriff durch den Aufrufer auf Paragraph-Ebene erforderlich.

2026-05-18 Version 2.64.0

  • Es wurde ein Eintrag für die Halbtontöne im ExtGState gemäß PDF 1.2 ISO 32000-1 10.5.5 (/HT) sowie ein Dictionary-Builder für Halbtontöne mit Spot-Funktion vom Typ 1 hinzugefügt. Eine neue Funktion `THotPDF.RegisterHalftoneType1` erstellt das PDF 1.7 Table 76 Type 1 Halbtontöne-Dictionary, wobei der Aufrufer die CMYK-Separation steuert (Frequenz in Linien pro Zoll, Winkel des Rasters in Grad, Form des Spots, optionale präzise Rasterung, Übertragungsfunktion, beschreibender Halbtontönename). Kombinieren Sie dies mit `THotPDF.RegisterHalftoneState`, um diese Dictionary-Referenz in einen ExtGState /HT-Eintrag zu verpacken, der mit `THPDFPage.SetGraphicsState` verwendet werden kann.
  • /SpotFunction akzeptiert entweder einen in der PDF 1.7 Tabelle 78 definierten, vordefinierten Farbnamen (SimpleDot, InvertedSimpleDot, DoubleDot, InvertedDoubleDot, CosineDot, Double, InvertedDouble, Line, LineX, LineY, Round, Ellipse, EllipseA, InvertedEllipseA, EllipseB, EllipseC, InvertedEllipseC, Square, Cross, Rhomboid, DiamondRhomboid) oder eine vom Aufrufer erstellte Referenz zu einem Farbdefinitionsobjekt. Unbekannte vordefinierte Namen führen zu einer Fehlermeldung, die die vollständige Liste der möglichen Namen enthält. Farbname und Farbdefinitionsobjekt sind exklusiv.
  • /TransferFunction ist optional. Übergeben Sie eine Referenz zu einem Funktions-Dictionary, um die Tonwiedergabe vom Aufrufer steuern zu können, oder setzen Sie TransferFunctionDefault = True, um /TransferFunction /Identity (Standard für den Konsumenten/Reader) auszugeben. Die beiden Formen schließen sich gegenseitig aus.
  • RegisterHalftoneState akzeptiert entweder eine Referenz zu einem Halfton-Dictionary (typischerweise der Rückgabewert von RegisterHalftoneType1) oder HTDefaultName = True für den Pfad, der den eingebauten Halfton des Lesegeräts wiederherstellt, indem der Name-Literal "/HT /Default" zurückgesetzt wird.
  • Alle Emissionen erhöhen automatisch die Dokumentversion auf PDF 1.2. Die Frequenz muss größer als 0 sein; ungültige Spot-Funktionsnamen führen zu einem Fehler, bevor das Dictionary zugewiesen wird.
  • Die verbleibenden Halftonarten sind für v2.65+ geplant: Mehrkomponenten-Halfton der Typ 5 sowie Schwellenwert-Halftons der Typen 6/10/16. Mit der Implementierung von Typ 1 ist ein Eintrag aus den "ExtGState"-Einträgen für eine vollständige Abdeckung verfügbar.

2026-05-18 Version 2.63.0

  • Hinzugefügt: PDF 1.4 ISO 32000-1 11.6.5 + 11.7.4 ExtGState Soft-Mask + Alpha-is-Shape Einträge. Das neue THotPDF.RegisterSoftMaskState bündelt die Transparenz-bezogenen Parameter /SMask und /AIS in einem ExtGState-Dictionary, wodurch die Abdeckung der ExtGState-Einträge für jede spezifizierte Einstellung vervollständigt wird, mit Ausnahme des mehrfach typisierten /HT Halftone-Bildschirms (geplant für v2.64+).
  • /SMask enthält entweder den Literalwert /None (der Aufrufer übergibt SMaskNone = True, ein häufiges Reset-Muster nach einem komplexen Komposit) oder eine indirekte Referenz auf ein Soft-Mask-Dictionary (der Aufrufer übergibt SMaskDict, ein fortgeschrittener Anwendungsfall). Die beiden Formen schließen sich gegenseitig aus. Der Aufrufer ist für den Inhalt des Soft-Mask-Dictionaries und das zugrunde liegende transparente Form-Objekt verantwortlich; ab Version 2.64 wird ein dedizierter Helfer für den Aufbau hinzugefügt.
  • /AIS steuert, ob die aktuellen Alpha-Werte als Alpha (false) oder als Form (true) für den Rest des Grafikstatus interpretiert werden. Der Standardwert für AIS ist -1, was dazu führt, dass der Eintrag /AIS vollständig übersprungen wird. Das Übergeben von AIS = 0 oder 1 erzeugt /AIS false bzw. /AIS true. Jeder andere AIS-Wert führt zu einer Fehlermeldung.
  • Mindestens eines der folgenden Elemente muss angegeben werden: /SMask (None oder Dict) oder /AIS; ein Aufruf mit allen Standardwerten führt zu einem Fehler. Jede ausgegebene Eingabe erhöht automatisch die Dokumentversion auf PDF 1.4.
  • Gibt den automatisch generierten ExtGState-Namen (GS1, GS2, ...) zurück, der mit THPDFPage.SetGraphicsState verwendet werden kann. Unterscheidet sich von v2.42.0 AddImageWithSMask: wobei letzteres eine Alpha-Ebene auf Pixelebene für ein einzelnes XObject ist, während dies eine ExtGState-Ebene für die Maske ist, die sich auf alle nachfolgenden Zeichenoperationen auswirkt.
  • Der verbleibende Eintrag für ExtGState ist für v2.64+ geplant: /HT für Halbtöne (Typ 1 / 5 / 6 / 10 / 16).

2026-05-18 Version 2.62.0

  • Hinzugefügt: Unterstützung für PDF 1.2/1.3+ und ISO 32000-1 11.7.5.4, sowie Einträge für ExtGState zur Schwarzgenerierung und Unterfarbentfernung. Ein neues `THotPDF.RegisterBlackGenerationState` fasst die vier Grafikparameter, die Funktionen referenzieren (/BG, /BG2, /UCR, /UCR2), in ein ExtGState-Dictionary zusammen. Dies ist für CMYK-Vorkonvertierungsprozesse in der Druckvorstufe gedacht, bei denen die RGB-zu-CMYK-Konvertierung während des Rasterisierens erfolgt (typisch für Zeitungen, Verpackungen und großformatige Druckprodukte, bei denen die Tintenauftragsentscheidungen geräteabhängig sind).
  • /BG und /UCR (PDF 1.2) sind Funktions-Dictionaries mit einem Eingang und einem Ausgang; /BG2 und /UCR2 (PDF 1.3+) sind entweder Funktions-Dictionaries oder der literale Name /Default, der die Standardkurve des Wiedergabe-Viewers wiederherstellt. Der Setter akzeptiert ein THPDFObject für jeden Funktions-Slot (normalerweise erstellt durch v2.52.0 RegisterSampledFunction) und zwei boolesche Flags BG2DefaultName / UCR2DefaultName für die Verwendung des Namens /Default. Die Verwendung eines Funktions-Dictionaries und des Default-Flags für denselben /BG2- oder /UCR2-Slot führt zu einer Fehlermeldung.
  • Mindestens eines der folgenden Elemente muss angegeben werden: /BG, /BG2, /UCR, /UCR2 (entweder als Funktion oder als Standardwert); ein Aufruf ohne Angabe führt zu einem Fehler. Wenn eines der Elemente /BG2 oder /UCR2 (entweder als Funktion oder als Standardwert) angegeben wird, wird die PDF-Version automatisch auf 1.3 aktualisiert.
  • Gibt den automatisch generierten Namen des ExtGState (GS1, GS2, ...) zurück, der mit THPDFPage.SetGraphicsState verwendet werden kann. Funktioniert gut mit v2.60.0 RegisterTransferFunctionState (Ausgabe-Kurven pro Kanal) – eine typische CMYK-Produktionskette registriert einen BG/UCR ExtGState für die RGB-zu-CMYK-Konvertierung sowie einen /TR ExtGState für die endgültige Tonwiedergabe auf dem Ausgabegerät.
  • Die verbleibenden ExtGState-Einträge sind für v2.63+ geplant: /HT für Halbtontöne (Typ 1 / 5 / 6 / 10 / 16) sowie /SMask und /AIS (Softmaske) auf ExtGState-Ebene.

2026-05-17 Version 2.61.0

  • Hinzugefügt: PDF 1.2/1.3+ ISO 32000-1 8.6.5.7 + 8.6.5.8 + 11.7.4 ExtGState-Einträge zur Drucksteuerung. Das neue THotPDF.RegisterPrintControlState fasst die für die Vorstufe relevanten Grafikparameter /OP, /op, /OPM, /SA, /RI und /FL in einem ExtGState-Dictionary zusammen, was für PDF/X-1/X-3/X-4-Produktionsworkflows geeignet ist, die Steuerungen für Überdruck, Strichanpassung, Rendering-Intent und Kurvenabbflachung benötigen.
  • Alle sechs Parameter sind unabhängig voneinander optional. Standardwerte: Overprint = -1 (überspringt /OP + /op), OverprintMode = -1 (überspringt /OPM), StrokeAdjustment = -1 (überspringt /SA), RenderingIntent = '' (überspringt /RI), Flatness < 0 (überspringt /FL). Der Aufrufer muss mindestens einen Eintrag bereitstellen; leere Dictionaries führen zu einem Fehler.
  • Überdeckungsregeln werden mit /OP und /op zusammengefasst (die PDF-Spezifikation setzt standardmäßig /op auf /OP, wenn nur letzteres angegeben ist, aber strenge PDF/X-Pipelines erwarten beide Einträge explizit). Wenn OverprintMode = 1 eingestellt ist, wird eine CMYK-Überdeckung gemäß PDF 1.3 aktiviert, wobei jede Null-Komponente transparent dargestellt wird; die Dokumentversion wird automatisch auf 1.3 aktualisiert.
  • `RenderingIntent` akzeptiert die vier Standardwerte 'AbsoluteColorimetric' / 'RelativeColorimetric' / 'Saturation' / 'Perceptual'; jeder andere nicht-leere String führt zu einem Fehler. `Flatness` wird auf den Bereich [0.0..100.0] begrenzt; Werte außerhalb dieses Bereichs führen zu einem Fehler.
  • Gibt den automatisch generierten Namen des ExtGState (GS1, GS2, ...) zurück, der mit THPDFPage.SetGraphicsState verwendet werden kann. Funktioniert gut mit v2.20.0 RegisterExtGState (Transparenz / Mischmodus) und v2.60.0 RegisterTransferFunctionState (Ausgabekurven) – eine typische PDF/X-Konfiguration verwendet oft eine von jeder dieser Funktionen.
  • Funktionsbasierte Einträge (/BG, /UCR, /BG2, /UCR2) für die Schwarzgenerierung und die Unterfarbentfernung sowie die komplexe /HT-Halbtontabellenmaske und die Softmaske auf ExtGState-Ebene bleiben Gegenstand zukünftiger Entwicklungen.

2026-05-17 Version 2.60.0

  • Hinzugefügt: Unterstützung für PDF 1.3+ ISO 32000-1 11.7.3.4 ExtGState /TR (Übertragungsfunktion). Die neue Methode `THotPDF.RegisterTransferFunctionState` registriert ein ExtGState-Dictionary, das einen `/TR`-Eintrag enthält, der eine Tonwiedergabekurve anwendet, während Farben rasterisiert werden. Die Kurve wird als Funktion vom Typ 0 (Sampled LUT) der Version v2.52.0 (oder ein anderes Funktions-Dictionary, das der Aufrufer erstellt hat) bereitgestellt; diese Wrapper-Funktion passt gut zu der vorhandenen `RegisterSampledFunction`-Funktion, um fein abgestimmte Gamma-/Helligkeits-/Druckcharakterisierungskurven zu erstellen, ohne die ICC-Profilmechanismen zu verwenden.
  • Zwei Aufrufpfade:
  • SingleFunc-Form: Eine Funktion wird auf jeden Ausgabekanal angewendet (Anwendungsfälle für Gamma/Helligkeit).
  • Array-Form pro Kanal: Ein 4-Elemente-Array [TR_R, TR_G, TR_B, TR_A] für RGB-A-Pipelines oder [TR_C, TR_M, TR_Y, TR_K] für CMYK-Reproduktionskurven; alle vier Felder müssen gemäß der PDF-Spezifikation nicht null sein.
  • Gibt den automatisch generierten ExtGState-Namen (GS1, GS2, ...) zurück, der mit THPDFPage.SetGraphicsState verwendet werden kann. Wenden Sie den Zustand an, bevor Sie Zeichenoperatoren (Text / Pfade / Bilder) ausführen, die die Übertragung behandeln sollen.
  • Wenn mehrere Aufrufer (SingleFunc nicht null und PerChannel nicht leer) gleichzeitig aktiv sind, wird eine Ausnahme ausgelöst, um die in der Spezifikation geforderte gegenseitige Ausschlussbedingung auf der API-Ebene durchzusetzen.

2026-05-17 Version 2.59.0

  • Es wurde eine Unterstützung für die Rechts-nach-links-Richtung für AcroForm Unicode /AP hinzugefügt (PDF 1.7 ISO 32000-1 12.7.4.3). Eine neue Eigenschaft `THotPDF.FormUnicodeRTL` vom Typ Boolean wurde hinzugefügt; wenn diese auf `true` gesetzt ist, kehren alle drei Unicode /AP-Helfer (einzeilig, mehrzeilig, kombiniert) die Reihenfolge der UTF-16-Codeeinheiten in ihren generierten Hex-Tj-Operatoren um, sodass vorformatierter arabischer/hebräischer/syrischer Inhalt in der visuellen Rechts-nach-links-Reihenfolge dargestellt wird. UTF-16-Surrogatpaare bleiben während der Umkehrung als Einheit erhalten (das obere Zeichen bleibt in der ursprünglichen Reihenfolge direkt vor dem unteren Zeichen, sodass SMP-Code-Punkte wie Schriftzeichen aus alten Schriften korrekt angezeigt werden).
  • Änderungen: v2.59.0 behandelt nur den Schritt der Richtungsumkehrung. Der Aufrufer ist für zwei vorbereitende Schritte verantwortlich, die v2.59.0 absichtlich NICHT ausführt: (1) die vollständige bidirektionale Algorithmuslösung gemäß UAX #9 (gemischte LTR / RTL / numerische / neutrale Inhalte) und (2) die kontextuelle Verbindung von Arabisch / Syrisch (Auswahl der Glyphenformen Initial / Medial / Final / Isolated). Aufrufer sollten Arabisch vor dem Aufruf von AddTextField in seine Unicode-Darstellungsformen umwandeln (U+FB50..U+FDFF + U+FE70..U+FEFF). Hebräisch benötigt keine kontextuelle Verbindung, daher funktioniert es ohne vorherige Umwandlung.
  • /V (logische Unicode-Reihenfolge) bleibt unverändert: PDF-Textzeichenketten enthalten immer die typisierte Reihenfolge, sodass standardskonforme Text-Extraktoren die korrekte logische Sequenz erkennen. Nur die /AP Tj-Operatoren ändern die Reihenfolge, sodass der Renderer die Zeichen visuell von rechts nach links darstellt. Mit dieser Version ist die internationale /AP-Kette für AcroForm in den Versionen v2.55.0-v2.59.0 vollständig: /RV-Reichtext, einzeilig/mehrzeilig sowie CID-Schriftart-/AP und vorgeformte RTL-Richtungsänderung. Die vollständige Unterstützung von UAX #9 sowie die automatische GSUB-Formatierung bleiben im Umfang von v2.60.0+.

2026-05-17 Version 2.58.0

  • Die Unterstützung für Unicode-Schriftarten, die vom Aufrufer bereitgestellt werden, wurde in der v2.56.0 / v2.57.0-Version für die /AP-Kette bis zum ffComb-Zweig erweitert (PDF 1.7 ISO 32000-1 12.7.4.3 Tx /Ff Bit 25). Wenn SetFormUnicodeFontDict eine Type 0-Kompositschriftart registriert hat und ein Tx-Widget mit ffComb und einem Nicht-ASCII-Anfangswert hinzugefügt wird, generiert HotPDF nun einen echten /AP /N-Erscheinungsstrom, der einen CJK-Codepunkt pro gleichbreiter Kammzelle unter Verwendung einer absoluten Tm-Matrix pro Zelle und UTF-16BE-Hex-String-Tj-Operanden platziert.
  • UTF-16-Surrogate-Paare (Codepunkte >= U+10000, z. B. Emojis und CJK-Erweiterung B/C/D-Ergänzungsideogramme) belegen eine einzelne Kombinationszelle, was der Art und Weise entspricht, wie Acrobat einzelne Glyphen-Kombinationsschrift-Kombinationszellen anordnet. Die Zellenmittelung erfolgt mit derselben Formel wie bei der ASCII-Kombinationsverzweigung ab Version 2.46.0, sodass die visuelle Ausgabe der ASCII-Einzelzeichenanordnung entspricht.
  • ASCII-Kombinationsfelder bleiben byte-identisch zur Ausgabe von v2.46.0. Nicht-ASCII-Kombinationen ohne SetFormUnicodeFontDict verwenden weiterhin den v2.46.0-Platzhalter für leere /AP (unverändert). Mit dieser Version ist die internationale /AP-Kette für AcroForm (einzeilig, mehrzeilig, kombiniert) in den Versionen v2.55.x bis v2.58.0 vollständig; die RTL-Bidi-Formatierung (UAX #9 + arabische Kontextverknüpfung) bleibt im Umfang von v2.59.0+.

2026-05-17 Version 2.57.0

  • Die Unterstützung für Unicode-Schriftarten, die vom Aufrufer bereitgestellt werden, wurde für mehrzeilige Textfelder (PDF 1.7 ISO 32000-1 12.7.4.3 ffMultiline / Tx /Ff Bit 13) erweitert. Wenn SetFormUnicodeFontDict eine Type 0-Kompositschriftart registriert hat und ein Tx-Widget mit ffMultiline und einem Nicht-ASCII-Anfangswert hinzugefügt wird, bricht HotPDF jetzt UTF-16-Text um und gibt für jede sichtbare Zeile einen UTF-16BE-Hex-String über Tj mit /TL aus (entsprechend dem ASCII-Mehrzeilenlayout in v2.46.0).
  • Die Textumbruchfunktion verwendet eine einfache Heuristik: 1 em für jedes CJK-/breite Code-Element (>= U+2E80) und 0,5 em für jedes schmale Code-Element (ASCII-Bereich und lateinische Zeichensetzung). Dadurch wird gemischter lateinischer/CJK-Inhalt sinnvoll umbrochen, ohne das `/W`-Array der Schriftart auszulesen. Harde Zeilenumbrüche (CR/LF/CRLF) werden berücksichtigt. Zeilen, die das Widget-Rechteck überschreiten, werden auf die Anzahl der Zeilen gekürzt, die bei der aktuellen Schriftgröße passen; dies ist das gleiche Abschneideverhalten wie bei der ASCII-Mehrzeilenfunktion.
  • ASCII-Mehrzeilen-, ASCII-Einzeilen-, ASCII-Kombinations- und die v2.56.0-Nicht-ASCII-Einzeilenpfade bleiben byteidentisch. Der Nicht-ASCII-Kombinationspfad (ffComb + mehrbyte-Text) leitet weiterhin an den v2.56.0-Einzeilen-Helfer weiter; das ffComb-spezifische Unicode-Layout sowie die RTL-Bidi-Formatierung (UAX #9 + arabische kontextuelle Verknüpfung) sind ab Version v2.58.0 verfügbar.

2026-05-17 Version 2.56.0

  • Es wurde eine vom Aufrufer bereitgestellte Unicode-Schriftartunterstützung für die Darstellung von AcroForm-/AP-Erscheinungsströmen hinzugefügt (PDF 1.7 ISO 32000-1 12.7.2 + 12.7.4.3). Vor dieser Version erzeugte der Pfad "GenerateTextFieldAP" einen leeren /AP-Platzhalter, wenn der Anfangswert des Felds ein Byte >= 0x80 enthielt, sodass nicht-ASCII-Text nur über die Regeneration mit /NeedAppearances=true (abhängig von den installierten Schriftarten des Leseprogramms) oder über den v2.55.0 /RV-Richtext-Pfad (abhängig von der Richtext-Engine des Leseprogramms) gerendert werden konnte. v2.56.0 schließt diese Lücke: Aufrufer können ein zusammengesetztes Schriftart-Dictionary vom Typ 0 /CIDFontType2 + Identity-H über SetFormUnicodeFontDict registrieren, und HotPDF erzeugt einen echten /AP-/N-Erscheinungsstrom, der die registrierte Schriftart über den Tf-Befehl auswählt und den Wert als UTF-16BE-Hex-String über den Tj-Operator rendert.
  • Neue Funktion: THotPDF.SetFormUnicodeFontDict(LogicalName, FontDict): registriert ein logisches Schriftnamen- und Schriftarten-Dictionary-Paar. Nach der Registrierung werden für das AcroForm-Level, für jedes Tx-Widget und für den /AP-Stream für nicht-ASCII-Tx-Initialwerte alle auf den logischen Namen umgestellt; das AcroForm /DR/Font-Dictionary enthält die Schriftart zusammen mit /Helv und /ZaDb; das /Resources/Font-Sub-Dictionary des Formular-X-Objekts referenziert ebenfalls dieselbe indirekte Schriftart, sodass der AP eigenständig ist und nicht von der /DR-Auflösung zur Renderzeit abhängt. Übergeben Sie einen leeren Wert und nil, um zur v2.46.0-Standardeinstellung mit nur /Helv zurückzukehren.
  • Neue THotPDF.CreateIndirectFontDict: Eine öffentliche Hilfsfunktion, die ein neues, leeres THPDFDictionaryObject erstellt und als indirektes PDF-Objekt registriert, sodass Aufrufer benutzerdefinierte Schrift-/Farb-/OCG-/Funktions-Dictionaries erstellen können, die als "N G R"-Referenzen serialisiert werden müssen. Funktioniert gut mit SetFormUnicodeFontDict zum Erstellen von Type 0-Komposit-Schrift-Dictionaries.
  • ASCII-Textfelder verwenden weiterhin "/Helv" und erzeugen eine byte-identische "/AP"-Ausgabe, wie bei den Versionen v2.46.0 und v2.55.0. Mehrbyte-Text ohne SetFormUnicodeFontDict greift weiterhin auf das Verhalten des leeren "/AP"-Platzhalters von v2.46.0 zurück (wird unverändert beibehalten) für die Kompatibilität.
  • Mehrzeilige und kombinierte Nicht-ASCII-Bereiche für /AP sowie RTL-Bidi-Formatierung (UAX #9 + arabische Kontextverknüpfung) bleiben im Umfang von v2.57.0 enthalten; v2.56.0 deckt einzeilige, logisch geordnete CJK-/Kyrillisch-/Vietnamesisch-/Griechisch-Schriften und ähnliche Skripte ab.

2026-05-17 Version 2.55.0

  • Es wurde Unterstützung für AcroForm-Rich-Text-Textfeldern hinzugefügt (PDF 1.7 ISO 32000-1 12.7.4.3 + Anhang L). Die neue Methode `THPDFPage.AddRichTextField` erzeugt ein Textfeld, das `/RV` (Rich-Text-XHTML-Inhalt), `/DS` (CSS-ähnlicher Standardstil), das `ffRichText`-Flag (Bit 26) und den Klartext `/V` + `/DV` als Fallback enthält, der von Leseprogrammen verwendet wird, die `/RV` nicht interpretieren. Acrobat und Foxit rendern direkt aus `/RV`, wenn das `RichText`-Flag gesetzt ist, und verwenden dabei Schriftarten-Fallback aus den im Leseprogramm installierten Unicode-Schriftarten, sodass mehrbyte-Inhalte (CJK/Kyrillisch/Arabisch/lateinische Zeichen mit Akzenten) korrekt angezeigt werden, ohne dass HotPDF eine CID-Schriftart in `/DR`-Ressourcen einbetten muss. Das Einbetten einer CID-Schriftart für den eigenen Erscheinungsbild-Generator (`/AP`) von HotPDF ist ein zukünftiges Projekt; Rich-Text-fähige Viewer benötigen dies nicht.
  • Sowohl `/V` als auch `/RV` erkennen automatisch mehrbyte-Eingaben und wechseln bei Bedarf zu einer UTF-16BE-Hex-String-Kodierung (FE FF BOM + Big-Endian-Codeeinheiten), was dem bestehenden Verhalten von `AddTextField` für internationale Klartextfelder entspricht. ASCII-Inhalte bleiben als literale PDF-Strings erhalten, um eine byte-identische Ausgabe wie beim Klartext-Ausgabepfad in v2.46.0 zu gewährleisten.
  • Drei weitere Punkte müssen in Bezug auf die internationale Zeichenunterstützung in AcroForm bearbeitet werden: (1) Der CID-Schriftartenpfad /DR-Ressourcen muss so angepasst werden, dass von HotPDF generierte /AP-Streams Nicht-ASCII-Zeichen ohne die Verwendung der Rich-Text-Engine des Leseprogramms verarbeiten können, (2) Die bidirektionale Formatierung (RTL) für arabischen/hebräischen Rich-Text muss verbessert werden und (3) der /AA /K-Tastenfolge-Helfer muss implementiert werden.

2026-05-17 Version 2.54.0

  • Erweiterte PDF 1.7 ISO 32000-1 7.10.2 Funktionstyp 0 (gesampelt) mit kubischer Spline-Interpolation. `RegisterSampledFunction` erhält einen neuen optionalen Parameter "Order" (Standardwert 1, akzeptierte Werte sind 1 oder 3 gemäß PDF 1.7 Tabelle 38). Wenn "Order" den Wert 3 hat, wird eine kubische Interpolation über jede Eingangsachse verwendet; wenn "Order" den Wert 1 hat, bleibt das bestehende lineare Verhalten unverändert, sodass Aufrufer von v2.52.0 und v2.53.0 keine sichtbaren Änderungen feststellen.
  • Es wurde eine umfassende Regressionstestabdeckung für den Code-Pfad von Funktionen mit mehreren Eingaben und mehreren Ausgaben hinzugefügt. Ein neuer Smoke-Test registriert eine Funktion mit 2 Eingaben und 3 Ausgaben auf einem 4x4-Raster mit kubischer Interpolation und testet die in der Spezifikation definierte Regel für die Reihenfolge der Abtastwerte ("die Eingabekoordinaten nehmen entlang der ersten Eingabedimension am schnellsten zu"). Dabei werden alle 16 Rasterpunkte x 3 Kanäle mit einer analytischen Formel verglichen, die im Python-Verifizierer neu abgeleitet wurde.
  • Acrobat, Foxit und qpdf unterstützen alle "Order = 3"; einige ältere mobile Viewer greifen bei unbekannten "Order"-Werten stillschweigend auf lineare Interpolation zurück. Kubische Interpolation bleibt optional, um maximale Kompatibilität mit den Leseprogrammen zu gewährleisten.

2026-05-17 Version 2.53.0

  • Es wurde ein hochrangiger Farbseparations-Farbraum-Registrar hinzugefügt, der eine abgetastete Funktion vom Typ 0 (LUT) als seine Farbtransformation verwendet (PDF 1.7 ISO 32000-1 8.6.6.4 + 7.10.2). Die neue Funktion `THotPDF.RegisterSeparationLUT (ColorantName, AlternateCS, Samples)` baut auf der in v2.52.0 eingeführten `RegisterSampledFunction`-Funktion auf, sodass Aufrufer eine vollständige nichtlineare Farbkurve als einen flachen Byte-Stream von (M-Tupel)-Werten angeben können, ohne ein Dictionary vom Typ 0 manuell erstellen zu müssen.
  • Verwenden Sie die neue LUT-Variante, wenn der Farbverlauf nicht linear ist (z. B. PANTONE Hexachrome-ähnliche Farbverläufe, gamma-korrigierte Dichtekurven, handgezeichnete Tonwertkurven, die eine Druckcharakterisierung widerspiegeln, sRGB-zu-Farbton-Konvertierungs-ICC-LUTs ohne die vollständige ICC-Profilfunktionalität). Verwenden Sie RegisterSeparation v2.45.0, wenn ein linearer Verlauf von 0 bis zum maximalen Farbwert ausreichend ist (was in den meisten Fällen für einzelne PANTONE-Farbwerte gilt).
  • Die Samples bestehen aus 8-Bit-RGB-/CMYK-/Graustufen-Bytes, die in der Reihenfolge (c0_0, c1_0, ..., cM-1_0, c0_1, ..., cM-1_S-1) angeordnet sind, wobei S die Anzahl der Rasterpunkte ist, die als Length(Samples) / M berechnet wird. S muss mindestens 2 sein, damit die Funktion einen interpolierbaren Bereich hat. Die lineare Interpolation zwischen den Rasterpunkten ist der Standard (PDF 1.7 /Order 1). Die Funktion gibt den registrierten Farbnamen (Sep1, Sep2, ...) zurück, der mit THPDFPage.SetFillColorSpace / SetStrokeColorSpace sowie SetFillColor([tint]) verwendet wird, wobei 0 <= tint <= 1 gilt.
  • Intern, THPDFSeparationParams.TintFunc wurde von THPDFDictionaryObject zu der gemeinsamen Basis THPDFObject erweitert, sodass sie entweder einen Function Type 2 (Pfad v2.45.0) oder einen Function Type 0 Stream (Pfad v2.53.0) enthalten kann; beide Formen werden identisch über THPDFArrayObject.AddObject als eine indirekte Referenz vom Typ "N G R" innerhalb des /Separation-Arrays serialisiert.

2026-05-17 Version 2.52.0

  • Es wurde die Registrierung des Funktionstyps 0 (gesampelt) gemäß PDF 1.7 ISO 32000-1 7.10.2 hinzugefügt. Gesampelte Funktionen definieren eine beliebige Eingabe-Ausgabe-Zuordnung als ein reguläres N-dimensionales Gitter von M-dimensionalen Ausgabepunkten; der Renderer interpoliert linear zwischen den Gitterpunkten, um Zwischeneingaben zu berechnen. Verwenden Sie Typ 0, wenn die ICC-Profilfunktionalität übertrieben wäre, aber eine fein abgestimmte Farb-LUT gewünscht ist (Tonkurven für /TransferFunction in ExtGState, gesampelte Farbtransformationen für /Separation / /DeviceN, zusätzlich zu den bereits unterstützten linearen Typ 2- und arithmetischen Typ 4-Pfaden, Halbtontonschwellenkurven oder jede andere PDF-Konstruktion, die ein Funktions-Dictionary verwendet).
  • Die neue Funktion `THotPDF.RegisterSampledFunction(Domain, Range, Size, BitsPerSample, Samples)` erzeugt einen indirekten Stream mit `/FunctionType 0`, der `/Domain (2N)`, `/Range (2M)`, `/Size (N)`, `/BitsPerSample (1, 2, 4, 8, 12, 16, 24 oder 32)`, `/Order 1` (lineare Interpolation) und die komprimierten Rohdaten der Samples enthält. Sie gibt das indirekte `THPDFStreamObject` zurück, sodass Aufrufer es dort verwenden können, wo ein Function-Dictionary erwartet wird.
  • Die Länge des Byte-Arrays für Samples wird anhand von ceil(GridPoints * M * BitsPerSample / 8) validiert. Die Werte für BitsPerSample (8 / 16 / 24 / 32) sind byteweise, im Big-Endian-Format, und Sub-Byte-Werte (1 / 2 / 4 / 12) folgen der in PDF 1.7 §7.10.2 beschriebenen MSB-first-Packmethode, wobei das letzte Byte mit Nullen aufgefüllt wird.
  • Funktionen vom Typ 3 (Zusammenfügung) und Typ 4 (PostScript-Rechner) waren seit v2.18.0 / v2.47.0 intern über HPDFRegisterFunctionType3 / HPDFRegisterFunctionType4 verfügbar; diese Version bringt Typ 0 auf das gleiche Niveau der öffentlichen API-Unterstützung.

2026-05-17 Version 2.51.6

  • Die v2.51.x-Sicherheitsprüfung für Binärdateien wurde abgeschlossen, indem der letzte verbleibende Fehler in der `TStringList` für die "Source=Target"-Rückgabewertverarbeitung behoben wurde: `FStructRoleMap` (PDF 1.7 ISO 32000-1 14.7.3 /StructTreeRoot /RoleMap). Benutzerdefinierte Strukturrollen, die über `AddStructRoleMap` registriert wurden, werden auf Windows-Systemen mit der Option "Beta: Use Unicode UTF-8" (CP_ACP=65001) nicht mehr stillschweigend verändert; die Speicherung wurde in ein dynamisches Array von (Source: TBytes; Target: TBytes)-Datensätzen migriert, wobei bei jedem Einfügen/Lesen ein byte-erhaltender `Move()`-Vorgang durchgeführt wird. Standard-PDF-Strukturtypen (Document, P, H1..H6, Span, Div usw.) sind gemäß Spezifikation ASCII, sodass frühere Versionen in der Praxis funktionierten; diese Korrektur ist nur für Aufrufer relevant, die autoringspezifische Latin-1-Rollen auf die Standardtypen abbilden.
  • Die PDF-Namens-Escape-Sequenz #XX (PDF 1.7 §7.3.5) wurde auf Dictionary-SCHLÜSSEL in `SaveDictionaryObject` erweitert. Zuvor wurden Dictionary-Schlüssel unverändert in den Ausgabestrom kopiert, wodurch Bytes >= 0x80 nicht escaped wurden und eine nicht-konforme Ausgabe erzeugt wurde – dies konnte über `AddStructRoleMap` mit einer nicht-ASCII-Quelldatei erreicht werden. Die Byte-Ebene-Trim- und #-XX-Escape-Logik befindet sich jetzt in einer gemeinsamen Hilfsfunktion (`_EscapePDFNameBytes`), die sowohl von `SaveNameObject` (Namenswerte) als auch von `SaveDictionaryObject` (Dictionary-Schlüssel) aufgerufen wird. ASCII-Schlüssel (der universelle Fall für von HotPDF generierte Dictionaries) werden in eine byte-identische Ausgabe umgewandelt, sodass bestehende Dateien und Tests nicht betroffen sind.
  • Nach dieser Veröffentlichung ist die v2.51.x-Binärsicherheitskette (für Empfänger von PubSec, DeviceN-Farbnamen, Ausgabe von PDF-Namenswerten, Ausgabe von PDF-Namenschlüsseln, Speicherung von Strukturrollen) strukturell vollständig – es gibt keine verbleibenden AnsiString-zu-UnicodeString-Konvertierungen für beliebige Byte-Blöcke, die HotPDF bekannt sind. 34 von 34 Tests sind erfolgreich, ebenso wie 27 von 27 Verifizierungen.

2026-05-17 Version 2.51.5

  • Die Überprüfung der Binärsicherheit wurde in zwei weiteren Bereichen fortgesetzt, die dazu führen könnten, dass Nicht-ASCII-Bytes auf Systemen, auf denen Windows CP_ACP=65001 ("Beta: Verwenden Sie Unicode UTF-8 für die weltweite Sprachunterstützung") aktiviert ist, unbemerkt beschädigt werden.
  • Die Namen der Farbkomponenten werden jetzt als ein dynamisches Array von `TBytes` innerhalb von `THPDFDeviceNParams` gespeichert (früher eine `TStringList` von `UnicodeString`-Einträgen). Die frühere Darstellung erzwang einen `AnsiString` -> `UnicodeString` -> `AnsiString`-Zyklus für jeden Farbnamen, was auf UTF-8-ANSI-Systemen dazu führte, dass jedes Byte >= 0x80 als die 3-Byte-Ersetzungssequenz EF BF BD neu geschrieben wurde. Farbnamen, die nur ASCII-Zeichen enthalten (z. B. PANTONE / Hexachrome und Farbnamen im Stil von "Rot" / "Blau"), waren davon nicht betroffen; benutzerdefinierte Farbnamen, die keine ASCII-Zeichen enthalten (z. B. lateinische Zeichen mit Akzenten in Druckworkflows, die nicht auf Englisch sind), wurden vor dieser Version stillschweigend beschädigt.
  • Der Pfad für die PDF-Namensausgabe (SaveNameObject) ist jetzt byteweise sicher und entspricht den Spezifikationen. Die vorherige Implementierung verwendete `AnsiString(Trim(String(ValObject.Value)))`, was bei jedem auf die Festplatte geschriebenen PDF-Namen denselben destruktiven Rundweg durchführte. Namen werden jetzt durch Bytevergleich ("char <= 0x20") getrimmt (was der Trim-Semantik von Delphi entspricht), und jedes Byte außerhalb des regulären Namensbereichs 0x21..0x7E wird gemäß den in PDF 1.7 ISO 32000-1 7.3.5 geforderten Escape-Sequenzen #XX ausgegeben. ASCII-Namen ohne führende/nachfolgende Leerzeichen und ohne eingebettete spezielle Bytes erzeugen weiterhin bitgenaue Ausgaben wie zuvor, sodass bestehende Dateien und Tests nicht betroffen sind.
  • Ein neuer Verifizierungsmechanismus (smoke_devicen_binary_safe) registriert eine DeviceN-Füllung, deren Name ein eingebettetes 0xA0-Byte enthält, und stellt sicher, dass das ausgegebene /Names-Array die spezifikationskonforme "#A0"-Sequenz enthält, anstatt der fehlerhaften "#EF#BF#BD"-Sequenz. Mit dieser Version wird die v2.51.x-Binärsicherheitskette (PubSec-Empfänger, DeviceN-Füllungsnamen, generische PDF-Namensausgabe) abgeschlossen; 33 von 33 Smoke-Tests und 26 von 26 Verifizierungen sind erfolgreich.

2026-05-17 Version 2.51.4

  • Es wurde ein stiller Datenverlust im Empfänger-Umschlag des Public-Key Security Handlers behoben (PDF 1.7, ISO 32000-1, 7.6.5). Wenn das Host-System die Option "Beta: Verwenden von Unicode UTF-8 für globale Sprachunterstützung" aktiviert hat (CP_ACP=65001), führte die vorherige Speicherung von PKCS#7 envelopedData-Blöcken in einer TStringList-basierten Struktur zu einer AnsiString -> UnicodeString -> AnsiString-Konvertierung, die jedes Nicht-ASCII-Byte als die UTF-8-Ersatzsequenz (EF BF BD) neu schrieb. Diese Beschädigung wurde sowohl in die SHA-1-Datei-Schlüsselberechnung (Algorithmus 9) als auch in die generierten /Recipients-Hex-Strings übernommen, sodass die erstellte PDF-Datei zwar mit HotPDFs eigenem, beschädigten Schlüssel entschlüsselt werden konnte, aber kein anderer Reader den gleichen Schlüssel aus den ursprünglichen Umschlag-Bytes ableiten konnte – was bedeutet, dass die verschlüsselte Datei effektiv nur mit HotPDF auf demselben System mit der CP_ACP-Einstellung lesbar war.
  • Die Korrektur ersetzt den Empfänger-Speicher durch ein dynamisches Array von TBytes; die öffentliche AddPubKeyRecipient-API-Signatur bleibt unverändert. Envelope-Bytes werden jetzt unverändert über Move() kopiert; es gibt keinen Codepage-Konvertierungspfad mehr.
  • /Recipients hex reproduziert jetzt die übergebenen Umschläge byte-für-byte, unabhängig von der Host-Locale; Acrobat, Foxit, qpdf und alle PKCS#7-fähigen Reader können den Dateiverschlüsselungsschlüssel wiederherstellen, wie in der Spezifikation definiert.
  • Ein neuer Verifizierungsmechanismus für den gesamten Prozess (smoke_pubsec_verify) wurde in Version v2.33.0 hinzugefügt und schlägt seitdem bei diesem Build fehl; Version v2.51.4 behebt dies und ändert den Status von "Fehler" zu "OK". Mit dieser Version ist die gesamte Überprüfungskette für v2.51.x abgeschlossen (R=5-Überprüfung, R=6-Benutzerpasswortüberprüfung, R=6-Eigentümerpasswort-K0-Korrektur, Korrektur für die öffentlichen Schlüssel-Empfängerbytes), und zum ersten Mal seit v2.33.0 bestehen alle 25 Smoke-Verifizierungen problemlos.

2026-05-16 Version 2.51.3

  • Behoben wurde die AES-256 V=5 R=6-Eigentümerpasswort-Validierungs-Hash-Funktion, sodass sie der in ISO 32000-2 Algorithmus 2.B beschriebenen Spezifikation entspricht. Die für PDF 2.0 definierte Hash-Berechnung legt den anfänglichen K-Zustand als SHA-256(Passwort || Salt || Udata) fest, wobei Udata für die Ableitung des Eigentümerpassworts der vollständige 48-Byte-Eintrag /U ist. In früheren HotPDF-Versionen (v2.22.0 bis v2.51.2) wurde Udata nur in den iterativen K1-Schritt integriert und nicht in den anfänglichen K aufgenommen, was zu einem nicht spezifikationskonformen /O[0:32]-Hash führte, den Acrobat-, Foxit- und qpdf-ähnliche Reader während der Eigentümerpasswort-Validierung ablehnten. Die Benutzerpasswort-Entschlüsselung war davon nicht betroffen, da ihre Hash-Berechnung mit einem leeren Udata-Argument aufgerufen wird und daher bitgenau gleich ist, unabhängig davon, ob die Korrektur angewendet wurde oder nicht.
  • Acrobat, Foxit und qpdf validieren jetzt das Besitzerpasswort anhand von von HotPDF generierten R=6-Dateien. /O[0:32]- und /OE-Werte, die vor v2.51.3 erstellt wurden, sind weiterhin lesbar für die Benutzerpasswortentschlüsselung, können aber nicht über ihr Besitzerpasswort durch standardkonforme Reader entsperrt werden; generieren Sie betroffene R=6-Dateien mit v2.51.3 neu, wenn eine externe Validierung des Besitzerpassworts erforderlich ist.
  • /U / /UE / /Perms: V=5 R=5; die Pfade sind byte-identisch zur Ausgabe vor v2.51.3; die Änderung ist auf den anfänglichen K SHA-256 innerhalb von PDF20HashDanceR6 beschränkt und ändert die Ausgabe nur, wenn sie mit einem nicht leeren UEntry aufgerufen wird (der Aufruf für das Besitzerpasswort in CreateKeysV5).
  • Ein neuer, bidirektionaler Audit-Prozess (smoke_aes256_r6_owner_verify) ermittelt /O[0:32] sowohl über den Präfix- als auch über den Spezifikationsalgorithmus; er stellt fest, dass das erzeugte /O[0:32] mit der Spezifikationsvariante übereinstimmt und dass die Präfix-Variante die Ausgabe nicht mehr reproduziert.

2026-05-16 Version 2.51.2

  • Die Prüfung von /Perms in der Version v2.51.1 wurde erweitert, um den Standard-Sicherheitsmechanismus V=5 R=6 ("hash dance") gemäß (ISO 32000-2 7.6.4.3.4 / Algorithmus 2.B) abzudecken. Ein neuer Verifizierer implementiert den iterativen SHA-256 / SHA-384 / SHA-512 + AES-128-CBC-Mixer in reinem Python, leitet den 32-Byte-Dateiverschlüsselungsschlüssel aus dem leeren Benutzerpasswort ab, entschlüsselt den 16-Byte-Block /Perms mit AES-256-ECB und überprüft jedes Feld anhand der Werte im Verschlüsselungs-Dictionary (/P im Little-Endian-Format, 0xFF als Füllzeichen, die Tags 'T' / 'F', die Literale 'a' 'd' 'b'). Es gibt keine Verhaltensänderung; diese Version deckt ausschließlich Regressionen für den Pfad R=6 ab, der mit der in v2.51.1 eingeführten Sperrung R=5 übereinstimmt.

2026-05-16 Version 2.51.1

  • Im Regressionstest wurde die Bindung von `/P` zu `/Perms` für den Standard-Sicherheitshandler mit V=5 und R=5 gesperrt. Der AES-256-Verschlüsselungspfad erzeugt einen 16-Byte-`/Perms`-Block gemäß ISO 32000-1 Algorithmus 10: Bytes 0-3 enthalten den `/P`-Wert im Format von 32-Bit-Little-Endian, Bytes 4-7 sind Füllbytes mit 0xFF, Byte 8 enthält das Tracking-Flag `/EncryptMetadata` ('T' oder 'F'), Bytes 9-11 sind die literalen Marker 'a', 'd', 'b', und Bytes 12-15 sind zufällige Füllbytes. Ein neuer Rundum-Audit leitet den Dateiverschlüsselungsschlüssel aus dem Benutzerpasswort mithilfe von Algorithmus 2.A ab (SHA-256(Passwort || U_Key_Salt) -> AES-CBC-Entschlüsselung von /UE -> Dateischlüssel), entschlüsselt `/Perms` mit AES-256-ECB und überprüft jedes Feld anhand der Werte im Verschlüsselungs-Dictionary. Es gibt keine Verhaltensänderung; diese Version dient ausschließlich der Regressionstests, um sicherzustellen, dass eine zukünftige Refaktorierung die spezifizierte Beziehung zwischen `/P` und `/Perms` nicht unbemerkt unterbricht.

2026-05-16 Version 2.51.0

  • Es wurde Unterstützung für Tensorprodukt-Patch-Mesh-Shading hinzugefügt (PDF 1.3+ ISO 32000-1 8.7.4.5.7, Shading Type 7), der letzte Eintrag in der Familie der Mesh-Shading-Typen, nach Type 4 (freiformig) in v2.48, Type 5 (Gitter) in v2.49 und Type 6 (Coons) in v2.50. Jeder Tensorprodukt-Patch enthält ein vollständiges 4x4-Gitter aus bikubischen Bezier-Kontrollpunkten p[i][j] (12 am Rand + 4 im Inneren) sowie eine Farbe pro Ecke, was eine feingranulare Steuerung sowohl der Patch-Grenze als auch ihres Inneren ermöglicht. Nützlich für SVG-Mesh-Gradient-Rundtrips und für alle Vektorgrafiken, die eine Tensorprodukt-Bezier-Oberfläche anstelle einer Coons-Oberfläche benötigen.
  • Neue Funktion: `THotPDF.RegisterTensorProductPatchMesh(XMin, YMin, XMax, YMax, NumComponents, Patches)` erzeugt einen binären Stream vom Typ `/ShadingType 7` mit `/BitsPerCoordinate 16`, `/BitsPerComponent 8` und `/BitsPerFlag 8`, verpackt ihn in ein Pattern vom Typ 2 und gibt einen Pattern-Namen (Sh1, Sh2, ...) zurück, der über die regulären Pipelines `SetFillPattern` bzw. `SetStrokePattern` verwendet werden kann.
  • Die Patches-Ebene packt jeden Patch als 16 Kontrollpunkte (32 Gleitkommazahlen X+Y in der Reihenfolge des Speeds: p[0][0..3], p[1][3], p[2][3], p[3][3], p[3][2..0], p[2][0], p[1][0], p[1][1], p[1][2], p[2][2], p[2][1]) gefolgt von 4 Eckfarben (4 * NumComponents Gleitkommazahlen bei p[0][0] / p[0][3] / p[3][3] / p[3][0]), wobei der Abstand stride = 32 + 4 * NumComponents beträgt. Jeder erzeugte Patch enthält das Flag = 0 (unabhängiger Patch).
  • Mit dieser Version werden alle Mesh-Shading-Familien (Typen 4, 5, 6 und 7) gemäß ISO 32000-1 8.7.4.5 abgedeckt.

2026-05-16 Version 2.50.0

  • Es wurde Unterstützung für die Coons-Patch-Mesh-Schattierung hinzugefügt (PDF 1.3+ ISO 32000-1 8.7.4.5.6, Schattierungstyp 6) – der dritte Eintrag in der Familie der Mesh-Schattierungen, nach Typ 4 (freiform) in v2.48 und Typ 5 (Gitter) in v2.49. Jedes Coons-Patch wird von vier kubischen Bézier-Kurven begrenzt und hat eine Farbe pro Ecke; der Renderer passt die Coons-Oberfläche zwischen den vier Kanten an und erzeugt so ein beliebig gekrümmtes, farbiges Viereck. Nützlich für Folien- und Metallic-Verläufe auf gebogenen Pfaden, SVG-abgeleiteten Farbverläufen und für jedes Viereck mit gekrümmten Kanten, das andernfalls viele kleine Dreiecke benötigen würde, um es zu approximieren.
  • Neue Funktion: `THotPDF.RegisterCoonsPatchMesh(XMin, YMin, XMax, YMax, NumComponents, Patches)` erzeugt einen binären Stream mit `/ShadingType 6`, wobei `/BitsPerCoordinate` auf 16, `/BitsPerComponent` auf 8 und `/BitsPerFlag` auf 8 gesetzt ist. Dieser Stream wird in ein Pattern vom Typ 2 eingebettet, und ein Pattern-Name (Sh1, Sh2, ...) wird zurückgegeben, der über die regulären Pipelines `SetFillPattern` bzw. `SetStrokePattern` verwendet werden kann.
  • Die Patches-Flachstruktur packt jeden Patch als 12 Kontrollpunkte (24 Gleitkommazahlen X+Y), gefolgt von 4 Eckfarben (4 * NumComponents Gleitkommazahlen), wobei der Abstand 24 + 4 * NumComponents beträgt. Die 12 Kontrollpunkte sind in der Reihenfolge c1 bis c12 angeordnet, im Uhrzeigersinn um die Patch-Grenze, beginnend bei Ecke 1, wobei c1, c4, c7 und c10 an den vier Ecken liegen und die restlichen 8 innere Bezier-Handgriffe sind. Jeder erzeugte Patch hat das Flag = 0 (unabhängiger Patch); die Fortsetzungs-Flags 1/2/3 (Kantenteilung) werden in dieser komfortablen Überladung nicht angezeigt.
  • Typ 7 (Tensorprodukt-Patch-Mesh) bleibt weiterhin Gegenstand zukünftiger Arbeiten.

2026-05-16 Version 2.49.0

  • Hinzugefügt wurde Unterstützung für dreieckige Gitternetzstrukturen mit Gouraud-Schattierung (PDF 1.3+ ISO 32000-1 8.7.4.5.5, Schattierungstyp 5), die die Ergänzung zu den frei geformten Typ-4-Objekten in v2.48.0 darstellt. Verwenden Sie diese Funktion, wenn die Quelldaten bereits in einem regelmäßigen Abtastgitter angeordnet sind (z. B. Gelände, FEA-Ergebnisse, wissenschaftliche Heatmaps) und die Anwendung keine explizite Dreieckt-Topologie ausgeben möchte – der Renderer trianguliert automatisch jedes benachbarte Paar von Zeilen zu einem Dreiecksstreifen.
  • Die neue Funktion `THotPDF.RegisterLatticeFormGouraudShading(XMin, YMin, XMax, YMax, NumComponents, VerticesPerRow, Vertices)` packt ein M-Zeilen x N-Spalten-Gitter in einen binären Schattierungs-Stream mit `/BitsPerCoordinate 16`, `/BitsPerComponent 8` und `/VerticesPerRow N`. Im Gegensatz zu Typ 4 gibt es kein Byte-Flag pro Vertex, und `/BitsPerFlag` ist im Schattierungs-Dictionary nicht vorhanden. Gibt einen Pattern-Namen (Sh1, Sh2, ...) zurück, der über die regulären Pipelines `SetFillPattern` / `SetStrokePattern` verwendet werden kann.
  • Das flache Array von Eckpunkten ist zeilenweise angeordnet, wobei jeder Eckpunkt die Werte (X, Y, c0, c1, ..., c_{NumComponents-1}) liefert; die Gesamtzahl der Eckpunkte muss ein Vielfaches von VerticesPerRow sein und mindestens zwei Zeilen enthalten. NumComponents akzeptiert die Werte 1 (DeviceGray), 3 (DeviceRGB) oder 4 (DeviceCMYK).
  • Die Mesh-Schattierungen vom Typ 6 (Coons-Patch) und vom Typ 7 (Tensorprodukt) sind weiterhin in der Planung.

2026-05-16 Version 2.48.0

  • Es wurde Unterstützung für freiformige Gouraud-schattierte Dreiechgitter hinzugefügt (PDF 1.3+ ISO 32000-1 8.7.4.5.4, Shading Type 4) für Farbverläufe in Vektorgrafiken, die allgemeiner sind als die vorhandenen axialen/radialen Varianten vom Typ 2/3. Jede triangulierte Oberfläche mit Farben pro Eckpunkt kann jetzt direkt eingebettet werden.
  • Die neue Funktion `THotPDF.RegisterFreeFormGouraudShading(XMin, YMin, XMax, YMax, NumComponents, Vertices)` verpackt das Dreiecksnetz in einen binären Shading-Stream mit `/BitsPerCoordinate 16`, `/BitsPerComponent 8` und `/BitsPerFlag 8`, umschließt es in einem Pattern vom Typ 2 und gibt einen Pattern-Namen (Sh1, Sh2, ...) zurück, der über die regulären Pipelines `THPDFPage.SetFillPattern` bzw. `THPDFPage.SetStrokePattern` verwendet werden kann.
  • Ebenen werden als flaches Array von Eckpunkten gespeichert (X, Y, c0, c1, ...), wobei jeder Eckpunkt; jede drei aufeinanderfolgende Eckpunkte bilden ein unabhängiges Dreieck. Die Ausgabekoordinaten/Komponenten sind als Big-Endian-vorzeichenlose Ganzzahlen kodiert; das "/Decode"-Array ordnet den kodierten Bereich zurück zum vom Benutzer angegebenen Begrenzungsrahmen im Benutzeraum.

2026-05-16 Version 2.47.0

  • Hinzugefügt wurde Unterstützung für den DeviceN-Farbraum (PDF 1.3+ ISO 32000-1 8.6.6.5), wodurch Separation für den Druck mit sechs Farben, metallischen/fluoreszierenden Tintenmischungen und benutzerdefinierten Farbworkflows in PDF/X verallgemeinert wird. Die neue Funktion `THotPDF.RegisterDeviceN(ColorantNames, AlternateCS, TintC1Matrix)` gibt einen automatisch generierten Farbnamen (DevN1, DevN2, ...) zurück, der die reguläre Pipeline `SetFillColorSpace + SetFillColor` mit N Farbanteil-Operanden im Bereich [0..1] steuert.
  • Die Farbton-Transformation ist eine PostScript-Berechnungsfunktion vom Typ 4, die eine lineare, gewichtete Mischung über die angegebene N x M-Matrix erzeugt. Wenn ein Wiedergabe-Programm keine Unterstützung für spezielle Farben bietet, wird jeder Ausgabekanal als Summe der Farbanteile interpoliert.
  • ColorantNames akzeptiert jeden beliebigen Farbnamen; Leerzeichen werden gemäß PDF 1.7 §7.3.5 durch den bestehenden Namensschreibpfad in "#20" umgewandelt. Der spezielle Name ""None"" kennzeichnet einen nicht verwendeten Farbanteil.
  • AlternateCS akzeptiert DeviceGray, DeviceRGB oder DeviceCMYK; jeder andere Wert führt zu einer Ausnahme.

2026-05-15 Version 2.46.0

  • Erweiterte Generierung von Erscheinungs-Streams für AcroForm-Textfeldern (AutoFormAppearances) gemäß PDF 1.7 ISO 32000-1 12.7.4.3. In der Basisversion v2.28.0 wurde für jedes Textfeld ein einzelner Literal-String erzeugt; mehrzeilige und Kombinationsfelder verwenden jetzt eigene AP-Layout-Pfade.
  • Mehrzeilige Textfelder (Flags einschließlich ffMultiline) setzen den ursprünglichen Wert um, um ihn an die Breite des Widgets anzupassen, berücksichtigen eingebettete CR/LF/CRLF-Trennzeichen, kürzen den Text auf die Anzahl der sichtbaren Zeilen und erzeugen ein korrektes mehrzeiliges Layout mit Td + T* und einem führenden /TL.
  • Kombinierte Textfelder (Flags einschließlich ffComb zusammen mit MaxLen > 0) rendern jedes Zeichen in einer eigenen, gleichbreiten Zelle, wobei für jedes Glyphe eine absolute Transformationsmatrix (Tm) verwendet wird, was dem entspricht, wie Acrobat es zeichnet.
  • Einzeilige Textfelder behalten das Layout der Version v2.28.0 byte für Byte, sodass ältere Aufrufer keine Verhaltensänderungen feststellen.

2026-05-14 Version 2.45.0

  • Hinzugefügte Unterstützung für Farbräume zur Trennung für Druckworkflows mit Sonderfarben gemäß ISO 32000-1 8.6.6.4. Die neue Funktion THotPDF.RegisterSeparation(ColorantName, AlternateCS, TintC1) gibt einen automatisch generierten Farbnamen (Sep1, Sep2, ...) zurück, der die reguläre Pipeline für SetFillColorSpace / SetStrokeColorSpace + SetFillColor([tint]) / SetStrokeColor([tint]) mit einem einzigen Farbwert in [0..1] steuert.
  • AlternateCS akzeptiert DeviceGray, DeviceRGB oder DeviceCMYK; TintC1 beschreibt die Farbe der Mischfarbe bei voller Stärke (tint = 1.0). Eine lineare Funktion vom Typ 2 für die Farbtonumwandlung wird intern erstellt, sodass eine alternative Darstellung in Viewern ohne Unterstützung für Mischfarben eine sanfte Interpolation zwischen keiner Farbmenge (tint = 0) und TintC1 (tint = 1) ermöglicht.
  • Pantone und andere Farbbegriffe mit Leerzeichen werden direkt akzeptiert – HotPDF wandelt diese in ""#20""-Sequenzen um, gemäß PDF 1.7 §7.3.5, beim Schreiben des Farbnamens.
  • Verweigert Dokumente, die älter als PDF 1.3 sind, durch die Einstellung "RequirePDFVersion", sodass die Ausgabe im strikten Modus 1.2 oder früher weiterhin konform bleibt.

2026-05-14 Version 2.44.0

  • Hinzugefügt wurde Unterstützung für den CIELab-Farbraum gemäß ISO 32000-1 8.6.5.3. Die neue Funktion `THotPDF.RegisterLabColorSpace(Xw, Yw, Zw, aMin, aMax, bMin, bMax)` gibt einen automatisch generierten Farbnamen (Lab1, Lab2, ...) zurück, der die reguläre `THPDFPage.SetFillColorSpace / SetStrokeColorSpace + SetFillColor([L, a, b]) / SetStrokeColor([L, a, b])`-Pipeline steuert.
  • Üblicher Arbeitsablauf: Für jeden Farbraum wird ein einzelner Wert registriert (D50 für ICC-Druck, D65 für sRGB-ähnliche Anzeige), anschließend wird mit L* im Bereich [0..100] und a*, b* im gewählten Bereich (typischerweise -128..127) eingefärbt. PDF-Reader (Adobe Acrobat, Foxit, MuPDF, Browser-Viewer) berücksichtigen den Weißpunkt bei der Umwandlung von Lab in den für die Anzeige verwendeten RGB-Farbraum.
  • Verweigert Dokumente, die älter als PDF 1.3 sind, durch die Einstellung "RequirePDFVersion", sodass die Ausgabe im strikten Modus 1.2 oder früher weiterhin konform bleibt.

2026-05-14 Version 2.43.1

  • Der vorhandene CCITTFaxDecode-Encoder wurde in einem realen Test mit einem zweitönigen Bild (240x120 pf1bit, abwechselnde Bandmuster) vollständig überprüft: Das Bild wird korrekt in allen drei Modi eingebettet (icCCITT31 G3 1D / icCCITT32 G3 2D / icCCITT42 G4 / T.6). Die Größen der codierten Datenströme entsprechen der erwarteten Komprimierungsreihenfolge G3-1D > G3-2D > G4. Die Datenströme werden in Adobe Acrobat / Foxit / MuPDF ohne Warnungen decodiert, und die Pixelabtastung bestätigt das abwechselnde Schwarz-Weiß-Bandmuster in allen drei Modi. Es wurden keine Änderungen am Encoder-Code vorgenommen; diese Version fixiert lediglich die vorhandene Abdeckung von PDF 1.7 und ISO 32000-1 7.4.9 im Smoke-Test-Suite.

2026-05-14 Version 2.43.0

  • Es wurde ein end-to-end-Füllmuster ohne Farbe (PaintType=2) gemäß ISO 32000-1 8.6.6.1 hinzugefügt. Der Musterstrom enthält nur die Geometrie des Musters (keine Farbe); die Füllfarbe wird über den scn / SCN-Operator im Seiteninhaltsstrom während des Füll-/Strichvorgangs angegeben.
  • Neue Methoden `SetFillPatternRGB`, `SetStrokePatternRGB`, `SetFillPatternGray`, `SetStrokePatternGray`, `SetFillPatternCMYK` und `SetStrokePatternCMYK` für `THPDFPage` akzeptieren einen registrierten Namen für ein undefiniertes Muster sowie die Farbanteile (DeviceRGB, DeviceGray oder DeviceCMYK im Bereich [0..1]). Jeder Aufruf registriert automatisch den entsprechenden Farb-Namespace [/Pattern /BaseCS] im Ressourcen-/Farb-Namespace des Seitenobjekts beim ersten Gebrauch.
  • Die vorhandenen Funktionen `SetFillPattern` und `SetStrokePattern` decken weiterhin die Farbvarianten von `PaintType=1` ab – die Füllung hat ihre eigene Farbe, und keine Farbanteile werden durch den Operator beeinflusst.
  • Beide Code-Pfade verwenden den vorhandenen Einstiegspunkt `RegisterTilingPattern`; wenn `Colored=true` gesetzt ist, wird `PaintType=1` (farbig) ausgegeben, während `Colored=false` `PaintType=2` (nicht farbig) ausgibt.

2026-05-14 Version 2.42.0

  • Hinzugefügte Unterstützung für PDF 1.4 Soft-Mask-Bilder (SMask). Die neue Methode `THotPDF.AddImageWithSMask` akzeptiert eine rohe RGB-Ebene und eine parallele 8-Bit-Alpha-Ebene, erzeugt das Farb-XObject zusammen mit einem DeviceGray-Soft-Mask-XObject und verknüpft die `/SMask`-Querverweise gemäß ISO 32000-1 8.9.5.4. Verwenden Sie den zurückgegebenen Bildindex mit der vorhandenen Methode `ShowImage` – keine anderen Änderungen sind erforderlich.
  • Es wurde die Hilfsfunktion THotPDF.AddImageWithSMask32 hinzugefügt, die die Farb- und Alpha-Ebenen aus einem 32-Bit-BGRA-TBitmap extrahiert, sodass PNG-ähnliche Bitmaps mit Alphakanal in einem einzigen Aufruf eingebettet werden können.
  • Beide Aufrufe werden bei Dokumenten, die älter als PDF 1.4 sind, abgelehnt, wodurch die strikte Modus-Ausgabe 1.3 weiterhin kompatibel bleibt.

2026-05-14 Version 2.41.0

  • Hinzugefügt: Unterstützung für die Ausgabe von PDF 1.5-Objektströmen. Wenn `THotPDF.UseObjectStreams` auf `true` gesetzt ist, zusammen mit den Optionen `UseXRefStream` und `SaveToStream`, werden indirekte Objekte (alles außer Strömen, dem Verschlüsselungs-Dictionary und den von der Trailer-Sektion referenzierten Catalog- und Info-Dictionaries) in einen oder mehrere Container-Streams vom Typ `/Type /ObjStm` geschrieben.
  • Reduzierung der Dateigröße bei umfangreichen PDF-Dokumenten (mit vielen Seiten, Annotationen, AcroForm-Elementen, Strukturbaum-Elementen oder optionalen Inhaltsbereichen). Ein Test mit rein grafischen Inhalten auf 30 Seiten reduziert die Dateigröße von 14502 Bytes auf 8488 Bytes (um 41,5 % kleiner), ohne sichtbare Änderungen.
  • Der Querverweis-Stream gibt jetzt Typ-2-komprimierte Objekte aus, wobei Feld 2 die Host-Objektnummer (ObjStm) ist und Feld 3 der Index des Eintrags innerhalb dieses Streams ist. `UseObjectStreams` wird automatisch auf `false` gesetzt, wenn `UseXRefStream` deaktiviert ist (da textuelle Querverweise keine Typ-2-Einträge kodieren können) oder wenn die Version unter PDF 1.5 liegt.

2026-05-12 Version 2.40.1

  • Behoben wurde die Darstellung generierter PDFs in Adobe Acrobat, Foxit, SumatraPDF und browserintegrierten Ansichten unter Windows 10/11, wenn die Option "Beta: Verwenden von Unicode UTF-8 für globale Sprachunterstützung" aktiviert ist. Seiteninhaltsströme enthalten nicht mehr eine unnötige UTF-8 BOM-Präambel, die von strikten PDF-Readern als Syntaxfehler abgelehnt wurde.

2026-05-11 Version 2.40.0

  • Es wurde eine CID-basierte CFF-Schriftart-Subsetting-Funktion hinzugefügt, die große CJK- und Multi-FD-OpenType-CFF-Schriftarten unterstützt, einschließlich Adobe CJK-Schriftarten, die FDArray- und FDSelect-Daten verwenden.
  • Verbesserte CFF-Subroutine-Verarbeitung, sodass große OpenType-CFF-Schriftarten als kompakte PDF-Teilmengen eingebettet werden können, anstatt als vollständige Schriftdateien.

2026-05-11 Version 2.39.1

  • Verbesserte Kompatibilität mit OpenType-CFF-Schriftarten in realen Anwendungsszenarien, einschließlich Schriftarten im Stil von Adobe MinionPro mit größeren CFF-Tabellen und mehrbyte-Offsets.
  • Es wurde das HPDFExtractTTFPostScriptName-Element freigelegt, sodass Anwendungen mit benutzerdefiniertem Font-Ladecode den PostScript-Namen aus TrueType- und OpenType-CFF-Fontdaten auslesen können.

2026-05-11 Version 2.39.0

  • Für CFF-Schriftarten wurde das globale und lokale Subsetting von Subroutinen hinzugefügt, wodurch die Größe der eingebetteten OpenType-CFF-Schriftarten weiter reduziert wird.
  • Beibehaltener CFF-Subroutine-Bytecode, wobei ungenutzte Einträge sicher durch kompakte Rückgabestubs ersetzt wurden.

2026-05-11 Version 2.38.0

  • In StoreFont wurde eine automatische OpenType-CFF-Einbettung hinzugefügt. HotPDF generiert jetzt CFF-basierte CID-Schriftarten über /FontFile3, wenn eine von GDI geladene Schriftart einen sfnt-basierten OpenType-CFF-Container ist.
  • Es wurden die Hilfs-APIs HPDFSfntIsOTF, HPDFOTFFindCFFTable und HPDFSubsetOTFContainer hinzugefügt, die für Anwendungen nützlich sind, die OpenType-CFF-Schriftarten direkt verarbeiten.

2026-05-11 Version 2.37.0

  • Es wurde HPDFSubsetCFF für das Compact Font Format und Type 1C-Schriftdateien hinzugefügt, wodurch kleinere eingebettete CFF-Schriftprogramme ermöglicht werden.
  • Die ursprünglichen Glyphen-IDs wurden während des CFF-Subsetting beibehalten, sodass die bestehende Type0 / Identity-H-Textausgabe weiterhin kompatibel ist.
  • Der CFF-Subsetter wurde für Anwendungen freigelegt, die Schriftarten über ihre eigene Pipeline laden, bevor Daten an HotPDF übergeben werden.

2026-05-10 Version 2.36.0

  • THotPDF wurde um optionales TrueType-Schriftart-Subsetting mit `THotPDF.EnableFontSubsetting` erweitert, wodurch die Größe der eingebetteten Schriftarten oft um mehr als 90 % reduziert wird, insbesondere bei Dokumenten, die nur einen kleinen Satz von Glyphen verwenden.
  • Für Identity-H-Text wurde eine PDF-Standard-Subset-Schriftartbenennung hinzugefügt, wobei die Glyphen-IDs der ursprünglichen Schriftart beibehalten wurden.
  • Die vollständige Schriftart-Einbettung wurde weiterhin als Standard für Workflows beibehalten, die das vollständige Schriftartprogramm erfordern.

2026-05-10 Version 2.35.1

  • Behoben wurde ein Absturz von Adobe Acrobat im Zusammenhang mit der Funktion "Schriftart erfassen", der beim Öffnen von PDFs auftrat, die mit ersetzten Windows-Schriftarten erstellt wurden. HotPDF ordnet jetzt PDF-Schriftartnamen dem PostScript-Namen innerhalb der eingebetteten TrueType-Daten zu.

2026-05-10 Version 2.35.0

  • Es wurde eine inkrementelle PDF-Update-Funktion hinzugefügt, die mit `THotPDF.BeginIncrementalUpdate` und `THotPDF.SaveIncrementalUpdate` verwendet wird. Vorhandene Quelldaten werden beibehalten, und neue PDF-Objekte werden in einer konformen inkrementellen Revision angehängt.
  • Es wurde THotPDF.MarkDirty hinzugefügt, sodass Anwendungen geänderte Objekte während inkrementeller Updates explizit erneut speichern können.
  • Mehrfachsignatur-Workflows wurden aktiviert, indem zuvor signierte Bytebereiche beibehalten und gleichzeitig spätere Signaturfelder oder Dokumentänderungen hinzugefügt wurden.

2026-05-10 Version 2.34.0

  • Es wurden neue Randstile für Anmerkungen über `THPDFPage.SetAnnotationBorderStyle` hinzugefügt, darunter durchgezogene, gestrichelte, abgeschrägte, eingelassene und unterstrichene Stile.
  • Es wurden verknüpfte Popup-Annotationen hinzugefügt. Neue Popups können nun auf ihre übergeordnete Annotation verweisen, sodass Betrachter die erwartete Kommentarverbindung anzeigen.
  • Hinzugefügt wurde THPDFPage.LastAnnotation, um die Formatierung von Annotationen und die Verkettung von Popups zu vereinfachen, ohne bestehende Aufrufe zur Erstellung von Annotationen ändern zu müssen.

2026-05-10 Version 2.33.0

  • Es wurde Unterstützung für Public-Key-Sicherheitsmechanismen für die PDF-Verschlüsselung hinzugefügt. Dokumente können jetzt für X.509-Zertifikatsinhaber verschlüsselt werden, anstatt nur mit gemeinsamen Passwörtern.
  • THotPDF.EnablePubKeyEncryption und THotPDF.AddPubKeyRecipient wurden hinzugefügt, um Verschlüsselungsabläufe mit Zertifikaten und Empfängern zu ermöglichen.
  • Es wurde eine reine Pascal-Implementierung von SHA-1 in HPDFCrypt hinzugefügt, zusätzlich zu den bereits vorhandenen Hash-Funktionen.

2026-05-10 Version 2.32.0

  • THPDFPage.SetTransparencyGroup und SetTransparencyGroupICC wurden hinzugefügt, um seitenbezogene Transparenzgruppen zu ermöglichen und eine vorhersehbare Komposition von transparenten PDF-Inhalten zu gewährleisten.
  • Es wurden die Optionen DeviceGray, DeviceRGB, DeviceCMYK, die Option für transparente Farbflächen und die ICC-Profil-Transparenzgruppe hinzugefügt.
  • THPDFPage.ClearTransparencyGroup wurde hinzugefügt, um eine zuvor zugewiesene Seitentransparenzgruppe zu entfernen.

2026-05-09 Version 2.31.0

  • Es wurden interaktive Aktionen für AcroForm-Buttons hinzugefügt. Vor dieser Version konnte HotPDF Button-Widgets platzieren, die korrekt angezeigt wurden, aber keine Funktion beim Anklicken hatten. Buttons können jetzt aktiv ein Formular absenden, Feldwerte zurücksetzen, ein JavaScript-Skript ausführen oder zu einer URI navigieren.
  • Die `SubmitForm`-Aktionen senden die aktuellen Feldwerte des AcroForm an eine Server-URL, wodurch PDF-basierte Datenerfassungsformulare ermöglicht werden, die in Adobe Reader und Foxit ohne separaten Web-Viewer funktionieren.
  • ResetForm setzt alle Felder auf ihre Standardwerte zurück, wobei optional eine benannte Teilmenge von Feldern berücksichtigt werden kann. JavaScript- und URI-Aktionen folgen der gleichen PDF-Versionsbeschränkung, die in v2.26.0 eingeführt wurde.
  • Vor dieser Version akzeptierte `AddPushButtonWithAction` nur visuelle Eigenschaften für das Button-Widget; jetzt können sowohl das Aussehen als auch das Klickverhalten vollständig in einem einzigen Aufruf gesteuert werden.

2026-05-09 Version 2.30.0

  • Für Vollbild-PDF-Präsentationen wurden Seiteneffekte mit `THPDFPage.SetPageTransition` hinzugefügt.
  • Es wurde THPDFPage.SetPageDuration hinzugefügt, sodass Präsentationsseiten nach einer bestimmten Verzögerung automatisch weitergehen können.
  • Es wurde eine versionsempfindliche Behandlung für PDF 1.5-Übergangsarten wie Fly, Push, Cover, Uncover und Fade hinzugefügt.

2026-05-09 Version 2.29.0

  • Die PDF 1.4 ViewerPreferences-Seite wurde vervollständigt, indem ViewArea und ViewClip hinzugefügt wurden, zusätzlich zu den bereits vorhandenen Eigenschaften PrintArea und PrintClip.
  • ViewArea steuert, welcher Seitenbereich vom Betrachter als sichtbarer Bereich auf dem Bildschirm verwendet wird (MediaBox, CropBox, TrimBox, BleedBox oder ArtBox). ViewClip steuert die Clipping-Grenze auf dem Bildschirm – wichtig für Design-Review-PDFs, die Beschnitt- und Randmarkierungen enthalten, die im normalen Anzeigemodus nicht angezeigt werden sollen.
  • Diese Optionen sind besonders nützlich in Vorabprüf- und Vorschau-Workflows, bei denen der angezeigte Bildausschnitt vom für den Druck verwendeten Ausschnitt abweichen muss. Beide Optionen erfordern PDF 1.4 und werden automatisch ausgelassen, wenn eine ältere PDF-Version verwendet wird.

2026-05-09 Version 2.28.0

  • Mit THotPDF.AutoFormAppearances wurde eine optionale Generierung von Erscheinungs-Streams für AcroForm hinzugefügt. Textfelder, Listenfelder, Schaltflächen, Kontrollkästchen und Optionsfelder können jetzt zuverlässig in Betrachtern dargestellt werden, die das "/NeedAppearances"-Flag ignorieren.
  • Es wurden Standard-AcroForm-Ressourcen für Helvetica und ZapfDingbats hinzugefügt, wenn automatische Darstellungen aktiviert sind.
  • Das vorherige Verhalten von AcroForm wurde beibehalten, indem die automatische Anzeige von Formularfeldern standardmäßig deaktiviert bleibt.

2026-05-09 Version 2.27.0

  • Erweiterte Versionsbeschränkungen für PDF-Dateien für die Einträge ViewerPreferences und PageMode. Jeder Präferenzwert erzwingt nun seine minimale PDF-Version: UseAttachments und UseOC erfordern PDF 1.5, PrintScaling erfordert PDF 1.6, und Duplex, NumCopies und PickTrayByPDFSize erfordern PDF 1.7.
  • Dokumente, die für ältere PDF-Versionen generiert werden, lassen nicht unterstützte Viewer-Präferenz-Einträge automatisch weg, um Viewer-Warnungen oder eine stille Fehlinterpretation in strengen PDF-Prozessoren und Archivierungsvalidatoren zu vermeiden.
  • Wenn THotPDF.StrictVersionLock aktiviert ist, enthalten PDF-Dateien der Version 1.3 oder 1.4 niemals neuere Viewer-Präferenzfelder, wodurch die Dateien weiterhin den Anforderungen von Druckproduktions- und Langzeitarchivierungs-Workflows entsprechen.

2026-05-09 Version 2.26.0

  • Zu mehreren älteren APIs wurden PDF-Versionsprüfungen hinzugefügt, die zuvor Funktionen unabhängig von der Ziel-Dokumentversion zuließen. Annotationstypen, JavaScript-Aktionen, Type 0-Schriftarten, ToUnicode-CMaps und Katalog-Zusatzaktionen überprüfen jetzt, ob die Dokumentversion diese unterstützt, bevor sie geschrieben werden.
  • Dokumente, die für PDF 1.0 oder PDF 1.1 erstellt wurden, werden automatisch auf die erforderliche Version aktualisiert, wenn eine neuere Funktion verwendet wird. Dadurch wird die automatische Generierung von Ausgaben, die gegen die Spezifikation verstoßen, verhindert, ohne dass Änderungen im aufrufenden Code erforderlich sind.
  • Wenn THotPDF.StrictVersionLock aktiviert ist, werden Funktionsaufrufe, die ein Versionsupdate erfordern, abgelehnt, anstatt das Dokument stillschweigend auf eine höhere Version zu aktualisieren. Dies unterstützt Arbeitsabläufe, die eine Ausgabe in einer exakten PDF-Version erfordern.
  • Diese Versionsprüfungs-Infrastruktur wurde in v2.27.0 auf ViewerPreferences und PageMode erweitert und deckt bis v2.31.0 alle wichtigen Funktionsbereiche ab.

2026-05-09 Version 2.25.0

  • Korrigiert die Ausgabe des PDF-Dictionaries, um Schlüssel vom Typ "Name" als case-sensitive zu behandeln, gemäß der PDF-Spezifikation. Zuvor wurden verwandte Namen, die sich nur in der Groß-/Kleinschreibung unterschieden – wie z.B. "/ca" (Füllalphawert) und "/CA" (Strichalphawert) in einem ExtGState-Dictionary – fälschlicherweise zusammengeführt, wobei ein Wert stillschweigend verworfen wurde.
  • Diese Korrektur stellt die korrekte Transparenzverarbeitung für Dokumente wieder her, die sowohl Füll- als auch Konturen-Alpha-Werte im selben Grafikstatus verwenden. Adobe Acrobat, Foxit und Browser-PDF-Viewer rendern die korrigierte Ausgabe wie erwartet.
  • Die öffentlichen API-Schnittstellen für die Abfrage von Dictionaries bleiben weiterhin unabhängig von Groß- und Kleinschreibung, sodass bestehender Code, der fehlerhafte PDF-Dateien mit inkonsistenter Groß- und Kleinschreibung der Schlüssel liest, weiterhin ohne Änderungen funktioniert.

2026-05-09 Version 2.24.0

  • Für Feature-APIs, die seit v2.4.0 eingeführt wurden, wurde eine PDF-Versionsbeschränkung hinzugefügt, um sicherzustellen, dass die generierten Dateien mit der ausgewählten PDF-Version kompatibel bleiben.
  • THotPDF.StrictVersionLock wurde hinzugefügt. Wenn diese Option deaktiviert ist, erhöht HotPDF die Dokumentversion automatisch bei Bedarf; wenn sie aktiviert ist, werden Aufrufe, die neuere PDF-Funktionen erfordern, abgelehnt.
  • Aktualisiert wurde "ConfigurePDFVersion", sodass XRef-Streams, XMP-Metadaten, Tagged PDF und AES-256-Optionen nicht mehr in ältere PDF-Versionen gelangen können.

2026-05-09 Version 2.23.0

  • Es wurde ein dreistufiger digitaler Signatur-Workflow hinzugefügt, um die Integration von THotPDF mit externen PKI- und CMS-/PKCS#7-Signaturbibliotheken zu ermöglichen: Erstellen Sie den Platzhalter für das Signaturfeld, berechnen Sie den Byte-Bereich und den Digest, der signiert werden soll, und fügen Sie dann die vollständige CMS-Signatur nach der externen Signatur ein.
  • Die Byte-Range-Strategie stellt sicher, dass der signierte Hash genau die Bereiche der Datei abdeckt, die sich außerhalb des Signaturcontainers befinden, und entspricht damit den Anforderungen von PDF-Signaturvalidatoren und PAdES-Konformitätsprüfern.
  • Alle kryptografischen Operationen – Zertifikatskette, CMS-Struktur, Zeitstempel-Token – werden an die Signaturbibliothek des Aufrufers delegiert (OpenSSL, Windows CAPI, Bouncy Castle usw.), wodurch HotPDF unabhängig von jeglicher PKI-Infrastruktur bleibt.
  • Unterstützt Dokumente mit mehreren Signaturen: Jede zusätzliche Signatur wird als inkrementelles Update hinzugefügt, wobei die zuvor signierten Bytebereiche erhalten bleiben, ohne die gesamte PDF-Datei neu zu generieren.

2026-05-09 Version 2.22.0

  • Unterstützung für den PDF 2.0 AES-256 Sicherheitsstandard (V=5, R=6) wurde über THotPDF hinzugefügt. Verwenden Sie "UseAES256R6".
  • In HPDFCrypt wurden native SHA-384- und SHA-512-Funktionen in reinem Pascal hinzugefügt.
  • Es wurde ein Helfer für die Hash-Berechnung im PDF-Format 2.0 hinzugefügt, der von Acrobat DC und den Verschlüsselungs-Workflows im PDF/A-4-Stil verwendet wird.

2026-05-09 Version 2.21.0

  • Erweiterte Unterstützung für Tagged PDFs von einer einfachen Markierung zu einer strukturierten PDF-Barrierefreiheitsstruktur.
  • Es wurden Rollenzuweisungen, die Zuweisung von Seiten zu Strukturübergeordneten und eine ParentTree-Ausgabe hinzugefügt, sodass PDF/UA-Validierer die Strukturbaumstruktur durchsuchen können.
  • Verbesserte die Verarbeitung von `StructTreeRoot`, sodass nachfolgende Aufrufe zur Erstellung von Tagged PDFs die gleiche Dokumentstruktur aktualisieren.

2026-05-09 Version 2.20.0

  • THotPDF: Unterstützung für /UserUnit und /Tabs auf Seitenebene hinzugefügt, über THPDFPage.SetUserUnit und THPDFPage.SetTabsOrder.
  • Optional Content (PDF-Ebenen) wurden mit THotPDF.RegisterOptionalContentGroup und THPDFPage.BeginOptionalContent / EndOptionalContent hinzugefügt.
  • Es wurden ExtGState-Hilfsfunktionen für Transparenz-Alpha- und Mischmodi über THotPDF.RegisterExtGState und THPDFPage.SetGraphicsState hinzugefügt.

2026-05-09 Version 2.19.0

  • Für Produktions-PDF-Workflows wurden Hilfsfunktionen für CropBox, BleedBox, TrimBox, ArtBox und Seitenrotation hinzugefügt.
  • THotPDF.AddStructureElement wurde hinzugefügt, um strukturierte PDF-Dateien mit Rollen, Seitenverknüpfungen und MCID-Referenzen zu erstellen.
  • Hinzugefügte Unterstützung für Musterschachtelung für wiederholte, farbige oder unfarbige PDF-Musterfüllungen und -Konturen.

2026-05-09 Version 2.18.0

  • THPDFPage.DrawInlineImage wurde hinzugefügt, sodass kleine Rasterbilder direkt in den Seiteninhaltsstrom geschrieben werden können.
  • Es wurden mehrstufige axiale Farbverläufe hinzugefügt, um weichere Schattierungen und Farbübergänge in PDF-Dokumenten zu erzielen.
  • Hinzugefügte Unterstützung für OutputIntents für PDF/A, PDF/X und Farbmanagement-Workflows.

2026-05-09 Version 2.17.0

  • Es wurde ein AES-256-Standard-Sicherheitshandler (PDF 1.7 Extension Level 3) hinzugefügt, für Dokumente, die einen stärkeren Schutz benötigen als der Standard-AES-128-Schutz. AES-256-verschlüsselte PDFs können in Adobe Acrobat 9 und späteren Versionen, Foxit Reader, Google Chrome, Apple Preview und allen modernen PDF-Anzeigeprogrammen geöffnet werden.
  • Benutzer- und Eigentümerpasswörter werden mithilfe von SHA-256-Hashing gemäß der Adobe Extension Level 3-Spezifikation generiert, wodurch die Kompatibilität mit jedem konformen PDF-Entschlüsselungsprogramm ohne spezielle Anpassungen gewährleistet wird.
  • AES-256-Verschlüsselung ist in dieser Version optional; der bestehende AES-128-Pfad bleibt standardmäßig aktiv, um eine breitere Abwärtskompatibilität mit älteren Acrobat-Versionen zu gewährleisten.
  • In der späteren Version v2.22.0 wird PDF 2.0 mit AES-256-R6 eingeführt, das einen verbesserten Schlüsselableitungsalgorithmus für maximale Sicherheit in Acrobat DC- und PDF/A-4-Workflows bietet.

2026-05-09 Version 2.16.0

  • Es wurden sechs neue Annotationstypen für Multimedia-, Rechts- und Barrierefreiheitsanwendungsfälle hinzugefügt: Wasserzeichen (Stempelüberlagerungen für Anzeige und Druck), Redaktion (Markierung von Bereichen zur Inhaltsentfernung), Bildschirm (eingebettete Video- und Audioinhalte), 3D (interaktive U3D- und PRC-Modellansichten), Rich Media (interaktive Medieninhalte) und Popup (Kommentarblasen, die mit übergeordneten Annotationen verknüpft sind).
  • Wasserzeichen-Annotationen unterstützen separate Anzeige- und Druckdarstellungen, sodass "ENTWERF" oder "VERTRAULICH"-Markierungen auf dem Bildschirm angezeigt werden können, ohne gedruckt zu werden, oder umgekehrt.
  • Annotationen maskieren Inhaltsbereiche, die vor der Dokumentverteilung entfernt werden sollen; der Redaktions-Workflow des Betrachters führt die endgültige Löschung durch und behält den ursprünglichen Inhalt bis zur Bestätigung bei.
  • Alle sechs Annotationstypen enthalten eine Versionsprüfung für PDF, sodass Dokumente, die älteren PDF-Standards entsprechen, automatisch neuere Annotationstypen auslassen und weiterhin den Spezifikationen entsprechen.

2026-05-09 Version 2.15.0

  • Es wurde Unterstützung für Type 3-Schriftarten hinzugefügt, um benutzerdefinierte Vektorglyphen direkt in die PDF-Ausgabe einzubetten. Type 3-Schriftarten eignen sich gut für Firmenlogos, proprietäre Symbolsets, Karten-Icons und jede grafische Notation, die nicht mit Standard-Schriftarten dargestellt werden kann.
  • Jedes Glyphe wird als PDF-Inhaltsstrom unter Verwendung von Standard-Zeichenoperatoren definiert, sodass Type-3-Glyphen in jeder Zoomstufe und Druckauflösung sauber skaliert werden, ohne dass eine externe Schriftdatei erforderlich ist.
  • Der gesamte Workflow – das Registrieren einer Schriftart, das Definieren einzelner Glyphen und das Auswählen der Schriftart auf einer Seite – wird von RegisterType3Font, AddType3Glyph und SetType3Font verwaltet.
  • Typ-3-Schriftarten werden korrekt von Adobe Reader, Foxit und allen standardskonformen PDF-Anzeigeprogrammen dargestellt, ohne dass eine Schriftartinstallation auf dem System des Anzeigeprogramms erforderlich ist.

2026-05-09 Version 2.14.0

  • Es wurden reine Pascal-Implementierungen von AES-256 und SHA-256 als interne kryptografische Funktionen hinzugefügt, um den Dokumentenschutz zu verbessern. Diese Algorithmen sind erforderlich für die Verschlüsselungsstandards PDF 1.7 Extension Level 3 und PDF 2.0.
  • Der neue kryptografische Code benötigt keine externen DLLs oder von Betriebssystemen bereitgestellten Kryptobibliotheken, wodurch HotPDF in allen unterstützten Delphi- und C++Builder-Umgebungen sowie Windows-Versionen eigenständig bleibt.
  • AES-128 bleibt das Standard-Dokumentverschlüsselungsformat in dieser Version; die neuen Funktionen bilden die Grundlage für den AES-256-Sicherheitsmechanismus, der in v2.17.0 hinzugefügt wurde, sowie für den PDF 2.0-Handler in v2.22.0.

2026-05-09 Version 2.13.0

  • Es wurden sanfte axiale (lineare) und radiale Farbverläufe für das Vektorgrafik-Rendering in PDF hinzugefügt. Vektorgrafiken erzeugen deutlich kleinere PDF-Dateien als gerasterte Äquivalente und bleiben in jeder Zoomstufe oder Druckauflösung scharf.
  • Beide Gradienttypen unterstützen die Farbräume DeviceGray, DeviceRGB und DeviceCMYK, wodurch Bildschirmanzeigen, RGB-Druck und vierfarbige CMYK-Produktionsworkflows abgedeckt werden.
  • Farbverläufe können als Füllungen oder Konturen auf jedem Seitenpfad angewendet werden und werden korrekt von Adobe Reader, Foxit, SumatraPDF und allen modernen PDF-Anzeigeprogrammen dargestellt.

2026-05-09 Version 2.12.0

  • Es wurden unsignierte Signaturfelder mit `THPDFPage.AddSignatureField` hinzugefügt. Die generierte PDF-Datei enthält einen visuellen Platzhalter für Signaturen, der von externen PKI-Workflows, Signaturportalen und CMS-/PKCS#7-Signaturbibliotheken mit einer echten kryptografischen Signatur gefüllt werden kann.
  • AcroForm-Signaturflags werden automatisch gesetzt, sobald mindestens ein Signaturfeld vorhanden ist, wodurch die Dokumentkonformität gewährleistet wird, ohne zusätzliche API-Aufrufe zu erfordern.
  • Signaturbereiche werden von Adobe Acrobat, Foxit und anderen PDF-Signierungslösungen als signierbar erkannt. Weitere Informationen zum vollständigen Byte-Range-Signierungsablauf finden Sie in der Version v2.23.0.

2026-05-09 Version 2.11.0

  • Es wurde eine Tagged-PDF-Infrastruktur hinzugefügt, die von PDF/UA und modernen Barrierefreiheitsstandards erforderlich ist. Tagged-Dokumente enthalten eine logische Lesereihenfolge und eine semantische Struktur, die von Bildschirmleseprogrammen, Hilfstechnologien und Text-Extraktionswerkzeugen verwendet werden kann.
  • THotPDF.EnableTaggedPDF aktiviert die Dokumentstruktur und THotPDF.Lang legt die Hauptsprache des Dokuments fest. Beide sind für die Konformität mit den Richtlinien zur Barrierefreiheit erforderlich.
  • Marked-content-Operatoren ermöglichen es, einzelne Zeichenoperationen auf der Seite mit semantischen Rollen (Absatz, Überschrift, Abbildung usw.) und Identifikatoren zu versehen, wodurch ein korrektes Umfließen und Extrahieren für Bildschirmleseprogramme aus generierten PDFs ermöglicht wird.
  • Strukturelemente und Markierungsinformationen werden pro Seite und pro Dokument verfolgt, was mit der PDF-Spezifikation für mehrseitige, strukturierte Dokumente übereinstimmt.

2026-05-09 Version 2.10.0

  • Für FlateDecode-Bildströme wurde Unterstützung für PNG-Prädiktoren und TIFF-horizontale Differenzprädiktoren hinzugefügt. Prädiktoren wenden eine adaptive zeilenweise Filterung an, bevor die Komprimierung erfolgt, wodurch die Ausgabegröße für Fotos und Bilder mit sanften Farbverläufen deutlich reduziert wird.
  • Der PNG-Optimierungsalgorithmus (adaptiver Zeilenmodus) und der TIFF-Algorithmus 2 (horizontale Differenzierung) sind als eigenständige Kodierungsfunktionen für benutzerdefinierte Bild-Einbettungs-Pipelines verfügbar.
  • Beide Vorhersagemethoden unterstützen Bilddaten im Format DeviceGray, DeviceRGB und DeviceCMYK, wodurch sowohl Bildschirmdarstellung als auch Vierfarbdruck-Workflows abgedeckt werden.

2026-05-09 Version 2.9.0

  • Es wurde ein XMP-Metadaten-Stream-Ausgabe hinzugefügt, zusätzlich zum traditionellen Dokument-Info-Dictionary. XMP ist der moderne Standard für eingebettete PDF-Metadaten und ist erforderlich für PDF/A, PDF/X und viele Archivierungs-Workflows.
  • Metadaten, die in XMP eingebettet sind, werden von Desktop-Suchmaschinen, digitalen Asset-Management-Systemen und PDF-Verarbeitungspipelines gelesen, die nicht mehr das ältere Info-Dictionary verwenden.
  • XMP-Streams werden in der Ausgabedatei unkomprimiert belassen, sodass externe Tools und Kommandozeilenprogramme Metadaten überprüfen können, ohne die Datei zu dekodieren.
  • Anwendungen, die genaue Metadaten benötigen, können ein vollständig benutzerdefiniertes UTF-8 XMP-Paket über THotPDF.CustomXMP bereitstellen und dabei die automatische Generierung umgehen.
  • Wenn die Dokumentverschlüsselung aktiviert ist, wird der XMP-Stream standardmäßig zusammen mit dem Rest des Dokuments verschlüsselt, um Metadaten vertraulich zu halten.

2026-05-09 Version 2.8.0

  • Es wurde eine optionale PDF 1.5-Querverweis-Stream-Ausgabe hinzugefügt. Querverweis-Streams kodieren die Objekt-Offset-Tabelle in einem kompakten binären Format anstelle des großen Textabschnitts, der von herkömmlichen Querverweistabellen verwendet wird, wodurch die Dateigröße für jedes Dokument reduziert wird.
  • Querverweis-Streams sind für PDF 1.5-Funktionen wie Objekt-Streams (eingeführt in v2.41.0) erforderlich und werden automatisch deaktiviert, wenn das Dokument auf eine PDF-Version unter 1.5 abzielt.
  • Generierte PDFs mit Querverweis-Streams werden von modernen Viewern, Archivierungstools und PDF/A-Validatoren effizienter verarbeitet.
  • Die traditionelle Text-Xref-Tabelle bleibt die Standardeinstellung, um die Kompatibilität mit älteren PDF-Readern und strengen Prozessoren zu gewährleisten.

2026-05-09 Version 2.7.0

  • Es wurde eine native DeviceCMYK-Farbunterstützung für Druck- und PDF/X-Workflows hinzugefügt.
  • THotPDF.RegisterICCProfile wurde hinzugefügt, um die Registrierung von ICC-basierten Farbräumen zu ermöglichen.
  • Es wurden generische APIs für Füll- und Umrissfarbräume für ICC-Profile und Farbwerte mit beliebiger Anzahl von Komponenten hinzugefügt.

2026-05-09 Version 2.6.0

  • Es wurden Hervorhebungen, Unterstreichungen, Wellenlinien und Durchstreichungen als Text-Markup-Annotationen hinzugefügt.
  • Polygon-, Polyline-, Ink- und Caret-Annotationen hinzugefügt.
  • Es wurden die Verknüpfungsaktionen "GoTo", "GoToR" und "Launch" hinzugefügt, um die Navigation innerhalb des Dokuments, zwischen Dokumenten und zu externen Dateien zu ermöglichen.

2026-05-09 Version 2.5.0

  • Hinzugefügte Unterstützung für AcroForm-Textfelder, Kontrollkästchen, Optionsfelder, Kombinationsfelder, Listenfelder und Schaltflächen.
  • Es wurde ein THPDFFormFieldFlags hinzugefügt, sodass Anwendungen gängige Formularfeldoptionen konfigurieren können, ohne Bitmanipulationen durchführen zu müssen.
  • Generierte Formulare setzen jetzt das Attribut "/NeedAppearances", sodass gängige PDF-Viewer Felder automatisch darstellen können.

2026-05-08 Version 2.4.0

  • Verbesserte die AES-128 PDF-Verschlüsselung. Zeichenketten und Datenströme werden jetzt tatsächlich mit AES-CBC für eine Sicherheitsstufe von V=4 / R=4 verschlüsselt.
  • CryptKeyLength=aes128 erzeugt jetzt verschlüsselte PDFs, die kompatible Viewer mit dem konfigurierten Benutzer- oder Besitzerpasswort öffnen können.
  • Es wurden Hilfsfunktionen für die Encoder ASCIIHexDecode, ASCII85Decode und RunLengthDecode hinzugefügt.
  • Aktualisierte die eingebundenen JBIG2- und JPEG 2000-Stub-Routinen, sodass sie nun un unterstützte Dekodierungen korrekt melden, anstatt Platzhalter-Bilddaten zurückzugeben.

2026-05-06 Version 2.3.23

  • Die in den Build-Dateien gebündelten Versionen von zlib-ng, libjpeg-turbo und libtiff wurden für die aktuellen RAD Studio- und Visual Studio-Toolchains optimiert.
  • Verbesserte Speicherplatzanpassung für native Komprimierungs- und Bildbibliotheken auf Delphi- und C++Builder-Plattformen.
  • Die automatisierten Regressionstests für Delphi und C++Builder wurden für die Zielplattformen Win32, Win64 und Win64x erfolgreich durchgeführt.

2026-05-05 Version 2.3.22

  • Aktiviert die zlib-ng Runtime-SIMD-Dispatch in den integrierten 64-Bit-Flate-Komprimierungsbuilds.
  • Win32 zlib-ng wurde aus Kompatibilitätsgründen mit der klassischen Toolchain weiterhin am stabilen, generischen Objektpfad belassen.
  • Optimierte native Objekt-Builds, sodass ein erfolgreicher Compiler-Durchlauf ohne erzeugte Objektdatei als Build-Fehler gewertet wird.

2026-05-05 Version 2.3.21

  • SIMD-Beschleunigung für libjpeg-turbo wurde in den mitgelieferten Win32-, Win64- und Win64x-Objektbuilds aktiviert.
  • SIMD-Unterstützung wurde durch ein HotPDF-Build-Flag explizit aktiviert.
  • Ein Problem bei der Win32 NASM OMF-Ausgabe wurde behoben, das verhindert hat, dass Delphi Win32 den SIMD-JPEG-Objektsatz verlinkt.
  • Ein Problem bei der Darstellung von TIFF-Bildern unter Win64 wurde behoben, das nach den SIMD- und zlib-ng-Neubauten aufgetreten war.

2026-05-05 Version 2.3.20

  • Der im Lieferumfang enthaltene Flate-Backend wurde durch zlib-ng im zlib-kompatiblen Modus für Seitendatenströme, Schriftarten, CMaps, Bilder, TIFF-Ausgabe und FlateDecode-Hilfsfunktionen ersetzt.
  • Behobene Probleme bei der komprimierten Datenübertragung und beim Import kleiner TIFF-Bilder, die während der Migration zu zlib-ng aufgetreten sind.
  • Die JPEG-Verarbeitung, die auf libjpeg-turbo basiert, und die TIFF-Verarbeitung, die auf libtiff basiert, wurden beibehalten.
  • Es wurde eine umfassende, automatisierte Regressionstests für die PDF-Generierung in Delphi und C++Builder hinzugefügt, sowie für Bildimport, Komprimierung, Verschlüsselung, Hyperlinks, Seiteneinrichtung und Copy-/Merge-/Edit-Workflows.

2026-05-01 Version 2.3.19

  • Behoben: Die Generierung des Seiten-Streams für die FlateDecode-Dekodierung wurde unter Win64 für die Ausgabe von dichten Barcodes korrigiert.
  • Die moderne Delphi-Seiten- und Schriftart-Stream-Komprimierung wurde mit dem stabilen RTL-zlib-Pfad synchronisiert.

2026-05-01 Version 2.3.18

  • Behobene: Korrektur der RC4-Schlüsselinitialisierung mit Pointer-Größe bei der verschlüsselten PDF-Generierung in C++Builder unter Win64x.
  • Behoben: Import von TIFF-Dateien bei Builds für C++Builder unter Windows 64 Bit.
  • Behobene Seitenanhänge-Workflows für PDFs, die mit LoadFromFile geöffnet werden, sodass angehängte Seiten mit sicheren Objektnummern gespeichert werden.

2026-05-01 Version 2.3.17

  • Die C++Builder-Demoanwendungen CanvasDrawing und GraphicDraw wurden aktualisiert, um den verbesserten Delphi-Grafikbeispielen zu entsprechen.
  • Die ViewerPref C++Builder Demo wurde verbessert, mit einer klareren Benutzeroberfläche, Validierung, Unterstützung für das Speichern und Laden von Voreinstellungen sowie einer dedizierten Funktion zur Einstellung der Ausrichtung.

2026-05-01 Version 2.3.16

  • Behoben wurde das Problem beim Kopieren von Seiten aus zusammengefügten PDF-Dateien, die eingebettete CID-TrueType-Schriftarten und verschachtelte Größenarrays enthalten.
  • Verbesserte Objektabbildung beim Kopieren von Seiten aus mehreren Quelldokumenten im PDF-Format in sequenzieller Reihenfolge.

2026-05-01 Version 2.3.15

  • Die ViewerPref-Demo für Delphi wurde verbessert, sodass optionenspezifische Steuerelemente nur dann aktiviert werden, wenn sie relevant sind.
  • Es wurden ViewerPref-Fehlerberichte, Validierung der Kopier- und Druckfunktion sowie benannte Voreinstellungen zum Speichern und Laden hinzugefügt.

2026-05-01 Version 2.3.14

  • Das PDFmerge-Delphi-Demo wurde überarbeitet und in ein eigenständiges Merge-Beispiel umgewandelt, das bei Bedarf Quelldateien im PDF-Format erstellt.
  • Verbesserte Validierung beim Zusammenführen, Indexierung der Ausgabedaten und UI-Meldungen für Erfolg/Fehler.

2026-05-01 Version 2.3.13

  • Die Delphi-Demoanwendungen "CanvasDraw" und "GraphicDraw" wurden optimiert, um eine klarere und reproduzierbare visuelle Ausgabe zu erzielen.
  • Verbesserte die Auswahl von TrueType-Schriftarten in den GDI-Schriftpfaden, wodurch Ausfälle während der Einbettungszeit, die durch Raster-Fallback-Schriftarten verursacht werden, reduziert wurden.
  • Korrigierte die Zeichenabstände, wenn die gleiche Schriftart in mehreren Textabschnitten in einer PDF-Datei verwendet wird.
  • Verbesserte Fehlermeldungen beim Einbetten von Schriftarten, die jetzt den angeforderten Schriftartnamen und Zeichensatz enthalten.

2026-05-01 Version 2.3.12

  • Die Demo "CopyPage" wurde verbessert, sodass sie PDFs mit nicht standardmäßigen "/Pages"-Strukturen ohne ein separates Tool kopieren kann.
  • CopyPage schreibt jetzt komprimierte Ausgabedaten im FlateDecode-Format, unabhängig davon, welcher Kopierpfad erfolgreich ist.
  • Das eigenständige CopyPageFixed-Beispiel wurde in die Haupt-CopyPage-Demo integriert.

2026-05-01 Version 2.3.11

  • Generierte PDFs werden jetzt standardmäßig so geöffnet, dass jede Seite an die Fensterhöhe angepasst wird.
  • Es wurden zahlreiche vordefinierte Seitengrößen ohne Präfix für Büro-, Großformat-, Zeichen-, Karten-, Ausweis-, Foto-, japanische, chinesische und taiwanesische Papierformate hinzugefügt, wobei die älteren Namen mit "ps-"-Präfix weiterhin kompatibel sind.
  • Die Delphi-Beispielprojekte für die Seitengrößen wurden überarbeitet und in die Projekte "LargeSize", "NormalSize" und "SmallSize" umgewandelt.

2026-04-29 Version 2.3.10

  • Behoben: Probleme beim Erstellen von RAD Studio XE7-Paketen im TIFF-Kompatibilitätsmodul.
  • Reduzierte Warnungen für RAD Studio 10 Seattle und 10.1 Berlin.
  • Korrigierte die Zuordnung für den Bibliotheksaufbau über die Kommandozeile für RAD Studio, Versionen 9.0 bis 12.0.
  • Wiederherstellung der Befehlszeilen-Paketbuilds für RAD Studio ProductVersion 9.0.
  • Behobene Probleme bei den RAD Studio XE2 Win64-Builds durch Deklarierung des CRT vsnprintf-Symbols, das von den Win64-Kompatibilitäts-Stub-Dateien benötigt wird.
  • Verbesserte Kompatibilität mit älteren Projekten, indem numerische boolesche Werte in älteren Delphi- und C++Builder-Projektdateien unterstützt werden.

2026-04-29 Version 2.3.9

  • Behoben: Probleme beim Erstellen von RAD Studio 10.1 Berlin-Bibliotheks-Paketen, indem Pakete aus dem Verzeichnis "Lib" kompiliert wurden.
  • In älteren Delphi-Compiler-Versionen wurden Probleme bei den Trial-Bibliotheksbuilds behoben, indem Inline-Variablendeklarationen aus dem Trial-Wasserzeichenpfad entfernt wurden.

2026-04-29 Version 2.3.8

  • Ein veralteter Compiler-Warnhinweis für `TStream.Seek` wurde aus dem TIFF-Stream-Callback-Pfad in den RAD Studio 10.3 Rio-Builds entfernt.

2026-04-29 Version 2.3.7

  • Korrigiert: Fehler bei der TIFF-zu-PDF-Konvertierung, der beim Verwenden der mitgelieferten libtiff-Objektdateien der Version 4.7.x auftrat.
  • Behoben: Kompilierung von RAD Studio Win32 für die mitgelieferte zlib-Pascal-Bibliothek unter strengeren Compiler-Einstellungen.
  • Hinzugefügte DUnitX-Regressionstests für die Konvertierung von TIFF in PDF.

2026-04-28 Version 2.3.5

  • Behoben: Probleme beim erneuten Aufbau der Quelldateien für die integrierten Bibliotheken zlib, libjpeg-turbo und libtiff, wobei der klassische Borland C++ Win32-Compiler verwendet wurde.
  • Die mitgelieferten Win32- und Win64-Objektdateien von Drittanbietern wurden neu erstellt und angepasst, um zuverlässigere Delphi- und C++Builder-Builds zu gewährleisten.
  • Keine öffentlichen API-Änderungen. Vorhandene Delphi-, C++Builder- und RAD Studio-Projekte können diese Version als Kompatibilitätsversion verwenden.

2026-04-19 Version 2.3.3

  • Die Zuverlässigkeit von RAD Studio-Projekten wurde verbessert, indem verhindert wurde, dass Host-INCLUDE-Umgebungseinstellungen die Kompilierung von HotPDF-Ressourcen beeinträchtigen.
  • Reduzierte die Anzahl doppelter Ressourcenwarnungen bei Paketbuilds, insbesondere für RAD Studio 13.1 Florence-Projekte.

2026-04-19 Version 2.3.2

  • Die Ordner für Pakete und Demo-Projekte folgen jetzt automatisch der aktiven RAD Studio-Version.
  • Verbesserte das Build-Verhalten des HotPDF370-Pakets, um zu verhindern, dass veraltete Ressourcen mit neu generierten Ressourcen verknüpft werden.

2026-04-19 Version 2.3.1

  • Das C++Builder TextOut-Demo lässt sich jetzt ohne manuelle Änderungen in allen unterstützten RAD Studio-Versionen erstellen.
  • Behoben wurde das Build-Verhalten für die TextOut-Demo unter Win64x, sodass die benötigte Ressourcendatei vor dem Linken eingebunden wird.

2026-04-19 Version 2.3.0

  • Hinzugefügte vollständige Unterstützung für C++Builder 13.1 Florence für die Zielplattformen Win32, Win64 und Win64x.
  • Die Verfügbarkeit der `TextOut`-Funktion wurde für Delphi und C++Builder vereinheitlicht, wobei gleichzeitig die Kompatibilität mit den älteren C++Builder-Hilfsnamen erhalten bleibt.
  • Bereinigung der statischen Verlinkung für Delphi Win64 durch Entfernen früherer Linker-Warnungen aus den gebündelten zlib-, libjpeg-turbo- und libtiff-Objektdateien.
  • Verbesserte die Ausgabe des Win64x-Pakets, sodass C++Builder-Projekte die generierte HotPDF-Bibliothek über die üblichen RAD Studio-Suchpfade finden können.

2026-04-17 Version 2.2.1

  • Entfernte Delphi Win32-Linker-Warnungen aus den gebündelten Drittanbieter-Komprimierungs- und Bildbibliotheken.
  • Verbesserte Kompatibilität mit statischen Bibliotheken für die Unterstützung von zlib, JPEG und TIFF in Delphi- und C++Builder-Builds.

2026-04-14 Version 2.2.0

  • Aktualisierte die enthaltenen Bibliotheken von Drittanbietern auf zlib 1.3.2, libjpeg-turbo 3.1.90 und libtiff 4.7.1.
  • Aktualisierte Win32- und Win64-statische Verlinkung für die aktualisierten Komprimierungs-, JPEG- und TIFF-Bibliotheken.
  • Erweiterte Unterstützung für Bildformate bei der PDF-Generierung, insbesondere bei Szenarien, die JPEG- oder TIFF-Eingaben verwenden.
  • Die HTML-Hilfe wurde aktualisiert, um der aktuellen THotPDF-API, den Beispielen und der Bibliotheksstruktur zu entsprechen.

2026-04-13 Version 2.1.4

  • Behoben: Kompilierung unter Win64 für RAD Studio XE2 bis XE8.
  • Verbesserte Kompatibilität der gebündelten Objektdateien, die von älteren Delphi-Compilern verwendet werden.
  • Entfernte veraltete Paketressourcendateien, die doppelte Ressourcen-Linker-Warnungen auslösen könnten.
  • Korrigierte Metadaten des Delphi XE3-Projekts für das HotPDF-Paket.

2026-04-12 Version 2.1.3

  • Das Delphi TestNumeric-Demo wurde zu einem praktischen Regressionstest für numerische PDF-Ausgaben erweitert.
  • Verbesserte die Validierung für Dezimalzahlen, Brüche und ganze Zahlen, sowie das Verhalten beim erneuten Laden von PDF-Dateien.
  • Debug-Ausgabedateien können jetzt optional über einen speziellen Compile-Zeit-Schalter aktiviert werden.
  • Aktualisierte Hilfeinformationen für Debug-Protokollierung und numerische Ausgabetests.

2026-04-10 Version 2.1.2

  • Verbesserte Darstellung von eingebetteten Schriftarten in den PDF-Ausgaben für Win32 und Win64.
  • Behoben wurde eine unvollständige Glyphenanzeige beim Wechsel zwischen eingebetteten Schriftarten, einschließlich gängiger Windows-Schriftarten wie Calibri.
  • Die FontTest-Demo wurde aktualisiert und Beispiel-PDF-Dateien wurden erstellt, um eine einfachere visuelle Überprüfung zu ermöglichen.
  • Aktualisierte HTML-Hilfeseiten für die Schriftartenintegration, die Unicode-Textausgabe und Beispiele für eingebettete Schriftarten.

2026-04-08 Version 2.1.1

  • Aktualisierte ViewerPreferences-Beispiele für Delphi und C++Builder, um sie an die aktuelle THotPDF-API anzupassen.
  • Hinzugefügte Unterstützung für neuere Optionen für PDF-Viewer-Einstellungen.
  • Verbesserte die generierte Demoausgabe, sodass sie nur die in der Benutzeroberfläche ausgewählten Viewer-Präferenz Einstellungen widerspiegelt.
  • Aktualisierte HTML-Hilfeseiten für ViewerPreferences und verwandte Dokumenteigenschaften.