Make GenericPathBuilder take &mut self

This commit is contained in:
pylbrecht 2019-06-24 19:59:21 +02:00 committed by Bastien Orivel
parent 4179f91f93
commit f9e398d9f6
2 changed files with 94 additions and 35 deletions

View file

@ -84,7 +84,7 @@ pub trait Backend {
/// azure's and raqote's PathBuilder.
pub trait GenericPathBuilder {
fn arc(
&self,
&mut self,
origin: Point2D<f32>,
radius: f32,
start_angle: f32,
@ -92,14 +92,14 @@ pub trait GenericPathBuilder {
anticlockwise: bool,
);
fn bezier_curve_to(
&self,
&mut self,
control_point1: &Point2D<f32>,
control_point2: &Point2D<f32>,
control_point3: &Point2D<f32>,
);
fn close(&self);
fn close(&mut self);
fn ellipse(
&self,
&mut self,
origin: Point2D<f32>,
radius_x: f32,
radius_y: f32,
@ -108,32 +108,32 @@ pub trait GenericPathBuilder {
end_angle: f32,
anticlockwise: bool,
);
fn get_current_point(&self) -> Point2D<f32>;
fn line_to(&self, point: Point2D<f32>);
fn move_to(&self, point: Point2D<f32>);
fn quadratic_curve_to(&self, control_point: &Point2D<f32>, end_point: &Point2D<f32>);
fn finish(&self) -> Path;
fn get_current_point(&mut self) -> 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>);
fn finish(&mut self) -> Path;
}
/// A wrapper around a stored PathBuilder and an optional transformation that should be
/// applied to any points to ensure they are in the matching device space.
struct PathBuilderRef<'a> {
builder: &'a Box<dyn GenericPathBuilder>,
builder: &'a mut Box<dyn GenericPathBuilder>,
transform: Transform2D<f32>,
}
impl<'a> PathBuilderRef<'a> {
fn line_to(&self, pt: &Point2D<f32>) {
fn line_to(&mut self, pt: &Point2D<f32>) {
let pt = self.transform.transform_point(*pt);
self.builder.line_to(pt);
}
fn move_to(&self, pt: &Point2D<f32>) {
fn move_to(&mut self, pt: &Point2D<f32>) {
let pt = self.transform.transform_point(*pt);
self.builder.move_to(pt);
}
fn rect(&self, rect: &Rect<f32>) {
fn rect(&mut self, rect: &Rect<f32>) {
let (first, second, third, fourth) = (
Point2D::new(rect.origin.x, rect.origin.y),
Point2D::new(rect.origin.x + rect.size.width, rect.origin.y),
@ -150,14 +150,14 @@ impl<'a> PathBuilderRef<'a> {
self.builder.close();
}
fn quadratic_curve_to(&self, cp: &Point2D<f32>, endpoint: &Point2D<f32>) {
fn quadratic_curve_to(&mut self, cp: &Point2D<f32>, endpoint: &Point2D<f32>) {
self.builder.quadratic_curve_to(
&self.transform.transform_point(*cp),
&self.transform.transform_point(*endpoint),
)
}
fn bezier_curve_to(&self, cp1: &Point2D<f32>, cp2: &Point2D<f32>, endpoint: &Point2D<f32>) {
fn bezier_curve_to(&mut self, cp1: &Point2D<f32>, cp2: &Point2D<f32>, endpoint: &Point2D<f32>) {
self.builder.bezier_curve_to(
&self.transform.transform_point(*cp1),
&self.transform.transform_point(*cp2),
@ -165,14 +165,21 @@ impl<'a> PathBuilderRef<'a> {
)
}
fn arc(&self, center: &Point2D<f32>, radius: f32, start_angle: f32, end_angle: f32, ccw: bool) {
fn arc(
&mut self,
center: &Point2D<f32>,
radius: f32,
start_angle: f32,
end_angle: f32,
ccw: bool,
) {
let center = self.transform.transform_point(*center);
self.builder
.arc(center, radius, start_angle, end_angle, ccw);
}
pub fn ellipse(
&self,
&mut self,
center: &Point2D<f32>,
radius_x: f32,
radius_y: f32,
@ -193,7 +200,7 @@ impl<'a> PathBuilderRef<'a> {
);
}
fn current_point(&self) -> Option<Point2D<f32>> {
fn current_point(&mut self) -> Option<Point2D<f32>> {
let inverse = match self.transform.inverse() {
Some(i) => i,
None => return None,
@ -569,7 +576,7 @@ impl<'a> CanvasData<'a> {
// If a user-space builder exists, create a finished path from it.
let new_state = match *self.path_state.as_mut().unwrap() {
PathState::UserSpacePathBuilder(ref builder, ref mut transform) => {
PathState::UserSpacePathBuilder(ref mut builder, ref mut transform) => {
Some((builder.finish(), transform.take()))
},
PathState::DeviceSpacePathBuilder(..) | PathState::UserSpacePath(..) => None,
@ -594,8 +601,8 @@ impl<'a> CanvasData<'a> {
// If a device-space builder is present, create a user-space path from its
// finished path by inverting the initial transformation.
let new_state = match self.path_state.as_ref().unwrap() {
PathState::DeviceSpacePathBuilder(ref builder) => {
let new_state = match *self.path_state.as_mut().unwrap() {
PathState::DeviceSpacePathBuilder(ref mut builder) => {
let path = builder.finish();
let inverse = match self.drawtarget.get_transform().inverse() {
Some(m) => m,
@ -604,7 +611,7 @@ impl<'a> CanvasData<'a> {
return;
},
};
let builder = path.transformed_copy_to_builder(&inverse);
let mut builder = path.transformed_copy_to_builder(&inverse);
Some(builder.finish())
},
PathState::UserSpacePathBuilder(..) | PathState::UserSpacePath(..) => None,
@ -694,19 +701,20 @@ impl<'a> CanvasData<'a> {
// and overwriting path_state in other ones. The following awkward use of duplicate
// matches works around the resulting borrow errors.
let new_state = {
match self.path_state.as_ref().unwrap() {
&PathState::UserSpacePathBuilder(_, None) |
&PathState::DeviceSpacePathBuilder(_) => None,
&PathState::UserSpacePathBuilder(ref builder, Some(ref transform)) => {
match *self.path_state.as_mut().unwrap() {
PathState::UserSpacePathBuilder(_, None) | PathState::DeviceSpacePathBuilder(_) => {
None
},
PathState::UserSpacePathBuilder(ref mut builder, Some(ref transform)) => {
let path = builder.finish();
Some(PathState::DeviceSpacePathBuilder(
path.transformed_copy_to_builder(transform),
))
},
&PathState::UserSpacePath(ref path, Some(ref transform)) => Some(
PathState::UserSpacePath(ref path, Some(ref transform)) => Some(
PathState::DeviceSpacePathBuilder(path.transformed_copy_to_builder(transform)),
),
&PathState::UserSpacePath(ref path, None) => Some(PathState::UserSpacePathBuilder(
PathState::UserSpacePath(ref path, None) => Some(PathState::UserSpacePathBuilder(
path.copy_to_builder(),
None,
)),
@ -716,14 +724,14 @@ impl<'a> CanvasData<'a> {
// There's a new builder value that needs to be stored.
Some(state) => self.path_state = Some(state),
// There's an existing builder value that can be returned immediately.
None => match self.path_state.as_ref().unwrap() {
&PathState::UserSpacePathBuilder(ref builder, None) => {
None => match *self.path_state.as_mut().unwrap() {
PathState::UserSpacePathBuilder(ref mut builder, None) => {
return PathBuilderRef {
builder,
transform: Transform2D::identity(),
};
},
&PathState::DeviceSpacePathBuilder(ref builder) => {
PathState::DeviceSpacePathBuilder(ref mut builder) => {
return PathBuilderRef {
builder,
transform: self.drawtarget.get_transform(),
@ -733,16 +741,16 @@ impl<'a> CanvasData<'a> {
},
}
match self.path_state.as_ref().unwrap() {
&PathState::UserSpacePathBuilder(ref builder, None) => PathBuilderRef {
match *self.path_state.as_mut().unwrap() {
PathState::UserSpacePathBuilder(ref mut builder, None) => PathBuilderRef {
builder,
transform: Transform2D::identity(),
},
&PathState::DeviceSpacePathBuilder(ref builder) => PathBuilderRef {
PathState::DeviceSpacePathBuilder(ref mut builder) => PathBuilderRef {
builder,
transform: self.drawtarget.get_transform(),
},
&PathState::UserSpacePathBuilder(..) | &PathState::UserSpacePath(..) => unreachable!(),
PathState::UserSpacePathBuilder(..) | PathState::UserSpacePath(..) => unreachable!(),
}
}

View file

@ -269,6 +269,57 @@ impl GenericDrawTarget for raqote::DrawTarget {
}
}
impl GenericPathBuilder for raqote::PathBuilder {
fn arc(
&mut self,
origin: Point2D<f32>,
radius: f32,
start_angle: f32,
end_angle: f32,
anticlockwise: bool,
) {
unimplemented!();
}
fn bezier_curve_to(
&mut self,
control_point1: &Point2D<f32>,
control_point2: &Point2D<f32>,
control_point3: &Point2D<f32>,
) {
unimplemented!();
}
fn close(&mut self) {
unimplemented!();
}
fn ellipse(
&mut self,
origin: Point2D<f32>,
radius_x: f32,
radius_y: f32,
rotation_angle: f32,
start_angle: f32,
end_angle: f32,
anticlockwise: bool,
) {
unimplemented!();
}
fn get_current_point(&mut self) -> Point2D<f32> {
unimplemented!();
}
fn line_to(&mut self, point: Point2D<f32>) {
unimplemented!();
}
fn move_to(&mut self, point: Point2D<f32>) {
unimplemented!();
}
fn quadratic_curve_to(&mut self, control_point: &Point2D<f32>, end_point: &Point2D<f32>) {
unimplemented!();
}
fn finish(&mut self) -> Path {
unimplemented!();
}
}
pub trait ToRaqoteStyle {
type Target;