1use crate::alloc::Vec;
5use serde::{Deserialize, Serialize};
6
7pub type Transform = euclid::default::Transform2D<f32>;
8pub type Angle = euclid::Angle<f32>;
9
10#[derive(Debug, PartialEq, Clone, Copy)]
12pub struct Rect {
13 pub x: f32,
14 pub y: f32,
15 pub width: f32,
16 pub height: f32,
17}
18
19impl Rect {
20 pub fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
22 Rect {
23 x,
24 y,
25 width,
26 height,
27 }
28 }
29}
30
31#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
33pub struct Point {
34 pub x: f32,
35 pub y: f32,
36}
37
38impl Point {
39 pub fn new(x: f32, y: f32) -> Self {
41 Point { x, y }
42 }
43}
44
45#[derive(Debug, PartialEq, Serialize, Deserialize)]
46pub enum PathOp {
47 MoveTo(Point),
48 LineTo(Point),
49 QuadTo(Point, Point),
50 CubicTo(Point, Point, Point),
51 Arc(Point, f32, f32, f32),
52 Close,
53}
54
55#[derive(Debug, Serialize, Deserialize, Default)]
57pub struct Path {
58 pub ops: Vec<PathOp>,
59 #[serde(skip)]
60 #[cfg(feature = "imports")]
61 pub(crate) ptr: Option<i32>,
62}
63
64impl Path {
65 pub fn rect(rect: &Rect) -> Self {
66 PathBuilder::new().rect(rect).build()
67 }
68}
69
70impl PartialEq for Path {
71 fn eq(&self, other: &Self) -> bool {
72 self.ops == other.ops
73 }
74}
75
76#[derive(Debug, Default)]
78pub struct PathBuilder {
79 path: Path,
80}
81
82impl PathBuilder {
83 pub fn new() -> Self {
85 PathBuilder::default()
86 }
87
88 pub fn move_to(mut self, x: f32, y: f32) -> Self {
90 self.path.ops.push(PathOp::MoveTo(Point::new(x, y)));
91 self
92 }
93
94 pub fn line_to(mut self, x: f32, y: f32) -> Self {
96 self.path.ops.push(PathOp::LineTo(Point::new(x, y)));
97 self
98 }
99
100 pub fn quad_to(mut self, cx: f32, cy: f32, x: f32, y: f32) -> Self {
103 self.path
104 .ops
105 .push(PathOp::QuadTo(Point::new(cx, cy), Point::new(x, y)));
106 self
107 }
108
109 pub fn rect(self, rect: &Rect) -> Self {
111 self.move_to(rect.x, rect.y)
112 .line_to(rect.x + rect.width, rect.y)
113 .line_to(rect.x + rect.width, rect.y + rect.height)
114 .line_to(rect.x, rect.y + rect.height)
115 .close()
116 }
117
118 pub fn cubic_to(mut self, x: f32, y: f32, cx1: f32, cy1: f32, cx2: f32, cy2: f32) -> Self {
121 self.path.ops.push(PathOp::CubicTo(
122 Point::new(x, y),
123 Point::new(cx1, cy1),
124 Point::new(cx2, cy2),
125 ));
126 self
127 }
128
129 pub fn arc(mut self, x: f32, y: f32, radius: f32, start_angle: f32, sweep_angle: f32) -> Self {
134 self.path.ops.push(PathOp::Arc(
135 Point::new(x, y),
136 radius,
137 start_angle,
138 sweep_angle,
139 ));
140 self
141 }
142
143 pub fn close(mut self) -> Self {
145 self.path.ops.push(PathOp::Close);
146 self
147 }
148
149 pub fn build(self) -> Path {
151 #[cfg(feature = "imports")]
152 {
153 use crate::imports::std::encode;
154 let mut path = self.path;
155 path.ptr = Some(unsafe { encode(&path) });
156 path
157 }
158 #[cfg(not(feature = "imports"))]
159 self.path
160 }
161}
162
163#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
165pub struct Color {
166 pub red: f32,
167 pub green: f32,
168 pub blue: f32,
169 pub alpha: f32,
170}
171
172impl Color {
173 pub fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
175 Self {
176 red,
177 green,
178 blue,
179 alpha,
180 }
181 }
182
183 pub fn black() -> Self {
185 Self::new(0.0, 0.0, 0.0, 1.0)
186 }
187
188 pub fn white() -> Self {
190 Self::new(255.0, 255.0, 255.0, 1.0)
191 }
192
193 pub fn red() -> Self {
195 Self::new(255.0, 0.0, 0.0, 1.0)
196 }
197
198 pub fn green() -> Self {
200 Self::new(0.0, 255.0, 0.0, 1.0)
201 }
202
203 pub fn blue() -> Self {
205 Self::new(0.0, 0.0, 255.0, 1.0)
206 }
207}
208
209impl Default for Color {
210 fn default() -> Self {
211 Self::black()
212 }
213}
214
215#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
217pub enum LineCap {
218 Round,
219 Square,
220 #[default]
221 Butt,
222}
223
224#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
226pub enum LineJoin {
227 Round,
228 Bevel,
229 #[default]
230 Miter,
231}
232
233#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
235pub struct StrokeStyle {
236 pub color: Color,
237 pub width: f32,
238 pub cap: LineCap,
239 pub join: LineJoin,
240 pub miter_limit: f32,
241 pub dash_array: Vec<f32>,
242 pub dash_offset: f32,
243}
244
245impl Default for StrokeStyle {
246 fn default() -> Self {
247 Self {
248 color: Default::default(),
249 width: 1.,
250 cap: Default::default(),
251 join: Default::default(),
252 miter_limit: 10.,
253 dash_array: Vec::new(),
254 dash_offset: 0.,
255 }
256 }
257}
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
261pub enum FontWeight {
262 UltraLight = 0,
263 Thin = 1,
264 Light = 2,
265 #[default]
266 Regular = 3,
267 Medium = 4,
268 Semibold = 5,
269 Bold = 6,
270 Heavy = 7,
271 Black = 8,
272}
273
274impl From<u8> for FontWeight {
275 fn from(value: u8) -> Self {
276 match value {
277 0 => FontWeight::UltraLight,
278 1 => FontWeight::Thin,
279 2 => FontWeight::Light,
280 3 => FontWeight::Regular,
281 4 => FontWeight::Medium,
282 5 => FontWeight::Semibold,
283 6 => FontWeight::Bold,
284 7 => FontWeight::Heavy,
285 8 => FontWeight::Black,
286 _ => FontWeight::Regular,
287 }
288 }
289}