diff --git a/canvas/src/lib.rs b/canvas/src/lib.rs index 8281e7fe..ad3e28a0 100644 --- a/canvas/src/lib.rs +++ b/canvas/src/lib.rs @@ -96,15 +96,13 @@ impl CanvasRenderingContext2D { let mut path = Path2D::new(); path.rect(rect); - let mut outline = path.into_outline(); - outline.transform(&self.current_state.transform); - let paint = Paint::transparent_black(); let paint = self.current_state.resolve_paint(&paint); let paint_id = self.scene.push_paint(&paint); - let mut path = DrawPath::new(outline, paint_id); + let mut path = DrawPath::new(path.into_outline(), paint_id); path.set_blend_mode(BlendMode::Clear); + path.set_transform(self.current_state.transform); self.scene.push_path(path); } @@ -198,13 +196,9 @@ impl CanvasRenderingContext2D { #[inline] pub fn fill_path(&mut self, path: Path2D, fill_rule: FillRule) { - let mut outline = path.into_outline(); - outline.transform(&self.current_state.transform); - let paint = self.current_state.resolve_paint(&self.current_state.fill_paint); let paint_id = self.scene.push_paint(&paint); - - self.push_path(outline, paint_id, fill_rule); + self.push_path(path.into_outline(), paint_id, fill_rule); } #[inline] @@ -236,7 +230,6 @@ impl CanvasRenderingContext2D { stroke_to_fill.offset(); outline = stroke_to_fill.into_outline(); - outline.transform(&self.current_state.transform); self.push_path(outline, paint_id, FillRule::Winding); } @@ -252,6 +245,7 @@ impl CanvasRenderingContext2D { } fn push_path(&mut self, outline: Outline, paint_id: PaintId, fill_rule: FillRule) { + let transform = self.current_state.transform; let clip_path = self.current_state.clip_path; let blend_mode = self.current_state.global_composite_operation.to_blend_mode(); let composite_op = self.current_state.global_composite_operation.to_composite_op(); @@ -264,13 +258,13 @@ impl CanvasRenderingContext2D { let paint = self.current_state.resolve_paint(&self.current_state.shadow_paint); let paint_id = self.scene.push_paint(&paint); - let mut outline = outline.clone(); - outline.transform(&Transform2F::from_translation(self.current_state.shadow_offset)); - let mut path = DrawPath::new(outline, paint_id); + let mut path = DrawPath::new(outline.clone(), paint_id); path.set_clip_path(clip_path); path.set_fill_rule(fill_rule); path.set_blend_mode(blend_mode); path.set_opacity(opacity); + path.set_transform(Transform2F::from_translation(self.current_state.shadow_offset) * + transform); self.scene.push_path(path); self.composite_shadow_blur_render_targets_if_needed(shadow_blur_render_target_ids); @@ -284,6 +278,7 @@ impl CanvasRenderingContext2D { path.set_fill_rule(fill_rule); path.set_blend_mode(blend_mode); path.set_opacity(opacity); + path.set_transform(transform); self.scene.push_path(path); self.composite_render_target_if_needed(composite_op, render_target_id); diff --git a/renderer/src/builder.rs b/renderer/src/builder.rs index 8e60398d..12c5c151 100644 --- a/renderer/src/builder.rs +++ b/renderer/src/builder.rs @@ -170,7 +170,9 @@ impl<'a> SceneBuilder<'a> { built_clip_paths: &[BuiltPath], ) -> BuiltDrawPath { let path_object = &scene.paths[path_index]; - let outline = scene.apply_render_options(path_object.outline(), built_options); + let mut outline = scene.apply_render_options(path_object.outline(), built_options); + outline.transform(&path_object.transform()); + let paint_id = path_object.paint(); let paint_metadata = &paint_metadata[paint_id.0 as usize]; let built_clip_path = diff --git a/renderer/src/scene.rs b/renderer/src/scene.rs index d7d48ce6..64b2e242 100644 --- a/renderer/src/scene.rs +++ b/renderer/src/scene.rs @@ -223,6 +223,7 @@ impl<'a> Iterator for PathIter<'a> { pub struct DrawPath { outline: Outline, paint: PaintId, + transform: Transform2F, clip_path: Option, fill_rule: FillRule, blend_mode: BlendMode, @@ -272,6 +273,7 @@ impl DrawPath { DrawPath { outline, paint, + transform: Transform2F::default(), clip_path: None, fill_rule: FillRule::Winding, blend_mode: BlendMode::SrcOver, @@ -285,6 +287,16 @@ impl DrawPath { &self.outline } + #[inline] + pub(crate) fn transform(&self) -> Transform2F { + self.transform + } + + #[inline] + pub fn set_transform(&mut self, new_transform: Transform2F) { + self.transform = new_transform + } + #[inline] pub(crate) fn clip_path(&self) -> Option { self.clip_path diff --git a/svg/src/lib.rs b/svg/src/lib.rs index 4866af5d..990cfd6e 100644 --- a/svg/src/lib.rs +++ b/svg/src/lib.rs @@ -133,7 +133,6 @@ impl BuiltSVG { path.visibility == Visibility::Visible => { if let Some(ref fill) = path.fill { let path = UsvgPathToSegments::new(path.data.iter().cloned()); - let path = Transform2FPathIter::new(path, &state.transform); let outline = Outline::from_segments(path); let name = format!("Fill({})", node.id()); @@ -158,8 +157,7 @@ impl BuiltSVG { let mut stroke_to_fill = OutlineStrokeToFill::new(&outline, stroke_style); stroke_to_fill.offset(); - let mut outline = stroke_to_fill.into_outline(); - outline.transform(&state.transform); + let outline = stroke_to_fill.into_outline(); let name = format!("Stroke({})", node.id()); self.push_draw_path(outline, @@ -238,6 +236,7 @@ impl BuiltSVG { path.set_fill_rule(fill_rule); path.set_name(name); path.set_opacity((opacity.value() * 255.0) as u8); + path.set_transform(state.transform); self.scene.push_path(path); } }