diff options
Diffstat (limited to 'components/style/values/specified/svg_path.rs')
-rw-r--r-- | components/style/values/specified/svg_path.rs | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/components/style/values/specified/svg_path.rs b/components/style/values/specified/svg_path.rs index 5509312256a..e5276e5cce8 100644 --- a/components/style/values/specified/svg_path.rs +++ b/components/style/values/specified/svg_path.rs @@ -29,16 +29,15 @@ use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; ToResolvedValue, ToShmem, )] -pub struct SVGPathData(Box<[PathCommand]>); +#[repr(C)] +pub struct SVGPathData( + // TODO(emilio): Should probably measure this somehow only from the + // specified values. + #[ignore_malloc_size_of = "Arc"] + pub crate::ArcSlice<PathCommand> +); impl SVGPathData { - /// Return SVGPathData by a slice of PathCommand. - #[inline] - pub fn new(cmd: Box<[PathCommand]>) -> Self { - debug_assert!(!cmd.is_empty()); - SVGPathData(cmd) - } - /// Get the array of PathCommand. #[inline] pub fn commands(&self) -> &[PathCommand] { @@ -46,9 +45,9 @@ impl SVGPathData { &self.0 } - /// Create a normalized copy of this path by converting each relative command to an absolute - /// command. - fn normalize(&self) -> Self { + /// Create a normalized copy of this path by converting each relative + /// command to an absolute command. + fn normalize(&self) -> Box<[PathCommand]> { let mut state = PathTraversalState { subpath_start: CoordPair::new(0.0, 0.0), pos: CoordPair::new(0.0, 0.0), @@ -58,7 +57,7 @@ impl SVGPathData { .iter() .map(|seg| seg.normalize(&mut state)) .collect::<Vec<_>>(); - SVGPathData(result.into_boxed_slice()) + result.into_boxed_slice() } } @@ -71,7 +70,7 @@ impl ToCss for SVGPathData { dest.write_char('"')?; { let mut writer = SequenceWriter::new(dest, " "); - for command in self.0.iter() { + for command in self.commands() { writer.item(command)?; } } @@ -104,7 +103,7 @@ impl Parse for SVGPathData { } } - Ok(SVGPathData::new(path_parser.path.into_boxed_slice())) + Ok(SVGPathData(crate::ArcSlice::from_iter(path_parser.path.into_iter()))) } } @@ -114,14 +113,17 @@ impl Animate for SVGPathData { return Err(()); } + // FIXME(emilio): This allocates three copies of the path, that's not + // great! Specially, once we're normalized once, we don't need to + // re-normalize again. let result = self .normalize() - .0 .iter() - .zip(other.normalize().0.iter()) + .zip(other.normalize().iter()) .map(|(a, b)| a.animate(&b, procedure)) .collect::<Result<Vec<_>, _>>()?; - Ok(SVGPathData::new(result.into_boxed_slice())) + + Ok(SVGPathData(crate::ArcSlice::from_iter(result.into_iter()))) } } @@ -131,9 +133,8 @@ impl ComputeSquaredDistance for SVGPathData { return Err(()); } self.normalize() - .0 .iter() - .zip(other.normalize().0.iter()) + .zip(other.normalize().iter()) .map(|(this, other)| this.compute_squared_distance(&other)) .sum() } |