Take paths by reference, not by value, in outline stroke-to-fill.

This commit is contained in:
Patrick Walton 2019-05-29 15:15:10 -07:00
parent 5dd9e8b67d
commit 51877426ea
4 changed files with 31 additions and 22 deletions

View File

@ -175,10 +175,12 @@ impl CanvasRenderingContext2D {
let mut stroke_style = self.current_state.stroke_style; let mut stroke_style = self.current_state.stroke_style;
stroke_style.line_width = f32::max(stroke_style.line_width, HAIRLINE_STROKE_WIDTH); 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.offset();
stroke_to_fill.outline.transform(&self.current_state.transform); let mut outline = stroke_to_fill.into_outline();
self.scene.push_path(PathObject::new(stroke_to_fill.outline, paint_id, String::new())) outline.transform(&self.current_state.transform);
self.scene.push_path(PathObject::new(outline, paint_id, String::new()))
} }
// Transformations // Transformations

View File

@ -16,13 +16,13 @@ use crate::basic::rect::RectF32;
use crate::outline::{Contour, Outline}; use crate::outline::{Contour, Outline};
use crate::segment::Segment; use crate::segment::Segment;
use std::f32; use std::f32;
use std::mem;
const TOLERANCE: f32 = 0.01; const TOLERANCE: f32 = 0.01;
pub struct OutlineStrokeToFill { pub struct OutlineStrokeToFill<'a> {
pub outline: Outline, input: &'a Outline,
pub style: StrokeStyle, output: Outline,
style: StrokeStyle,
} }
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
@ -45,15 +45,15 @@ pub enum LineJoin {
Bevel, Bevel,
} }
impl OutlineStrokeToFill { impl<'a> OutlineStrokeToFill<'a> {
#[inline] #[inline]
pub fn new(outline: Outline, style: StrokeStyle) -> OutlineStrokeToFill { pub fn new(input: &Outline, style: StrokeStyle) -> OutlineStrokeToFill {
OutlineStrokeToFill { outline, style } OutlineStrokeToFill { input, output: Outline::new(), style }
} }
pub fn offset(&mut self) { pub fn offset(&mut self) -> &mut OutlineStrokeToFill<'a> {
let mut new_contours = vec![]; 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 closed = input.closed;
let mut stroker = ContourStrokeToFill::new(input, let mut stroker = ContourStrokeToFill::new(input,
Contour::new(), Contour::new(),
@ -82,8 +82,15 @@ impl OutlineStrokeToFill {
let mut new_bounds = None; let mut new_bounds = None;
new_contours.iter().for_each(|contour| contour.update_bounds(&mut new_bounds)); new_contours.iter().for_each(|contour| contour.update_bounds(&mut new_bounds));
self.outline.contours = new_contours; self.output.contours = new_contours;
self.outline.bounds = new_bounds.unwrap_or_else(|| RectF32::default()); 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, fn push_stroked_contour(&mut self,
@ -131,16 +138,16 @@ impl OutlineStrokeToFill {
} }
} }
struct ContourStrokeToFill { struct ContourStrokeToFill<'a> {
input: Contour, input: &'a Contour,
output: Contour, output: Contour,
radius: f32, radius: f32,
join: LineJoin, join: LineJoin,
} }
impl ContourStrokeToFill { impl<'a> ContourStrokeToFill<'a> {
#[inline] #[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 } ContourStrokeToFill { input, output, radius, join }
} }

View File

@ -145,9 +145,9 @@ impl BuiltSVG {
let path = UsvgPathToSegments::new(path.segments.iter().cloned()); let path = UsvgPathToSegments::new(path.segments.iter().cloned());
let outline = Outline::from_segments(path); 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(); stroke_to_fill.offset();
let mut outline = stroke_to_fill.outline; let mut outline = stroke_to_fill.into_outline();
outline.transform(&transform); outline.transform(&transform);
let name = format!("Stroke({})", node.id()); let name = format!("Stroke({})", node.id());

View File

@ -70,9 +70,9 @@ impl SceneExt for Scene {
let mut outline = outline_builder.build(); let mut outline = outline_builder.build();
if let TextRenderMode::Stroke(stroke_style) = render_mode { 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(); 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())); self.push_path(PathObject::new(outline, paint_id, String::new()));