Files
vtracer/crates
Chris Tsang ba2b80455e Give each disjoint patch of a region its own face in cutout mode
Face assembly bucketed contours by region label, so a region appearing as
several disjoint patches contributed all of their contours to one face — and
compose emitted them as subpaths of a single <path>. Isolated islands were
therefore not separately addressable downstream.

Faces are now keyed by (region, island). `islands` flood-fills the label map
into connected components in one pass, and `island_of` attributes a contour via
the region-side pixel flanking its first directed edge: every contour is walked
with its region on the left, so that pixel is interior to the patch the contour
bounds, and an outer ring agrees with the holes inside it. graph gains
`left_pixel_coord` (the coordinate half of `left_pixel_at`, which now delegates
to it) and `dir_from_delta`, needed because a ring has no start node or
first_dir. A BTreeMap keeps face order deterministic: region ascending, then
island in raster-scan order.

Connectivity is 8-way to match the successor rule, which pinches a checkerboard
corner into a single contour: lobes meeting only at a diagonal are walked as one
contour and must stay in one face. Splitting them could separate a hole contour
from the ring enclosing it, and a lone hole ring fills solid under nonzero.

Gum tree in cutout goes 492 -> 517 paths and the tank sprite 1022 -> 1023, with
renders byte-identical in both cases: the change is structural only. Costs one
O(W*H) pass over a pipeline that is already O(W*H).
2026-07-25 20:01:16 +01:00
..