Move the path transform iterator to the geometry crate
This commit is contained in:
parent
77f4f6b188
commit
dcee161f6a
|
@ -11,6 +11,7 @@
|
||||||
//! Applies a transform to paths.
|
//! Applies a transform to paths.
|
||||||
|
|
||||||
use crate::point::Point2DF32;
|
use crate::point::Point2DF32;
|
||||||
|
use crate::segment::Segment;
|
||||||
use crate::simd::F32x4;
|
use crate::simd::F32x4;
|
||||||
use euclid::Transform2D;
|
use euclid::Transform2D;
|
||||||
use lyon_path::PathEvent;
|
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.
|
/// Transforms a path with a Euclid 2D transform.
|
||||||
pub struct Transform2DPathIter<I> where I: Iterator<Item = PathEvent> {
|
pub struct Transform2DPathIter<I> where I: Iterator<Item = PathEvent> {
|
||||||
inner: I,
|
inner: I,
|
||||||
|
|
|
@ -30,7 +30,7 @@ use pathfinder_geometry::segment::{PathEventsToSegments, Segment, SegmentFlags};
|
||||||
use pathfinder_geometry::segment::{SegmentKind, SegmentsToPathEvents};
|
use pathfinder_geometry::segment::{SegmentKind, SegmentsToPathEvents};
|
||||||
use pathfinder_geometry::simd::{F32x4, I32x4};
|
use pathfinder_geometry::simd::{F32x4, I32x4};
|
||||||
use pathfinder_geometry::stroke::{StrokeStyle, StrokeToFillIter};
|
use pathfinder_geometry::stroke::{StrokeStyle, StrokeToFillIter};
|
||||||
use pathfinder_geometry::transform::Transform2DF32;
|
use pathfinder_geometry::transform::{Transform2DF32, Transform2DF32PathIter};
|
||||||
use pathfinder_geometry::util;
|
use pathfinder_geometry::util;
|
||||||
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||||
use rayon::ThreadPoolBuilder;
|
use rayon::ThreadPoolBuilder;
|
||||||
|
@ -257,7 +257,7 @@ impl Scene {
|
||||||
let style = scene.push_paint(&Paint::from_svg_paint(&fill.paint));
|
let style = scene.push_paint(&Paint::from_svg_paint(&fill.paint));
|
||||||
|
|
||||||
let path = UsvgPathToSegments::new(path.segments.iter().cloned());
|
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 path = MonotonicConversionIter::new(path);
|
||||||
let outline = Outline::from_segments(path);
|
let outline = Outline::from_segments(path);
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ impl Scene {
|
||||||
let path = PathIter::new(path);
|
let path = PathIter::new(path);
|
||||||
let path = StrokeToFillIter::new(path, StrokeStyle::new(stroke_width));
|
let path = StrokeToFillIter::new(path, StrokeStyle::new(stroke_width));
|
||||||
let path = PathEventsToSegments::new(path);
|
let path = PathEventsToSegments::new(path);
|
||||||
let path = PathTransformingIter::new(path, &transform);
|
let path = Transform2DF32PathIter::new(path, &transform);
|
||||||
let path = MonotonicConversionIter::new(path);
|
let path = MonotonicConversionIter::new(path);
|
||||||
let outline = Outline::from_segments(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
|
// Monotonic conversion utilities
|
||||||
|
|
||||||
// TODO(pcwalton): I think we only need to be monotonic in Y, maybe?
|
// TODO(pcwalton): I think we only need to be monotonic in Y, maybe?
|
||||||
|
|
Loading…
Reference in New Issue