From d593a175440b634cb6c37885edce841481e1780d Mon Sep 17 00:00:00 2001 From: pylbrecht Date: Thu, 20 Jun 2019 10:21:50 +0200 Subject: [PATCH 1/8] Implement DrawOptions.set_alpha() --- components/canvas/canvas_data.rs | 2 +- components/canvas/raqote_backend.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index eb2cf963e702..2f1c10b5c485 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -359,7 +359,7 @@ pub enum DrawOptions { #[cfg(feature = "azure_backend")] Azure(azure::azure_hl::DrawOptions), #[cfg(feature = "raqote_backend")] - Raqote(()), + Raqote(raqote::DrawOptions), } #[derive(Clone)] diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 6e49026606e3..03276f129d68 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -73,7 +73,7 @@ impl Backend for RaqoteBackend { impl<'a> CanvasPaintState<'a> { pub fn new(_antialias: AntialiasMode) -> CanvasPaintState<'a> { CanvasPaintState { - draw_options: DrawOptions::Raqote(()), + draw_options: DrawOptions::Raqote(raqote::DrawOptions::new()), fill_style: Pattern::Raqote(()), stroke_style: Pattern::Raqote(()), stroke_opts: StrokeOptions::Raqote(PhantomData), @@ -112,7 +112,7 @@ impl<'a> StrokeOptions<'a> { impl DrawOptions { pub fn set_alpha(&mut self, _val: f32) { match self { - DrawOptions::Raqote(()) => unimplemented!(), + DrawOptions::Raqote(draw_options) => draw_options.alpha = _val, } } } From cea667a822e7aa947acf2483b6a05b26af11baa5 Mon Sep 17 00:00:00 2001 From: pylbrecht Date: Thu, 20 Jun 2019 10:58:06 +0200 Subject: [PATCH 2/8] Implement StrokeOptions --- components/canvas/canvas_data.rs | 2 +- components/canvas/raqote_backend.rs | 48 ++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index 2f1c10b5c485..4b3d832cbdc7 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -367,7 +367,7 @@ pub enum StrokeOptions<'a> { #[cfg(feature = "azure_backend")] Azure(azure::azure_hl::StrokeOptions<'a>), #[cfg(feature = "raqote_backend")] - Raqote(PhantomData<&'a ()>), + Raqote(raqote::StrokeStyle, PhantomData<&'a ()>), } #[derive(Clone, Copy)] diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 03276f129d68..4b60366fe624 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -76,7 +76,7 @@ impl<'a> CanvasPaintState<'a> { draw_options: DrawOptions::Raqote(raqote::DrawOptions::new()), fill_style: Pattern::Raqote(()), stroke_style: Pattern::Raqote(()), - stroke_opts: StrokeOptions::Raqote(PhantomData), + stroke_opts: StrokeOptions::Raqote(Default::default(), PhantomData), transform: Transform2D::identity(), shadow_offset_x: 0.0, shadow_offset_y: 0.0, @@ -96,16 +96,24 @@ impl Pattern { impl<'a> StrokeOptions<'a> { pub fn set_line_width(&mut self, _val: f32) { - unimplemented!() + match self { + StrokeOptions::Raqote(options, _) => options.width = _val, + } } pub fn set_miter_limit(&mut self, _val: f32) { - unimplemented!() + match self { + StrokeOptions::Raqote(options, _) => options.miter_limit = _val, + } } pub fn set_line_join(&mut self, _val: LineJoinStyle) { - unimplemented!() + match self { + StrokeOptions::Raqote(options, _) => options.join = _val.to_raqote_style(), + } } pub fn set_line_cap(&mut self, _val: LineCapStyle) { - unimplemented!() + match self { + StrokeOptions::Raqote(options, _) => options.cap = _val.to_raqote_style(), + } } } @@ -260,3 +268,33 @@ impl GenericDrawTarget for raqote::DrawTarget { unimplemented!() } } + +pub trait ToRaqoteStyle { + type Target; + + fn to_raqote_style(self) -> Self::Target; +} + +impl ToRaqoteStyle for LineJoinStyle { + type Target = raqote::LineJoin; + + fn to_raqote_style(self) -> raqote::LineJoin { + match self { + LineJoinStyle::Round => raqote::LineJoin::Round, + LineJoinStyle::Bevel => raqote::LineJoin::Bevel, + LineJoinStyle::Miter => raqote::LineJoin::Miter, + } + } +} + +impl ToRaqoteStyle for LineCapStyle { + type Target = raqote::LineCap; + + fn to_raqote_style(self) -> raqote::LineCap { + match self { + LineCapStyle::Butt => raqote::LineCap::Butt, + LineCapStyle::Round => raqote::LineCap::Round, + LineCapStyle::Square => raqote::LineCap::Square, + } + } +} From aa970aa1a533f9c296ef35e98cdf8dceda8fcdc7 Mon Sep 17 00:00:00 2001 From: pylbrecht Date: Mon, 24 Jun 2019 19:59:21 +0200 Subject: [PATCH 3/8] Make GenericPathBuilder take &mut self --- components/canvas/canvas_data.rs | 78 ++++++++++++++++------------- components/canvas/raqote_backend.rs | 51 +++++++++++++++++++ 2 files changed, 94 insertions(+), 35 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index 4b3d832cbdc7..78cd26572aa5 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -83,7 +83,7 @@ pub trait Backend { /// azure's and raqote's PathBuilder. pub trait GenericPathBuilder { fn arc( - &self, + &mut self, origin: Point2D, radius: f32, start_angle: f32, @@ -91,14 +91,14 @@ pub trait GenericPathBuilder { anticlockwise: bool, ); fn bezier_curve_to( - &self, + &mut self, control_point1: &Point2D, control_point2: &Point2D, control_point3: &Point2D, ); - fn close(&self); + fn close(&mut self); fn ellipse( - &self, + &mut self, origin: Point2D, radius_x: f32, radius_y: f32, @@ -107,32 +107,32 @@ pub trait GenericPathBuilder { end_angle: f32, anticlockwise: bool, ); - fn get_current_point(&self) -> Point2D; - fn line_to(&self, point: Point2D); - fn move_to(&self, point: Point2D); - fn quadratic_curve_to(&self, control_point: &Point2D, end_point: &Point2D); - fn finish(&self) -> Path; + fn get_current_point(&mut self) -> Point2D; + fn line_to(&mut self, point: Point2D); + fn move_to(&mut self, point: Point2D); + fn quadratic_curve_to(&mut self, control_point: &Point2D, end_point: &Point2D); + 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, + builder: &'a mut Box, transform: Transform2D, } impl<'a> PathBuilderRef<'a> { - fn line_to(&self, pt: &Point2D) { + fn line_to(&mut self, pt: &Point2D) { let pt = self.transform.transform_point(pt); self.builder.line_to(pt); } - fn move_to(&self, pt: &Point2D) { + fn move_to(&mut self, pt: &Point2D) { let pt = self.transform.transform_point(pt); self.builder.move_to(pt); } - fn rect(&self, rect: &Rect) { + fn rect(&mut self, rect: &Rect) { let (first, second, third, fourth) = ( Point2D::new(rect.origin.x, rect.origin.y), Point2D::new(rect.origin.x + rect.size.width, rect.origin.y), @@ -151,14 +151,14 @@ impl<'a> PathBuilderRef<'a> { self.builder.close(); } - fn quadratic_curve_to(&self, cp: &Point2D, endpoint: &Point2D) { + fn quadratic_curve_to(&mut self, cp: &Point2D, endpoint: &Point2D) { self.builder.quadratic_curve_to( &self.transform.transform_point(cp), &self.transform.transform_point(endpoint), ) } - fn bezier_curve_to(&self, cp1: &Point2D, cp2: &Point2D, endpoint: &Point2D) { + fn bezier_curve_to(&mut self, cp1: &Point2D, cp2: &Point2D, endpoint: &Point2D) { self.builder.bezier_curve_to( &self.transform.transform_point(cp1), &self.transform.transform_point(cp2), @@ -166,14 +166,21 @@ impl<'a> PathBuilderRef<'a> { ) } - fn arc(&self, center: &Point2D, radius: f32, start_angle: f32, end_angle: f32, ccw: bool) { + fn arc( + &mut self, + center: &Point2D, + 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, radius_x: f32, radius_y: f32, @@ -194,7 +201,7 @@ impl<'a> PathBuilderRef<'a> { ); } - fn current_point(&self) -> Option> { + fn current_point(&mut self) -> Option> { let inverse = match self.transform.inverse() { Some(i) => i, None => return None, @@ -570,7 +577,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, @@ -595,8 +602,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, @@ -605,7 +612,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, @@ -695,19 +702,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, )), @@ -717,14 +725,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(), @@ -734,16 +742,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!(), } } diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 4b60366fe624..1e82e7bc577b 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -269,6 +269,57 @@ impl GenericDrawTarget for raqote::DrawTarget { } } +impl GenericPathBuilder for raqote::PathBuilder { + fn arc( + &mut self, + origin: Point2D, + radius: f32, + start_angle: f32, + end_angle: f32, + anticlockwise: bool, + ) { + unimplemented!(); + } + fn bezier_curve_to( + &mut self, + control_point1: &Point2D, + control_point2: &Point2D, + control_point3: &Point2D, + ) { + unimplemented!(); + } + fn close(&mut self) { + unimplemented!(); + } + fn ellipse( + &mut self, + origin: Point2D, + 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 { + unimplemented!(); + } + fn line_to(&mut self, point: Point2D) { + unimplemented!(); + } + fn move_to(&mut self, point: Point2D) { + unimplemented!(); + } + fn quadratic_curve_to(&mut self, control_point: &Point2D, end_point: &Point2D) { + unimplemented!(); + } + fn finish(&mut self) -> Path { + unimplemented!(); + } +} + pub trait ToRaqoteStyle { type Target; From fd44556289ac79d791a2170b105c812e06e41e4b Mon Sep 17 00:00:00 2001 From: pylbrecht Date: Tue, 25 Jun 2019 16:48:03 +0200 Subject: [PATCH 4/8] Implement provided raqote::PathBuilder's methods for GenericPathBuilder --- components/canvas/raqote_backend.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 1e82e7bc577b..517101cff899 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -278,7 +278,7 @@ impl GenericPathBuilder for raqote::PathBuilder { end_angle: f32, anticlockwise: bool, ) { - unimplemented!(); + self.arc(origin.x, origin.y, radius, start_angle, end_angle); } fn bezier_curve_to( &mut self, @@ -286,10 +286,17 @@ impl GenericPathBuilder for raqote::PathBuilder { control_point2: &Point2D, control_point3: &Point2D, ) { - unimplemented!(); + self.cubic_to( + control_point1.x, + control_point1.y, + control_point2.x, + control_point2.y, + control_point3.x, + control_point3.y, + ); } fn close(&mut self) { - unimplemented!(); + self.close(); } fn ellipse( &mut self, @@ -307,16 +314,16 @@ impl GenericPathBuilder for raqote::PathBuilder { unimplemented!(); } fn line_to(&mut self, point: Point2D) { - unimplemented!(); + self.line_to(point.x, point.y); } fn move_to(&mut self, point: Point2D) { - unimplemented!(); + self.move_to(point.x, point.y); } fn quadratic_curve_to(&mut self, control_point: &Point2D, end_point: &Point2D) { - unimplemented!(); + self.quad_to(control_point.x, control_point.y, end_point.x, end_point.y); } fn finish(&mut self) -> Path { - unimplemented!(); + self.finish() } } From 46caa122b34b87d6c62677860a43880aec9bdb45 Mon Sep 17 00:00:00 2001 From: pylbrecht Date: Tue, 2 Jul 2019 19:14:15 +0200 Subject: [PATCH 5/8] WIP: Make GenericPathBuilder's methods take &mut self --- components/canvas/canvas_data.rs | 26 +++-- components/canvas/raqote_backend.rs | 145 ++++++++++++++-------------- 2 files changed, 88 insertions(+), 83 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index 78cd26572aa5..6f94922f91f9 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -216,7 +216,12 @@ impl<'a> PathBuilderRef<'a> { // The prototypes are derived from azure's methods. pub trait GenericDrawTarget { fn clear_rect(&self, rect: &Rect); - fn copy_surface(&self, surface: SourceSurface, source: Rect, destination: Point2D); + fn copy_surface( + &mut self, + surface: SourceSurface, + source: Rect, + destination: Point2D, + ); fn create_gradient_stops( &self, gradient_stops: Vec, @@ -251,24 +256,24 @@ pub trait GenericDrawTarget { sigma: f32, operator: CompositionOp, ); - fn fill(&self, path: &Path, pattern: Pattern, draw_options: &DrawOptions); - fn fill_rect(&self, rect: &Rect, pattern: Pattern, draw_options: Option<&DrawOptions>); + fn fill(&mut self, path: &Path, pattern: Pattern, draw_options: &DrawOptions); + fn fill_rect(&mut self, rect: &Rect, pattern: Pattern, draw_options: Option<&DrawOptions>); fn get_format(&self) -> SurfaceFormat; fn get_size(&self) -> Size2D; fn get_transform(&self) -> Transform2D; - fn pop_clip(&self); - fn push_clip(&self, path: &Path); - fn set_transform(&self, matrix: &Transform2D); + fn pop_clip(&mut self); + fn push_clip(&mut self, path: &Path); + fn set_transform(&mut self, matrix: &Transform2D); fn snapshot(&self) -> SourceSurface; fn stroke( - &self, + &mut self, path: &Path, pattern: Pattern, stroke_options: &StrokeOptions, draw_options: &DrawOptions, ); fn stroke_line( - &self, + &mut self, start: Point2D, end: Point2D, pattern: Pattern, @@ -276,7 +281,7 @@ pub trait GenericDrawTarget { draw_options: &DrawOptions, ); fn stroke_rect( - &self, + &mut self, rect: &Rect, pattern: Pattern, stroke_options: &StrokeOptions, @@ -660,7 +665,8 @@ impl<'a> CanvasData<'a> { pub fn clip(&mut self) { self.ensure_path(); - self.drawtarget.push_clip(&self.path()); + let path = self.path(); + self.drawtarget.push_clip(&path); } pub fn is_point_in_path( diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 517101cff899..051febc36e62 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -143,129 +143,128 @@ impl Path { } impl GenericDrawTarget for raqote::DrawTarget { - fn clear_rect(&self, _rect: &Rect) { - unimplemented!() + fn clear_rect(&self, rect: &Rect) { + unimplemented!(); } - fn copy_surface( - &self, - _surface: SourceSurface, - _source: Rect, - _destination: Point2D, + &mut self, + surface: SourceSurface, + source: Rect, + destination: Point2D, ) { - unimplemented!() + unimplemented!(); } - fn create_gradient_stops( &self, - _gradient_stops: Vec, - _extend_mode: ExtendMode, + gradient_stops: Vec, + extend_mode: ExtendMode, ) -> GradientStops { - unimplemented!() + unimplemented!(); } - fn create_path_builder(&self) -> Box { - unimplemented!() + unimplemented!(); } - fn create_similar_draw_target( &self, - _size: &Size2D, - _format: SurfaceFormat, + size: &Size2D, + format: SurfaceFormat, ) -> Box { - unimplemented!() + unimplemented!(); } fn create_source_surface_from_data( &self, - _data: &[u8], - _size: Size2D, - _stride: i32, + data: &[u8], + size: Size2D, + stride: i32, ) -> Option { - unimplemented!() + unimplemented!(); } fn draw_surface( &self, - _surface: SourceSurface, - _dest: Rect, - _source: Rect, - _filter: Filter, - _draw_options: &DrawOptions, + surface: SourceSurface, + dest: Rect, + source: Rect, + filter: Filter, + draw_options: &DrawOptions, ) { - unimplemented!() + unimplemented!(); } fn draw_surface_with_shadow( &self, - _surface: SourceSurface, - _dest: &Point2D, - _color: &Color, - _offset: &Vector2D, - _sigma: f32, - _operator: CompositionOp, + surface: SourceSurface, + dest: &Point2D, + color: &Color, + offset: &Vector2D, + sigma: f32, + operator: CompositionOp, ) { - unimplemented!() + unimplemented!(); } - fn fill(&self, _path: &Path, _pattern: Pattern, _draw_options: &DrawOptions) { - unimplemented!() + fn fill(&mut self, path: &Path, pattern: Pattern, draw_options: &DrawOptions) { + unimplemented!(); } - fn fill_rect(&self, _rect: &Rect, _pattern: Pattern, _draw_options: Option<&DrawOptions>) { - unimplemented!() + fn fill_rect( + &mut self, + rect: &Rect, + pattern: Pattern, + draw_options: Option<&DrawOptions>, + ) { + unimplemented!(); } fn get_format(&self) -> SurfaceFormat { - unimplemented!() + unimplemented!(); } fn get_size(&self) -> Size2D { - unimplemented!() + unimplemented!(); } fn get_transform(&self) -> Transform2D { - unimplemented!() + unimplemented!(); } - fn pop_clip(&self) { - unimplemented!() + fn pop_clip(&mut self) { + unimplemented!(); } - fn push_clip(&self, _path: &Path) { - unimplemented!() + fn push_clip(&mut self, path: &Path) { + unimplemented!(); } - fn set_transform(&self, _matrix: &Transform2D) { - unimplemented!() + fn set_transform(&mut self, matrix: &Transform2D) { + unimplemented!(); } fn snapshot(&self) -> SourceSurface { - unimplemented!() + unimplemented!(); } fn stroke( - &self, - _path: &Path, - _pattern: Pattern, - _stroke_options: &StrokeOptions, - _draw_options: &DrawOptions, + &mut self, + path: &Path, + pattern: Pattern, + stroke_options: &StrokeOptions, + draw_options: &DrawOptions, ) { - unimplemented!() + unimplemented!(); } fn stroke_line( - &self, - _start: Point2D, - _end: Point2D, - _pattern: Pattern, - _stroke_options: &StrokeOptions, - _draw_options: &DrawOptions, + &mut self, + start: Point2D, + end: Point2D, + pattern: Pattern, + stroke_options: &StrokeOptions, + draw_options: &DrawOptions, ) { - unimplemented!() + unimplemented!(); } fn stroke_rect( - &self, - _rect: &Rect, - _pattern: Pattern, - _stroke_options: &StrokeOptions, - _draw_options: &DrawOptions, + &mut self, + rect: &Rect, + pattern: Pattern, + stroke_options: &StrokeOptions, + draw_options: &DrawOptions, ) { - unimplemented!() + unimplemented!(); } - - fn snapshot_data(&self, _f: &Fn(&[u8]) -> Vec) -> Vec { - unimplemented!() + fn snapshot_data(&self, f: &Fn(&[u8]) -> Vec) -> Vec { + unimplemented!(); } - fn snapshot_data_owned(&self) -> Vec { - unimplemented!() + unimplemented!(); } } From 56d1d7339a839822115c4cd967a7772fe151f916 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 3 Jul 2019 21:24:48 -0400 Subject: [PATCH 6/8] Deal with fallout from mutable trait method change. --- components/canvas/canvas_data.rs | 34 ++++---- components/canvas/raqote_backend.rs | 126 +++++++++++++++------------- 2 files changed, 85 insertions(+), 75 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index 6f94922f91f9..eac4abd35f70 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -344,11 +344,12 @@ pub enum SourceSurface { Raqote(()), } +#[derive(Clone)] pub enum Path { #[cfg(feature = "azure_backend")] Azure(azure::azure_hl::Path), #[cfg(feature = "raqote_backend")] - Raqote(()), + Raqote(raqote::Path), } #[derive(Clone)] @@ -438,7 +439,7 @@ impl<'a> CanvasData<'a> { } pub fn draw_image( - &self, + &mut self, image_data: Vec, image_size: Size2D, dest_rect: Rect, @@ -454,14 +455,15 @@ impl<'a> CanvasData<'a> { image_data.into() }; - let writer = |draw_target: &GenericDrawTarget| { + let draw_options = self.state.draw_options.clone(); + let writer = |draw_target: &mut GenericDrawTarget| { write_image( draw_target, image_data, source_rect.size, dest_rect, smoothing_enabled, - &self.state.draw_options, + &draw_options, ); }; @@ -474,7 +476,7 @@ impl<'a> CanvasData<'a> { // TODO(pylbrecht) pass another closure for raqote self.draw_with_shadow(&rect, writer); } else { - writer(&*self.drawtarget); + writer(&mut *self.drawtarget); } } @@ -497,7 +499,7 @@ impl<'a> CanvasData<'a> { ); } - pub fn fill_rect(&self, rect: &Rect) { + pub fn fill_rect(&mut self, rect: &Rect) { if self.state.fill_style.is_zero_size_gradient() { return; // Paint nothing if gradient size is zero. } @@ -510,7 +512,7 @@ impl<'a> CanvasData<'a> { ); if self.need_to_draw_shadow() { - self.draw_with_shadow(&draw_rect, |new_draw_target: &GenericDrawTarget| { + self.draw_with_shadow(&draw_rect, |new_draw_target: &mut GenericDrawTarget| { new_draw_target.fill_rect( &draw_rect, self.state.fill_style.clone(), @@ -530,13 +532,13 @@ impl<'a> CanvasData<'a> { self.drawtarget.clear_rect(rect); } - pub fn stroke_rect(&self, rect: &Rect) { + pub fn stroke_rect(&mut self, rect: &Rect) { if self.state.stroke_style.is_zero_size_gradient() { return; // Paint nothing if gradient size is zero. } if self.need_to_draw_shadow() { - self.draw_with_shadow(&rect, |new_draw_target: &GenericDrawTarget| { + self.draw_with_shadow(&rect, |new_draw_target: &mut GenericDrawTarget| { new_draw_target.stroke_rect( rect, self.state.stroke_style.clone(), @@ -643,7 +645,7 @@ impl<'a> CanvasData<'a> { self.ensure_path(); self.drawtarget.fill( - &self.path(), + &self.path().clone(), self.state.fill_style.clone(), &self.state.draw_options, ); @@ -656,7 +658,7 @@ impl<'a> CanvasData<'a> { self.ensure_path(); self.drawtarget.stroke( - &self.path(), + &self.path().clone(), self.state.stroke_style.clone(), &self.state.stroke_opts, &self.state.draw_options, @@ -665,7 +667,7 @@ impl<'a> CanvasData<'a> { pub fn clip(&mut self) { self.ensure_path(); - let path = self.path(); + let path = self.path().clone(); self.drawtarget.push_clip(&path); } @@ -1038,7 +1040,7 @@ impl<'a> CanvasData<'a> { } fn create_draw_target_for_shadow(&self, source_rect: &Rect) -> Box { - let draw_target = self.drawtarget.create_similar_draw_target( + let mut draw_target = self.drawtarget.create_similar_draw_target( &Size2D::new( source_rect.size.width as i32, source_rect.size.height as i32, @@ -1054,11 +1056,11 @@ impl<'a> CanvasData<'a> { fn draw_with_shadow(&self, rect: &Rect, draw_shadow_source: F) where - F: FnOnce(&GenericDrawTarget), + F: FnOnce(&mut GenericDrawTarget), { let shadow_src_rect = self.state.transform.transform_rect(rect); - let new_draw_target = self.create_draw_target_for_shadow(&shadow_src_rect); - draw_shadow_source(&*new_draw_target); + let mut new_draw_target = self.create_draw_target_for_shadow(&shadow_src_rect); + draw_shadow_source(&mut *new_draw_target); self.drawtarget.draw_surface_with_shadow( new_draw_target.snapshot(), &Point2D::new( diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 051febc36e62..891b0b7cb005 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -143,71 +143,71 @@ impl Path { } impl GenericDrawTarget for raqote::DrawTarget { - fn clear_rect(&self, rect: &Rect) { + fn clear_rect(&self, _rect: &Rect) { unimplemented!(); } fn copy_surface( &mut self, - surface: SourceSurface, - source: Rect, - destination: Point2D, + _surface: SourceSurface, + _source: Rect, + _destination: Point2D, ) { unimplemented!(); } fn create_gradient_stops( &self, - gradient_stops: Vec, - extend_mode: ExtendMode, + _gradient_stops: Vec, + _extend_mode: ExtendMode, ) -> GradientStops { unimplemented!(); } fn create_path_builder(&self) -> Box { - unimplemented!(); + Box::new(PathBuilder::new()) } fn create_similar_draw_target( &self, - size: &Size2D, - format: SurfaceFormat, + _size: &Size2D, + _format: SurfaceFormat, ) -> Box { unimplemented!(); } fn create_source_surface_from_data( &self, - data: &[u8], - size: Size2D, - stride: i32, + _data: &[u8], + _size: Size2D, + _stride: i32, ) -> Option { unimplemented!(); } fn draw_surface( &self, - surface: SourceSurface, - dest: Rect, - source: Rect, - filter: Filter, - draw_options: &DrawOptions, + _surface: SourceSurface, + _dest: Rect, + _source: Rect, + _filter: Filter, + _draw_options: &DrawOptions, ) { unimplemented!(); } fn draw_surface_with_shadow( &self, - surface: SourceSurface, - dest: &Point2D, - color: &Color, - offset: &Vector2D, - sigma: f32, - operator: CompositionOp, + _surface: SourceSurface, + _dest: &Point2D, + _color: &Color, + _offset: &Vector2D, + _sigma: f32, + _operator: CompositionOp, ) { unimplemented!(); } - fn fill(&mut self, path: &Path, pattern: Pattern, draw_options: &DrawOptions) { + fn fill(&mut self, _path: &Path, _pattern: Pattern, _draw_options: &DrawOptions) { unimplemented!(); } fn fill_rect( &mut self, - rect: &Rect, - pattern: Pattern, - draw_options: Option<&DrawOptions>, + _rect: &Rect, + _pattern: Pattern, + _draw_options: Option<&DrawOptions>, ) { unimplemented!(); } @@ -223,10 +223,10 @@ impl GenericDrawTarget for raqote::DrawTarget { fn pop_clip(&mut self) { unimplemented!(); } - fn push_clip(&mut self, path: &Path) { + fn push_clip(&mut self, _path: &Path) { unimplemented!(); } - fn set_transform(&mut self, matrix: &Transform2D) { + fn set_transform(&mut self, _matrix: &Transform2D) { unimplemented!(); } fn snapshot(&self) -> SourceSurface { @@ -234,33 +234,33 @@ impl GenericDrawTarget for raqote::DrawTarget { } fn stroke( &mut self, - path: &Path, - pattern: Pattern, - stroke_options: &StrokeOptions, - draw_options: &DrawOptions, + _path: &Path, + _pattern: Pattern, + _stroke_options: &StrokeOptions, + _draw_options: &DrawOptions, ) { unimplemented!(); } fn stroke_line( &mut self, - start: Point2D, - end: Point2D, - pattern: Pattern, - stroke_options: &StrokeOptions, - draw_options: &DrawOptions, + _start: Point2D, + _end: Point2D, + _pattern: Pattern, + _stroke_options: &StrokeOptions, + _draw_options: &DrawOptions, ) { unimplemented!(); } fn stroke_rect( &mut self, - rect: &Rect, - pattern: Pattern, - stroke_options: &StrokeOptions, - draw_options: &DrawOptions, + _rect: &Rect, + _pattern: Pattern, + _stroke_options: &StrokeOptions, + _draw_options: &DrawOptions, ) { unimplemented!(); } - fn snapshot_data(&self, f: &Fn(&[u8]) -> Vec) -> Vec { + fn snapshot_data(&self, _f: &Fn(&[u8]) -> Vec) -> Vec { unimplemented!(); } fn snapshot_data_owned(&self) -> Vec { @@ -268,16 +268,24 @@ impl GenericDrawTarget for raqote::DrawTarget { } } -impl GenericPathBuilder for raqote::PathBuilder { +struct PathBuilder(Option); + +impl PathBuilder { + fn new() -> PathBuilder { + PathBuilder(Some(raqote::PathBuilder::new())) + } +} + +impl GenericPathBuilder for PathBuilder { fn arc( &mut self, origin: Point2D, radius: f32, start_angle: f32, end_angle: f32, - anticlockwise: bool, + _anticlockwise: bool, ) { - self.arc(origin.x, origin.y, radius, start_angle, end_angle); + self.0.as_mut().unwrap().arc(origin.x, origin.y, radius, start_angle, end_angle); } fn bezier_curve_to( &mut self, @@ -285,7 +293,7 @@ impl GenericPathBuilder for raqote::PathBuilder { control_point2: &Point2D, control_point3: &Point2D, ) { - self.cubic_to( + self.0.as_mut().unwrap().cubic_to( control_point1.x, control_point1.y, control_point2.x, @@ -295,17 +303,17 @@ impl GenericPathBuilder for raqote::PathBuilder { ); } fn close(&mut self) { - self.close(); + self.0.as_mut().unwrap().close(); } fn ellipse( &mut self, - origin: Point2D, - radius_x: f32, - radius_y: f32, - rotation_angle: f32, - start_angle: f32, - end_angle: f32, - anticlockwise: bool, + _origin: Point2D, + _radius_x: f32, + _radius_y: f32, + _rotation_angle: f32, + _start_angle: f32, + _end_angle: f32, + _anticlockwise: bool, ) { unimplemented!(); } @@ -313,16 +321,16 @@ impl GenericPathBuilder for raqote::PathBuilder { unimplemented!(); } fn line_to(&mut self, point: Point2D) { - self.line_to(point.x, point.y); + self.0.as_mut().unwrap().line_to(point.x, point.y); } fn move_to(&mut self, point: Point2D) { - self.move_to(point.x, point.y); + self.0.as_mut().unwrap().move_to(point.x, point.y); } fn quadratic_curve_to(&mut self, control_point: &Point2D, end_point: &Point2D) { - self.quad_to(control_point.x, control_point.y, end_point.x, end_point.y); + self.0.as_mut().unwrap().quad_to(control_point.x, control_point.y, end_point.x, end_point.y); } fn finish(&mut self) -> Path { - self.finish() + Path::Raqote(self.0.take().unwrap().finish()) } } From 873ced0ccc1691805c701b2fdfb5a6efce47bbcd Mon Sep 17 00:00:00 2001 From: pylbrecht Date: Sun, 7 Jul 2019 20:26:10 +0200 Subject: [PATCH 7/8] Implement fill() for raqote::DrawTarget --- components/canvas/canvas_data.rs | 9 ++++--- components/canvas/raqote_backend.rs | 37 ++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index eac4abd35f70..f9c32c34979f 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -352,12 +352,11 @@ pub enum Path { Raqote(raqote::Path), } -#[derive(Clone)] -pub enum Pattern { +pub enum Pattern<'a> { #[cfg(feature = "azure_backend")] Azure(azure::azure_hl::Pattern), #[cfg(feature = "raqote_backend")] - Raqote(()), + Raqote(raqote::Source<'a>), } pub enum DrawSurfaceOptions { @@ -1114,8 +1113,8 @@ impl<'a> Drop for CanvasData<'a> { #[derive(Clone)] pub struct CanvasPaintState<'a> { pub draw_options: DrawOptions, - pub fill_style: Pattern, - pub stroke_style: Pattern, + pub fill_style: Pattern<'a>, + pub stroke_style: Pattern<'a>, pub stroke_opts: StrokeOptions<'a>, /// The current 2D transform matrix. pub transform: Transform2D, diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 891b0b7cb005..7e98d26b62ee 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -72,10 +72,11 @@ impl Backend for RaqoteBackend { impl<'a> CanvasPaintState<'a> { pub fn new(_antialias: AntialiasMode) -> CanvasPaintState<'a> { + let solid_src = raqote::SolidSource { r: 0, g: 0, b: 0, a: 255 }; CanvasPaintState { draw_options: DrawOptions::Raqote(raqote::DrawOptions::new()), - fill_style: Pattern::Raqote(()), - stroke_style: Pattern::Raqote(()), + fill_style: Pattern::Raqote(raqote::Source::Solid(solid_src)), + stroke_style: Pattern::Raqote(raqote::Source::Solid(solid_src)), stroke_opts: StrokeOptions::Raqote(Default::default(), PhantomData), transform: Transform2D::identity(), shadow_offset_x: 0.0, @@ -86,10 +87,15 @@ impl<'a> CanvasPaintState<'a> { } } -impl Pattern { +impl Pattern<'_> { pub fn is_zero_size_gradient(&self) -> bool { match *self { - Pattern::Raqote(()) => unimplemented!(), + Pattern::Raqote(_) => unimplemented!(), + } + } + pub fn as_raqote(&self) -> &raqote::Source { + match self { + Pattern::Raqote(p) => p, } } } @@ -123,6 +129,11 @@ impl DrawOptions { DrawOptions::Raqote(draw_options) => draw_options.alpha = _val, } } + pub fn as_raqote(&self) -> &raqote::DrawOptions { + match self { + DrawOptions::Raqote(options) => options, + } + } } impl Path { @@ -140,6 +151,12 @@ impl Path { pub fn copy_to_builder(&self) -> Box { unimplemented!() } + + pub fn as_raqote(&self) -> &raqote::Path { + match self { + Path::Raqote(p) => p, + } + } } impl GenericDrawTarget for raqote::DrawTarget { @@ -200,8 +217,8 @@ impl GenericDrawTarget for raqote::DrawTarget { ) { unimplemented!(); } - fn fill(&mut self, _path: &Path, _pattern: Pattern, _draw_options: &DrawOptions) { - unimplemented!(); + fn fill(&mut self, path: &Path, pattern: Pattern, draw_options: &DrawOptions) { + self.fill(path.as_raqote(), pattern.as_raqote(), draw_options.as_raqote()); } fn fill_rect( &mut self, @@ -363,3 +380,11 @@ impl ToRaqoteStyle for LineCapStyle { } } } + +// TODO(pylbrecht) +#[cfg(feature = "raqote_backend")] +impl Clone for Pattern<'_> { + fn clone(&self) -> Self { + unimplemented!(); + } +} From dceb81a94a005c16c7c4137d82fb4a18d6b9c2e9 Mon Sep 17 00:00:00 2001 From: pylbrecht Date: Mon, 8 Jul 2019 18:29:17 +0200 Subject: [PATCH 8/8] Implement some of GenericDrawTarget's methods for raqote --- components/canvas/raqote_backend.rs | 32 +++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 7e98d26b62ee..3099b8c70247 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -121,6 +121,11 @@ impl<'a> StrokeOptions<'a> { StrokeOptions::Raqote(options, _) => options.cap = _val.to_raqote_style(), } } + pub fn as_raqote(&self) -> &raqote::StrokeStyle { + match self { + StrokeOptions::Raqote(options, _) => options, + } + } } impl DrawOptions { @@ -235,28 +240,33 @@ impl GenericDrawTarget for raqote::DrawTarget { unimplemented!(); } fn get_transform(&self) -> Transform2D { - unimplemented!(); + *self.get_transform() } fn pop_clip(&mut self) { - unimplemented!(); + self.pop_clip(); } - fn push_clip(&mut self, _path: &Path) { - unimplemented!(); + fn push_clip(&mut self, path: &Path) { + self.push_clip(path.as_raqote()); } - fn set_transform(&mut self, _matrix: &Transform2D) { - unimplemented!(); + fn set_transform(&mut self, matrix: &Transform2D) { + self.set_transform(matrix); } fn snapshot(&self) -> SourceSurface { unimplemented!(); } fn stroke( &mut self, - _path: &Path, - _pattern: Pattern, - _stroke_options: &StrokeOptions, - _draw_options: &DrawOptions, + path: &Path, + pattern: Pattern, + stroke_options: &StrokeOptions, + draw_options: &DrawOptions, ) { - unimplemented!(); + self.stroke( + path.as_raqote(), + pattern.as_raqote(), + stroke_options.as_raqote(), + draw_options.as_raqote(), + ); } fn stroke_line( &mut self,