geometry.rs

  1use super::scene::{Path, PathVertex};
  2use crate::color::ColorU;
  3pub use pathfinder_geometry::*;
  4use rect::RectF;
  5use vector::{vec2f, Vector2F};
  6
  7pub struct PathBuilder {
  8    vertices: Vec<PathVertex>,
  9    start: Vector2F,
 10    current: Vector2F,
 11    contour_count: usize,
 12    bounds: RectF,
 13}
 14
 15enum PathVertexKind {
 16    Solid,
 17    Quadratic,
 18}
 19
 20impl PathBuilder {
 21    pub fn new() -> Self {
 22        Self {
 23            vertices: Vec::new(),
 24            start: vec2f(0., 0.),
 25            current: vec2f(0., 0.),
 26            contour_count: 0,
 27            bounds: RectF::default(),
 28        }
 29    }
 30
 31    pub fn reset(&mut self, point: Vector2F) {
 32        self.vertices.clear();
 33        self.start = point;
 34        self.current = point;
 35        self.contour_count = 0;
 36    }
 37
 38    pub fn line_to(&mut self, point: Vector2F) {
 39        self.contour_count += 1;
 40        if self.contour_count > 1 {
 41            self.push_triangle(self.start, self.current, point, PathVertexKind::Solid);
 42        }
 43
 44        self.current = point;
 45    }
 46
 47    pub fn curve_to(&mut self, point: Vector2F, ctrl: Vector2F) {
 48        self.contour_count += 1;
 49        if self.contour_count > 1 {
 50            self.push_triangle(self.start, self.current, point, PathVertexKind::Solid);
 51        }
 52
 53        self.push_triangle(self.current, ctrl, point, PathVertexKind::Quadratic);
 54        self.current = point;
 55    }
 56
 57    pub fn build(self, color: ColorU) -> Path {
 58        Path {
 59            bounds: self.bounds,
 60            color,
 61            vertices: self.vertices,
 62        }
 63    }
 64
 65    fn push_triangle(&mut self, a: Vector2F, b: Vector2F, c: Vector2F, kind: PathVertexKind) {
 66        if self.vertices.is_empty() {
 67            self.bounds = RectF::new(a, Vector2F::zero());
 68        }
 69        self.bounds = self.bounds.union_point(a).union_point(b).union_point(c);
 70
 71        match kind {
 72            PathVertexKind::Solid => {
 73                self.vertices.push(PathVertex {
 74                    xy_position: a,
 75                    st_position: vec2f(0., 1.),
 76                });
 77                self.vertices.push(PathVertex {
 78                    xy_position: b,
 79                    st_position: vec2f(0., 1.),
 80                });
 81                self.vertices.push(PathVertex {
 82                    xy_position: c,
 83                    st_position: vec2f(0., 1.),
 84                });
 85            }
 86            PathVertexKind::Quadratic => {
 87                self.vertices.push(PathVertex {
 88                    xy_position: a,
 89                    st_position: vec2f(0., 0.),
 90                });
 91                self.vertices.push(PathVertex {
 92                    xy_position: b,
 93                    st_position: vec2f(0.5, 0.),
 94                });
 95                self.vertices.push(PathVertex {
 96                    xy_position: c,
 97                    st_position: vec2f(1., 1.),
 98                });
 99            }
100        }
101    }
102}