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}