Handle empty paths in PathBuilder::get_current_point()

The case of calling get_current_point() on empty paths has not been
handled and caused panics.
This commit is contained in:
pylbrecht 2019-10-31 19:11:56 +01:00
parent 606ad20544
commit b8b33788b6
3 changed files with 15 additions and 17 deletions

View file

@ -189,9 +189,9 @@ impl GenericPathBuilder for azure_hl::PathBuilder {
anticlockwise,
);
}
fn get_current_point(&mut self) -> Point2D<f32> {
fn get_current_point(&mut self) -> Option<Point2D<f32>> {
let AzPoint { x, y } = azure_hl::PathBuilder::get_current_point(self);
Point2D::new(x as f32, y as f32)
Some(Point2D::new(x as f32, y as f32))
}
fn line_to(&mut self, point: Point2D<f32>) {
azure_hl::PathBuilder::line_to(self, point as Point2D<AzFloat>);

View file

@ -108,7 +108,7 @@ pub trait GenericPathBuilder {
end_angle: f32,
anticlockwise: bool,
);
fn get_current_point(&mut self) -> Point2D<f32>;
fn get_current_point(&mut self) -> Option<Point2D<f32>>;
fn line_to(&mut self, point: Point2D<f32>);
fn move_to(&mut self, point: Point2D<f32>);
fn quadratic_curve_to(&mut self, control_point: &Point2D<f32>, end_point: &Point2D<f32>);
@ -205,8 +205,10 @@ impl<'a> PathBuilderRef<'a> {
Some(i) => i,
None => return None,
};
let current_point = self.builder.get_current_point();
Some(inverse.transform_point(Point2D::new(current_point.x, current_point.y)))
match self.builder.get_current_point() {
Some(point) => Some(inverse.transform_point(Point2D::new(point.x, point.y))),
None => None,
}
}
}

View file

@ -564,22 +564,18 @@ impl GenericPathBuilder for PathBuilder {
}
}
fn get_current_point(&mut self) -> Point2D<f32> {
fn get_current_point(&mut self) -> Option<Point2D<f32>> {
let path = self.finish();
self.0 = Some(path.as_raqote().clone().into());
for op in path.as_raqote().ops.iter().rev() {
match op {
PathOp::MoveTo(point) | PathOp::LineTo(point) => {
return Point2D::new(point.x, point.y)
},
PathOp::CubicTo(_, _, point) => return Point2D::new(point.x, point.y),
PathOp::QuadTo(_, point) => return Point2D::new(point.x, point.y),
PathOp::Close => {},
};
}
panic!("dead end");
path.as_raqote().ops.iter().last().and_then(|op| match op {
PathOp::MoveTo(point) | PathOp::LineTo(point) => Some(Point2D::new(point.x, point.y)),
PathOp::CubicTo(_, _, point) => Some(Point2D::new(point.x, point.y)),
PathOp::QuadTo(_, point) => Some(Point2D::new(point.x, point.y)),
PathOp::Close => None,
})
}
fn line_to(&mut self, point: Point2D<f32>) {
self.0.as_mut().unwrap().line_to(point.x, point.y);
}