diff --git a/canvas/src/lib.rs b/canvas/src/lib.rs index 01435f77..123dc100 100644 --- a/canvas/src/lib.rs +++ b/canvas/src/lib.rs @@ -175,10 +175,12 @@ impl CanvasRenderingContext2D { let mut stroke_style = self.current_state.stroke_style; stroke_style.line_width = f32::max(stroke_style.line_width, HAIRLINE_STROKE_WIDTH); - let mut stroke_to_fill = OutlineStrokeToFill::new(path.into_outline(), stroke_style); + let outline = path.into_outline(); + let mut stroke_to_fill = OutlineStrokeToFill::new(&outline, stroke_style); stroke_to_fill.offset(); - stroke_to_fill.outline.transform(&self.current_state.transform); - self.scene.push_path(PathObject::new(stroke_to_fill.outline, paint_id, String::new())) + let mut outline = stroke_to_fill.into_outline(); + outline.transform(&self.current_state.transform); + self.scene.push_path(PathObject::new(outline, paint_id, String::new())) } // Transformations diff --git a/geometry/src/stroke.rs b/geometry/src/stroke.rs index a3f06c94..5e03ad16 100644 --- a/geometry/src/stroke.rs +++ b/geometry/src/stroke.rs @@ -16,13 +16,13 @@ use crate::basic::rect::RectF32; use crate::outline::{Contour, Outline}; use crate::segment::Segment; use std::f32; -use std::mem; const TOLERANCE: f32 = 0.01; -pub struct OutlineStrokeToFill { - pub outline: Outline, - pub style: StrokeStyle, +pub struct OutlineStrokeToFill<'a> { + input: &'a Outline, + output: Outline, + style: StrokeStyle, } #[derive(Clone, Copy, Debug, PartialEq)] @@ -45,15 +45,15 @@ pub enum LineJoin { Bevel, } -impl OutlineStrokeToFill { +impl<'a> OutlineStrokeToFill<'a> { #[inline] - pub fn new(outline: Outline, style: StrokeStyle) -> OutlineStrokeToFill { - OutlineStrokeToFill { outline, style } + pub fn new(input: &Outline, style: StrokeStyle) -> OutlineStrokeToFill { + OutlineStrokeToFill { input, output: Outline::new(), style } } - pub fn offset(&mut self) { + pub fn offset(&mut self) -> &mut OutlineStrokeToFill<'a> { let mut new_contours = vec![]; - for input in mem::replace(&mut self.outline.contours, vec![]) { + for input in &self.input.contours { let closed = input.closed; let mut stroker = ContourStrokeToFill::new(input, Contour::new(), @@ -82,8 +82,15 @@ impl OutlineStrokeToFill { let mut new_bounds = None; new_contours.iter().for_each(|contour| contour.update_bounds(&mut new_bounds)); - self.outline.contours = new_contours; - self.outline.bounds = new_bounds.unwrap_or_else(|| RectF32::default()); + self.output.contours = new_contours; + self.output.bounds = new_bounds.unwrap_or_else(|| RectF32::default()); + + self + } + + #[inline] + pub fn into_outline(self) -> Outline { + self.output } fn push_stroked_contour(&mut self, @@ -131,16 +138,16 @@ impl OutlineStrokeToFill { } } -struct ContourStrokeToFill { - input: Contour, +struct ContourStrokeToFill<'a> { + input: &'a Contour, output: Contour, radius: f32, join: LineJoin, } -impl ContourStrokeToFill { +impl<'a> ContourStrokeToFill<'a> { #[inline] - fn new(input: Contour, output: Contour, radius: f32, join: LineJoin) -> ContourStrokeToFill { + fn new(input: &Contour, output: Contour, radius: f32, join: LineJoin) -> ContourStrokeToFill { ContourStrokeToFill { input, output, radius, join } } diff --git a/svg/src/lib.rs b/svg/src/lib.rs index 34e739a6..c4d21c4d 100644 --- a/svg/src/lib.rs +++ b/svg/src/lib.rs @@ -145,9 +145,9 @@ impl BuiltSVG { let path = UsvgPathToSegments::new(path.segments.iter().cloned()); let outline = Outline::from_segments(path); - let mut stroke_to_fill = OutlineStrokeToFill::new(outline, stroke_style); + let mut stroke_to_fill = OutlineStrokeToFill::new(&outline, stroke_style); stroke_to_fill.offset(); - let mut outline = stroke_to_fill.outline; + let mut outline = stroke_to_fill.into_outline(); outline.transform(&transform); let name = format!("Stroke({})", node.id()); diff --git a/text/src/lib.rs b/text/src/lib.rs index 8c3d9223..19c5701a 100644 --- a/text/src/lib.rs +++ b/text/src/lib.rs @@ -70,9 +70,9 @@ impl SceneExt for Scene { let mut outline = outline_builder.build(); if let TextRenderMode::Stroke(stroke_style) = render_mode { - let mut stroke_to_fill = OutlineStrokeToFill::new(outline, stroke_style); + let mut stroke_to_fill = OutlineStrokeToFill::new(&outline, stroke_style); stroke_to_fill.offset(); - outline = stroke_to_fill.outline; + outline = stroke_to_fill.into_outline(); } self.push_path(PathObject::new(outline, paint_id, String::new()));