diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index 3f66525b7c0..c2feabeac02 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -239,7 +239,7 @@ pub trait GenericDrawTarget { stride: i32, ) -> Option; fn draw_surface( - &self, + &mut self, surface: SourceSurface, dest: Rect, source: Rect, @@ -340,7 +340,7 @@ pub enum SourceSurface { #[cfg(feature = "canvas2d-azure")] Azure(azure::azure_hl::SourceSurface), #[cfg(feature = "canvas2d-raqote")] - Raqote(()), + Raqote(Vec), // TODO: See if we can avoid the alloc (probably?) } #[derive(Clone)] @@ -1133,7 +1133,7 @@ pub struct CanvasPaintState<'a> { /// dest_rect: Area of the destination target where the pixels will be copied /// smoothing_enabled: It determines if smoothing is applied to the image result fn write_image( - draw_target: &dyn GenericDrawTarget, + draw_target: &mut dyn GenericDrawTarget, image_data: Vec, image_size: Size2D, dest_rect: Rect, diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index 4ceb0c26f5b..2aea31ad460 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -188,7 +188,7 @@ impl Path { } pub fn copy_to_builder(&self) -> Box { - unimplemented!() + Box::new(PathBuilder(Some(raqote::PathBuilder::from(self.as_raqote().clone())))) } pub fn as_raqote(&self) -> &raqote::Path { @@ -221,13 +221,23 @@ impl GenericDrawTarget for raqote::DrawTarget { &options, ); } + #[allow(unsafe_code)] fn copy_surface( &mut self, - _surface: SourceSurface, - _source: Rect, - _destination: Point2D, + surface: SourceSurface, + source: Rect, + destination: Point2D, ) { - unimplemented!(); + let mut dt = raqote::DrawTarget::new(source.size.width, source.size.height); + let data = surface.as_raqote(); + let s = unsafe { std::slice::from_raw_parts(data.as_ptr() as *const u32, data.len() / 4) }; + dt.get_data_mut().copy_from_slice(s); + raqote::DrawTarget::copy_surface( + self, + &dt, + source.to_box2d(), + destination + ); } fn create_gradient_stops( &self, @@ -248,21 +258,40 @@ impl GenericDrawTarget for raqote::DrawTarget { } fn create_source_surface_from_data( &self, - _data: &[u8], + data: &[u8], _size: Size2D, _stride: i32, ) -> Option { - unimplemented!(); + Some(SourceSurface::Raqote(data.to_vec())) } + #[allow(unsafe_code)] fn draw_surface( - &self, - _surface: SourceSurface, - _dest: Rect, - _source: Rect, + &mut self, + surface: SourceSurface, + dest: Rect, + source: Rect, _filter: Filter, - _draw_options: &DrawOptions, + draw_options: &DrawOptions, ) { - unimplemented!(); + let v = surface.as_raqote(); + let image = raqote::Image { + width: source.size.width as i32, + height: source.size.height as i32, + data: unsafe { + std::slice::from_raw_parts( + v.as_ptr() as *const u32, + v.len() * std::mem::size_of::(), + ) }, + }; + raqote::DrawTarget::draw_image_with_size_at( + self, + dest.size.width as f32, + dest.size.height as f32, + dest.origin.x as f32, + dest.origin.y as f32, + &image, + draw_options.as_raqote(), + ); } fn draw_surface_with_shadow( &self, @@ -617,3 +646,11 @@ impl ToRaqoteStyle for CompositionStyle { } } } + +impl SourceSurface { + fn as_raqote(&self) -> &Vec { + match self { + SourceSurface::Raqote(s) => s, + } + } +}