Skip to main content

native/skia_native/src/generated_path.rs

// Generated by mix skia.codegen. Do not edit by hand.

fn build_path(path_term: Term) -> NifResult<skia_safe::Path> {
    if let Ok((tag, svg)) = path_term.decode::<(Atom, String)>() {
        if tag == atoms::svg() {
            return skia_safe::Path::from_svg(svg).ok_or(rustler::Error::BadArg);
        }
    }
    if let Ok((tag, segments)) = path_term.decode::<(Atom, Vec<Term>)>() {
        if tag == atoms::p() {
            return build_compact_path(segments);
        }
    }
    if let Ok(svg_term) = path_term.map_get(atoms::svg()) {
        if let Ok(svg) = svg_term.decode::<String>() {
            return skia_safe::Path::from_svg(svg).ok_or(rustler::Error::BadArg);
        }
    }
    let segments = path_term.map_get(atoms::segments())?.decode::<Vec<Term>>()?;
    let mut builder = PathBuilder::new();
    for segment in segments.into_iter().rev() {
        if let Ok(op) = segment.decode::<Atom>() {
            if op == atoms::close() {
                builder.close();
            }
        } else if let Ok((op, x, y)) = segment.decode::<(Atom, f64, f64)>() {
            if op == atoms::move_to() {
                builder.move_to((x as f32, y as f32));
            } else if op == atoms::line_to() {
                builder.line_to((x as f32, y as f32));
            } else if op == atoms::r_move_to() {
                builder.r_move_to((x as f32, y as f32));
            } else if op == atoms::r_line_to() {
                builder.r_line_to((x as f32, y as f32));
            }
        } else if let Ok((op, cx, cy, x, y)) = segment
            .decode::<(Atom, f64, f64, f64, f64)>()
        {
            if op == atoms::quad_to() {
                builder.quad_to((cx as f32, cy as f32), (x as f32, y as f32));
            } else if op == atoms::r_quad_to() {
                builder.r_quad_to((cx as f32, cy as f32), (x as f32, y as f32));
            }
        } else if let Ok((op, cx, cy, x, y, weight)) = segment
            .decode::<(Atom, f64, f64, f64, f64, f64)>()
        {
            if op == atoms::conic_to() {
                builder
                    .conic_to(
                        (cx as f32, cy as f32),
                        (x as f32, y as f32),
                        weight as f32,
                    );
            } else if op == atoms::r_conic_to() {
                builder
                    .r_conic_to(
                        (cx as f32, cy as f32),
                        (x as f32, y as f32),
                        weight as f32,
                    );
            }
        } else if let Ok((op, x, y, width, height, start, arc_opts)) = segment
            .decode::<(Atom, f64, f64, f64, f64, f64, Term)>()
        {
            if op == atoms::arc_to() {
                let (sweep, force_move_to) = arc_opts.decode::<(f64, bool)>()?;
                builder
                    .arc_to(
                        Rect::from_xywh(x as f32, y as f32, width as f32, height as f32),
                        start as f32,
                        sweep as f32,
                        force_move_to,
                    );
            }
        } else if let Ok((op, rx, ry, x_axis_rotate, arc_opts)) = segment
            .decode::<(Atom, f64, f64, f64, Term)>()
        {
            if op == atoms::r_arc_to() {
                let (large_arc, sweep, dx, dy) = arc_opts
                    .decode::<(bool, Atom, f64, f64)>()?;
                let arc_size = if large_arc {
                    skia_safe::path_builder::ArcSize::Large
                } else {
                    skia_safe::path_builder::ArcSize::Small
                };
                builder
                    .r_arc_to(
                        (rx as f32, ry as f32),
                        x_axis_rotate as f32,
                        arc_size,
                        decode_path_direction(sweep)?,
                        (dx as f32, dy as f32),
                    );
            }
        } else if let Ok((op, x, y, width, height, rx, ry)) = segment
            .decode::<(Atom, f64, f64, f64, f64, f64, f64)>()
        {
            if op == atoms::rrect() {
                builder
                    .add_rrect(
                        RRect::new_rect_xy(
                            Rect::from_xywh(
                                x as f32,
                                y as f32,
                                width as f32,
                                height as f32,
                            ),
                            rx as f32,
                            ry as f32,
                        ),
                        None,
                        None,
                    );
            }
        } else if let Ok((op, c1x, c1y, c2x, c2y, x, y)) = segment
            .decode::<(Atom, f64, f64, f64, f64, f64, f64)>()
        {
            if op == atoms::cubic_to() {
                builder
                    .cubic_to(
                        (c1x as f32, c1y as f32),
                        (c2x as f32, c2y as f32),
                        (x as f32, y as f32),
                    );
            } else if op == atoms::r_cubic_to() {
                builder
                    .r_cubic_to(
                        (c1x as f32, c1y as f32),
                        (c2x as f32, c2y as f32),
                        (x as f32, y as f32),
                    );
            }
        }
    }
    Ok(builder.detach())
}
fn build_compact_path(segments: Vec<Term>) -> NifResult<skia_safe::Path> {
    let mut builder = PathBuilder::new();
    for segment in segments {
        if let Ok((14,)) = segment.decode::<(i64,)>() {
            builder.close();
        } else if let Ok((op, x, y)) = segment.decode::<(i64, f64, f64)>() {
            match op {
                1 => {
                    builder.move_to((x as f32, y as f32));
                }
                2 => {
                    builder.line_to((x as f32, y as f32));
                }
                6 => {
                    builder.r_move_to((x as f32, y as f32));
                }
                7 => {
                    builder.r_line_to((x as f32, y as f32));
                }
                _ => {}
            };
        } else if let Ok((op, cx, cy, x, y)) = segment
            .decode::<(i64, f64, f64, f64, f64)>()
        {
            match op {
                3 => {
                    builder.quad_to((cx as f32, cy as f32), (x as f32, y as f32));
                }
                8 => {
                    builder.r_quad_to((cx as f32, cy as f32), (x as f32, y as f32));
                }
                _ => {}
            };
        } else if let Ok((op, cx, cy, x, y, weight)) = segment
            .decode::<(i64, f64, f64, f64, f64, f64)>()
        {
            match op {
                4 => {
                    builder
                        .conic_to(
                            (cx as f32, cy as f32),
                            (x as f32, y as f32),
                            weight as f32,
                        );
                }
                9 => {
                    builder
                        .r_conic_to(
                            (cx as f32, cy as f32),
                            (x as f32, y as f32),
                            weight as f32,
                        );
                }
                _ => {}
            };
        } else if let Ok((op, c1x, c1y, c2x, c2y, x, y)) = segment
            .decode::<(i64, f64, f64, f64, f64, f64, f64)>()
        {
            if op == 5 {
                builder
                    .cubic_to(
                        (c1x as f32, c1y as f32),
                        (c2x as f32, c2y as f32),
                        (x as f32, y as f32),
                    );
            } else if op == 10 {
                builder
                    .r_cubic_to(
                        (c1x as f32, c1y as f32),
                        (c2x as f32, c2y as f32),
                        (x as f32, y as f32),
                    );
            } else if op == 13 {
                builder
                    .add_rrect(
                        RRect::new_rect_xy(
                            Rect::from_xywh(
                                c1x as f32,
                                c1y as f32,
                                c2x as f32,
                                c2y as f32,
                            ),
                            x as f32,
                            y as f32,
                        ),
                        None,
                        None,
                    );
            }
        } else if let Ok((op, x, y, width, height, start, arc_opts)) = segment
            .decode::<(i64, f64, f64, f64, f64, f64, Term)>()
        {
            if op == 11 {
                let (sweep, force_move_to) = arc_opts.decode::<(f64, bool)>()?;
                builder
                    .arc_to(
                        Rect::from_xywh(x as f32, y as f32, width as f32, height as f32),
                        start as f32,
                        sweep as f32,
                        force_move_to,
                    );
            }
        } else if let Ok((op, rx, ry, x_axis_rotate, arc_opts)) = segment
            .decode::<(i64, f64, f64, f64, Term)>()
        {
            if op == 12 {
                let (large_arc, sweep, dx, dy) = arc_opts
                    .decode::<(bool, Atom, f64, f64)>()?;
                let arc_size = if large_arc {
                    skia_safe::path_builder::ArcSize::Large
                } else {
                    skia_safe::path_builder::ArcSize::Small
                };
                builder
                    .r_arc_to(
                        (rx as f32, ry as f32),
                        x_axis_rotate as f32,
                        arc_size,
                        decode_path_direction(sweep)?,
                        (dx as f32, dy as f32),
                    );
            }
        }
    }
    Ok(builder.detach())
}
fn decode_path_direction(value: Atom) -> NifResult<PathDirection> {
    if value == atoms::cw() {
        Ok(PathDirection::CW)
    } else if value == atoms::ccw() {
        Ok(PathDirection::CCW)
    } else {
        Err(rustler::Error::BadArg)
    }
}