Skip to content

Änderungsprotokoll

Alle wesentlichen Änderungen an PDF Oxide sind hier dokumentiert.


v0.3.38 – 2026-04-22

DocumentBuilder kommt in jeder Bindung an; AES-256 auf dem Schreibpfad; Signaturprüfung; Multi-Target-WASM; Go-purego-Backend

Schreibseitige API-Parität über alle Bindungen hinweg (#384)

  • DocumentBuilder + FluentPageBuilder + EmbeddedFont stehen nun neben Rust auch in Python, Node/TypeScript, C#, Go und WASM bereit. Mehrseitige Erstellung mit voller Unterstützung für CJK / Kyrillisch / Griechisch über eingebettete Schriften. Schließt #382 sprachübergreifend.
  • 15 Annotationsmethoden in jeder Bindung: link_url / link_page / link_named, highlight, underline, strikeout, squiggly, Haftnotiz, Stempel (14 Standard + benutzerdefiniert), Freitext, watermark (benutzerdefiniert / DRAFT / CONFIDENTIAL).
  • 5 AcroForm-Widget-Typen in jeder Bindung: text_field, checkbox, combo_box, radio_group, push_button.
  • Grafikprimitive in jeder Bindung: rect, filled_rect, line.
  • HTML+CSS-PipelinePdf.from_html_css(...) und from_html_css_with_fonts(...) für Mehrschriftkaskaden in jeder Bindung.

AES-256-Verschlüsselung auf dem Schreibpfad (#386)

  • save_encrypted(path, user_pw, owner_pw) / to_bytes_encrypted(user_pw, owner_pw) auf dem DocumentBuilder in jeder Bindung.
  • save_with_encryption in Rust für benutzerdefinierten Algorithmus + Berechtigungen.

Echtes Schrift-Subsetting (#385 / FONT-3b)

  • CJK-Schnitte werden nun als Teilmenge statt als vollständiger Schnitt eingebettet. Ein aus einer ~17 MB großen CJK-Schrift erstelltes PDF mit 5 Zeichen bleibt typischerweise unter 100 KB. Inhaltsströme, /W-Breiten und die ToUnicode-CMap werden auf den GID-Raum der Teilmenge umgeschlüsselt; der Hin- und Rückweg von extract_text bleibt unverändert.
  • Änderung der internen Writer-API: EmbeddedFont::encode_string / encode_shaped_run geben Vec<u16> zurück, und build_embedded_font_objects gibt einen GlyphRemapper zurück, den die Aufrufer an ContentStreamBuilder::build_with_remappers übergeben. Keine Änderung an den High-Level-APIs.

Prüfung digitaler Signaturen (#208, Prüfhälfte)

  • Signature.verify() und Signature.verify_detached(pdf_bytes) (und bindungsnative Entsprechungen) in jeder Bindung. Prüfungen der Signaturattribute nach RFC 5652 §5.4 + messageDigest nach §11.2.
  • RSA-PKCS#1 v1.5 über SHA-1 / SHA-256 / SHA-384 / SHA-512 gibt Valid / Invalid zurück. RSA-PSS und ECDSA erscheinen als Unknown / UnsupportedFeatureException; Aufrufer können das Zertifikat dennoch lesen und ihre eigene Prüfung durchführen.
  • Certificate — DER-Inspektion (Subject, Issuer, Seriennummer, Gültigkeit, is_valid) über x509-parserjede Bindung.
  • Signature — auflisten + inspizieren + .get_certificate()jede Bindung.
  • Timestamp — Parsen von TSTInfo nach RFC 3161 (Zeit, Seriennummer, Richtlinie, TSA-Name, Hash-Algorithmus, Message Imprint) — jede Bindung.
  • TsaClient — HTTP POST nach RFC 3161 mit Nonce und HTTP-Basic-Authentifizierung hinter einem tsa-client-Cargo-Feature — jede Bindung außer WASM. Bewusst nicht in WASM verdrahtet (ureq ist nicht wasm-kompatibel).
  • Metadaten-Writer DocumentEditor::set_producer / set_creation_date.
  • render_page_region und render_page_fit — beschnittene und eingepasste Rendering-Oberfläche.
  • Bikubische Bildfilterung (Parität mit pdf.js #19978) — gescannte / zweistufige Seiten mit Multiply-gemischten Overlays lassen ihren Graustufenbereich beim Herunterskalieren nicht mehr kollabieren.

Das Signieren selbst (im Gegensatz zur Prüfung) wird nicht abgedeckt; #208 bleibt für diese Hälfte offen.

Multi-Target-WASM-Paketierung (#392)

  • pdf-oxide-wasm liefert nun drei Builds nebeneinander mit bedingten Exports in der package.json: nodejs/, bundler/ (Vite / webpack / Rollup / esbuild / Bun) und web/ (Browser / Deno / Cloudflare Workers).
  • Behebt den unter Browser-Bundlern geworfenen ReferenceError: Can't find variable: __dirname.
  • Unterpfad-Importe (pdf-oxide-wasm/web, /nodejs, /bundler) sind für manuelles Routing verfügbar.

Go-Bindung — purego-Backend + Installation im Cache-Verzeichnis

  • Ein zweites Backend über ebitengine/purego führt zur Laufzeit dlopen auf libpdf_oxide.{so,dylib,dll} aus. Builds mit CGO_ENABLED=0 funktionieren jetzt. Die Backend-Auswahl ist automatisch — //go:build cgo → vollständige CGo-API, //go:build !cgo → purego.
  • purego-Umfang: PdfDocument öffnen (Pfad / Bytes / Passwort), Seitenanzahl, Version, Text- / Markdown- / HTML- / Klartext-Extraktion, Schriften, Annotationen, Seitenelemente, Suche, Seitenabmessungen, Logging, sowie PdfCreator.FromMarkdown für Test-Fixtures.
  • Nur CGo (Kompilierfehler unter !cgo): DocumentEditor, DocumentBuilder, Barcodes, Signaturen, TSA, Rendering, OCR, Formularmutation.
  • Installer: Das neue Flag -shared holt die cdylib statt der staticlib und gibt CGO_ENABLED=0 + PDF_OXIDE_LIB_PATH=… zum Exportieren aus.
  • Das Installationsverzeichnis wurde nach os.UserCacheDir() verschoben — ~/.cache/pdf_oxide (Linux), ~/Library/Caches/pdf_oxide (macOS), %LocalAppData%\pdf_oxide (Windows). Entspricht Gos eigener GOCACHE-Konvention.
  • Release-Assets enthalten nun pdf_oxide-go-ffi-shared-<platform>.tar.gz für jede Tier-1-Plattform neben den bestehenden staticlib-Archiven.

Fehlerbehebungen

  • #395RenderPage löst keine SignatureException mehr aus, wenn eine Seite nicht parsbare Metadaten eines Signaturfelds enthält, aber kein interaktives Signatur-Widget. Gemeldet von @gevorgter.

Dank


v0.3.37 – 2026-04-20

HTML + CSS → PDF (#248) — die erste glaubwürdige Pipeline in reinem Rust

Neue API — Pdf::from_html_css

let font = std::fs::read("DejaVuSans.ttf")?;
let pdf = Pdf::from_html_css(
    "<h1>Hello</h1><p>World</p>",
    "h1 { color: blue; font-size: 24pt }",
    font,
)?;
pdf.save("out.pdf")?;

Übergeben Sie HTML + CSS + Schrift-Bytes und erhalten Sie ein paginiertes PDF zurück. Reines Rust, nur MIT/Apache (keine transitiven MPL-Abhängigkeiten), der Hin- und Rückweg von extract_text ist byte-identisch, sodass erzeugte PDFs an der bestehenden Testinfrastruktur teilnehmen.

Was ausgeliefert wurde

  • Schrift-Subsystem — TTF/OTF-Einbettung mit Emission von Type 0 / CIDFontType2 / Identity-H / ToUnicode; Latein, Kyrillisch, Griechisch, Hebräisch, Arabisch durchlaufen den Hin- und Rückweg über extract_text. Systemschrift-Erkennung über fontdb, Text-Shaping über rustybuzz.
  • Selbstgeschriebene CSS-Engine (~6.500 Codezeilen, null MPL-Abhängigkeiten) – Tokenizer, Parser, L3+L4-Selektoren (:is/:where/:not/:has), Matcher, Kaskade, calc() / min() / max() / clamp(), var() mit Zykluserkennung, typisierte Eigenschaftswerte, At-Rules (@media print, @page mit :first/:left/:right/:blank, @font-face, @import, @supports), Zähler, Pseudoelement-Inhalt.
  • HTML – HTML5-Tokenizer, flaches Arena-DOM, Stylesheet-Extraktion (<style>, <link rel="stylesheet">, Inline-style=""), Ressourcenextraktion (<img> + srcset, <picture>/<source>, <a href>).
  • Layout – Taffy-gestütztes block / flex / grid, Zeilenumbruch nach UAX #14, Margin-Collapsing, Mehrspaltigkeit, Tabellen (auto + fixed).
  • Malen – Text + Ränder, RTL über rustybuzz, <a href>/Link-Annotation, <img>-Data-URI → /XObject, ::before / ::after, page-break-{before,after}: always, opacity, transform: translate*(), Listenmarker <ul> / <ol>, eingebettete Schriften über DocumentBuilder::register_embedded_font (#382).

Mehrschriftkaskade

  • Pdf::from_html_css_with_fonts(html, css, Vec<(family, bytes)>) — das CSS-font-family an jedem Element wird gegen registrierte Familien aufgelöst (ohne Beachtung der Groß-/Kleinschreibung, mit/ohne Anführungszeichen, mehrwortig ohne Anführungszeichen).

Fehlerbehebungen im Randfall-Durchlauf

  • Base-14-Fettschrift wird nun fett gerendert (Nichtübereinstimmung des Ressourcen-Dictionary-Schlüssels gegen Tf /Helvetica-Bold).
  • TTC-Systemschriften (Helvetica.ttc, msgothic.ttc) werden nun über Source::SharedFile von fontdb aufgelöst.
  • Mehrwortiges font-family ohne Anführungszeichen wird korrekt tokenisiert.
  • Speicherleck in den Pdf::from_html_css-Factories geschlossen (vier Box::leak-Stellen durch gescopte lokale Variablen ersetzt).
  • PNG-Alpha / Soft-Mask (SMask) wird nun gerendert.
  • Geshapeter Text durchläuft den Hin- und Rückweg über extract_text (encode_shaped_run bildet Glyphencluster auf die Quell-Codepunkte zurück ab).
  • PdfWriter::finish bettet Schriften in Registrierungsreihenfolge ein (zuvor in zufälliger HashMap-Reihenfolge).
  • Namenskollisionen eingebetteter Schriften über monoton steigende EFn-Ressourcennamen isoliert.
  • Der Mutex von fontdb wird nicht mehr über den fs::read der Schrift-Bytes hinweg gehalten.

Außerhalb des Umfangs

CSS-Filter, 3D-Transformationen, Animationen, SVG-in-HTML (jede brauchbare Rust-SVG-Crate ist MPL), MathML, hyphens: auto, shape-outside, JavaScript, Vollmatrix-transform (scale/rotate), Verläufe, box-shadow.

Lizenzaudit

cargo deny check licenses besteht mit null transitiven MPL-Abhängigkeiten. Der CSS-Stack von Mozilla (cssparser, selectors, html5ever, lightningcss, stylo) ist durchweg MPL-2.0; v0.3.37 schreibt die Entsprechungen von Hand, um pdf_oxide vollständig unter MIT/Apache zu halten.

Dank

  • @jmriebold – #248 („CSS-Unterstützung") ist die Wurzel der gesamten HTML+CSS→PDF-Pipeline dieses Releases.

v0.3.36 – 2026-04-19

Strukturelle Markdown-Extraktion — Emission von Überschriften/Listen aus getaggtem PDF, mehrspaltige Lesereihenfolge, sicherere RTL-Behandlung

Strukturelle Markdown-Extraktion (#377)

to_markdown() verdrahtet nun /StructTreeRoot direkt in die Markdown-Pipeline, statt Überschriftsebenen aus Schriftgrößen-Heuristiken und Listenmarker aus Glyphenerkennung neu abzuleiten:

  • Emission von Überschriften und Listen aus /StructTreeRoot. Neue StructRole (Heading(1..6), ListItem, ListItemLabel, ListItemBody), an jeden Span angehängt. Mit Word getaggte Dokumente stellen ihre vollständige Überschriftshierarchie wieder her; Listen geben - item mit Absatzumbrüchen an jedem Rollenwechsel aus.
  • Rolle durch verschachtelte MCRs propagiert. Die Muster H1 → Span → MCR und LI → LBody → Span → MCR tragen nun die korrekte semantische Rolle über InheritedContext { heading_level, list_role }.
  • Blockgrenze pro /StructTreeRoot erzwingt Absatzumbruch. OrderedContent.block_id wird bei jedem Eintritt in /P, /H1..6, /LI, /Lbl, /LBody, /Sect, /Div, /Art, /TR, /TH, /TD, /Note, /Reference, /BibEntry, /Code inkrementiert; Layouts mit engen Abständen verschmelzen nicht mehr.
  • Gleiche-Grundlinie-Schranke gegen Überfragmentierung von Formularüberschriften — Spans auf gleicher Grundlinie fügen sich wieder zu einer Überschrift zusammen.
  • Mehrspaltige Rinnen-Erkennung — Spans auf gleicher Grundlinie, getrennt durch > max(3 × font_size, 30 pt), werden als spaltenübergreifend behandelt.
  • Rückwärts-x-Lesereihenfolge-Umbrucherkennung — spaltenweise Lesereihenfolge (letzter Span von Spalte 1 bei x=976 → erster Span von Spalte 2 bei x=192 auf gleicher Grundlinie) bricht nun Absätze um, statt sie zu verbinden.
  • Geometrische Überschrifts- + Listenpräfix-Erkennung für ungetaggte Dokumente. Fett + 5 % Größenzuwachs wird zu H4 hochgestuft. Das neue is_ordered_list_marker erkennt 1. / 12. / a) / iv. / A. und weist dabei Abbildungsbeschriftungen und Jahreszahlen zurück.

RTL-Text — standardmäßig sicher

  • Falsche **bold**-Marker um arabische kontextabhängige Glyphen werden nun entfernt (Shaping-Übergänge brachten den Schriftgewicht-Detektor durcheinander).
  • Bidi-Neuordnung ist standardmäßig AUS. Ein früherer Entwurf führte die Visuell→Logisch-Neuordnung von unicode-bidi auf jeder RTL-Zeile aus, was zuvor korrekte PDFs in logischer Reihenfolge zerstörte (der hebräische Name בנימין wurde umgekehrt). Der Neuordnungs-Helfer verbleibt in text::bidi::reorder_visual_to_logical für Aufrufer, deren Eingabe in visueller Reihenfolge vorliegt.

Markdown-Ausgabe

  • Inline-Bild-Base64-Data-URIs auf 200 KB begrenzt. PDFs mit hochauflösenden Diagrammen blähten die Markdown-Ausgabe zuvor um das 10- bis 20-Fache auf (eine 1,9 MB große Arbeit erzeugte 11,3 MB Markdown). Bilder über dem Limit geben einen HTML-Kommentar-Platzhalter mit der Originalgröße aus. Die dateibasierte Bildausgabe (image_output_dir) ist nicht betroffen.

Empirische Auswirkung

Gegen v0.3.35 auf einer 369-PDF-Regression validiert, die akademische, behördliche, Formular-, Zeitungs-, technische, Dissertations-, IRS-, pdfium-, pdfjs-, safedocs- und Slow-Corpus-Teilmengen umspannt:

  • 0 katastrophale Regressionen.
  • Token-Jaccard gegen pdfium und pdftotext: Median 1,000, ≥0,95 bei 95/106 Fixtures.
  • Token-Jaccard gegen pymupdf4llm: Median 0,978, ≥0,95 bei 65/106 Fixtures.
  • ~2× mehr emittierte Überschriften als pymupdf4llm über den Korpus hinweg.

Dank

  • @Goldziher (kreuzberg) – reichte #377 mit einer Benchmark-Methodik über 727 Dokumente plus 9 reproduzierenden PDFs ein. Die Rahmung („TF1 innerhalb von ±3 %, der Textinhalt ist also in Ordnung, die Struktur ist das Problem") machte die gesamte Untersuchung handhabbar.

v0.3.35 – 2026-04-19

Erhaltung von Dubletten schmaler Glyphen bei der Textextraktion

Korrektheit der Textextraktion

  • Benachbarte Dubletten schmaler Glyphen kollabieren bei kleinen Schriftgrößen nicht mehr (#378, PR #379). TextExtractor::deduplicate_overlapping_chars und deduplicate_overlapping_spans verwendeten einen fest codierten absoluten Schwellenwert von 2 pt; bei schmalen Glyphen (l, r, I, i) in kompakten Schriften bei kleinen Größen sinkt die Vorschubbreite pro Glyphe auf ≤ 2 pt (Helvetica l ≈ 2,5 pt bei 9 pt), sodass legitime benachbarte Dubletten, die genau einen vollen Vorschub auseinanderliegen, in das Deduplizierungsfenster fielen und eine der beiden Glyphen still verworfen wurde. Sichtbare Korruption umfasste controller → controler, billed → biled, warranty → warrnty, following → folowing, VIII → VII. Der Schwellenwert skaliert nun mit der eigenen advance_width jeder Glyphe als min(advance_width * 0.30, 2.0). Die einstellbaren Parameter wurden in die zugehörigen Konstanten TextExtractor::DEDUP_OVERLAP_RATIO / DEDUP_OVERLAP_CAP_PT hochgezogen.

Dank

  • @Hugues-DTANKOUO – meldete #378 mit präziser Ursachenanalyse und verfasste PR #379 mit dem vorschubskalierten Schwellenwert und einer parametrisierten Regressionsmatrix (4 schmale Glyphen × 3 Fließtextgrößen).

v0.3.34 – 2026-04-17

Idiomatische Seiten-API über alle Bindungen hinweg; strukturierte Tabellenextraktion

Neue Funktionen

  • Seiten-API (#371) – Python, Node.js, C# und Go stellen nun ein PdfPage-Objekt bereit. Iterieren Sie mit for page in doc, for (const p of doc), foreach (var p in doc.Pages) oder doc.Pages(); indizieren Sie mit doc[i], doc.page(i), doc[i] oder doc.Page(i). Jede Seite stellt verzögert ausgewertete text, markdown(), html(), words, lines, tables, images, paths, annotations, search() und mehr bereit.
  • Strukturierte Tabellenextraktion (#289)extract_tables() (Python), ExtractTables() (C#/Go) und extractTables() (Node.js) geben nun Zeilen und Zellen mit Text plus Begrenzungsrahmen zurück, nicht nur Markdown. Verfügbar sowohl auf PdfDocument als auch auf der neuen PdfPage.
  • Node.js-ParitätextractWords, extractTextLines, extractTables, extractPaths, getEmbeddedImages, ocrExtractText in die TypeScript-Schicht verdrahtet (zuvor nur nativ).
  • ExtractedTableTable – Umbenennung im Rust-Kern; das redundante Präfix Extracted entfällt. FFI-zugewandte Typen aktualisiert.

Qualität der Textextraktion

  • XY-Cut-Spaltenerkennung auf Seiten mit gemischtem Layout (#319) – die Schutzbedingung is_multi_column_page wurde verschärft, sodass mindestens 15 Spans pro Spalte erforderlich sind; spaltenweise geordnete Spans werden nicht mehr durch die zeilenbewusste Sortierung in extract_text neu sortiert.

Dank

  • @SeanPedersen für den Vorschlag der seitenorientierten API (#371). @pdenapo für die Anfrage der strukturierten Tabellenextraktion (#289).

v0.3.33 – 2026-04-16

Korrekturen für Textextraktion, Bildkorrektheit und Speichersicherheit

Fehlerbehebungen

  • ToUnicode-CMap-Fehltreffer (#363) – Subset-Type0-Schriften geben nun U+FFFD aus, wenn eine CID in der ToUnicode-CMap fehlt, statt in Identity-H-Chiffretext durchzufallen (z. B. %B+$%8A//$2*%01*1%6APP).
  • Wortinternes TJ-Kerning teilt keine Wörter mehr (#365) – Buchstabenpaar-Kerning von 0,10–0,20 em innerhalb einzelner Wörter ([(diffe) -150 (rent)]) löst keine Leerzeicheneinfügung mehr aus.
  • Kyrillischer UTF-8-Mojibake wiederhergestellt (#317) – Schriften mit reiner Latein-Kodierung und rohen UTF-8-Byte-Sequenzen werden nun korrekt dekodiert.
  • FlateDecode-Teilwiederherstellung weist Müllausgabe zurück (#364) – PDFs von MS Reporting Services, deren Inhaltsströme mitten in der Dekompression scheitern, geben keine 128 Byte pseudozufälliger Daten mehr zurück.
  • Indexed + ICCBased-Palette (#373) – nicht aufgelöste ICC-Stream-Referenzen innerhalb des Indexed-Basisarrays setzen /N nicht mehr standardmäßig auf 3 statt auf 4 für CMYK, was Diagonalstreifen-Artefakte behebt. Gemeldet von @Charltsing.
  • Lab-basierte Indexed-Paletten → sRGB (#337) – CIE-L*a*b*-Palettenbytes werden nun Lab→XYZ→sRGB konvertiert, statt als rohes RGB neu interpretiert zu werden.

Speicher und Leistung

  • Alle internen Caches begrenzt (PRs #369, #354) – Objekt-Cache (64 MB), Schrift-Caches (256–512 Einträge), XObject-Span-/Bild-Caches (1024 Einträge) und globaler CMap-Cache (1024 Einträge) verwenden nun FIFO-Verdrängung.
  • OOM bei der Pfadextraktion auf diagrammlastigen PDFs behoben (#369) – CTM-bewusste XObject-Deduplizierung hinzugefügt, sodass dasselbe XObject an derselben Position dedupliziert wird, dasselbe XObject an verschiedenen Positionen jedoch separat verarbeitet wird.
  • Resilienz gegen Mutex-VergiftungMutexExt::lock_or_recover() ersetzt 72 .lock().unwrap()-Aufrufstellen.

Abhängigkeiten

  • RustCrypto-cipher-0.5-Ökosystem (PRs #352, #295, #291): aes 0.8→0.9, cbc 0.1→0.2, sha2/sha1/md-5 0.10→0.11.

Test-Suite

  • 13 tote/veraltete ignorierte Tests entfernt; 3 zuvor ignorierte Tests behoben. Regressionstests für jede obige Fehlerbehebung hinzugefügt. Die Suite umfasst nun 6.300 bestanden, 0 fehlgeschlagen, 228 ignoriert.

Dank

  • @Charltsing für die Fehlermeldung zur Indexed-±CMYK-Bildextraktion (#373).
  • @ddxtanx für das Profiling des unbegrenzten Speicherwachstums während der Mehrseitenextraktion (#354).
  • @andrewjradcliffe für PR #369: begrenzte FIFO-Caches, CTM-bewusste XObject-Deduplizierung, MutexExt-Vergiftungswiederherstellungs-Trait, Härtung der Python-Bindung.

v0.3.32 – 2026-04-15

Korrektur der Release-Pipeline für das Go-FFI-Tarball unter Windows-x64

Release-Pipeline

  • Behebt den Build-Fehler der nativen x86_64-pc-windows-gnu-Bibliothek, der das v0.3.31-Release scheitern ließscripts/shrink-staticlib.sh führte objcopy --strip-debug auf jedem Archivelement aus, aber die MinGW-Cross-Compile-Toolchain emittiert aufgeteilte Debug-.dwo-Elemente, die nur DWARF-Abschnitte enthalten; nach dem Strippen hatte das Element keine Abschnitte mehr, und objcopy brach das gesamte Archiv ab. Behebung: .dwo-Archivelemente per ar d entfernen, bevor objcopy aufgerufen wird. Keine funktionale Änderung an den Rust-, Python-, Node-, WASM- oder C#-Artefakten – dieses Release existiert ausschließlich, um den Go-Installationspfad unter Windows-x64 freizugeben.

v0.3.31 – 2026-04-13

Fehlerbehebungen, Go-Build-Änderungen, Verbesserungen der Release-Infrastruktur

Fehlerbehebungen

  • Xref-Wiederherstellung – Wiederherstellung für falsch markierte freie Seitenobjekte und um wenige Bytes verschobene Xref-Offset-Einträge behoben.

Inkompatible Änderungen

  • Native Go-Bibliotheken – native Bibliotheken werden nicht mehr in go/lib/ committet. Nutzer müssen einmal pro Rechner go run github.com/yfedoseev/pdf_oxide/go/cmd/install@latest ausführen.

Release-Infrastruktur

  • Rust-staticlibs um 63 % verkleinert (von 71 MB auf 26 MB), das npm-.node-Addon gestrippt, Sourcemaps aus npm entfernt, das Crate-sdist-Leck behoben, das NuGet-snupkg-Packaging verschärft.

v0.3.27 – 2026-04-12

Go-staticlib, native Node.js-Bindungen, C#-NativeAOT, OCR-FFI, große Fehlerbehebungen

Neue Funktionen

  • Go-staticlib-Migration – Umstellung von cdylib auf staticlib für eigenständige Go-Binärdateien.
  • Native Node.js-Bindungen – vorgebaute Plattform-Unterpakete über Verteilung im napi-rs-Stil.
  • C#-LibraryImport – 881 P/Invoke-Deklarationen von DllImport auf LibraryImport migriert für NativeAOT-Kompatibilität.
  • OCR-FFI-Brücke – OCR-Unterstützung nun in den Go-, C#- und Node.js-Bindungen verfügbar.
  • Regressions-Harness – kuratierter Korpus von 60 PDFs für automatisierte Qualitätstests.

Fehlerbehebungen

  • Bilder mit Indexed-Farbraum, AES-256-Verschlüsselung (V=5, R=6), Lesereihenfolge für einspaltigen und tabellarischen Inhalt, arabische Textextraktion, Worttrennung, Schriftbreiten-Fallback, Objekt-Cache-Invalidierung, Rendering-Verbesserungen.

v0.3.24 – 2026-04-09

Offizielle Bindungen für JavaScript/TypeScript, Go und C#

Neue Funktionen

  • JavaScript/TypeScript-Bindungen – auf npm mit vollständiger API-Abdeckung veröffentlicht.
  • Go-Bindungen – natives Go-Paket mit vollständiger API-Oberfläche.
  • C#-Bindungen – auf NuGet veröffentlichtes .NET-Paket.
  • C-FFI-Schicht – über 270 extern "C"-Funktionen mit gemeinsamem pdf_oxide.h-Header.
  • Globale Log-Level-Steuerung – in allen Bindungen konfigurierbar.

v0.3.23 – 2026-04-09

Kritische Stabilitätskorrekturen

Fehlerbehebungen

  • SIGABRT auf Seiten mit degenerierter CTM aus rotierten dvips-PDFs behoben.
  • Behoben, dass Bilder/XObjects beim Speichern entfernt wurden.
  • Verzerrtes Rendering auf Systemen ohne gängige Schriften behoben.
  • Behoben, dass der Seitenindex eines Formularfelds stets 0 zurückgab.

v0.3.22 – 2026-04-08

Threadsichere Dokumente, asynchrones Python, free-threaded Python, Feinabstimmung der Wort-/Zeilensegmentierung

Neue Funktionen

  • Threadsicheres PdfDocumentSend + Sync über Mutex (ersetzte RefCell).
  • Asynchrone Python-APIAsyncPdfDocument, AsyncPdf, AsyncOfficeConverter.
  • Free-threaded Python – Unterstützung für cp314t (No-GIL-Builds).
  • Segmentierungsschwellenword_gap_threshold, line_gap_threshold, profile zur Abstimmung der Wort-/Zeilenerkennung.

Fehlerbehebungen

  • Leere Seiten bei CLI-Split/Merge, Rendering-Übersprung für fehlerhafte Bilder, SIGSEGV durch Zyklus im Strukturbaum, Schaltung der Tabellenstrategie.

Leistung

  • Strukturbaum und dekomprimierte Inhaltsströme gecacht, MCID-Lookup in O(1), Seitenbaum-Traversierung in O(log n), verzögerte Befüllung des Seitenbaums.

v0.3.21 – 2026-04-04

Mehrarchitektur-Python-Wheels, Log-Level-Korrektur

Fehlerbehebungen

  • Der Log-Level wird in Python nun vollständig beachtet (Makros an die log-Crate weitergeleitet).

Neue Funktionen

  • Mehrarchitektur-Python-Wheels – Linux aarch64, musl x86_64/aarch64, Windows ARM64; glibc-Anforderung auf 2_28 gesenkt.

v0.3.20 – 2026-04-04

Große Neufassung der Tabellenextraktion, Textqualitätsverbesserungen, standardmäßig stilles Logging

Neue Funktionen

  • Neufassung der Tabellenextraktions-Engine – Schnittpunkt-Pipeline, Textkanten-Erkennung, erweitertes Raster, spaltenbewusste Texterkennung, Rekonstitution gepunkteter/gestrichelter Linien, hybride Zeilenerkennung.
  • Qualität der Textextraktion – Abstände zwischen benachbarten Werten, Zusammenführung geteilter Dezimalzahlen, Konsolidierung fetter Spans, HTML-Überschriftshierarchie, Label-Wert-Paarung, Zusammenführung von Spaltengruppen.
  • Stilles Logging – Logging ist nun in allen Bindungen standardmäßig still; Python-Logs fließen über das logging-Modul via pyo3-log.

Fehlerbehebungen

  • Klare Fehlermeldung bei verschlüsseltem PDF, Entschlüsselung von ObjStm/XRef-Streams, Behandlung des abschließenden Zeilenumbruchs durch den Stream-Parser.

v0.3.19 – 2026-04-02

Seitenextraktion in einem einzigen Aufruf, spaltenbewusste Lesereihenfolge, Begrenzungsrahmen pro Zeichen

Neue Funktionen

  • extract_page_text() – DTO mit einem einzigen Aufruf für eine schlanke Seitenextraktion.
  • Spaltenbewusste Lesereihenfolge – XY-Cut-Raumpartitionierung für mehrspaltige Dokumente.
  • Begrenzungsrahmen pro Zeichen – aus Schriftmetriken abgeleitet für präzise Zeichenpositionierung.
  • is_monospace-Flag – auf TextSpan und TextChar verfügbar.
  • Pdf::from_bytes() – neuer Konstruktor über alle Bindungen hinweg.
  • Pfadoperationenextract_paths() in den Python-Bindungen.

Fehlerbehebungen

  • UTF-8-Panik bei mehrbyte-Debug-Log, Markdown-Abstände, /Matrix von Form-XObject, Matrix für rotierten Text, CTM-Verlust beim Prescan, Deduplizierung, Textverlust bei Tm-Skalierung, Wortzusammenführung in Markdown, leere Dokumente beim CLI-Merge.

Inkompatible Änderungen

  • WASM – JSON-Feldnamen verwenden nun camelCase.

v0.3.18 – 2026-04-01

Generalüberholung der Rendering-Engine, neue Python- und WASM-APIs, Python „mit Batterien"

Neue Funktionen

  • Generalüberholung der Rendering-Engine – korrekte Zeichenabstände, Unterstützung für eingebettete Schriften, Standard-Schriftmetriken, Füllen-und-Stricheln, Beschneidungspfad, Verlaufsschattierung, Alpha-Transparenz, Schablonen-Bildmasken, Seitenrotation, Schmuckfarben-Farbräume.
  • Neue Python-APIsvalidate_pdf_a, validate_pdf_ua, validate_pdf_x, extract_pages, delete_page, move_page, flatten_to_images, Passwort-Konstruktor, merge.
  • Neue WASM-APIsvalidatePdfA, deletePage, extractPages, save, Passwort-Konstruktor, merge.
  • Python „mit Batterien" – Rendering, Parallelität, Signaturen und Office-Konvertierung standardmäßig aktiviert.

Fehlerbehebungen

  • Abbruch bei degenerierter CTM, FlateDecode-Flate-Bomb-Schutz (256-MB-Limit), Synchronisierung des Beschneidungs-Stacks.

v0.3.17 – 2026-03-08

Verfeinerung der Tabellenerkennung, Optimierung von getaggtem PDF

Verbesserungen

  • Verfeinerte Tabellenerkennung – erfordert 2+ Spalten, was Fehlalarme reduziert.
  • Optimierte Extraktions-Pipeline für getaggtes PDF.

Fehlerbehebungen

  • RefCell already borrowed-Panik bei rekursiver Form-XObject-Verarbeitung behoben.

v0.3.16 – 2026-03-08

Intelligente hybride Tabellenextraktion, Python-Typ-Stubs, pathlib-Unterstützung

Neue Funktionen

  • Intelligente hybride Tabellenextraktion – Union-Find-Clustering, Analyse visueller Linien, visuelle Spans/Header.
  • Professionelle ASCII-Tabellen – mehrzeiliger Umbruch für die Terminalausgabe.
  • Python-Typ-Stubs – automatisch generiert über mypy stubgen.
  • Python-PdfDocument – akzeptiert pathlib.Path und unterstützt Kontextmanager.

Fehlerbehebungen

  • Segfault in verschachteltem Form-XObject, Koordinatenskalierung in Python, UTF-8-Panik in ASCII-Tabelle.

v0.3.15 – 2026-03-06

Kopf-/Fußzeilenverwaltung, Seitenvorlagen, eingegrenzte Extraktion

Neue Funktionen

  • API zur Kopf-/Fußzeilenverwaltung – PDF-Artefakte hinzufügen, entfernen und bearbeiten.
  • Seitenvorlagen – dynamische Platzhalter für Seitennummerierung, Datumsangaben usw.
  • Eingegrenzte Extraktion – berücksichtigt erase_regions für gefilterte Ausgabe.
  • PdfDocument.from_bytes() – neuer Python-Konstruktor.

Fehlerbehebungen

  • Mehrspaltige Lesereihenfolge (XY-Cut), Schriftidentitäts-Kollisionen, Fehlalarme der Lines-Tabellenstrategie.

v0.3.14 – 2026-03-03

High-Level-Rendering, Wort-/Zeilenextraktion, geometrische Primitive, hybride Tabellen

Neue Funktionen

  • High-Level-Rendering-APIPdf::render_page in Rust, Python und WASM.
  • Wort- und Zeilenextraktionextract_words, extract_text_lines über alle Bindungen hinweg.
  • Extraktion geometrischer Primitiveextract_rects, extract_lines.
  • Hybride Tabellenerkennung – Hinweise aus Vektorlinien verbessern die Erkennung von Tabellengrenzen.
  • API-Harmonisierung – flüssiges .within(page, rect)-Muster.
  • CLI-Befehlerender- und paths-Befehle mit --area-Filterung.

Fehlerbehebungen

  • Erkennung der OCR-Feature-Schaltung, Vergiftung des XObject-Span-Caches, V=4-Crypt-Filter, verschlüsselte CIDToGIDMap.

v0.3.13 – 2026-03-02

Korrekturen der CJK-Textextraktion

Fehlerbehebungen

  • Mehrbyte-Dekodierung in extract_chars für CJK/Type0-Schriften, verbesserte Genauigkeit der Zeichenpositionierung, Skalierung der Zeichenabstände.

v0.3.12 – 2026-03-01

Qualität der Textextraktion, Markdown-Konvertierung, Leistung

Verbesserungen

  • Qualität der Textextraktion – Berechnung der CID-Schriftbreite, Worterkennung bei Schriftwechsel, Fallback für nicht standardmäßiges CID-Mapping, Richtungsbestimmung von RTL-Text.
  • Markdown-Konvertierung – rekursive XY-Cut-Raumpartitionierung, Überschriftserkennung, Listenrekonstruktion.

Leistung

  • Kopierfreie Seitenbaum-Traversierung, Strukturbaum-Caching, frühzeitiger Ausstieg beim BT-Operator, größerer I/O-Puffer, Schwellenwert für die Xref-Rekonstruktion entfernt.

v0.3.10 – 2026-02-26

Parallele Extraktion, WASM/JavaScript-Unterstützung, Stapelverarbeitung, Textqualitätsverbesserungen

Neue Funktionen

  • WASM/JavaScript-Unterstützung – WebAssembly-Bindungen über wasm-bindgen. Vollständige Textextraktion, PDF-Erstellung, -Bearbeitung, Formularfelder und Suche im Browser und in Node.js verfügbar. Als pdf-oxide-wasm auf npm veröffentlicht.

  • Parallele Seitenextraktion – neues parallel-Feature-Flag mit rayon-basierter Multithread-Extraktion. Der ParallelExtractor verteilt Seiten auf Worker-Threads. Ein globaler Schrift-Cache stellt sicher, dass Schriften nur einmal geparst werden.

  • API zur Stapelverarbeitung – neuer BatchProcessor für Workflows mit mehreren PDFs, mit Fortschritts-Callbacks und Fehlersammlung. Unterstützt sowohl sequentielle als auch parallele Verarbeitung.

  • Hybride OCR-Erkennung – neues PageType-Enum (NativeText, ScannedPage, HybridPage) mit Multi-Heuristik-Erkennung für intelligenten OCR-Fallback.

  • Vollständige WASM/Python-API-Parität – 10 neue Methodengruppen über die WASM- und Python-Bindungen hinweg: Formularfeld-get/set, Extraktion von Bild-Bytes, PDF-aus-Bildern, Formular-Flattening, PDF-Zusammenführung, Datei-Einbettung, Seitenbeschriftungen, XMP-Metadaten.

Fehlerbehebungen

  • Segfault bei zirkulärem XObject – Segfault durch zirkuläre Form-XObject-Referenzen während der Bildextraktion behoben
  • Überlauf der XRef-/Prev-Kette – das Parsen der XRef-/Prev-Kette von rekursiv auf iterativ mit Zykluserkennung umgeschrieben
  • Defekter Ligaturentext – der Nachbearbeiter repair_ligatures() behebt beschädigten Text aus LaTeX-PDFs
  • Qualität der Textextraktion – Textextraktion aus Annotationen, Normalisierung von Führungspunkten, CMap-Unterstützung der Priorität 3
  • Tabellenextraktion – zusammengeführte Zellen, mehrzeiliger Zelleninhalt, schriftbasierte Header-Erkennung
  • Persistenz von Formularfeldern – das inkrementelle Speichern persistiert nun korrekt Wertänderungen von Formularfeldern

Leistung

  • Übersprung von Seiten nur mit Bildern – die Vorprüfung page_cannot_have_text() überspringt die Dekompression für Seiten ohne Schriften
  • SmallVec-Operator-Operanden – auf dem Stack allozierte Operanden eliminieren die Heap-Allokation pro Operator
  • Dokumentübergreifender Schrift-Cache – prozessweiter LRU-Schrift-Cache, der über alle PdfDocument-Instanzen hinweg geteilt wird

v0.3.9 – 2026-02-24

20+ Mikro-Optimierungen – Textextraktion 40 % schneller

Leistung

  • Korrektur der O(n^2)-Stringverkettung – ein vorab allozierter Vec<&str>, am Ende verbunden, ersetzt die quadratische String::push_str()-Akkumulation
  • Inhaltsstrom-Parser nur für Bilder – neuer schneller Pfad für extract_images(), der Text- und Grafikoperatoren überspringt (3-5x schneller)
  • Fingerabdruckbasierter Schrift-Cache – Schriftidentität durch Hashing von encoding+widths+flags statt vollständigem Struct-Vergleich
  • Streaming-Parser – Inhaltsstrom-Operatoren werden gestreamt statt in einen Vec gesammelt
  • Schneller Inline-Parser für BT/ET – direkter Byte-Abgleich für gängige Textoperatoren
  • Byte-zu-Char-Lookup-Tabelle – eine Lookup-Tabelle mit 256 Einträgen ersetzt die HashMap im heißen Pfad
  • Breiten-Lookup-Tabelle – ein Array fester Größe ersetzt die HashMap für Glyphenbreiten
  • Verkleinerung des Operator-Enums – von 112 auf 40 Byte durch Boxing der großen Varianten (64 % kleiner)
  • zlib-rs-Backend – 15-25 % schnellere Stream-Dekompression über eine zlib-ng-Portierung

Fehlerbehebungen

  • Schriftkodierung mit eingebetteten Programmen – korrekte Auflösung der Basiskodierung gemäß PDF-Spezifikation
  • Ergänzendes Unicode (U+10000+) – Abschneiden ergänzender Codepunkte behoben
  • StandardEncoding-Ligatur-Mapping – korrektes Mapping von fi, fl, ff, ffi, ffl über die Adobe Glyph List
  • Normalisierung der Kangxi-Radikale – vollständige Mapping-Tabelle U+2F00-U+2FD5
  • Zeichenreihenfolge bei RTL-Text – Arabisch/Hebräisch in logischer Leserichtung extrahiert
  • Trennung mehrspaltigen Texts – verbesserte Spaltenerkennung durch Lückenanalyse

Funktionen

  • extract_all_text() – neue Komfortmethode für die Textextraktion über alle Seiten
  • source_role für StructElem – bewahrt den ursprünglichen PDF-Rollennamen vor dem Rollen-Mapping

v0.3.8 – 2026-02-20

Parser nur für Text – grafiklastige Seiten 10-30x schneller

Leistung

  • Inhaltsstrom-Parser nur für Text – der neue schnelle Pfad parse_content_stream_text_only() überspringt Grafikoperatoren außerhalb von BT/ET-Blöcken mittels Scannen auf Byte-Ebene statt vollständigem nom-Parsen
  • Grafik-Scanner auf Byte-Ebene – rohe Indexarithmetik ersetzt die nom-basierte Operandenschleife und verarbeitet nahe Memcpy-Geschwindigkeit
  • Überspringen von Farboperatoren – 12 Farboperatoren zur Übersprungsliste auf Byte-Ebene hinzugefügt
  • Aufgeschobene q/cm/Q-Emission – Grafikzustandsoperationen werden aufgeschoben, bis Text bestätigt ist, was ~75 % des Backtrack-Overheads eliminiert
  • Arc-umhüllter FontInfo-Cache – vermeidet das Klonen vollständiger FontInfo-Structs bei Cache-Treffern
  • Seitenkarten-Konstruktion in O(n) – eine Single-Pass-Traversierung ersetzt den rekursiven Abstieg
  • XObject-Name-zu-Referenz-Cache – eliminiert das O(n^2)-Klonen von Dictionaries auf XObject-lastigen Seiten

v0.3.7 – 2026-02-19

Qualität der Textextraktion: von 95,7 % auf 99,6 % saubere Rate

Verifiziert – Korpus aus 3.829 PDFs

Metrik v0.3.6 v0.3.7 Änderung
Saubere Rate 95,7 % 99,6 % 3.812 von 3.829 PDFs
Verschmutzte PDFs 165 17 -90 %

Hinzugefügt – Parser & Decoder

  • BrotliDecode-Stream-Filter (PDF 2.0) – neuer Decoder für Brotli-komprimierte Streams
  • Xref-Trailer-Auswahl – korrekte Trailer-Auswahl, wenn mehrere Trailer vorhanden sind
  • Wiederherstellung von PDFs ohne Header – Suche nach dem ersten Objektmarker, wenn der %PDF--Header fehlt

Hinzugefügt – Schriftkodierung

  • CFF-Schriftkodierungs-Parser – parst CFF/OpenType-Schriftprogramme für die Zeichenkodierung
  • Type1-Schriftkodierungs-Parser – parst eingebettete Type-1-Schriftprogramme für Glyphen-Mappings
  • 80K+ CID-zu-Unicode-Mappings – erweiterte Adobe-CNS1, Adobe-GB1, Adobe-Japan1, Adobe-Korea1
  • Shift-JIS/RKSJ-Dekodierung – Unterstützung für CMap-Streams in japanischem Shift-JIS
  • Identity-H-cmap-Propagierung – propagiert TrueType-cmap-Tabellen von CIDFont-Nachkommen

Behoben – Textextraktions-Pipeline

  • Tf-Pufferleerung – leert ausstehenden Text beim Schriftwechsel, um Textverlust zu verhindern
  • Adaptiver Leerzeichen-Schwellenwert – ersetzt den festen 0,25em-Schwellenwert durch bbox-basierte Abstände
  • Span-Deduplizierung – dedupliziert überlappende Spans, die für Fett-/Schatteneffekte gerendert wurden
  • Zeichen-Deduplizierung – entfernt doppelte Zeichen innerhalb von 2pt auf derselben Zeile
  • Entfernung der BT-Operatorprüfung – behebt die fehlerhafte Validierung, die gültige Textblöcke übersprang
  • ByteMode-Dekodierung – korrekte Dekodierung von 1-Byte-, 2-Byte- und Zeichencodes variabler Breite
  • Textextraktion aus Annotationen – extrahiert Text aus Widget, FreeText und Erscheinungsbild-Streams

v0.3.6 – 2026-02-16

10x schneller – zwei O(n)-Engpässe eliminiert

Leistung

  • Massen-Cache des Seitenbaums – beim ersten Seitenzugriff wird der gesamte Seitenbaum einmal durchlaufen und alle Seiten werden gecacht. Zuvor traversierte get_page() für jede ungecachte Seite von der Wurzel aus, was O(n) pro Seite und O(n^2) insgesamt bei sequentiellem Zugriff ergab. Nun O(1) pro Seite nach einem einzigen O(n)-Durchlauf. Eine veraPDF-Testdatei mit 10.000 Seiten ging von 55.667ms auf 332ms (168x schneller).

  • Scan-für-Objekt-Offset-Cache – wenn Objekte in der Xref-Tabelle fehlen, las scan_for_object() zuvor die gesamte PDF-Datei für jedes fehlende Objekt. Getaggte PDFs mit Hunderten von Strukturbaum-Elementen außerhalb der Xref lösten Hunderte vollständiger Dateilesevorgänge aus. Nun wird die Datei einmal gescannt und alle Objekt-Offsets werden gecacht. Ein getaggtes PDF mit 10 Seiten ging von ~10s auf 68ms (146x schneller). Ein akademisches PDF mit 154 Seiten und 571 Schriften ging von ~18s auf 405ms (44x schneller).

  • Single-Pass-Textextraktionextract_spans() führt nicht mehr zwei Durchläufe aus (Dokumenttyp klassifizieren, dann extrahieren). Der Klassifizierungsdurchlauf wurde vollständig eliminiert; adaptive schriftbewusste Schwellenwerte liefern nun gleiche oder bessere Ergebnisse in einem einzigen Durchlauf.

  • Vorab-Allokation des Inhaltsstrom-Vecparse_content_stream() allokiert die Kapazität des Operator-Vec basierend auf der Stream-Größe vorab, was Reallokationen für große Inhaltsströme reduziert.

Verifiziert – Korpus aus 3.830 PDFs (von v0.3.5 auf v0.3.6)

Metrik v0.3.5 v0.3.6 Änderung
Erfolgsrate 99,8 % 99,8 % 3.823 von 3.830 gültigen PDFs
Langsam (>5s) 2 0 Eliminiert
Mittelwert 23,3ms 2,1ms -91 %
p50 0,6ms 0,6ms
p90 3,0ms 2,6ms -13 %
p99 33,2ms 18,0ms -46 %
Max 68.722ms 625ms -99 %
Summe (alle PDFs) 89,1s 8,0s -91 %

Die Textausgabe wurde auf 11 PDFs (862 KB extrahierter Text) als byte-identisch verifiziert. 4 PDFs zeigten durch adaptive Abstände eine verbesserte Extraktionsqualität.


v0.3.5 – 2026-02-15

Leistung, Stabilität bei 3.830 PDFs und Fehlerwiederherstellung

Leistung

  • Schrift-Caching über Seiten hinweg – ein dokumentweiter Schrift-Cache, mit ObjectRef indiziert, vermeidet das erneute Parsen gemeinsam genutzter Schriften auf jeder Seite
  • Caching von Seitenobjektenget_page() cacht aufgelöste Seitenobjekte und eliminiert die wiederholte Seitenbaum-Traversierung bei der Mehrseitenextraktion
  • Strukturbaum-Caching – das Strukturbaum-Ergebnis wird nach dem ersten Zugriff gecacht, was redundantes Parsen bei jedem extract_text()-Aufruf vermeidet
  • Frühzeitiger Ausstieg beim BT-Operator – die Textextraktion überspringt die vollständige Pipeline für Seiten nur mit Bildern, die keine BT-Operatoren (Begin Text) enthalten
  • Größerer I/O-Puffer für große Dateien – die BufReader-Kapazität für Dateien über 100 MB von 8 KB auf 256 KB erhöht
  • Schwellenwert für die Xref-Rekonstruktion entfernt – die Heuristik eliminiert, die eine vollständige Dateirekonstruktion bei gültigen Portfolio-PDFs mit wenigen Objekten auslöste

Verifiziert – Korpus aus 3.830 PDFs

  • 100 % Erfolgsrate bei 3.830 PDFs über veraPDF (2.907), Mozilla pdf.js (897), SafeDocs (26)
  • Null Timeouts, null Paniken
  • p50 = 0,6ms, p90 = 3,0ms, p99 = 33ms

Hinzugefügt – Verschlüsselung

  • Authentifizierung mit Eigentümerpasswort – Algorithmus 7 für R<=4, Algorithmus 12 für R>=5
  • R>=5-Benutzerpasswortprüfung mit SASLprep – vollständige AES-256-Passwortprüfung mittels SHA-256
  • Öffentliche API zur PasswortauthentifizierungPdf::authenticate(password) und PdfDocument::authenticate(password)

Hinzugefügt – PDF/A-Konformitätsprüfung

  • XMP-Metadatenprüfung – prüft die Einträge pdfaid:part und pdfaid:conformance
  • Farbraumprüfung – scannt Seiten-Inhaltsströme nach geräteabhängigen Farboperatoren ohne Output Intent
  • AFRelationship-Prüfung – Prüfung der PDF/A-3-Spezifikation für eingebettete Dateien

Hinzugefügt – PDF/X-Konformitätsprüfung

  • XMP-PDF/X-Identifikation – prüft pdfxid:GTS_PDFXVersion
  • Prüfung der Seitenrahmen-Beziehungen – TrimBox innerhalb BleedBox innerhalb MediaBox
  • ExtGState-Transparenzerkennung – Prüfungen von SMask, CA/ca, BM
  • Geräteabhängige Farberkennung – markiert nicht unterstützte Farbräume
  • ICC-Profilprüfung – prüft ICCBased-Profil-Streams

Hinzugefügt – Rendering

  • Spezifikationskonformes Beschneiden – Beschneidungszustand auf q/Q-Speichern/Wiederherstellen begrenzt
  • Berechnung der Glyphen-Vorschubbreite – gemäß PDF-Spezifikation Abschnitt 9.4.4
  • Form-XObject-Rendering – parst die /Matrix-Transformation, verwendet die /Resources des Formulars

Behoben – Fehlerwiederherstellung (28+ reale PDFs)

  • Fehlende Objekte werden gemäß PDF-Spezifikation Abschnitt 7.3.10 zu Null aufgelöst
  • Nachsichtiges Parsen der Header-Version für ungewöhnliche Versionszeichenketten
  • Abgleich nicht standardmäßiger Verschlüsselungsalgorithmen (V=1-, R=3-Kombinationen)
  • Resources, die kein Dictionary sind, werden als leer behandelt statt einen Fehler auszulösen
  • Null-Knoten im Seitenbaum werden elegant übersprungen
  • Beschädigte Inhaltsströme geben leeren Inhalt statt Fehlern zurück
  • Verbesserter Seitenbaum-Scan mit der /Resources+/Parent-Heuristik

Behoben – DoS-Schutz

  • Die Seitenanzahl wird gegen das Limit aus Anhang C.2 der PDF-Spezifikation (8.388.607) geprüft

Behoben – Bildextraktion

  • Bildextraktion aus dem Inhaltsstrom über Do-Operatoren
  • Verschachtelte Form-XObject-Bilder mit Zykluserkennung
  • Inline-Bilder (BI…ID…EI-Sequenzen)
  • CTM-Transformationen für die Bildpositionierung
  • Auflösung indirekter ColorSpace-Referenzen

Behoben – Robustheit des Parsers

  • Mehrzeilige Objekt-Header (Format 1 0\nobj, von Google-generierten PDFs verwendet)
  • Header-Suche von 1024 auf 8192 Byte erweitert
  • Nachsichtiges Versions-Parsen für fehlerhafte Header

Behoben – Robustheit des Seitenzugriffs

  • Seiten ohne /Contents geben leeren Inhalt zurück
  • Die Erkennung zyklischer Seitenbäume verhindert Stapelüberlauf
  • Null-Stream-Referenzen werden elegant behandelt
  • Seiten ohne /Type-Eintrag werden über die Schlüssel /MediaBox oder /Contents gefunden

Behoben – Robustheit der Verschlüsselung

  • AES-Entschlüsselung mit zu kleinen Schlüsseln gibt einen Fehler statt einer Panik zurück
  • Xref-Stream-Parsen gegen fehlerhafte Einträge gehärtet
  • Indirekte /Encrypt-Referenzen vor dem Parsen aufgelöst

Behoben – Inhaltsstromverarbeitung

  • Dictionary-as-Stream-Fallback für nackte Dictionaries
  • Abgekürzte Filternamen (AHx, A85, LZW, Fl, RL, CCF, DCT)
  • Limit für Inhaltsstrom-Operatoren (Standard 1.000.000)

Behoben – Codequalität

  • Indirekte Objektreferenzen des Strukturbaums werden zur Parse-Zeit aufgelöst
  • Disambiguierung der R/RG-Tokens im Lexer
  • Das Trimmen von Leerzeichen im Stream entfernt keine NUL-Bytes oder Leerzeichen mehr aus Binärdaten

Tests

  • 8 zuvor ignorierte Tests entignoriert und behoben

Entfernt

  • Leerer PdfImage-Stub (die Extraktion verwendet ImageInfo)
  • Auskommentierter DocumentType::detect()-Testblock

v0.3.4 – 2026-02-12

Robustheit des Parsens, Zeichenextraktion und XObject-Pfade

Inkompatible Änderungen

  • Die Signatur von parse_header() wurde von (u8, u8) auf (u8, u8, u64) geändert, um den Byte-Offset einzuschließen

Behoben – Robustheit des PDF-Parsens (Issue #41)

  • PDFs mit binären Präfixen oder BOM-Headern öffnen nun erfolgreich
  • Die Header-Suche scannt die ersten 1024 Byte nach dem %PDF--Marker
  • Unterstützt UTF-8-BOM, E-Mail-Header und andere führende Binärdaten
  • Der nachsichtige Modus behandelt reale fehlerhafte PDFs; der strikte Modus für Konformitätstests

Hinzugefügt – Textextraktion auf Zeichenebene (Issue #39)

  • extract_chars() gibt Vec<TextChar> mit Positionierung pro Zeichen zurück
  • Enthält Transformationsmatrix, Rotationswinkel, Vorschubbreite
  • In Leserichtung sortiert mit Deduplizierung überlappender Zeichen
  • 30-50 % schneller als die Span-Extraktion für reine Zeichen-Anwendungsfälle
  • Sowohl in der Rust- als auch in der Python-API verfügbar

Hinzugefügt – XObject-Pfadextraktion (Issue #40)

  • extract_paths() verarbeitet Form-XObjects rekursiv über den Do-Operator
  • Koordinatentransformationen über /Matrix korrekt angewendet
  • Grafikzustand ordnungsgemäß isoliert (speichern/wiederherstellen)
  • Die Erkennung doppelter XObjects verhindert Endlosschleifen
  • Verschachtelte XObjects werden unterstützt

Geändert

  • Die nom-Parser-Bibliothek von 7.1 auf 8.0 aktualisiert

v0.3.3 – 2026-02-11

CJK-Unterstützung, Verbesserungen des Strukturbaums und Konformitätsgrundlagen

Enthält alle Änderungen aus v0.2.5 und v0.2.6 als konsolidiertes Release.

Höhepunkte

  • TagSuspect/MarkInfo-Unterstützung – parst das MarkInfo-Dictionary aus dem Dokumentkatalog
  • Word-Break-/WB-Strukturelement für CJK-Text
  • Unterstützung vordefinierter CMaps für Adobe-GB1 (vereinfachtes Chinesisch), Adobe-Japan1 (Japanisch), Adobe-CNS1 (traditionelles Chinesisch), Adobe-Korea1 (Koreanisch)
  • Unterstützung der Abkürzungserweiterung /E
  • Type-0-/W-Array-Parsen für CIDFont-Glyphenbreiten
  • Korrektur der Behandlung des weichen Trennstrichs (U+00AD)
  • Verbesserte Artefaktfilterung mit Subtyp-Unterstützung
  • Bildeinbettung in der HTML- und Markdown-Ausgabe (Base64-Data-URIs)
  • Bilddateiexport mit embed_images=false und image_output_dir
  • Methoden PdfImage::to_base64_data_uri() und to_png_bytes()

v0.3.2 – 2026-02-01

Bearbeitung, Verschlüsselung und Dokumentsicherheit

Hinzugefügt – PDF-Bearbeitung

  • DocumentEditor zum Modifizieren bestehender PDFs
  • Vollständige Annotationsunterstützung (Textauszeichnung, Formen, Stempel, Tinte, Dateianhänge, Schwärzungen)
  • Erstellung interaktiver Formularfelder (Text, Checkbox, Radio, Dropdown, Liste, Button)
  • Formular-Flattening
  • Link-Annotationen (URLs, interne Seitennavigation)
  • Gliederungs-/Lesezeichen-Builder
  • PDF-Ebenen (Optional Content Groups)

Hinzugefügt – Verschlüsselung

  • Verschlüsselung beim Schreiben (AES-256, AES-128, RC4-128, RC4-40)
  • Berechtigungssteuerung (drucken, kopieren, modifizieren, annotieren)
  • EncryptionConfig-Builder mit EncryptionAlgorithm und Permissions
  • Grundlage für digitale Signaturen

v0.3.1 – 2026-01-14

Formularfelder, Multimedia, Erstellungswerkzeuge und Suche

Hinzugefügt – PDF-Erstellung

  • Pdf::from_markdown(), Pdf::from_html(), Pdf::from_text(), Pdf::from_image()
  • Flüssiges PdfBuilder-Muster für Metadaten- und Layoutkonfiguration
  • DocumentBuilder für die programmatische PDF-Generierung
  • Tabellen-Rendering mit TableRenderer
  • Grafik-API: Farben, Verläufe, Muster, Mischmodi, Transparenz
  • Seitenvorlagen mit Kopfzeilen, Fußzeilen, Seitennummerierung, Wasserzeichen
  • Barcode-Generierung (QR, Code128, EAN-13, UPC-A, Code39, ITF)

Hinzugefügt – Suche

  • Textsuche mit Regex, Groß-/Kleinschreibung beachtend/ignorierend, ganzes Wort, Seitenbereiche
  • Typen SearchOptions und SearchResult
  • Positionsverfolgung mit Seite/Koordinaten

Hinzugefügt – Formularfeld-Abdeckung (95 %)

  • Hierarchische Felderstellung (Eltern-/Kind-Strukturen mit Punktnamen)
  • Modifikation von Feldeigenschaften (schreibgeschützt, erforderlich, Rechteck, Tooltip, Maximallänge, Ausrichtung, Standardwert)
  • FDF/XFDF-Export für den Austausch von Formulardaten

Hinzugefügt – Multimedia-Annotationen

  • MovieAnnotation, SoundAnnotation, ScreenAnnotation, RichMediaAnnotation
  • ThreeDAnnotation mit Unterstützung der Formate U3D und PRC

Hinzugefügt – XFA-Formularunterstützung

  • XfaExtractor, XfaParser, XfaConverter (Konvertierung von XFA zu AcroForm)

Geändert – Python-Bindungen

  • Echte Python-3.8-3.14-Unterstützung über abi3-py38
  • Modernes Tooling: uv-, pdm-, ruff-Integration

v0.3.0 – 2026-01-10

Extraktionsgrundlage – vereinheitlichte API und Kernfunktionen

Hinzugefügt – Vereinheitlichte Pdf-API

  • Pdf::open() zum Lesen bestehender PDFs
  • DOM-ähnliche Seitennavigation mit pdf.page(0)
  • Low-Level-Handle PdfDocument für fortgeschrittene Anwendungsfälle

Hinzugefügt – Textextraktion

  • extract_text() – Klartext der gesamten Seite
  • extract_spans() – gestylte Textläufe mit Schrift-Metadaten
  • Strukturbaum-basierte Lesereihenfolge für getaggte PDFs
  • Intelligente Zeilenumbruch- und Leerzeichenerkennung für ungetaggte PDFs

Hinzugefügt – Bildextraktion

  • extract_images() – extrahiert alle Bilder einer Seite
  • Formaterkennung (JPEG, PNG, TIFF, JBIG2, CCITT)
  • Farbraumbehandlung (DeviceRGB, DeviceCMYK, DeviceGray, ICCBased)

Hinzugefügt – Metadatenextraktion

  • Dokument-Info-Dictionary (Titel, Autor, Betreff, Schlüsselwörter)
  • XMP-Metadaten lesen/schreiben
  • Seiteninformationen (Abmessungen, Rotation, media-/crop-/trim-Boxen)

Hinzugefügt – Formularextraktion

  • extract_form_fields() für die Aufzählung von AcroForm-Feldern
  • Feldtypen Text, Button, Auswahl und Signatur

Hinzugefügt – Konvertierung

  • to_markdown() – Markdown-Konvertierung auf Seitenebene
  • to_html() – HTML-Konvertierung auf Seitenebene
  • to_plain_text() – konfigurierbare Klartextausgabe

Hinzugefügt – Konformität

  • PDF/A-Prüfung (ISO 19005, Stufen 1a bis 3b)
  • PDF/X-Prüfung (ISO 15930, Stufen X-1a bis X-6p)
  • PDF/UA-Prüfung (ISO 14289, Stufen UA-1 und UA-2)

Hinzugefügt – Rendering (erfordert das rendering-Feature)

  • Seiten über tiny-skia zu PNG/JPEG rendern
  • Konfigurierbare DPI und Skalierung

Hinzugefügt – Python-Bindungen

  • PdfDocument-Klasse mit vollständiger Extraktions-API
  • Pdf-Klasse mit Erstellungs- und High-Level-API
  • Auf PyO3 basierend, auf PyPI als pdf_oxide veröffentlicht

v0.2.4 – 2026-01-09

  • CTM-Transformationskorrektur für die Textpositionierung
  • Parsen von /Alt und /Pg des Strukturbaums
  • FormulaRenderer für Formelbilder

v0.2.3 – 2026-01-07

  • BT/ET-Matrix-Reset gemäß PDF-Spezifikation
  • Geometrische Abstandserkennung im Markdown-Konverter
  • apply_intelligent_text_processing() für Ligaturen und Silbentrennung

v0.2.2 – 2025-12-15

  • Schlüsselwortoptimierung für die Auffindbarkeit

v0.2.1 – 2025-12-15

  • Verbesserungen bei der Dekodierung verschlüsselter Streams

v0.1.4 – 2025-12-12

  • Korrekturen bei der Dekodierung verschlüsselter Streams

v0.1.0 – 2025-11-06

  • Erstes Release
  • PDF-Textextraktion mit spezifikationskonformem Unicode-Mapping
  • Intelligente Erkennung der Lesereihenfolge
  • Python-Bindungen über PyO3
  • Unterstützung für verschlüsselte PDFs
  • Formularfeldextraktion
  • Bildextraktion