svg2gerber/src/path_convert.rs

47 wiersze
1.4 KiB
Rust

// from https://raw.githubusercontent.com/nical/lyon/master/examples/svg_render/src/path_convert.rs
use std::iter;
use std::slice;
use lyon::math::Point;
use lyon::path::PathEvent;
use lyon::path::iterator::PathIter;
use usvg::{Path, PathSegment};
fn point(x: f64, y: f64) -> Point {
Point::new(x as f32, y as f32)
}
// Map usvg::PathSegment to lyon::path::PathEvent
fn as_event(ps: &PathSegment) -> PathEvent {
match *ps {
PathSegment::MoveTo { x, y } => PathEvent::MoveTo(point(x, y)),
PathSegment::LineTo { x, y } => PathEvent::LineTo(point(x, y)),
PathSegment::CurveTo { x1, y1, x2, y2, x, y, } => {
PathEvent::CubicTo(point(x1, y1), point(x2, y2), point(x, y))
}
PathSegment::ClosePath => PathEvent::Close,
}
}
pub struct PathConv<'a>(SegmentIter<'a>);
// Alias for the iterator returned by usvg::Path::iter()
type SegmentIter<'a> = slice::Iter<'a, PathSegment>;
// Alias for our `interface` iterator
type PathConvIter<'a> = iter::Map<SegmentIter<'a>, fn(&PathSegment) -> PathEvent>;
// Provide a function which gives back a PathIter which is compatible with
// tesselators, so we don't have to implement the PathIterator trait
impl<'a> PathConv<'a> {
pub fn path_iter(self) -> PathIter<PathConvIter<'a>> {
PathIter::new(self.0.map(as_event))
}
}
pub fn convert_path<'a>(p: &'a Path) -> PathConv<'a> {
PathConv(p.segments.iter())
}