pub fn path_to_dashed_lines<PathIn, PathOut, DashPattern>(path_in: &PathIn, dash_pattern: DashPattern, pattern_offset: f64) -> Vec<PathOut> 
where
PathIn:         BezierPath,
PathOut:        BezierPathFactory<Point=PathIn::Point>,
DashPattern:    Iterator<Item=f64> {
    // Create the resulting set of paths (most will have just a single curve in them)
    let mut output_paths        = vec![];

    // Cycle the dash pattern
    let dash_pattern            = dash_pattern.collect::<Vec<_>>();
    let dash_pattern            = if dash_pattern.len() == 0 { vec![1.0] } else { dash_pattern };
    let mut dash_pos            = 0;
    let max_dash_pos            = dash_pattern.len() - 1;

    // Initial remaining length is that of the first dash in the pattern
    let mut remaining_length    = dash_pattern[dash_pos];

    // We alternate between drawing and not drawing dashes
    let mut draw_dash           = false;

    // Apply the dash pattern offset
    if pattern_offset > 0.0 {
        let mut remaining_offset = pattern_offset;

        while remaining_offset > 0.0 {
            let dash_length     = remaining_length;

            if dash_length > remaining_offset {
                remaining_length -= remaining_offset;
                break;
            } else {
                remaining_offset    -= dash_length;

                dash_pos            = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 };
                remaining_length    = dash_pattern[dash_pos];
                draw_dash           = !draw_dash;
            }
        }
    }

    // Generate dashed lines for each path segment
    let mut start_point         = path_in.start_point();
    let mut current_path_start  = start_point;
    let mut current_path_points = vec![];

    for (cp1, cp2, end_point) in path_in.points() {
        // Create a curve for this section
        let curve                   = Curve::from_points(start_point, (cp1, cp2), end_point);

        if remaining_length <= 0.0 {
            dash_pos                = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 };
            remaining_length        = dash_pattern[dash_pos];
            draw_dash               = !draw_dash;
        }

        // Walk it, starting with the remaining length and then moving on according to the dash pattern
        let mut next_length     = remaining_length;
        let curve_dash_pattern  = iter::once(next_length).chain(dash_pattern.iter().cycle().skip(dash_pos+1).cloned());

        for section in walk_curve_evenly(&curve, 1.0, 0.05).vary_by(curve_dash_pattern) {
            // Toggle if we show the dash or not
            draw_dash                       = !draw_dash;

            // walk_curve_evenly uses chord lengths (TODO: arc lengths would be better)
            let section_length              = chord_length(&section);

            // Update the remaining length
            remaining_length                = next_length - section_length;

            // Add the dash to the current path
            let (section_cp1, section_cp2)  = section.control_points();
            let section_end_point           = section.end_point();
            current_path_points.push((section_cp1, section_cp2, section_end_point));

            // If there's enough space for the whole dash, invert the 'draw_dash' state and add the current path to the result
            if remaining_length < 0.01 {
                // Add this dash to the output
                if draw_dash {
                    output_paths.push(PathOut::from_points(current_path_start, current_path_points));
                }

                // Clear the current path
                current_path_start  = section_end_point;
                current_path_points = vec![];
            }

            // Fetch the next length from the dash pattern
            dash_pos                        = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 };
            next_length                     = dash_pattern[dash_pos];
        }

        // Walk back a dash position (remaining_length is the distance left in this dash)
        dash_pos    = if dash_pos == 0 { max_dash_pos } else { dash_pos-1 };
        draw_dash   = !draw_dash;

        // The start point of the next curve in this path is the end point of this one
        start_point     = end_point;
    }

    // If there's any remaining parts of the current path, add them
    if current_path_points.len() > 0 && draw_dash {
        output_paths.push(PathOut::from_points(current_path_start, current_path_points));
    }

    output_paths
}
///
/// Converts a bezier path to a set of paths by a dash patter
///
Converts a bezier path to a set of paths by a dash patter
Converts a bezier path to a set of paths by a dash patter
pub fn path_to_dashed_lines<PathIn, PathOut, DashPattern>(path_in: &PathIn, dash_pattern: DashPattern, pattern_offset: f64) -> Vec<PathOut> 
where
PathIn:         BezierPath,
PathOut:        BezierPathFactory<Point=PathIn::Point>,
DashPattern:    Iterator<Item=f64> {
    // Create the resulting set of paths (most will have just a single curve in them)
    let mut output_paths        = vec![];
    // Cycle the dash pattern
    let dash_pattern            = dash_pattern.collect::<Vec<_>>();
    let dash_pattern            = if dash_pattern.len() == 0 { vec![1.0] } else { dash_pattern };
    let mut dash_pos            = 0;
    let max_dash_pos            = dash_pattern.len() - 1;
    // Initial remaining length is that of the first dash in the pattern
    let mut remaining_length    = dash_pattern[dash_pos];
    // We alternate between drawing and not drawing dashes
    let mut draw_dash           = false;
    // Apply the dash pattern offset
    if pattern_offset > 0.0 {
        let mut remaining_offset = pattern_offset;
        while remaining_offset > 0.0 {
            let dash_length     = remaining_length;
            if dash_length > remaining_offset {
                remaining_length -= remaining_offset;
                break;
            } else {
                remaining_offset    -= dash_length;
                dash_pos            = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 };
                remaining_length    = dash_pattern[dash_pos];
                draw_dash           = !draw_dash;
            }
        }
    }
    // Generate dashed lines for each path segment
    let mut start_point         = path_in.start_point();
    let mut current_path_start  = start_point;
    let mut current_path_points = vec![];
    for (cp1, cp2, end_point) in path_in.points() {
        // Create a curve for this section
        let curve                   = Curve::from_points(start_point, (cp1, cp2), end_point);
        if remaining_length <= 0.0 {
            dash_pos                = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 };
            remaining_length        = dash_pattern[dash_pos];
            draw_dash               = !draw_dash;
        }
        // Walk it, starting with the remaining length and then moving on according to the dash pattern
        let mut next_length     = remaining_length;
        let curve_dash_pattern  = iter::once(next_length).chain(dash_pattern.iter().cycle().skip(dash_pos+1).cloned());
        for section in walk_curve_evenly(&curve, 1.0, 0.05).vary_by(curve_dash_pattern) {
            // Toggle if we show the dash or not
            draw_dash                       = !draw_dash;
            // walk_curve_evenly uses chord lengths (TODO: arc lengths would be better)
            let section_length              = chord_length(&section);
            // Update the remaining length
            remaining_length                = next_length - section_length;
            // Add the dash to the current path
            let (section_cp1, section_cp2)  = section.control_points();
            let section_end_point           = section.end_point();
            current_path_points.push((section_cp1, section_cp2, section_end_point));
            // If there's enough space for the whole dash, invert the 'draw_dash' state and add the current path to the result
            if remaining_length < 0.01 {
                // Add this dash to the output
                if draw_dash {
                    output_paths.push(PathOut::from_points(current_path_start, current_path_points));
                }
                // Clear the current path
                current_path_start  = section_end_point;
                current_path_points = vec![];
            }
            // Fetch the next length from the dash pattern
            dash_pos                        = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 };
            next_length                     = dash_pattern[dash_pos];
        }
        // Walk back a dash position (remaining_length is the distance left in this dash)
        dash_pos    = if dash_pos == 0 { max_dash_pos } else { dash_pos-1 };
        draw_dash   = !draw_dash;
        // The start point of the next curve in this path is the end point of this one
        start_point     = end_point;
    }
    // If there's any remaining parts of the current path, add them
    if current_path_points.len() > 0 && draw_dash {
        output_paths.push(PathOut::from_points(current_path_start, current_path_points));
    }
    output_paths
}
pub fn path_to_dashed_lines < PathIn , PathOut , DashPattern > ( path_in : & PathIn , dash_pattern : DashPattern , pattern_offset : f64 ) -> Vec < PathOut > where PathIn : BezierPath , PathOut : BezierPathFactory < Point = PathIn :: Point > , DashPattern : Iterator < Item = f64 > { // Create the resulting set of paths (most will have just a single curve in them) let mut output_paths = vec ! [ ] ; // Cycle the dash pattern let dash_pattern = dash_pattern . collect :: < Vec < _ > > ( ) ; let dash_pattern = if dash_pattern . len ( ) == 0 { vec ! [ 1.0 ] } else { dash_pattern } ; let mut dash_pos = 0 ; let max_dash_pos = dash_pattern . len ( ) - 1 ; // Initial remaining length is that of the first dash in the pattern let mut remaining_length = dash_pattern [ dash_pos ] ; // We alternate between drawing and not drawing dashes let mut draw_dash = false ; // Apply the dash pattern offset if pattern_offset > 0.0 { let mut remaining_offset = pattern_offset ; while remaining_offset > 0.0 { let dash_length = remaining_length ; if dash_length > remaining_offset { remaining_length -= remaining_offset ; break ; } else { remaining_offset -= dash_length ; dash_pos = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 } ; remaining_length = dash_pattern [ dash_pos ] ; draw_dash = ! draw_dash ; } } } // Generate dashed lines for each path segment let mut start_point = path_in . start_point ( ) ; let mut current_path_start = start_point ; let mut current_path_points = vec ! [ ] ; for ( cp1 , cp2 , end_point ) in path_in . points ( ) { // Create a curve for this section let curve = Curve :: from_points ( start_point , ( cp1 , cp2 ) , end_point ) ; if remaining_length <= 0.0 { dash_pos = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 } ; remaining_length = dash_pattern [ dash_pos ] ; draw_dash = ! draw_dash ; } // Walk it, starting with the remaining length and then moving on according to the dash pattern let mut next_length = remaining_length ; let curve_dash_pattern = iter :: once ( next_length ) . chain ( dash_pattern . iter ( ) . cycle ( ) . skip ( dash_pos + 1 ) . cloned ( ) ) ; for section in walk_curve_evenly ( & curve , 1.0 , 0.05 ) . vary_by ( curve_dash_pattern ) { // Toggle if we show the dash or not draw_dash = ! draw_dash ; // walk_curve_evenly uses chord lengths (TODO: arc lengths would be better) let section_length = chord_length ( & section ) ; // Update the remaining length remaining_length = next_length - section_length ; // Add the dash to the current path let ( section_cp1 , section_cp2 ) = section . control_points ( ) ; let section_end_point = section . end_point ( ) ; current_path_points . push ( ( section_cp1 , section_cp2 , section_end_point ) ) ; // If there's enough space for the whole dash, invert the 'draw_dash' state and add the current path to the result if remaining_length < 0.01 { // Add this dash to the output if draw_dash { output_paths . push ( PathOut :: from_points ( current_path_start , current_path_points ) ) ; } // Clear the current path current_path_start = section_end_point ; current_path_points = vec ! [ ] ; } // Fetch the next length from the dash pattern dash_pos = if dash_pos >= max_dash_pos { 0 } else { dash_pos + 1 } ; next_length = dash_pattern [ dash_pos ] ; } // Walk back a dash position (remaining_length is the distance left in this dash) dash_pos = if dash_pos == 0 { max_dash_pos } else { dash_pos - 1 } ; draw_dash = ! draw_dash ; // The start point of the next curve in this path is the end point of this one start_point = end_point ; } // If there's any remaining parts of the current path, add them if current_path_points . len ( ) > 0 && draw_dash { output_paths . push ( PathOut :: from_points ( current_path_start , current_path_points ) ) ; } output_paths }
Converts a bezier path to a set of paths by a dash patter
Converts a bezier path to a set of paths by a dash patter
path_in
&PathIn
dash_pattern
DashPattern
pattern_offset
f64