Text extraction correctness
- Adjacent narrow-glyph doublets no longer collapsed at small font sizes (#378, PR #379).
TextExtractor::deduplicate_overlapping_charsand
deduplicate_overlapping_spansused a hardcoded 2 pt absolute threshold to
detect duplicate glyphs from stroke+fill render passes. For narrow glyphs
(l,r,I,i) in compact fonts at small sizes the per-glyph advance
width drops to ≤ 2 pt (Helvetical≈ 2.5 pt at 9 pt), so legitimate
adjacent doublets one full advance apart fell inside the dedup window and
one of the two glyphs was silently dropped. Visible corruption included
controller → controler,billed → biled,warranty → warrnty,
following → folowing, andVIII → VII. Builds on prior #102 / #253,
which added same-text and same-character identity guards but kept the 2 pt
threshold — this fix addresses the residual case where both glyphs are
identical (passing the identity check) yet still legitimate neighbours.
Threshold now scales with each glyph's ownadvance_width(fallback
bbox.width) asmin(advance_width * 0.30, 2.0). Real render-pass
duplicates sit well under 5 % of one advance apart and continue to
collapse; heaviest kerning observed in the wild is ≤ 20 % of advance, so
legitimate kerned neighbours are preserved. Tunables hoisted to
TextExtractor::DEDUP_OVERLAP_RATIO/DEDUP_OVERLAP_CAP_PTassociated
constants so both dedup paths share one source of truth. Regression
coverage spans the matrix of four narrow glyphs × three small body-text
sizes (7 / 9 / 11 pt) on both the per-char and per-span paths, plus
positive cases proving stroke+fill duplicates at ~0 pt offset still
collapse.
Community Contributors
- @Hugues-DTANKOUO — Reported #378
with a precise root-cause analysis (the 2 pt absolute threshold falling
below one advance width for narrow glyphs in compact fonts at small sizes)
and authored PR #379 with the advance-scaled threshold and a
parametrised regression matrix covering the four narrow glyphs across
three body-text sizes.
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.