From f10a164c8d29222a816b0420ea8ffb4233e7ca0a Mon Sep 17 00:00:00 2001 From: Aitor Moreno Date: Mon, 15 Jun 2026 16:06:24 +0200 Subject: [PATCH] :bug: Fix stroke to path extra points --- render-wasm/src/shapes/paths.rs | 15 +++++++++++++-- render-wasm/src/shapes/stroke_paths.rs | 8 ++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/render-wasm/src/shapes/paths.rs b/render-wasm/src/shapes/paths.rs index 33666bb0de..94f7521c3e 100644 --- a/render-wasm/src/shapes/paths.rs +++ b/render-wasm/src/shapes/paths.rs @@ -156,6 +156,7 @@ impl Path { let mut current_point = 0; let mut current_conic = 0; let mut last_point = skia::Point::new(0.0, 0.0); + let mut subpath_start = skia::Point::new(0.0, 0.0); for verb in verbs { match verb { @@ -163,12 +164,15 @@ impl Path { let p = points[current_point]; segments.push(Segment::MoveTo((p.x, p.y))); last_point = p; + subpath_start = p; current_point += 1; } skia::PathVerb::Line => { let p = points[current_point]; - segments.push(Segment::LineTo((p.x, p.y))); - last_point = p; + if p != last_point { + segments.push(Segment::LineTo((p.x, p.y))); + last_point = p; + } current_point += 1; } skia::PathVerb::Quad => { @@ -239,6 +243,13 @@ impl Path { current_point += 3; } skia::PathVerb::Close => { + if let Some(Segment::LineTo(p)) = segments.last() { + if (p.0 - subpath_start.x).abs() < 1e-5 + && (p.1 - subpath_start.y).abs() < 1e-5 + { + segments.pop(); + } + } segments.push(Segment::Close); } } diff --git a/render-wasm/src/shapes/stroke_paths.rs b/render-wasm/src/shapes/stroke_paths.rs index 358be86141..2877e5d21e 100644 --- a/render-wasm/src/shapes/stroke_paths.rs +++ b/render-wasm/src/shapes/stroke_paths.rs @@ -60,6 +60,9 @@ pub fn stroke_to_path( // Set EvenOdd to preserve the annular ring's inner hole, // then as_winding() on the result fixes contour winding // for Penpot's NonZero fill rule. + // Center strokes skip the conversion: fill_path_with_paint + // already produces correctly-wound contours, so as_winding() + // would only add unnecessary reconstruction points. let final_path = match render_kind { StrokeKind::Inner => { stroke_outline.set_fill_type(skia::PathFillType::EvenOdd); @@ -75,10 +78,7 @@ pub fn stroke_to_path( .unwrap_or(stroke_outline); outer.as_winding().unwrap_or(outer) } - StrokeKind::Center => { - stroke_outline.set_fill_type(skia::PathFillType::EvenOdd); - stroke_outline.as_winding().unwrap_or(stroke_outline) - } + StrokeKind::Center => stroke_outline, }; // If there was a path_transform, invert it back to local coords