From 9b204867c018ad67798de8142eb253e4730ed8e4 Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Wed, 4 Jun 2025 17:01:50 +0200 Subject: [PATCH] canvas: ensure there is a subpath in PathBuilder or else we hit debug asserts in vello Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- components/canvas/canvas_data.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index ea30589d0af..063d95b255a 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -154,7 +154,18 @@ struct PathBuilderRef<'a, B: Backend> { } impl PathBuilderRef<'_, B> { + /// + fn ensure_there_is_a_subpath(&mut self, point: &Point2D) { + if self.builder.get_current_point().is_none() { + self.builder.move_to(*point); + } + } + + /// fn line_to(&mut self, pt: &Point2D) { + // 2. If the object's path has no subpaths, then ensure there is a subpath for (x, y). + self.ensure_there_is_a_subpath(pt); + let pt = self.transform.transform_point(*pt); self.builder.line_to(pt); } @@ -182,14 +193,22 @@ impl PathBuilderRef<'_, B> { self.move_to(&first); } + /// fn quadratic_curve_to(&mut self, cp: &Point2D, endpoint: &Point2D) { + // 2. Ensure there is a subpath for (cpx, cpy). + self.ensure_there_is_a_subpath(cp); + self.builder.quadratic_curve_to( &self.transform.transform_point(*cp), &self.transform.transform_point(*endpoint), ) } + /// fn bezier_curve_to(&mut self, cp1: &Point2D, cp2: &Point2D, endpoint: &Point2D) { + // 2. Ensure there is a subpath for (cp1x, cp1y). + self.ensure_there_is_a_subpath(cp1); + self.builder.bezier_curve_to( &self.transform.transform_point(*cp1), &self.transform.transform_point(*cp2), @@ -210,6 +229,7 @@ impl PathBuilderRef<'_, B> { .arc(center, radius, start_angle, end_angle, ccw); } + /// fn arc_to(&mut self, cp1: &Point2D, cp2: &Point2D, radius: f32) { let cp0 = if let (Some(inverse), Some(point)) = (self.transform.inverse(), self.builder.get_current_point()) @@ -218,6 +238,9 @@ impl PathBuilderRef<'_, B> { } else { *cp1 }; + + // 2. Ensure there is a subpath for (x1, y1) is done by one of self.line_to calls + if (cp0.x == cp1.x && cp0.y == cp1.y) || cp1 == cp2 || radius == 0.0 { self.line_to(cp1); return;