Problem
Fill-only Rect and Ellipse nodes derive damage coverage from the producer's
node.bounds, which is computed by applying the original affine to absolute
local coordinates. The private painter takes a rounding-distinct route: it
first composes the box origin into world in f32, then maps a 0..width /
0..height primitive through that composed matrix.
Those routes are algebraically equal but not bit-equivalent. Under
cancellation, the private fill can reach a finite pixel coordinate outside the
recorded damage envelope, so an incremental repaint can omit changed fill ink.
The stroke-width percentage-saturation rung closes this for stroked boxes by
unioning the direct projection with the actual composed-box projection. It
deliberately does not broaden that capability patch into fill-only damage.
Reproduction shape
The stroke-side arithmetic audit found a final-encoding witness with:
- affine
a = 0x947982c2, tx = 0x214afd2a, other x-row cross term zero;
- rect
x = 0xee47e90e, width = 0x6e1245fa, y = 0, height = 1;
- frame
0,0,64,64.
For the analogous composed box route, compare the absolute-coordinate
math2::rect_transform envelope against
node.transform.then(translate(rect.x, rect.y)) applied to the origin and far
edge, through final outward RectF encoding. Pin a fill-only witness whose
private endpoint lies outside the current coverage. The originating exhaustive
search compared those two operation orders at each finite f32 bit pattern and
then tested containment only after the same frame clip and outward RectF
encoding used by the product.
Required outcome
- Fill coverage for Rect and Ellipse follows or conservatively encloses the
same composed f32 world that the private painter executes.
- Path coverage keeps its absolute-coordinate route.
- Projection remains outward-conservative, finite, and frame-bounded; paint
reference boxes remain geometry bounds.
- Add exact Rect and Ellipse regressions through final damage encoding and a
before/after diff_frame law.
Scope
This is a pre-existing fill damage/provenance defect, not a Web stroke-width or
paint-semantic gap. It is related to, but distinct from, the generic union
representation failures tracked in #87.
Problem
Fill-only Rect and Ellipse nodes derive damage coverage from the producer's
node.bounds, which is computed by applying the original affine to absolutelocal coordinates. The private painter takes a rounding-distinct route: it
first composes the box origin into
worldinf32, then maps a0..width/0..heightprimitive through that composed matrix.Those routes are algebraically equal but not bit-equivalent. Under
cancellation, the private fill can reach a finite pixel coordinate outside the
recorded damage envelope, so an incremental repaint can omit changed fill ink.
The stroke-width percentage-saturation rung closes this for stroked boxes by
unioning the direct projection with the actual composed-box projection. It
deliberately does not broaden that capability patch into fill-only damage.
Reproduction shape
The stroke-side arithmetic audit found a final-encoding witness with:
a = 0x947982c2,tx = 0x214afd2a, other x-row cross term zero;x = 0xee47e90e,width = 0x6e1245fa,y = 0,height = 1;0,0,64,64.For the analogous composed box route, compare the absolute-coordinate
math2::rect_transformenvelope againstnode.transform.then(translate(rect.x, rect.y))applied to the origin and faredge, through final outward
RectFencoding. Pin a fill-only witness whoseprivate endpoint lies outside the current coverage. The originating exhaustive
search compared those two operation orders at each finite
f32bit pattern andthen tested containment only after the same frame clip and outward
RectFencoding used by the product.
Required outcome
same composed
f32world that the private painter executes.reference boxes remain geometry bounds.
before/after
diff_framelaw.Scope
This is a pre-existing fill damage/provenance defect, not a Web stroke-width or
paint-semantic gap. It is related to, but distinct from, the generic union
representation failures tracked in #87.