diff --git a/render-wasm/src/shapes.rs b/render-wasm/src/shapes.rs index 92d49c7c30..fa4a71a46d 100644 --- a/render-wasm/src/shapes.rs +++ b/render-wasm/src/shapes.rs @@ -705,16 +705,21 @@ impl Shape { } pub fn set_path_segments(&mut self, segments: Vec) { - let path = Path::new(segments); match &mut self.shape_type { Type::Bool(Bool { bool_type, .. }) => { + let path = match bool_type { + // Exclusion booleans are computed with even-odd semantics but + // PathData uploads do not carry the fill rule. + BoolType::Exclusion => Path::new(segments).with_even_odd(true), + _ => Path::new(segments), + }; self.shape_type = Type::Bool(Bool { bool_type: *bool_type, path, }); } Type::Path(_) => { - self.shape_type = Type::Path(path); + self.shape_type = Type::Path(Path::new(segments)); } _ => {} }; diff --git a/render-wasm/src/shapes/modifiers/flex_layout.rs b/render-wasm/src/shapes/modifiers/flex_layout.rs index 7c7b911c1f..5bdd64e488 100644 --- a/render-wasm/src/shapes/modifiers/flex_layout.rs +++ b/render-wasm/src/shapes/modifiers/flex_layout.rs @@ -667,9 +667,12 @@ pub fn reflow_flex_layout( transform.post_concat(&Matrix::translate(delta_v)); } - result.push_back(Modifier::transform_propagate(child.id, transform)); - if child.has_layout() { - result.push_back(Modifier::reflow(child.id, force_reflow)); + // Skip identity: propagating it fans out through the whole subtree. + if !math::identitish(&transform) { + result.push_back(Modifier::transform_propagate(child.id, transform)); + if child.has_layout() { + result.push_back(Modifier::reflow(child.id, force_reflow)); + } } shape_anchor = next_anchor( diff --git a/render-wasm/src/shapes/modifiers/grid_layout.rs b/render-wasm/src/shapes/modifiers/grid_layout.rs index 7ddc877d91..a9749b9d8f 100644 --- a/render-wasm/src/shapes/modifiers/grid_layout.rs +++ b/render-wasm/src/shapes/modifiers/grid_layout.rs @@ -884,9 +884,12 @@ pub fn reflow_grid_layout( transform.post_concat(&Matrix::translate(delta_v)); } - result.push_back(Modifier::transform_propagate(child.id, transform)); - if child.has_layout() { - result.push_back(Modifier::reflow(child.id, force_reflow)); + // Skip identity: propagating it fans out through the whole subtree. + if !math::identitish(&transform) { + result.push_back(Modifier::transform_propagate(child.id, transform)); + if child.has_layout() { + result.push_back(Modifier::reflow(child.id, force_reflow)); + } } } diff --git a/render-wasm/src/shapes/paths.rs b/render-wasm/src/shapes/paths.rs index 33666bb0de..eac01fbde9 100644 --- a/render-wasm/src/shapes/paths.rs +++ b/render-wasm/src/shapes/paths.rs @@ -251,6 +251,9 @@ impl Path { pub fn to_skia_path(&self, svg_attrs: Option<&SvgAttrs>) -> skia::Path { let mut path = self.skia_path.snapshot(); + if self.is_even_odd() { + path.set_fill_type(skia::PathFillType::EvenOdd); + } if let Some(attrs) = svg_attrs { if attrs.fill_rule == FillRule::Evenodd { path.set_fill_type(skia::PathFillType::EvenOdd);