1use crate::{Point, Px, Rect, ids::PathId, scene::DashPatternV1};
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4pub enum PathCommand {
5 MoveTo(Point),
6 LineTo(Point),
7 QuadTo {
8 ctrl: Point,
9 to: Point,
10 },
11 CubicTo {
12 ctrl1: Point,
13 ctrl2: Point,
14 to: Point,
15 },
16 Close,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
20pub enum FillRule {
21 #[default]
22 NonZero,
23 EvenOdd,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq)]
27pub struct FillStyle {
28 pub rule: FillRule,
29}
30
31impl Default for FillStyle {
32 fn default() -> Self {
33 Self {
34 rule: FillRule::NonZero,
35 }
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq)]
40pub struct StrokeStyle {
41 pub width: Px,
42}
43
44impl Default for StrokeStyle {
45 fn default() -> Self {
46 Self { width: Px(1.0) }
47 }
48}
49
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
51pub enum StrokeJoinV1 {
52 #[default]
53 Miter,
54 Bevel,
55 Round,
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
59pub enum StrokeCapV1 {
60 #[default]
61 Butt,
62 Square,
63 Round,
64}
65
66#[derive(Debug, Clone, Copy, PartialEq)]
67pub struct StrokeStyleV2 {
68 pub width: Px,
69 pub join: StrokeJoinV1,
70 pub cap: StrokeCapV1,
71 pub miter_limit: f32,
75 pub dash: Option<DashPatternV1>,
77}
78
79impl Default for StrokeStyleV2 {
80 fn default() -> Self {
81 Self {
82 width: Px(1.0),
83 join: StrokeJoinV1::Miter,
84 cap: StrokeCapV1::Butt,
85 miter_limit: 4.0,
86 dash: None,
87 }
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq)]
92pub enum PathStyle {
93 Fill(FillStyle),
94 Stroke(StrokeStyle),
95 StrokeV2(StrokeStyleV2),
96}
97
98#[derive(Debug, Clone, Copy, PartialEq)]
99pub struct PathConstraints {
100 pub scale_factor: f32,
102}
103
104impl Default for PathConstraints {
105 fn default() -> Self {
106 Self { scale_factor: 1.0 }
107 }
108}
109
110#[derive(Debug, Default, Clone, Copy, PartialEq)]
111pub struct PathMetrics {
112 pub bounds: Rect,
113}
114
115pub trait PathService {
116 fn prepare(
117 &mut self,
118 commands: &[PathCommand],
119 style: PathStyle,
120 constraints: PathConstraints,
121 ) -> (PathId, PathMetrics);
122
123 fn measure(
124 &mut self,
125 commands: &[PathCommand],
126 style: PathStyle,
127 constraints: PathConstraints,
128 ) -> PathMetrics {
129 let (id, metrics) = self.prepare(commands, style, constraints);
130 self.release(id);
131 metrics
132 }
133
134 fn release(&mut self, path: PathId);
135}