raqote 0.1.2

2D graphics library
Documentation
use crate::path_builder::*;

use euclid::{Point2D, Vector2D};

type Point = Point2D<f32>;

use lyon_geom::LineSegment;


pub fn dash_path(path: &Path, dash_array: &[f32], dash_offset: f32) -> Path {
    let mut dashed = PathBuilder::new();

    let mut cur_pt = Point::zero();
    let mut current_dash = 0;
    let mut start_point = Point::zero();
    let mut remaining_dash_length = dash_array[current_dash % dash_array.len()];
    let mut dash_on = true;

    // adjust our position in the dash array by the dash offset
    while dash_offset > remaining_dash_length {
        remaining_dash_length = dash_array[current_dash % dash_array.len()];
        current_dash += 1;
        dash_on = !dash_on;
    }
    remaining_dash_length -= dash_offset;

    for op in &path.ops {
        match *op {
            PathOp::MoveTo(pt) => {
                cur_pt = pt;
                start_point = pt;
                dashed.move_to(pt.x, pt.y);
            }
            PathOp::LineTo(pt) => {
                let mut start = cur_pt;
                let line = LineSegment { from: start, to: pt};
                let mut len = line.length();
                let lv = line.to_vector().normalize();
                while len > remaining_dash_length {
                    let seg = start + lv * remaining_dash_length;
                    if dash_on {
                        dashed.line_to(seg.x, seg.y);
                    } else {
                        dashed.move_to(seg.x, seg.y);
                    }
                    dash_on = !dash_on;
                    current_dash += 1;
                    len -= remaining_dash_length;
                    remaining_dash_length = dash_array[current_dash % dash_array.len()];
                    start = seg;
                }
                if dash_on {
                    dashed.line_to(pt.x, pt.y);
                } else {
                    dashed.move_to(pt.x, pt.y);
                }
                remaining_dash_length -= len;

                cur_pt = pt;

            }
            PathOp::Close => {
                let line = LineSegment { from: cur_pt, to: start_point};
                let mut len = line.length();
                let lv = line.to_vector().normalize();
                while len > remaining_dash_length {
                    let seg = lv * remaining_dash_length;
                    if dash_on {
                        dashed.line_to(seg.x, seg.y);
                    } else {
                        dashed.move_to(seg.x, seg.y);
                    }
                    dash_on = !dash_on;
                    current_dash += 1;
                    len -= remaining_dash_length;
                    remaining_dash_length = dash_array[current_dash % dash_array.len()];
                }
                if dash_on {
                    dashed.close();
                }
                remaining_dash_length -= len;
            },
            PathOp::QuadTo(..) => {
                panic!("Only flat paths handled")
            }
            PathOp::CubicTo(..) => {
                panic!("Only flat paths handled")
            }
        }
    }
    dashed.finish()
}