The handoff was written as a message to relay information; several decisions lived only there. Split into permanent homes: - docs/spec.md — scope, geometry model, pipeline order, detection, levels, editor, project file, markers, bundle format, noteman's changes, reference values - ADR 0002 — raster only in release 1; SVG slices measured at 40x WebP naive, 2.6x with a bounding-box cull, deferred on risk not size - ADR 0003 — lossless WebP with levels and 16-level alpha; every lossy option and alternative format measured larger for line art - ADR 0004 — detection proposes, the human disposes; no unattended mode - ADR 0005 — PyMuPDF for all PDF access, accepting AGPL - ADR 0006 — systems are found by vertical brackets, not row-darkness gaps, which miscount every page of a 6-voice score Also from testing against the hardest score in the repertoire: scanned PDFs carry their scan as an embedded image and must be extracted at native resolution rather than re-rendered at 600 DPI, and per-page deskew is mandatory (skew varies -2.6 to +1.2 within one PDF).
37 lines
1.9 KiB
Markdown
37 lines
1.9 KiB
Markdown
# PyMuPDF for all PDF access, accepting AGPL
|
|
|
|
All PDF work — rasterizing at a chosen DPI, exporting SVG, and inspecting page
|
|
content to classify a source as bitmap or vector — goes through **PyMuPDF**. It
|
|
is a single wheel with MuPDF bundled, so the tool needs no system packages. Its
|
|
licence is **AGPL-3.0**, which we accept.
|
|
|
|
## Why not the permissive combination
|
|
|
|
The obvious permissive stack was `pypdfium2` (Apache/BSD) for rasterizing plus
|
|
`mutool` or `pdftocairo` shelled out for SVG. Both of those are **system
|
|
packages** — `mupdf-tools`, `poppler` — and a system package on the vector path
|
|
is precisely the failure the language choice was made to avoid: the tool is
|
|
supposed to install once and run from any directory on any machine.
|
|
|
|
The SVG step can't simply be skipped, either. Music glyphs come from a notation
|
|
font (Emmentaler, Bravura, or Sibelius/Finale's). An SVG that *references* a font
|
|
renders as garbage on a device that lacks it, so text must be converted to paths
|
|
at export. PyMuPDF does this **by default** — `page.get_svg_image(text_as_path=1)`,
|
|
verified to emit `<path>` elements and zero `<text>` — so the font risk is closed
|
|
with no extra tooling.
|
|
|
|
Mixing the two (pypdfium2 for raster, PyMuPDF only for SVG) is the worst option:
|
|
two libraries with overlapping responsibilities, and AGPL linked in anyway.
|
|
|
|
## Consequences
|
|
|
|
- **The AGPL propagates only if the slicer is published.** For a local personal
|
|
tool it costs nothing. A future permissive release would need the rasterizer
|
|
swapped back to `pypdfium2` — a contained change, since PDF access sits behind
|
|
the renderer-agnostic geometry model.
|
|
- **Source-type detection comes free** from the same library: `get_images()` plus
|
|
a full-page-image area check distinguishes a scan from an engraving.
|
|
- The SVG export path is present and working even though the SVG *renderer* is
|
|
deferred — see
|
|
[ADR 0002](0002-raster-only-svg-renderer-deferred.md).
|