mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Make GenericPathBuilder take &mut self
This commit is contained in:
parent
4179f91f93
commit
f9e398d9f6
2 changed files with 94 additions and 35 deletions
|
@ -84,7 +84,7 @@ pub trait Backend {
|
||||||
/// azure's and raqote's PathBuilder.
|
/// azure's and raqote's PathBuilder.
|
||||||
pub trait GenericPathBuilder {
|
pub trait GenericPathBuilder {
|
||||||
fn arc(
|
fn arc(
|
||||||
&self,
|
&mut self,
|
||||||
origin: Point2D<f32>,
|
origin: Point2D<f32>,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
start_angle: f32,
|
start_angle: f32,
|
||||||
|
@ -92,14 +92,14 @@ pub trait GenericPathBuilder {
|
||||||
anticlockwise: bool,
|
anticlockwise: bool,
|
||||||
);
|
);
|
||||||
fn bezier_curve_to(
|
fn bezier_curve_to(
|
||||||
&self,
|
&mut self,
|
||||||
control_point1: &Point2D<f32>,
|
control_point1: &Point2D<f32>,
|
||||||
control_point2: &Point2D<f32>,
|
control_point2: &Point2D<f32>,
|
||||||
control_point3: &Point2D<f32>,
|
control_point3: &Point2D<f32>,
|
||||||
);
|
);
|
||||||
fn close(&self);
|
fn close(&mut self);
|
||||||
fn ellipse(
|
fn ellipse(
|
||||||
&self,
|
&mut self,
|
||||||
origin: Point2D<f32>,
|
origin: Point2D<f32>,
|
||||||
radius_x: f32,
|
radius_x: f32,
|
||||||
radius_y: f32,
|
radius_y: f32,
|
||||||
|
@ -108,32 +108,32 @@ pub trait GenericPathBuilder {
|
||||||
end_angle: f32,
|
end_angle: f32,
|
||||||
anticlockwise: bool,
|
anticlockwise: bool,
|
||||||
);
|
);
|
||||||
fn get_current_point(&self) -> Point2D<f32>;
|
fn get_current_point(&mut self) -> Point2D<f32>;
|
||||||
fn line_to(&self, point: Point2D<f32>);
|
fn line_to(&mut self, point: Point2D<f32>);
|
||||||
fn move_to(&self, point: Point2D<f32>);
|
fn move_to(&mut self, point: Point2D<f32>);
|
||||||
fn quadratic_curve_to(&self, control_point: &Point2D<f32>, end_point: &Point2D<f32>);
|
fn quadratic_curve_to(&mut self, control_point: &Point2D<f32>, end_point: &Point2D<f32>);
|
||||||
fn finish(&self) -> Path;
|
fn finish(&mut self) -> Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper around a stored PathBuilder and an optional transformation that should be
|
/// 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.
|
/// applied to any points to ensure they are in the matching device space.
|
||||||
struct PathBuilderRef<'a> {
|
struct PathBuilderRef<'a> {
|
||||||
builder: &'a Box<dyn GenericPathBuilder>,
|
builder: &'a mut Box<dyn GenericPathBuilder>,
|
||||||
transform: Transform2D<f32>,
|
transform: Transform2D<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PathBuilderRef<'a> {
|
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);
|
let pt = self.transform.transform_point(*pt);
|
||||||
self.builder.line_to(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);
|
let pt = self.transform.transform_point(*pt);
|
||||||
self.builder.move_to(pt);
|
self.builder.move_to(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rect(&self, rect: &Rect<f32>) {
|
fn rect(&mut self, rect: &Rect<f32>) {
|
||||||
let (first, second, third, fourth) = (
|
let (first, second, third, fourth) = (
|
||||||
Point2D::new(rect.origin.x, rect.origin.y),
|
Point2D::new(rect.origin.x, rect.origin.y),
|
||||||
Point2D::new(rect.origin.x + rect.size.width, 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();
|
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.builder.quadratic_curve_to(
|
||||||
&self.transform.transform_point(*cp),
|
&self.transform.transform_point(*cp),
|
||||||
&self.transform.transform_point(*endpoint),
|
&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.builder.bezier_curve_to(
|
||||||
&self.transform.transform_point(*cp1),
|
&self.transform.transform_point(*cp1),
|
||||||
&self.transform.transform_point(*cp2),
|
&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);
|
let center = self.transform.transform_point(*center);
|
||||||
self.builder
|
self.builder
|
||||||
.arc(center, radius, start_angle, end_angle, ccw);
|
.arc(center, radius, start_angle, end_angle, ccw);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ellipse(
|
pub fn ellipse(
|
||||||
&self,
|
&mut self,
|
||||||
center: &Point2D<f32>,
|
center: &Point2D<f32>,
|
||||||
radius_x: f32,
|
radius_x: f32,
|
||||||
radius_y: 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() {
|
let inverse = match self.transform.inverse() {
|
||||||
Some(i) => i,
|
Some(i) => i,
|
||||||
None => return None,
|
None => return None,
|
||||||
|
@ -569,7 +576,7 @@ impl<'a> CanvasData<'a> {
|
||||||
|
|
||||||
// If a user-space builder exists, create a finished path from it.
|
// If a user-space builder exists, create a finished path from it.
|
||||||
let new_state = match *self.path_state.as_mut().unwrap() {
|
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()))
|
Some((builder.finish(), transform.take()))
|
||||||
},
|
},
|
||||||
PathState::DeviceSpacePathBuilder(..) | PathState::UserSpacePath(..) => None,
|
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
|
// If a device-space builder is present, create a user-space path from its
|
||||||
// finished path by inverting the initial transformation.
|
// finished path by inverting the initial transformation.
|
||||||
let new_state = match self.path_state.as_ref().unwrap() {
|
let new_state = match *self.path_state.as_mut().unwrap() {
|
||||||
PathState::DeviceSpacePathBuilder(ref builder) => {
|
PathState::DeviceSpacePathBuilder(ref mut builder) => {
|
||||||
let path = builder.finish();
|
let path = builder.finish();
|
||||||
let inverse = match self.drawtarget.get_transform().inverse() {
|
let inverse = match self.drawtarget.get_transform().inverse() {
|
||||||
Some(m) => m,
|
Some(m) => m,
|
||||||
|
@ -604,7 +611,7 @@ impl<'a> CanvasData<'a> {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let builder = path.transformed_copy_to_builder(&inverse);
|
let mut builder = path.transformed_copy_to_builder(&inverse);
|
||||||
Some(builder.finish())
|
Some(builder.finish())
|
||||||
},
|
},
|
||||||
PathState::UserSpacePathBuilder(..) | PathState::UserSpacePath(..) => None,
|
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
|
// and overwriting path_state in other ones. The following awkward use of duplicate
|
||||||
// matches works around the resulting borrow errors.
|
// matches works around the resulting borrow errors.
|
||||||
let new_state = {
|
let new_state = {
|
||||||
match self.path_state.as_ref().unwrap() {
|
match *self.path_state.as_mut().unwrap() {
|
||||||
&PathState::UserSpacePathBuilder(_, None) |
|
PathState::UserSpacePathBuilder(_, None) | PathState::DeviceSpacePathBuilder(_) => {
|
||||||
&PathState::DeviceSpacePathBuilder(_) => None,
|
None
|
||||||
&PathState::UserSpacePathBuilder(ref builder, Some(ref transform)) => {
|
},
|
||||||
|
PathState::UserSpacePathBuilder(ref mut builder, Some(ref transform)) => {
|
||||||
let path = builder.finish();
|
let path = builder.finish();
|
||||||
Some(PathState::DeviceSpacePathBuilder(
|
Some(PathState::DeviceSpacePathBuilder(
|
||||||
path.transformed_copy_to_builder(transform),
|
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::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(),
|
path.copy_to_builder(),
|
||||||
None,
|
None,
|
||||||
)),
|
)),
|
||||||
|
@ -716,14 +724,14 @@ impl<'a> CanvasData<'a> {
|
||||||
// There's a new builder value that needs to be stored.
|
// There's a new builder value that needs to be stored.
|
||||||
Some(state) => self.path_state = Some(state),
|
Some(state) => self.path_state = Some(state),
|
||||||
// There's an existing builder value that can be returned immediately.
|
// There's an existing builder value that can be returned immediately.
|
||||||
None => match self.path_state.as_ref().unwrap() {
|
None => match *self.path_state.as_mut().unwrap() {
|
||||||
&PathState::UserSpacePathBuilder(ref builder, None) => {
|
PathState::UserSpacePathBuilder(ref mut builder, None) => {
|
||||||
return PathBuilderRef {
|
return PathBuilderRef {
|
||||||
builder,
|
builder,
|
||||||
transform: Transform2D::identity(),
|
transform: Transform2D::identity(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
&PathState::DeviceSpacePathBuilder(ref builder) => {
|
PathState::DeviceSpacePathBuilder(ref mut builder) => {
|
||||||
return PathBuilderRef {
|
return PathBuilderRef {
|
||||||
builder,
|
builder,
|
||||||
transform: self.drawtarget.get_transform(),
|
transform: self.drawtarget.get_transform(),
|
||||||
|
@ -733,16 +741,16 @@ impl<'a> CanvasData<'a> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.path_state.as_ref().unwrap() {
|
match *self.path_state.as_mut().unwrap() {
|
||||||
&PathState::UserSpacePathBuilder(ref builder, None) => PathBuilderRef {
|
PathState::UserSpacePathBuilder(ref mut builder, None) => PathBuilderRef {
|
||||||
builder,
|
builder,
|
||||||
transform: Transform2D::identity(),
|
transform: Transform2D::identity(),
|
||||||
},
|
},
|
||||||
&PathState::DeviceSpacePathBuilder(ref builder) => PathBuilderRef {
|
PathState::DeviceSpacePathBuilder(ref mut builder) => PathBuilderRef {
|
||||||
builder,
|
builder,
|
||||||
transform: self.drawtarget.get_transform(),
|
transform: self.drawtarget.get_transform(),
|
||||||
},
|
},
|
||||||
&PathState::UserSpacePathBuilder(..) | &PathState::UserSpacePath(..) => unreachable!(),
|
PathState::UserSpacePathBuilder(..) | PathState::UserSpacePath(..) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
pub trait ToRaqoteStyle {
|
||||||
type Target;
|
type Target;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue