address review: create every outline slot before attaching holes

This commit is contained in:
Dylan M. Taylor
2026-11-04 03:49:09 +00:00
parent 7963e8df74
commit 84713e2d4f
2 changed files with 25 additions and 3 deletions
+8 -3
View File
@@ -157,12 +157,17 @@ pub fn group_contours(contours: Vec<Vec<P>>) -> Vec<Outline> {
let mut slot = vec![usize::MAX; n];
let mut order: Vec<usize> = (0..n).collect();
order.sort_by_key(|&i| depth[i]);
for i in order {
// Every outline gets its slot before any hole is attached: with overlapping paths a hole's
// parent can be deeper than the hole itself.
for &i in &order {
if depth[i].is_multiple_of(2) {
slot[i] = outlines.len();
outlines.push(Outline { outer: cs[i].clone(), holes: vec![] });
} else if let Some(p) = parent[i]
&& slot[p] != usize::MAX
}
}
for &i in &order {
if !depth[i].is_multiple_of(2)
&& let Some(p) = parent[i]
{
outlines[slot[p]].holes.push(cs[i].clone());
}
+17
View File
@@ -452,6 +452,23 @@ fn a_contour_inside_a_hole_takes_the_innermost_outline_not_the_hole() {
assert_eq!(g.iter().map(|o| o.holes.len()).collect::<Vec<_>>(), [1, 1], "C is a hole of A, D a hole of B (not dropped)");
}
#[test]
fn a_hole_whose_outline_is_deeper_than_it_is_still_attached() {
let rect = |x0: f64, y0: f64, x1: f64, y1: f64| vec![[x0, y0], [x1, y0], [x1, y1], [x0, y1]];
// D is three deep and its innermost outline A four deep: A's slot must exist before D is attached.
let a = rect(0.0, 0.0, 10.0, 10.0);
let g = group_contours(vec![
a.clone(),
rect(-1.0, -1.0, 20.0, 20.0),
rect(-2.0, -2.0, 25.0, 25.0),
rect(5.0, 5.0, 6.0, 6.0),
rect(-100.0, -100.0, 3.0, 3.0),
rect(-0.5, -1000.0, 0.5, 1000.0),
]);
let o = g.iter().find(|o| o.outer == a).expect("A is an outline");
assert_eq!(o.holes.len(), 1, "D is a hole of A");
}
#[test]
fn gltf_images_naming_one_file_share_their_wrap_variants() {
let png = {