Skip to content

Union of many paths in one coverage pass (#28) - #29

Merged
timzifer merged 1 commit into
mainfrom
fix/union-28
Oct 4, 2026
Merged

timzifer merged 1 commit into
mainfrom
fix/union-28

Conversation

@timzifer

@timzifer timzifer commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Shapes of one paint drawn one after another leave seams where they abut
or overlap along antialiased edges (1 − (1 − a)(1 − b) instead of a + b).
A Union collects fills, strokes and shapes, and Canvas.FillUnion sums
their coverage in one accumulator and composites once.

  • Stroker outlines wind one way everywhere (documented on LineSink,
    tested over random strokes); elements winding the other way (mirrored
    non-hairline strokes, fills by their exact signed area) are reversed.
  • Strokes keep the analytic path: Rasterizer.addStrip sums the
    closed-form rows into the accumulator band by band, so the union does
    not fall back to walking outline edges.
  • Shapes contribute their recorded edges and strips, so banded unions
    stroke once per page. EvenOdd fills and dense dashes are drawn on
    their own.
  • Tests against the supersampled union (overlapping/abutting rectangles
    of both orientations, dense hatches), single-element equality, bands,
    concurrency, zero allocations. ADR 0006 records the design and numbers.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_014ndd7AKiqjKUpYoL1CoEmU

Shapes of one paint drawn one after another leave seams where they abut
or overlap along antialiased edges (1 − (1 − a)(1 − b) instead of a + b).
A Union collects fills, strokes and shapes, and Canvas.FillUnion sums
their coverage in one accumulator and composites once.

- Stroker outlines wind one way everywhere (documented on LineSink,
  tested over random strokes); elements winding the other way (mirrored
  non-hairline strokes, fills by their exact signed area) are reversed.
- Strokes keep the analytic path: Rasterizer.addStrip sums the
  closed-form rows into the accumulator band by band, so the union does
  not fall back to walking outline edges.
- Shapes contribute their recorded edges and strips, so banded unions
  stroke once per page. EvenOdd fills and dense dashes are drawn on
  their own.
- Tests against the supersampled union (overlapping/abutting rectangles
  of both orientations, dense hatches), single-element equality, bands,
  concurrency, zero allocations. ADR 0006 records the design and numbers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ndd7AKiqjKUpYoL1CoEmU
@timzifer
timzifer merged commit eaa0881 into main Oct 4, 2026
13 checks passed
@timzifer
timzifer deleted the fix/union-28 branch October 4, 2026 05:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants