Commit Graph

1 Commits

Author SHA1 Message Date
Levi Neuwirth 24f8c8099a Editor T4-pre W2: the glyph outlines become a shared typed seam
A canvas tessellator needs typed vector paths, and the outlines were private to
render-svg as SVG `d` strings. They move to a new epiphany-glyphs crate, which
implements layout-ir's GlyphCatalog with a real render_data.

The seam was already designed and merely unpopulated: PathCommand,
GlyphRenderData, and GlyphCatalog::render_data all existed, and BravuraCatalog
returned None by deliberate documented honesty -- reporting Some would claim
render data that does not exist. Like W1, this packet fills a structure rather
than building one.

Typed paths are parsed from the `d` strings rather than regenerated, because
Bravura.otf is not vendored -- tools/ carries only the extractor and its OFL
notice, and the generated header pins source hashes verified at extraction
time. Equivalence is therefore proven rather than assumed: parse every bundled
glyph, re-emit, compare byte-for-byte. All thirty-seven round-trip exactly, so
the sanctioned coordinate-comparison fallback was not needed. The real grammar
is wider than the contract's summary claimed -- absolute V/H lineto shorthand
appears in twenty-three of thirty-seven glyphs, and numbers carry nought to
three fractional digits with trailing zeros stripped, never a fixed four. The
parser lowers V/H to LineTo and the emitter reconstructs the shorthand from
geometry.

Nothing rendered moves. The outline data is byte-identical to its previous home
(the only edit is BravuraOutline's visibility), render-svg keeps emitting the
stored strings and re-exports bundled_glyph_count and smufl_codepoint
unchanged, and BRAVURA_METRICS is untouched -- it feeds metrics_hash and hence
GlyphCatalogIdentity, which is inside the resolved layout's canonical bytes.
Verified: all eight reference fixtures produce byte-identical canonical layouts,
and all five GUI goldens are unchanged.

The cross-table test locks what glyph.rs asserted only in prose: every glyph's
declared metrics bbox contains its drawn ink, re-derived through true
cubic-bezier extrema rather than control points. Worst-case deviation across the
whole table is exactly zero, at noteheadBlack's left edge. Stated honestly, this
is a rounding-chain lock rather than an independent cross-check -- the same
extractor emits both tables and deliberately rounds the metric box outward so it
always contains the ink -- but it catches a unit-conversion error, a
regeneration mismatch, or a future inward rounding, none of which had a test
before.

Five of six mutations killed, all coordinator-re-verified independently. The
sixth is an honest survivor and a defect in the contract rather than the work:
it asked for proof that re-emitting from the typed form breaks the goldens,
which the round-trip pin makes a no-op. The goldens were re-proven live a
different way -- perturbing one glyph's stored path by one digit flips one pixel
of 279,992 and fails all five.

Gate: 35 suites / 1351 tests / 0 failed, conformance 9/9 with golden-gate and
8/8 without, requirement labels 6/6, clippy 0, cargo tree showing exactly one
dependency and no third-party crate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 18:54:30 -04:00