fix: stroke arcs and splines analytically — opaque core, angle-independent weight
LICE_Arc never reaches opacity and ThickFLine's width is minor-axis. One distance-to-polyline coverage mask, blended once, replaces both.
This commit is contained in:
@@ -101,6 +101,7 @@ L7 sub-pass, 2026-07-27):
|
||||
- `tooltip` — pure tooltip placement + prefix-strip: strips the `ReaSampler:` display prefix from the registered action phrase; width clamped to the client rect.
|
||||
- `card_drag` — pure drag-gesture precedence + slot hit-test: leave-client → OS drag-out; other-bank → move/copy; same-bank → reorder / Alt-over-occupied → replace.
|
||||
- `card_meta` — pure card-metadata formatters: bars.beats.subdivisions and seconds.milliseconds; blank when the sample is unstamped.
|
||||
- `stroke_aa` — analytic antialiased thick-stroke COVERAGE (the shell blends it): `StrokeCanvas`, a reusable mask holding distance-to-polyline coverage MAX-accumulated across segments, plus `strokePolyline` / `strokeBounds` / `appendArc`. An arc is just a flattened polyline, so ONE path serves the knob arcs, the inner dial, the envelope polyline and both spline traces. Coverage is `clamp(halfWidth + 0.5 - distance, 0, 1)`, which makes perpendicular weight exactly `2·halfWidth` at every angle and gives an opaque core for any width above 1 px. Long segments are subdivided before rasterizing — EXACT, not an approximation (min-distance to a partition of a segment is min-distance to the whole), purely to keep each piece's bounding box tight, since one long diagonal's box has area O(len²).
|
||||
|
||||
## Gotchas
|
||||
|
||||
@@ -122,3 +123,17 @@ L7 sub-pass, 2026-07-27):
|
||||
- `rect`'s prior role names survive only as `using` aliases at their old call
|
||||
sites — changing `rect.h` itself ripples across every directory that aliases
|
||||
it (e.g. `editor_geometry::Rect`); check all alias sites, not just this one.
|
||||
- **`stroke_aa`'s mask is deliberately NOT cleared on `reset`.** Only
|
||||
`[rowLo, rowHi)` of each row holds meaningful coverage; everything else is
|
||||
whatever the reused buffer last held. That is what keeps a stroke's cost
|
||||
proportional to its ink rather than to its bounding box — but it means any new
|
||||
reader must respect the row extents, and any new writer must grow them through
|
||||
`extendRow`, which zero-fills the newly-valid cells INCLUDING the gap when a
|
||||
stroke revisits a row far from where it left it (a circle touches most rows on
|
||||
both sides). Reading the raw buffer outside the extents returns garbage by
|
||||
design, not zero.
|
||||
- **Neither `LICE_Arc` nor `LICE_ThickFLine` can draw these strokes** — the first
|
||||
never reaches an opaque core, the second's width is along the minor axis so its
|
||||
perpendicular weight falls off as `cos θ`. The evidence and the measurements
|
||||
live in `docs/product/visual-design-language.md` §8; do not "simplify" a stroke
|
||||
site back onto either primitive.
|
||||
|
||||
Reference in New Issue
Block a user