# pdf-toolkit
A pure Rust PDF toolkit: fast, bounded and safe by construction. No C libraries, no threads in the core, no
JavaScript or actions ever executed. Layout fidelity targets 80 to 90 percent; speed and clean internals come first.
MIT.
## Crates
Most users want the umbrella crate, `pdf-toolkit`, with features: `text` (default), `render`, `raster`, `write`,
`edit`, `jpx` (JPEG 2000 images through ps-hayro-jpeg2000), `jxl` (JPEG XL images, filter /JXLDecode, through ps-jxl-oxide); `default-features = false` gives the no_std reader alone. Its modules are the layered crates below, which
can also be used directly (embedders such as a browser take only the no_std core and text layers).
| `pdf-toolkit-core` (no_std + alloc) | Zero-copy object model over one shared `Arc<[u8]>`; xref tables, xref streams, hybrid files and `/Prev` chains; object streams; filters (Flate, LZW, ASCII85, ASCIIHex, RunLength, PNG/TIFF predictors, CCITT G3/G4, JBIG2); page tree with inheritance; explicit xref repair mode. Every limit is a named refusal. |
| `pdf-toolkit-text` (no_std + alloc) | Type1, TrueType, Type3 and Type0/CID fonts, encodings, ToUnicode CMaps, a content interpreter producing positioned glyphs, layout with columns, reading order and headings, plain text extraction, a semantic document (styled spans, links, outline), annotation listing, and image XObjects to RGBA or JPEG payloads (JPEG 2000 with the `jpx` feature, JPEG XL with `jxl`). |
| `pdf-toolkit-render` (no_std + alloc) | Page display lists: paths, clips, colours, shadings, images and glyph outlines from embedded TrueType, CFF (via skrifa) and Type 1 fonts; annotation appearance streams with multiply blending. |
| `pdf-toolkit-raster` | Rasterizes display lists to RGBA and PNG with tiny-skia; JPEG via zune-jpeg. |
| `pdf-toolkit-write` | Deterministic writer: standard fonts, subset-embedded TrueType, images with alpha, links, annotations with appearance streams, outlines, xref streams and object streams. |
| `pdf-toolkit-edit` | Incremental updates that keep the original bytes: annotations, page rotation, deletion, reordering and import, document info, and `pdf-roundtrip`, which checks the writer and editor by reading their output back. |
| `pdf-toolkit-inspect` | The `pdf-inspect` binary: `summary`, `streams`, `text`, `receipt`, `semantic`, `image`, `render`, `repair`, `bench`, `mutate` (deterministic mutation fuzzing) and `check` (fixture manifests). |
## Example
```rust
let bytes = std::fs::read("book.pdf")?;
let source = pdf_toolkit::core::PdfSource::new(bytes)?;
let text = pdf_toolkit::text::extract::extract_text(source, pdf_toolkit::core::Limits::default())?;
println!("{}", text.text);
```
The viewer application built on this library lives in its own repository.
## Checking
Behaviour is proven by fixtures, not unit tests. The fixture PDFs in `fixtures/house` are generated by
`pdf-fixtures` (in `pdf-toolkit-write`, which does not depend on the reader) together with ground-truth manifests.
```sh
cargo build --release
./target/release/pdf-fixtures fixtures/house
./target/release/pdf-inspect check fixtures/house
./target/release/pdf-roundtrip target/roundtrip fixtures/house
./target/release/pdf-inspect mutate fixtures/house/hybrid.pdf --seed 1 --count 2000
./target/release/pdf-inspect render some.pdf 0 page.png --dpi 96
```
See `NOTICE` for imported data.