Schema major 2 Phase F: ratify repeat + slur rendering into Chapter 7
The schema-major-2 push's rendering consumers (E1 repeat barlines/volta brackets, E2 slur cubic-béziers) lifted into core spec Chapter 7 — layout-IR only, non-canonical, so no wire form and no companion-version bump (Operation Catalog stays 0.7.0, Binary Format 0.6.0), mirroring the schema-major-1 Phase-F engrave-ratify-only precedent. Three req:layoutir:* requirements added at §ResolvedLayoutIR: - resolved-primitives: ResolvedLayoutIR carries non-glyph line Strokes (staff lines, stems, barlines, volta brackets — present since staff lines, never previously ratified) and cubic-bézier Curves (slurs, E2); each provenance- traced (the hit-test basis), re-spaced like a glyph, non-canonical. The struct listing gains strokes/curves and the Stroke/Curve shapes; the RenderIR provenance requirement widened from "originating ResolvedGlyph" to "ResolvedGlyph, Stroke, or Curve". - repeat-render (E1): a barline-drawing RepeatStructure renders a repeat barline at each resolved boundary, each Volta a bracket with ending numbers; unresolvable boundaries draw no ink (honest placement); jump-kind marks and cross-region repeats deferred. - slur-curve (E2): a Slur renders as a cubic bézier honoring CurvatureOverride; an endpoint not on a single staff of one region draws no curve; a non-Solid line style MUST be surfaced (diagnostic), not silently rendered solid. The curvature-computing algorithm and the RenderIR encoding stay forward- referenced out. Ch5 §Slurs / §Repeat Structures and the Ch7 Forward References gain labels for the cross-references. Revision-history row + a schema-major-2 rendering tranche in PASS12_RATIFICATION_LOG.md; layout-ir DECISIONS carry the Phase-F cross-refs. Spec builds clean (latexmk -xelatex, 0 undefined refs). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
28f210e16f
commit
693150e43e
|
|
@ -483,6 +483,13 @@ emission set (successive-notehead no-collision chains + per-glyph containment
|
|||
|
||||
## Repeat barlines and volta brackets (schema major 2, E1, 2026-07-07)
|
||||
|
||||
> **Ratified (Phase F, 2026-07-08):** these decisions are now the normative
|
||||
> Minimal-tier floor `req:layoutir:repeat-render` in core spec Chapter 7
|
||||
> (§ResolvedLayoutIR); the non-glyph primitives the volta brackets use are
|
||||
> `req:layoutir:resolved-primitives`. Layout geometry is non-canonical, so no
|
||||
> wire/companion-version change (PASS12_RATIFICATION_LOG.md, schema-major-2
|
||||
> tranche).
|
||||
|
||||
The first repeat-structure ink (Chapter 5 `RepeatStructure` / `RepeatKind` /
|
||||
`Volta`, ratified by the major-2 Phase A). Rendering is spec-unconstrained
|
||||
(Ch7's `BarLine` payload is undefined and voltas have no layout variant), so
|
||||
|
|
@ -559,6 +566,15 @@ these are E1 implementation decisions for the Phase-F ratification pass:
|
|||
|
||||
## Slur curves + the cubic-bézier curve primitive (schema major 2, E2, 2026-07-08)
|
||||
|
||||
> **Ratified (Phase F, 2026-07-08):** the slur rendering floor is
|
||||
> `req:layoutir:slur-curve` and the `Curve`/`Stroke` primitive vocabulary is
|
||||
> `req:layoutir:resolved-primitives` in core spec Chapter 7 (§ResolvedLayoutIR)
|
||||
> — the struct listing now carries `strokes`/`curves` and the `Stroke`/`Curve`
|
||||
> shapes, and the RenderIR provenance requirement was widened to name all three
|
||||
> primitive kinds. The curvature *algorithm* and dash rendering stay
|
||||
> forward-referenced out. Non-canonical, so no wire/companion-version change
|
||||
> (PASS12_RATIFICATION_LOG.md, schema-major-2 tranche).
|
||||
|
||||
The third pipeline primitive kind. Primitives were two parallel flat Vecs
|
||||
(`glyphs`, `strokes`) at each of the three IR stages; a `Curve` (four control
|
||||
points + thickness/layer/style/provenance, mirroring `Stroke`) adds a third
|
||||
|
|
|
|||
|
|
@ -177,3 +177,34 @@ returned a successful empty derivation under the requested profile. Resolution:
|
|||
the **spec text stands**; the code moved — `derive_annotations` now returns
|
||||
`Result` and rejects unregistered ids up front (`PrePassError`). No spec
|
||||
change; core DECISIONS records the reasoning.
|
||||
|
||||
## Schema-major-2 tranche (2026-07-08) — rendering (E1/E2), engrave ratify-only
|
||||
|
||||
The schema-major-2 push's *rendering* consumers, ratified into core spec
|
||||
Chapter 7. The data model (Phases A–C) and the repeat-authoring op pair (Phase
|
||||
D) already landed with their own revision-history rows and companion-version
|
||||
bumps (Operation Catalog 0.7.0, Binary Format 0.6.0); this tranche records
|
||||
**Phase F**, which is layout-IR (Chapter 7) only. Delivered as the E1
|
||||
(`7a9bf42` + `6651ae5`), E2 (`81b7f42` + `28f210e`) commit series. Layout
|
||||
geometry is non-canonical (no content hash, no wire form — see
|
||||
`req:layoutir:object-id-derivation`), so this is a ratify-as-implemented with
|
||||
**no byte-layout change and no companion bump**, mirroring the schema-major-1
|
||||
Phase-F precedent.
|
||||
|
||||
| Item | Disposition | Spec locus | Consumer |
|
||||
|---|---|---|---|
|
||||
| Non-glyph resolved primitives | **adopt (ratify pre-existing + E2 reality)** — Ch7 gains Requirement `req:layoutir:resolved-primitives`: `ResolvedLayoutIR` carries, beyond glyphs, non-glyph line `Stroke`s (staff lines, stems, barlines, volta brackets — present since staff lines, never previously ratified) and cubic-Bézier `Curve`s (slurs, E2). Each carries provenance (the hit-testing basis) and is re-spaced by the solver like a glyph; both are non-canonical. The struct listing and the `Stroke`/`Curve` shapes are added; the RenderIR provenance requirement widened from "originating `ResolvedGlyph`" to "…`ResolvedGlyph`, `Stroke`, or `Curve`" | core_spec Ch7 §ResolvedLayoutIR (`req:layoutir:resolved-primitives`) | `epiphany-layout-ir` (`constrained.rs::{Stroke,Curve}`, `resolved.rs`); `epiphany-render-svg` |
|
||||
| E1 repeat / volta rendering | **adopt** — Ch7 gains Requirement `req:layoutir:repeat-render`: a barline-drawing `RepeatStructure` renders a repeat barline at each resolved boundary (the precomposed sign, replacing a coinciding measure barline or standing alone; the dot pair beside a never-replaced final barline), each `Volta` a bracket with ending numbers; an unresolvable boundary draws no ink (traced anchor, honest placement); jump-kind (`DaCapo`/`DalSegno`) marks and cross-region repeats deferred. The glyph vocabulary/spacing stay engraving-algorithm concerns | core_spec Ch7 §ResolvedLayoutIR (`req:layoutir:repeat-render`); references Ch5 §Repeat Structures | `epiphany-layout-ir` (`logical.rs`, `constrained.rs`); `epiphany-engrave` (casting) |
|
||||
| E2 slur rendering | **adopt** — Ch7 gains Requirement `req:layoutir:slur-curve`: a `Slur` renders as a cubic Bézier between its endpoint columns, honoring `CurvatureOverride` (direction, height); an endpoint that does not resolve to a column on a single staff of one region draws no curve (traced anchor); a non-`Solid` `SpanStyle` line MAY be deferred but MUST be surfaced (a layout diagnostic), never silently rendered solid. The curvature algorithm and dash rendering stay forward-referenced out | core_spec Ch7 §ResolvedLayoutIR (`req:layoutir:slur-curve`); references Ch5 §Slurs and Phrase Marks | `epiphany-layout-ir` (`logical.rs`, `constrained.rs`, `hittest.rs`); `epiphany-editor-core` |
|
||||
|
||||
**Version movements.** None on the wire: core spec Chapter 7 gains three
|
||||
`req:layoutir:*` requirements + the `Stroke`/`Curve` struct listings + a
|
||||
revision-history row (Phase F). Operation Catalog stays 0.7.0, Binary Format
|
||||
stays 0.6.0 — layout geometry is non-canonical.
|
||||
|
||||
**Deferred (documented, not open candidates).** Dashed/dotted slur *rendering*
|
||||
(surfaced as a diagnostic today), kind-differentiated slur appearance
|
||||
(Phrase/Editorial), jump-kind repeat marks, cross-region and cross-system-break
|
||||
curve splitting (de Casteljau), and the `slur_shape` quality metric moving off
|
||||
`0.0`-by-construction — all Standard-tier / Push-3 work, named in the crate
|
||||
DECISIONS, none a Pass-13 ambiguity.
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -5066,6 +5066,7 @@ pub struct CrossCuttingRegistry {
|
|||
\end{lstlisting}
|
||||
|
||||
\subsection{Slurs and Phrase Marks}
|
||||
\label{sec:graph:slurs}
|
||||
|
||||
\begin{lstlisting}[language=Rust]
|
||||
pub struct Slur {
|
||||
|
|
@ -5357,6 +5358,7 @@ pub enum MarkerKind {
|
|||
\end{lstlisting}
|
||||
|
||||
\subsection{Repeat Structures}
|
||||
\label{sec:graph:repeats}
|
||||
|
||||
\begin{lstlisting}[language=Rust]
|
||||
pub struct RepeatStructure {
|
||||
|
|
@ -9213,8 +9215,8 @@ pub enum BreakKind {
|
|||
\label{sec:layoutir:resolved}
|
||||
|
||||
\texttt{ResolvedLayoutIR} is the output of the constraint solver:
|
||||
every glyph has a definitive position. This is the IR consumed by
|
||||
the renderer.
|
||||
every glyph, stroke, and curve has a definitive position. This is the
|
||||
IR consumed by the renderer.
|
||||
|
||||
\begin{lstlisting}[language=Rust]
|
||||
pub struct ResolvedLayoutIR {
|
||||
|
|
@ -9226,6 +9228,14 @@ pub struct ResolvedLayoutIR {
|
|||
/// Glyph-level objects with resolved positions.
|
||||
pub glyphs: Vec<ResolvedGlyph>,
|
||||
|
||||
/// Non-glyph line primitives (staff lines, stems, barlines,
|
||||
/// volta brackets, ...), positioned alongside the glyphs.
|
||||
pub strokes: Vec<Stroke>,
|
||||
|
||||
/// Cubic-Bezier curve primitives (slurs, ...), positioned
|
||||
/// alongside the glyphs.
|
||||
pub curves: Vec<Curve>,
|
||||
|
||||
/// Engraving decisions, including any made by the constraint
|
||||
/// solver (e.g., soft system breaks placed by casting-off).
|
||||
pub engraving_decisions: Vec<EngravingDecision>,
|
||||
|
|
@ -9256,8 +9266,88 @@ pub struct ResolvedGlyph {
|
|||
pub style: GlyphStyle,
|
||||
pub layer: i32,
|
||||
}
|
||||
|
||||
/// A line primitive the solver positions but the vertical-band
|
||||
/// model does not contain (a staff line, stem, barline, or bracket).
|
||||
pub struct Stroke {
|
||||
pub provenance: Provenance,
|
||||
pub from: Point2D,
|
||||
pub to: Point2D,
|
||||
pub thickness: StaffSpace,
|
||||
pub layer: i32,
|
||||
pub style: GlyphStyle,
|
||||
}
|
||||
|
||||
/// A cubic-Bezier curve primitive (a slur), its four control
|
||||
/// points in `p0`..`p3` drawing order.
|
||||
pub struct Curve {
|
||||
pub provenance: Provenance,
|
||||
pub p0: Point2D,
|
||||
pub p1: Point2D,
|
||||
pub p2: Point2D,
|
||||
pub p3: Point2D,
|
||||
pub thickness: StaffSpace,
|
||||
pub layer: i32,
|
||||
pub style: GlyphStyle,
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{requirement}
|
||||
\label{req:layoutir:resolved-primitives}
|
||||
\textbf{Non-glyph resolved primitives (ratified schema-major-2,
|
||||
Phase~F).} Beyond glyphs, \texttt{ResolvedLayoutIR} carries
|
||||
non-glyph \emph{line-stroke} primitives (staff lines, stems,
|
||||
barlines, brackets) and \emph{cubic-B\'ezier curve} primitives
|
||||
(slurs). Each \MUST{} carry provenance --- the basis of hit-testing
|
||||
(\ref{sec:layoutir:provenance}) --- and is positioned by the solver
|
||||
like a glyph: a spanning stroke or curve is re-spaced by the same
|
||||
horizontal coordinate map its endpoint columns move under. These
|
||||
primitives are \emph{non-canonical}: like layout identifiers and
|
||||
glyph positions, they are not part of document state and enter no
|
||||
content hash (\ref{req:layoutir:object-id-derivation}). A conformant
|
||||
renderer draws them alongside the glyphs; the renderer encoding
|
||||
itself is out of scope (\ref{sec:layoutir:render}).
|
||||
\end{requirement}
|
||||
|
||||
\begin{requirement}
|
||||
\label{req:layoutir:repeat-render}
|
||||
\textbf{Minimal-tier repeat and volta rendering (ratified
|
||||
schema-major-2, Phase~F).} A \texttt{RepeatStructure}
|
||||
(\ref{sec:graph:repeats}) whose kind draws barlines
|
||||
(\texttt{SimpleRepeat}, \texttt{Volta}) \MUST{} render a repeat
|
||||
barline at each of its resolved boundaries --- the precomposed
|
||||
repeat sign, either replacing a coinciding measure barline or
|
||||
standing at the boundary column when none coincides, and the
|
||||
repeat-dot pair beside a region-closing final barline (which is
|
||||
never replaced). Each \texttt{Volta} \MUST{} render a bracket
|
||||
spanning its resolved extent, with its ending numbers. A boundary
|
||||
that does not resolve to a spacing column draws \emph{no} ink: a
|
||||
traced anchor preserves the structure's provenance rather than
|
||||
placing a mark at a false position. The jump kinds
|
||||
(\texttt{DaCapo}, \texttt{DalSegno}) draw no Minimal-tier marks ---
|
||||
their segno / coda / instruction text awaits a text primitive ---
|
||||
and a repeat spanning more than one region renders in no single
|
||||
region at this tier. The precise glyph vocabulary and spacing are
|
||||
engraving-algorithm concerns (\ref{sec:layoutir:forward}).
|
||||
\end{requirement}
|
||||
|
||||
\begin{requirement}
|
||||
\label{req:layoutir:slur-curve}
|
||||
\textbf{Minimal-tier slur rendering (ratified schema-major-2,
|
||||
Phase~F).} A \texttt{Slur} (\ref{sec:graph:slurs}) \MUST{} render
|
||||
as a cubic-B\'ezier \texttt{Curve} arcing between its two endpoint
|
||||
event columns, honoring an authored \texttt{CurvatureOverride}
|
||||
(direction and apex height) when present and choosing them
|
||||
otherwise. A slur whose endpoint does not resolve to a column on a
|
||||
single staff of one region draws \emph{no} curve: a traced anchor
|
||||
preserves its provenance rather than a floating arc. An authored
|
||||
non-\texttt{Solid} \texttt{SpanStyle} line (dashed, dotted) \MAY{}
|
||||
be deferred to a higher tier, but \MUST{} be surfaced (a layout
|
||||
diagnostic), never silently rendered solid. The curvature-computing
|
||||
algorithm and the dash rendering are engraving-specification
|
||||
concerns (\ref{sec:layoutir:forward}).
|
||||
\end{requirement}
|
||||
|
||||
\section{RenderIR (Interface Only)}
|
||||
\label{sec:layoutir:render}
|
||||
|
||||
|
|
@ -9291,9 +9381,11 @@ pub struct RenderConfiguration {
|
|||
\begin{requirement}
|
||||
Implementations producing \texttt{RenderIR} \MUST{} preserve
|
||||
provenance from \texttt{ResolvedLayoutIR}: every renderer primitive
|
||||
\MUST{} be traceable to its originating \texttt{ResolvedGlyph} (and
|
||||
therefore to its score graph source). This is the basis of
|
||||
hit-testing, selection, and back-reference navigation in the UI.
|
||||
\MUST{} be traceable to its originating \texttt{ResolvedLayoutIR}
|
||||
primitive --- a \texttt{ResolvedGlyph}, \texttt{Stroke}, or
|
||||
\texttt{Curve} --- and therefore to its score graph source. This is
|
||||
the basis of hit-testing, selection, and back-reference navigation
|
||||
in the UI.
|
||||
|
||||
The full RenderIR type and its production rules are specified in
|
||||
the renderer specification, outside the scope of this document.
|
||||
|
|
@ -9515,6 +9607,7 @@ pub struct GlyphCatalogIdentity {
|
|||
\end{requirement}
|
||||
|
||||
\section{Forward References}
|
||||
\label{sec:layoutir:forward}
|
||||
|
||||
\begin{itemize}
|
||||
\item The constraint solver consuming \texttt{ConstrainedLayoutIR}
|
||||
|
|
@ -15392,6 +15485,28 @@ layouts they own versus inherit:
|
|||
per-payload stamping (create born at v2; delete a minor kind append
|
||||
at major~0): Binary Format companion 0.5.0~$\rightarrow$~0.6.0.
|
||||
\\
|
||||
\today & Schema major 2 (rendering, Phase F) &
|
||||
The rendering consumers of the schema-major-2 data model are
|
||||
ratified into Chapter~7. \texttt{ResolvedLayoutIR} gains the
|
||||
non-glyph primitive vocabulary it has always carried in
|
||||
implementation --- line \texttt{Stroke}s (staff lines, stems,
|
||||
barlines, volta brackets) and cubic-B\'ezier \texttt{Curve}s
|
||||
(slurs) --- as \ref{req:layoutir:resolved-primitives}
|
||||
(provenance-traced, non-canonical). Two Minimal-tier rendering
|
||||
floors join the constraint floor: \ref{req:layoutir:repeat-render}
|
||||
(E1: repeat barlines at resolved boundaries, volta brackets with
|
||||
ending numbers, honest non-drawing of unresolvable boundaries,
|
||||
jump-kind marks and cross-region repeats deferred) and
|
||||
\ref{req:layoutir:slur-curve} (E2: a slur renders as a cubic
|
||||
B\'ezier honoring \texttt{CurvatureOverride}, honest non-drawing of
|
||||
unresolvable or cross-staff spans, a non-\texttt{Solid} line style
|
||||
surfaced not silently rendered solid). The curvature-computing
|
||||
algorithm and the \texttt{RenderIR} encoding stay forward-referenced
|
||||
out (\ref{sec:layoutir:forward}, \ref{sec:layoutir:render}). Layout
|
||||
geometry is non-canonical, so no wire form and no companion version
|
||||
moves --- an engrave-side ratify-as-implemented, mirroring the
|
||||
schema-major-1 Phase~F precedent.
|
||||
\\
|
||||
\bottomrule
|
||||
\end{longtable}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue