The Elliptical Marquee tested and wrote every pixel one at a time
(Surface::write_pixel), single-threaded, with no shared full tiles. The
add/subtract/intersect modes read both selections over the whole canvas
into f32 buffers. On 6000x4000 an ellipse took ~0.6-1.1 s and a mode
combination ~0.3-0.5 s.
ellipse_surface builds the shape per row: a run of fully selected pixels
(bounded analytically, checked with the exact f32 tests at both ends)
and edge pixels that get the original per-pixel coverage test. Tiles are
built in parallel, and fully selected tiles share one tile.
combine_surfaces maps two GRAY8 selections tile by tile through a
256x256 byte table, sharing tiles that come through unchanged. Both
produce exactly the old bytes (equivalence test against the old
per-pixel code).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Border built a hard band r pixels wide (expand r/2 minus contract r/2).
Photoshop's Border is soft and twice as wide: measured on Photoshop
27.11 (scripted), Border 4 on a 32 px square gives 63, 127, 191, 255 |
255, 191, 127, 63 across the edge, and the same along the inside of a
corner; PhotoCraft gave 0, 0, 255, 255 | 255, 255, 0, 0.
A pixel D away (centre to centre) from the nearest pixel on the other
side of the edge is now selected 1 - (D - 1) / r, using the existing
exact distance transform. That matches every sampled pixel within 1.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>