Rendering Engine — Visual Parity
Major rendering improvements achieving near-perfect visual fidelity across academic papers, government documents, CJK content, presentations, forms, and complex multi-layer PDFs.
Font Rendering
- Correct Character Spacing — Fixed proportional width resolution for CID, CFF, and TrueType subset fonts. Documents that previously rendered with monospace-like spacing now display with correct kerning and proportional widths.
- Embedded Font Support — Render directly from embedded CFF and TrueType font programs, producing accurate glyph shapes that match the original document's typography.
- Standard Font Metrics — Built-in width tables for the PDF standard 14 fonts (Times, Helvetica, Courier). Fixes uniform character spacing when explicit widths are absent.
- Improved Font Matching — Better system font fallback for URW, LaTeX, and other common font families. Automatic serif/sans-serif detection for appropriate substitution.
Operators & Path Rendering
- Fill-and-Stroke Support — Full implementation of combined fill-and-stroke operators (
B,B*,b,b*), fixing missing border strokes on rectangles and paths. - Clip Path Support — Proper handling of clip-without-paint patterns, resolving issues where body text was hidden behind unclipped background fills.
- Gradient Shading — Axial (linear) and radial gradient rendering with support for exponential interpolation and stitching functions.
- Negative Rectangle Handling — Correct normalization of rectangles with negative dimensions per the PDF specification.
Transparency & Compositing
- Alpha Transparency — Fixed fill and stroke alpha application per PDF specification. Semi-transparent rectangles, images, and paths now blend correctly.
- Graphics State Resolution — Proper indirect reference resolution for extended graphics state parameters, ensuring alpha and blend mode values are applied.
- Isolated Transparency Groups — Support for rendering transparency groups to separate compositing surfaces.
Image Rendering
- Stencil Image Masks — Support for 1-bit stencil masks with CCITT Group 4 decompression. Fixes decorative borders, corner ornaments, and masked image elements.
Page Handling
- Page Rotation — Full support for the
/Rotateattribute (90°, 180°, 270°), correctly rendering landscape slides and rotated documents.
Color Space
- Separation Color Spaces — Proper tint transform evaluation for Separation and DeviceN colors against their alternate color spaces.
Bug Fixes
- Fixed process abort on degenerate CTM coordinates — A malformed CTM could place text spans at extreme coordinates, causing allocation abort. Projection functions now safely skip the split instead of crashing.
- FlateDecode flate-bomb protection — All zlib/deflate decompression paths are now capped, preventing a crafted PDF stream from exhausting virtual memory. The cap defaults to 256 MB and can be adjusted via the
PDF_OXIDE_MAX_DECOMPRESS_MBenvironment variable or programmatically withFlateDecoder::with_limit(n). - Fixed Clipping Stack Synchronization — Resolved a critical issue where the clipping stack could get out of sync with the graphics state, leading to incorrect content being hidden.
- Standardized Image Extraction — Refactored the image extraction logic to support document-wide color space resolution.
- Fixed Python Rendering Accessibility (#240) — Resolved an issue where the
render_pagemethod was unreachable in standard Python builds.
Changed
- Python type stubs — Switched from mypy stubgen to Rylai for generating
.pyifrom PyO3 Rust source statically (no compilation). CI and release workflows updated.
API — Python
New methods on PdfDocument:
validate_pdf_a(level)— PDF/A compliance validation (1a/1b/2a/2b/2u/3a/3b/3u)validate_pdf_ua()— PDF/UA accessibility validationvalidate_pdf_x(level)— PDF/X print complianceextract_pages(pages, output)— Extract page subset to a new PDF filedelete_page(index)— Remove a page by indexmove_page(from, to)— Reorder pagesflatten_to_images(dpi)— Create flattened PDF from rendered pagesPdfDocument(path, password=)— Open encrypted PDFs in one step (#247)PdfDocument.from_bytes(data, password=)— Same for in-memory PDFsPdf.merge(paths)— Merge multiple PDF files into one
API — WASM / JavaScript
New methods on WasmPdfDocument:
validatePdfA(level)— PDF/A compliance validationdeletePage(index)— Remove a pageextractPages(pages)— Extract pages to new PDF bytessave()— Save modified PDF (alias forsaveToBytes())new WasmPdfDocument(data, password?)— Open encrypted PDFs (#247)WasmPdf.merge(pdfs)— Merge multiple PDFs from byte arrays
Core Rust API
rendering::flatten_to_images(doc, dpi)— Shared implementation for all bindingsapi::merge_pdfs(paths)— Merge multiple PDFs (shared across all bindings)
Features
- Rendering Engine Overhaul — Major improvements to the rendering pipeline, achieving high visual parity with industry standards.
- Batteries-Included Python Bindings — The Python distribution now automatically enables page rendering, parallel extraction, digital signatures, and office document conversion by default. (#240)
🏆 Community Contributors
🥇 @tiennh-h2 — Thank you for reporting the rendering accessibility issue (#240). Your feedback helped us identify that our Python distribution was too minimal, leading to an improved "batteries-included" experience for all Python users! 🚀
🥈 @Suleman-Elahi — Thank you for the suggestion to add flattened PDF creation (#240). This led to the new flatten_to_images() API available across Rust, Python, and WASM! 🚀
🥉 @hoesler — Thank you for the XY-cut projection fix (#274) that prevents allocation abort on degenerate CTM coordinates, and the FlateDecoder configurability improvement (#275)! 🚀
🏅 @Leon-Degel-Koehn — Thank you for fixing the Quick Start Rust documentation (#277)! 🚀
🏅 @XO9A8 — Thank you for improving the PdfDocument::from_bytes documentation (#276)! 🚀
🏅 @monchin — Thank you for replacing manual stub generation with Rylai (#250) and for helping diagnose the password API issue (#247) with a clear workaround and API improvement suggestion! 🚀
🏅 @marph91 — Thank you for reporting the password constructor issue (#247), improving the developer experience for encrypted PDF workflows! 🚀
Installation
Rust (crates.io)
cargo add pdf_oxidePython (PyPI)
pip install pdf_oxideJavaScript/WASM (npm)
npm install pdf-oxide-wasmCLI (Homebrew)
brew install yfedoseev/tap/pdf-oxideCLI (Scoop — Windows)
scoop bucket add pdf-oxide https://github.com/yfedoseev/scoop-pdf-oxide
scoop install pdf-oxideCLI (Shell installer)
curl -fsSL https://raw.githubusercontent.com/yfedoseev/pdf_oxide/main/install.sh | shCLI (cargo-binstall)
cargo binstall pdf_oxide_cliMCP Server (for AI assistants)
cargo install pdf_oxide_mcpPre-built Binaries
Download archives for Linux, macOS, and Windows from the assets below. Each archive includes both pdf-oxide (CLI) and pdf-oxide-mcp (MCP server).
Platform Support
| Platform | Architecture | Archive |
|---|---|---|
| Linux | x86_64 (glibc) | pdf_oxide-linux-x86_64-*.tar.gz
|
| Linux | x86_64 (musl) | pdf_oxide-linux-x86_64-musl-*.tar.gz
|
| Linux | ARM64 | pdf_oxide-linux-aarch64-*.tar.gz
|
| macOS | x86_64 (Intel) | pdf_oxide-macos-x86_64-*.tar.gz
|
| macOS | ARM64 (Apple Silicon) | pdf_oxide-macos-aarch64-*.tar.gz
|
| Windows | x86_64 | pdf_oxide-windows-x86_64-*.zip
|
Changelog
See CHANGELOG.md for full details.