// pathfinder/content/src/transform.rs // // Copyright © 2019 The Pathfinder Project Developers. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! Utilities for transforming paths. use crate::segment::Segment; use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::transform3d::Perspective; /// Transforms a path with a SIMD 2D transform. pub struct Transform2FPathIter where I: Iterator, { iter: I, transform: Transform2F, } impl Iterator for Transform2FPathIter where I: Iterator, { type Item = Segment; #[inline] fn next(&mut self) -> Option { // 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 Transform2FPathIter where I: Iterator, { #[inline] pub fn new(iter: I, transform: &Transform2F) -> Transform2FPathIter { Transform2FPathIter { iter, transform: *transform, } } } /// Transforms a path with a perspective projection. pub struct PerspectivePathIter where I: Iterator, { iter: I, perspective: Perspective, } impl Iterator for PerspectivePathIter where I: Iterator, { type Item = Segment; #[inline] fn next(&mut self) -> Option { let mut segment = self.iter.next()?; if !segment.is_none() { segment.baseline.set_from( self.perspective.transform_point_2d(segment.baseline.from()), ); segment.baseline.set_to(self.perspective.transform_point_2d(segment.baseline.to())); if !segment.is_line() { segment.ctrl.set_from(self.perspective.transform_point_2d(segment.ctrl.from())); if !segment.is_quadratic() { segment.ctrl.set_to(self.perspective.transform_point_2d(segment.ctrl.to())); } } } Some(segment) } } impl PerspectivePathIter where I: Iterator, { #[inline] pub fn new(iter: I, perspective: &Perspective) -> PerspectivePathIter { PerspectivePathIter { iter, perspective: *perspective, } } }