Move the path transform iterator to the geometry crate

This commit is contained in:
Patrick Walton 2019-01-14 11:13:43 -08:00
parent 77f4f6b188
commit dcee161f6a
2 changed files with 58 additions and 56 deletions

View File

@ -11,6 +11,7 @@
//! Applies a transform to paths.
use crate::point::Point2DF32;
use crate::segment::Segment;
use crate::simd::F32x4;
use euclid::Transform2D;
use lyon_path::PathEvent;
@ -69,6 +70,60 @@ impl Transform2DF32 {
}
}
/// Transforms a path with a SIMD 2D transform.
pub struct Transform2DF32PathIter<I>
where
I: Iterator<Item = Segment>,
{
iter: I,
transform: Transform2DF32,
}
impl<I> Iterator for Transform2DF32PathIter<I>
where
I: Iterator<Item = Segment>,
{
type Item = Segment;
#[inline]
fn next(&mut self) -> Option<Segment> {
// TODO(pcwalton): Can we go faster by transforming an entire line segment with SIMD?
let mut segment = self.iter.next()?;
if !segment.is_none() {
segment
.baseline
.set_from(&self.transform.transform_point(&segment.baseline.from()));
segment
.baseline
.set_to(&self.transform.transform_point(&segment.baseline.to()));
if !segment.is_line() {
segment
.ctrl
.set_from(&self.transform.transform_point(&segment.ctrl.from()));
if !segment.is_quadratic() {
segment
.ctrl
.set_to(&self.transform.transform_point(&segment.ctrl.to()));
}
}
}
Some(segment)
}
}
impl<I> Transform2DF32PathIter<I>
where
I: Iterator<Item = Segment>,
{
#[inline]
pub fn new(iter: I, transform: &Transform2DF32) -> Transform2DF32PathIter<I> {
Transform2DF32PathIter {
iter,
transform: *transform,
}
}
}
/// Transforms a path with a Euclid 2D transform.
pub struct Transform2DPathIter<I> where I: Iterator<Item = PathEvent> {
inner: I,

View File

@ -30,7 +30,7 @@ use pathfinder_geometry::segment::{PathEventsToSegments, Segment, SegmentFlags};
use pathfinder_geometry::segment::{SegmentKind, SegmentsToPathEvents};
use pathfinder_geometry::simd::{F32x4, I32x4};
use pathfinder_geometry::stroke::{StrokeStyle, StrokeToFillIter};
use pathfinder_geometry::transform::Transform2DF32;
use pathfinder_geometry::transform::{Transform2DF32, Transform2DF32PathIter};
use pathfinder_geometry::util;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use rayon::ThreadPoolBuilder;
@ -257,7 +257,7 @@ impl Scene {
let style = scene.push_paint(&Paint::from_svg_paint(&fill.paint));
let path = UsvgPathToSegments::new(path.segments.iter().cloned());
let path = PathTransformingIter::new(path, &transform);
let path = Transform2DF32PathIter::new(path, &transform);
let path = MonotonicConversionIter::new(path);
let outline = Outline::from_segments(path);
@ -280,7 +280,7 @@ impl Scene {
let path = PathIter::new(path);
let path = StrokeToFillIter::new(path, StrokeStyle::new(stroke_width));
let path = PathEventsToSegments::new(path);
let path = PathTransformingIter::new(path, &transform);
let path = Transform2DF32PathIter::new(path, &transform);
let path = MonotonicConversionIter::new(path);
let outline = Outline::from_segments(path);
@ -1362,59 +1362,6 @@ where
}
}
// Path transformation utilities
struct PathTransformingIter<I>
where
I: Iterator<Item = Segment>,
{
iter: I,
transform: Transform2DF32,
}
impl<I> Iterator for PathTransformingIter<I>
where
I: Iterator<Item = Segment>,
{
type Item = Segment;
fn next(&mut self) -> Option<Segment> {
// TODO(pcwalton): Can we go faster by transforming an entire line segment with SIMD?
let mut segment = self.iter.next()?;
if !segment.is_none() {
segment
.baseline
.set_from(&self.transform.transform_point(&segment.baseline.from()));
segment
.baseline
.set_to(&self.transform.transform_point(&segment.baseline.to()));
if !segment.is_line() {
segment
.ctrl
.set_from(&self.transform.transform_point(&segment.ctrl.from()));
if !segment.is_quadratic() {
segment
.ctrl
.set_to(&self.transform.transform_point(&segment.ctrl.to()));
}
}
}
Some(segment)
}
}
impl<I> PathTransformingIter<I>
where
I: Iterator<Item = Segment>,
{
fn new(iter: I, transform: &Transform2DF32) -> PathTransformingIter<I> {
PathTransformingIter {
iter,
transform: *transform,
}
}
}
// Monotonic conversion utilities
// TODO(pcwalton): I think we only need to be monotonic in Y, maybe?