#![allow(clippy::needless_collect)]
use super::bounds::*;
use super::to_curves::*;
use super::super::curve::*;
use super::super::super::geo::*;
use itertools::*;
use std::vec;
use std::iter;
pub trait BezierPath : Geo+Clone+Sized {
type PointIter: Iterator<Item=(Self::Point, Self::Point, Self::Point)>;
fn start_point(&self) -> Self::Point;
fn points(&self) -> Self::PointIter;
#[inline]
fn bounding_box<Bounds: BoundingBox<Point=Self::Point>>(&self) -> Bounds {
path_bounding_box(self)
}
fn fast_bounding_box<Bounds: BoundingBox<Point=Self::Point>>(&self) -> Bounds {
path_fast_bounding_box(self)
}
#[inline]
fn to_curves<Curve: BezierCurveFactory<Point=Self::Point>>(&self) -> Vec<Curve> {
path_to_curves(self).collect()
}
fn reversed<POut: BezierPathFactory<Point=Self::Point>>(&self) -> POut {
let fake_first_point = (Self::Point::origin(), Self::Point::origin(), self.start_point());
let points = self.points();
let points = iter::once(fake_first_point).chain(points);
let reversed_points = points
.tuple_windows()
.map(|((_, _, start_point), (cp1, cp2, _))| (cp2, cp1, start_point))
.collect::<Vec<_>>();
POut::from_points(self.start_point(), reversed_points.into_iter().rev())
}
}
pub trait BezierPathFactory : BezierPath {
fn from_points<FromIter: IntoIterator<Item=(Self::Point, Self::Point, Self::Point)>>(start_point: Self::Point, points: FromIter) -> Self;
fn from_path<FromPath: BezierPath<Point=Self::Point>>(path: &FromPath) -> Self {
Self::from_points(path.start_point(), path.points())
}
}
impl<Point: Clone+Coordinate> Geo for (Point, Vec<(Point, Point, Point)>) {
type Point = Point;
}
impl<Point: Clone+Coordinate> BezierPath for (Point, Vec<(Point, Point, Point)>) {
type PointIter = vec::IntoIter<(Point, Point, Point)>;
fn start_point(&self) -> Self::Point {
self.0
}
fn points(&self) -> Self::PointIter {
self.1.clone().into_iter()
}
}
impl<Point: Clone+Coordinate> BezierPathFactory for (Point, Vec<(Point, Point, Point)>) {
fn from_points<FromIter: IntoIterator<Item=(Self::Point, Self::Point, Self::Point)>>(start_point: Self::Point, points: FromIter) -> Self {
(start_point, points.into_iter().collect())
}
}
pub type SimpleBezierPath = (Coord2, Vec<(Coord2, Coord2, Coord2)>);