hex_renderer 0.2.6

Renderer for patterns in hexcasting (a mod for minecraft)
Documentation
use tiny_skia::{Color, Paint, Path, PathBuilder, Pixmap, Shader, Stroke, Transform};

use super::HexCoord;

pub struct LineDrawer<'a> {
    prev_point: HexCoord,
    paths: Vec<(Path, Stroke, Paint<'a>)>,
    priority_paths: Vec<(Path, Stroke, Paint<'a>)>,
    path: PathBuilder,
    stroke: Stroke,
    paint: Paint<'a>,
}
impl<'a> LineDrawer<'a> {
    pub fn new(start_point: HexCoord, stroke: Stroke, paint: Paint<'a>) -> Self {
        let mut path = PathBuilder::new();
        path.move_to(start_point.0, start_point.1);
        Self {
            prev_point: start_point,
            paths: Vec::new(),
            priority_paths: Vec::new(),
            path,
            stroke,
            paint,
        }
    }
    pub fn line_to(&mut self, point: HexCoord) {
        self.prev_point = point;
        self.path.line_to(point.0, point.1);
    }

    fn new_path(&mut self, start_point: HexCoord, mut stroke: Stroke, mut paint: Paint<'a>) {
        let mut tmp_path = PathBuilder::new();
        tmp_path.move_to(start_point.0, start_point.1);

        self.prev_point = start_point;

        std::mem::swap(&mut tmp_path, &mut self.path);
        std::mem::swap(&mut paint, &mut self.paint);
        std::mem::swap(&mut stroke, &mut self.stroke);
        if let Some(path) = tmp_path.finish() {
            self.paths.push((path, stroke, paint));
        }
    }

    pub fn move_to(&mut self, point: HexCoord) {
        self.new_path(point, self.stroke.clone(), self.paint.clone());
    }

    pub fn set_color(&mut self, color: Color) {
        self.new_path(self.prev_point, self.stroke.clone(), self.paint.clone());
        self.paint.set_color(color);
    }

    pub fn set_shader(&mut self, shader: Shader<'a>) {
        let mut paint = self.paint.clone();
        paint.shader = shader;
        self.new_path(self.prev_point, self.stroke.clone(), paint);
    }
    pub fn set_width(&mut self, width: f32) {
        self.new_path(self.prev_point, self.stroke.clone(), self.paint.clone());
        self.stroke.width = width;
    }

    pub fn set_stroke(&mut self, stroke: Stroke) {
        self.new_path(self.prev_point, stroke, self.paint.clone());
    }

    pub fn priority_finish(&mut self) {
        let mut tmp = PathBuilder::new();
        tmp.move_to(self.prev_point.0, self.prev_point.1);

        std::mem::swap(&mut tmp, &mut self.path);

        if let Some(path) = tmp.finish() {
            self.priority_paths
                .push((path, self.stroke.clone(), self.paint.clone()));
        }
    }

    pub fn draw(&mut self, pixmap: &mut Pixmap) {
        self.new_path(self.prev_point, self.stroke.clone(), self.paint.clone());
        for (path, stroke, paint) in self.paths.iter().rev() {
            pixmap.stroke_path(path, paint, stroke, Transform::identity(), None)
        }
    }
    pub fn draw_priority(self, pixmap: &mut Pixmap) {
        for (path, stroke, paint) in self.priority_paths {
            pixmap.stroke_path(&path, &paint, &stroke, Transform::identity(), None)
        }
    }
    pub fn draw_all(mut self, pixmap: &mut Pixmap) {
        self.draw(pixmap);
        self.draw_priority(pixmap);
    }
}