epiphany/crates
Levi Neuwirth 9539b1652b layout-ir, engrave: ledger lines
Notes above or below the staff now get ledger lines — the gap the GUI surfaced
the moment a note is moved off the staff. Each notehead carries its StaffStep;
to_constrained emits one short horizontal stroke per whole step between the
staff (lines at steps 0..=8) and the note, reaching LEDGER_LINE_EXTENSION past
each side of the note's actual bounding box (so a wide whole note gets a wider
ledger), synthesized from the pitch so the strokes are deterministic and
hit-testable. The synthesis key splits component (high 64 bits) from signed step
(low 64) so two components of a very low note can never collide.

Ledger lines are fixed-width marks, not system-spanning lines, so the Engraver's
horizontal spacing must not scale them. is_rigid_width_stroke marks them; the
remap translates such a stroke rigidly by its *owning glyph's* column delta
(found by source, not the stroke midpoint — which for a wide head can fall nearer
a neighbouring column), so it keeps both its length and its offset from the
notehead. The spacing pass folds each ledger's extent into its notehead's slot,
so adjacent off-staff notes' ledgers reserve room and do not overlap. The stub
solver passes ledgers through unchanged.

Tests cover the step geometry, key distinctness (incl. steps below -128), the
bbox span, width preservation and offset (no-drift) through the Engraver, the
adjacent-overlap spacing, and an explicit two-whole-note off-staff drift case.
Render goldens regenerated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NAtEiJtt9yKVV1zjKYmZhS
2026-06-29 17:12:56 -04:00
..
epiphany-bundle Pass 11 audit follow-up: honest LayoutObjectId status + doc/test gaps 2026-06-22 10:02:05 -04:00
epiphany-core Agent I-0: real clef + key-signature data in the core graph 2026-06-26 10:31:16 -04:00
epiphany-determinism P12-I2: wire the ratified MUSCLOID layout-object id derivation 2026-06-27 12:46:19 -04:00
epiphany-editor-core editor-core: expose the resolved layout for renderers 2026-06-29 11:46:31 -04:00
epiphany-editor-gui editor-gui: a thin native (egui) editor over the editor-core seam 2026-06-29 11:47:25 -04:00
epiphany-engrave layout-ir, engrave: ledger lines 2026-06-29 17:12:56 -04:00
epiphany-layout-ir layout-ir, engrave: ledger lines 2026-06-29 17:12:56 -04:00
epiphany-ops epiphany-editor-core: a headless editor API + a conformance UI-seam gate 2026-06-27 16:47:34 -04:00
epiphany-render-svg layout-ir, engrave: ledger lines 2026-06-29 17:12:56 -04:00
epiphany-testkit epiphany-editor-core: a headless editor API + a conformance UI-seam gate 2026-06-27 16:47:34 -04:00