PaperForge
A comprehensive, pure-Rust PDF generation, editing, inspection, rendering, and document-processing engine.
Overview
PaperForge is a native Rust alternative to Python ReportLab and fragmented Rust PDF tooling. One coherent API for generating, editing, parsing, rendering, and extracting PDF documents.
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
Generate a PDF:
use *;
Features
| Feature | Status |
|---|---|
| PDF Generation | โ |
| PDF Parsing | โ |
| PDF Editing | ๐ (merge/split via CLI + paperforge-pdf edit API) |
| Text + Unicode | โ |
| Font Embedding | ๐ (loading scaffold; TTF parsing/subsetting planned) |
| JPEG/PNG Images | โ
(JPEG pass-through, PNG decode, /SMask) |
| Vector Graphics | โ |
| Basic Layout | ๐ |
| Tables | ๐ |
| Forms | ๐ |
| Rendering | ๐ |
| Encryption | ๐ |
| PDF/A | ๐ |
Architecture
paperforge/
โโโ paperforge/ # Main public crate
โโโ paperforge-core/ # PDF-independent abstractions
โโโ paperforge-pdf/ # PDF serialization/parsing
โโโ paperforge-layout/ # High-level document layout
โโโ paperforge-fonts/ # Font handling
โโโ paperforge-images/ # Image support
โโโ paperforge-render/ # PDF rendering
โโโ paperforge-forms/ # AcroForm support
โโโ paperforge-annotations/ # Annotations
โโโ paperforge-security/ # Encryption/security
โโโ paperforge-extract/ # Text/image extraction
โโโ paperforge-cli/ # CLI tool
Benchmarks
Measured with criterion (30 samples, median) on an AMD Ryzen 5 7235HS / Windows 11 (2026-08-12). Workload: a 100-page A4 text document โ one heading and one body line per page โ built with each library's high-level (or object-level, for lopdf) API and then parsed from the same in-memory bytes. Every library builds the identical workload. Reproduce with cargo bench -p paperforge-bench.
| Benchmark | paperforge | lopdf 0.34 | printpdf 0.7 |
|---|---|---|---|
| Generate 100-page text doc | 1.30 ms | 306 ยตs | 3.66 ms |
| Generate, content compression off | 363 ยตs | 306 ยตs ยน | โ |
| Parse 100-page doc (~36 KB) | 254 ยตs | 377 ยตs | โ |
| Output size (100 pages) | 35.9 KB | 27.4 KB | 60.9 KB |
ยน lopdf writes uncompressed streams by default; both columns use each library's default settings.
Notes:
- Generation beats printpdf by ~2.8ร. paperforge (default: flate-compressed content, level 6) generates the 100-page document in 1.30 ms โ 5ร faster than the previous release (5.97 ms) and ~2.8ร faster than printpdf (3.66 ms). lopdf remains the fastest because its default output skips compression entirely and is object-level; with compression disabled paperforge (363 ยตs) is within ~20% of lopdf (306 ยตs) on the same uncompressed workload.
- Parsing beats lopdf by ~33% โ 254 ยตs vs 377 ยตs on the same compressed 100-page document.
- Output is 1.7ร smaller than printpdf (35.9 KB vs 60.9 KB). paperforge's output is also 25% smaller than the previous release (47.7 KB) thanks to a single shared
/Resourcesobject referenced by every page. lopdf's 27.4 KB is uncompressed object-level output that omits required structure such as the/Parentlink; paperforge keeps full spec compliance (ISO 32000-1). - The speedups come from reusing zlib compressor state across content streams (4โ6ร faster flate on many small streams), building content streams into a reused buffer without per-command
format!allocations, a fast hasher for dictionary keys, and manual integer/number parsing in the parser (no per-number UTF-8 validation orstr::parse). - The parse benchmark surfaced a real interop bug: xref table entries were 19 bytes instead of the spec-mandated 20 (ISO 32000-1 ยง7.5.4), which strict parsers such as lopdf reject. Entries are now spec-compliant, locked in by
serializer::tests::xref_entries_are_exactly_20_bytes. - Criterion also writes per-run reports and regression tracking to
target/criterion/.
Full methodology and analysis are in docs/benchmarks.md.
Feature Flags
[]
= { = "0.1", = ["generate", "parse", "layout", "fonts", "images"] }
Available features: generate, parse, edit, layout, fonts, images, render, forms, annotations, security, extract, svg.
License
Dual-licensed under MIT OR Apache-2.0.