[][src]Module lyon_path::iterator

Tools to iterate over paths.

Lyon path iterators

Overview

This module provides a collection of traits to extend the Iterator trait when iterating over paths.

Examples

extern crate lyon_path;
use lyon_path::iterator::*;
use lyon_path::math::{point, vector};
use lyon_path::{PathEvent, SvgEvent, FlattenedEvent};

fn main() {
    let events = vec![
        SvgEvent::MoveTo(point(1.0, 1.0)),
        SvgEvent::RelativeQuadraticTo(vector(4.0, 5.0), vector(-1.0, 4.0)),
        SvgEvent::CubicTo(point(3.0, 0.0), point(3.0, 1.0), point(10.0, -3.0)),
        SvgEvent::Close,
    ];

    // A simple std::iter::Iterator<SvgEvent>,
    let simple_iter = events.iter().cloned();

    // Make it a SvgIterator (keeps tracks of the path state).
    let svg_path_iter = SvgPathIter::new(simple_iter);

    // Make it a PathEvent iterator.
    let path_iter = svg_path_iter.path_events();

    // Make it an iterator over even simpler primitives: FlattenedEvent,
    // which do not contain any curve. To do so we approximate each curve
    // linear segments according to a tolerance threshold which controls
    // the tradeoff between fidelity of the approximation and amount of
    // generated events. Let's use a tolerance threshold of 0.01.
    // The beauty of this approach is that the flattening happens lazily
    // while iterating without allocating memory for the path.
    let flattened_iter = path_iter.flattened(0.01);

    for evt in flattened_iter {
        match evt {
            FlattenedEvent::MoveTo(p) => { println!(" - move to {:?}", p); }
            FlattenedEvent::Line(segment) => { println!(" - line {:?}", segment); }
            FlattenedEvent::Close(segment) => { println!(" - close {:?}", segment); }
        }
    }
}

An equivalent (shorter) version of the above code takes advantage of the fact you can get a flattening iterator directly from an SvgIterator:

extern crate lyon_path;
use lyon_path::iterator::*;
use lyon_path::math::{point, vector};
use lyon_path::SvgEvent;

fn main() {
    let events = vec![
        SvgEvent::MoveTo(point(1.0, 1.0)),
        SvgEvent::RelativeQuadraticTo(vector(4.0, 5.0), vector(-1.0, 4.0)),
        SvgEvent::SmoothCubicTo(point(3.0, 1.0), point(10.0, -3.0)),
        SvgEvent::Close,
    ];

    for evt in SvgPathIter::new(events.iter().cloned()).flattened(0.01) {
        // ...
    }
}

Sometimes, working with segments directly without dealing with MoveTo/Close events can be more convenient:

extern crate lyon_path;
use lyon_path::iterator::*;
use lyon_path::math::{point, vector};
use lyon_path::geom::BezierSegment;
use lyon_path::Path;

fn main() {
    // In practice it is more common to iterate over Path objects than vectors
    // of SVG commands (the former can be constructed from the latter).
    let mut builder = Path::builder();
    builder.move_to(point(1.0, 1.0));
    builder.line_to(point(2.0, 1.0));
    builder.quadratic_bezier_to(point(2.0, 2.0), point(1.0, 2.0));
    builder.cubic_bezier_to(point(0.0, 2.0), point(0.0, 0.0), point(1.0, 0.0));
    let path = builder.build();

    // Iterate over bézier segments directly.
    for segment in path.iter().bezier_segments() {
        match segment {
            BezierSegment::Linear(segment) => { println!("{:?}", segment); }
            BezierSegment::Quadratic(segment) => { println!("{:?}", segment); }
            BezierSegment::Cubic(segment) => { println!("{:?}", segment); }
        }
    }

    // It is also possible to iterate over line segments directly with flattened paths.
    for segment in path.iter().flattened(0.1).line_segments() {
        println!("line segment {:?} -> {:?}", segment.from, segment.to);
    }
}

Chaining the provided iterators allow performing some path manipulations lazily without allocating actual path objects to hold the result of the transformations.

extern crate lyon_path;
use lyon_path::iterator::*;
use lyon_path::geom::euclid::{Angle, Transform2D};
use lyon_path::math::point;
use lyon_path::Path;

fn main() {
    // In practice it is more common to iterate over Path objects than vectors
    // of SVG commands (the former can be constructed from the latter).
    let mut builder = Path::builder();
    builder.move_to(point(1.0, 1.0));
    builder.line_to(point(2.0, 1.0));
    builder.quadratic_bezier_to(point(2.0, 2.0), point(1.0, 2.0));
    builder.cubic_bezier_to(point(0.0, 2.0), point(0.0, 0.0), point(1.0, 0.0));
    builder.close();
    let path = builder.build();

    let mut transform = Transform2D::create_rotation(Angle::radians(1.0));

    for evt in path.iter().transformed(&transform).bezier_segments() {
        // ...
    }
}

Structs

BezierSegments

Turns an iterator of PathEvent into an iterator of BezierSegment<f32>.

Flattened

An iterator that consumes PathEvent iterator and yields FlattenedEvents.

FromPolyline

An iterator that consumes an iterator of Points and produces FlattenedEvents.

LineSegments

Turns an iterator of FlattenedEvent into an iterator of LineSegment<f32>.

PathEvents

Turns an iterator of SVG path commands into an iterator of PathEvent.

SvgPathIter

An adapter iterator that implements SvgIterator on top of an Iterator<Item=SvgEvent>.

Transformed

Applies a 2D transform to a path iterator and yields the resulting path iterator.

Traits

FlattenedIterator

An extension to the common Iterator interface, that adds information which is useful when chaining path-specific iterators.

PathIterator

An extension trait for PathEvent iterators.

QuadraticPathIterator

An extension to the common Iterator interface, that adds information which is useful when chaining path-specific iterators.

SvgIterator

An extension to the common Iterator interface, that adds information which is useful when chaining path-specific iterators.