1use bytemuck::{Pod, Zeroable};
2use core::fmt::Debug;
3use derive_more::{Add, AddAssign, Div, Mul, Sub, SubAssign};
4use refineable::Refineable;
5use std::ops::{Add, Mul};
6
7#[derive(Refineable, Default, Add, AddAssign, Sub, Mul, Div, Copy, Debug, PartialEq, Eq, Hash)]
8#[refineable(debug)]
9#[repr(C)]
10pub struct Point<T: Clone + Debug> {
11 pub x: T,
12 pub y: T,
13}
14
15pub fn point<T: Clone + Debug>(x: T, y: T) -> Point<T> {
16 Point { x, y }
17}
18
19impl<T: Clone + Debug> Point<T> {
20 pub fn new(x: T, y: T) -> Self {
21 Self { x, y }
22 }
23
24 pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Point<U> {
25 Point {
26 x: f(self.x.clone()),
27 y: f(self.y.clone()),
28 }
29 }
30}
31
32impl<T: Clone + Debug> Clone for Point<T> {
33 fn clone(&self) -> Self {
34 Self {
35 x: self.x.clone(),
36 y: self.y.clone(),
37 }
38 }
39}
40
41unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Point<T> {}
42
43unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Point<T> {}
44
45#[derive(Refineable, Default, Clone, Copy, Debug, PartialEq)]
46#[refineable(debug)]
47pub struct Size<T: Clone + Debug> {
48 pub width: T,
49 pub height: T,
50}
51
52pub fn size<T: Clone + Debug>(width: T, height: T) -> Size<T> {
53 Size { width, height }
54}
55
56impl Size<Length> {
57 pub fn full() -> Self {
58 Self {
59 width: relative(1.),
60 height: relative(1.),
61 }
62 }
63}
64
65impl Size<DefiniteLength> {
66 pub fn zero() -> Self {
67 Self {
68 width: px(0.).into(),
69 height: px(0.).into(),
70 }
71 }
72}
73
74impl Size<Length> {
75 pub fn auto() -> Self {
76 Self {
77 width: Length::Auto,
78 height: Length::Auto,
79 }
80 }
81}
82
83#[derive(Refineable, Clone, Default, Debug, PartialEq)]
84#[refineable(debug)]
85pub struct Bounds<T: Clone + Debug> {
86 pub origin: Point<T>,
87 pub size: Size<T>,
88}
89
90impl<T: Clone + Debug + Copy + Add<T, Output = T>> Bounds<T> {
91 pub fn upper_right(&self) -> Point<T> {
92 Point {
93 x: self.origin.x + self.size.width,
94 y: self.origin.y,
95 }
96 }
97}
98
99impl<T: Clone + Debug + Copy> Copy for Bounds<T> {}
100
101#[derive(Refineable, Clone, Default, Debug)]
102#[refineable(debug)]
103pub struct Edges<T: Clone + Debug> {
104 pub top: T,
105 pub right: T,
106 pub bottom: T,
107 pub left: T,
108}
109
110impl Edges<Length> {
111 pub fn auto() -> Self {
112 Self {
113 top: Length::Auto,
114 right: Length::Auto,
115 bottom: Length::Auto,
116 left: Length::Auto,
117 }
118 }
119
120 pub fn zero() -> Self {
121 Self {
122 top: px(0.).into(),
123 right: px(0.).into(),
124 bottom: px(0.).into(),
125 left: px(0.).into(),
126 }
127 }
128}
129
130impl Edges<DefiniteLength> {
131 pub fn zero() -> Self {
132 Self {
133 top: px(0.).into(),
134 right: px(0.).into(),
135 bottom: px(0.).into(),
136 left: px(0.).into(),
137 }
138 }
139}
140
141impl Edges<AbsoluteLength> {
142 pub fn zero() -> Self {
143 Self {
144 top: px(0.).into(),
145 right: px(0.).into(),
146 bottom: px(0.).into(),
147 left: px(0.).into(),
148 }
149 }
150
151 pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
152 Edges {
153 top: self.top.to_pixels(rem_size),
154 right: self.right.to_pixels(rem_size),
155 bottom: self.bottom.to_pixels(rem_size),
156 left: self.left.to_pixels(rem_size),
157 }
158 }
159}
160
161impl Edges<Pixels> {
162 pub fn is_empty(&self) -> bool {
163 self.top == px(0.) && self.right == px(0.) && self.bottom == px(0.) && self.left == px(0.)
164 }
165}
166
167#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
168#[repr(transparent)]
169pub struct Pixels(pub(crate) f32);
170
171impl From<Pixels> for f64 {
172 fn from(pixels: Pixels) -> Self {
173 pixels.0.into()
174 }
175}
176
177impl Mul<f32> for Pixels {
178 type Output = Pixels;
179
180 fn mul(self, other: f32) -> Pixels {
181 Pixels(self.0 * other)
182 }
183}
184
185impl Mul<Pixels> for Pixels {
186 type Output = Pixels;
187
188 fn mul(self, rhs: Pixels) -> Self::Output {
189 Pixels(self.0 * rhs.0)
190 }
191}
192
193impl Pixels {
194 pub fn round(&self) -> Self {
195 Self(self.0.round())
196 }
197}
198
199impl Eq for Pixels {}
200
201impl Ord for Pixels {
202 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
203 self.0.partial_cmp(&other.0).unwrap()
204 }
205}
206
207impl std::hash::Hash for Pixels {
208 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
209 self.0.to_bits().hash(state);
210 }
211}
212
213unsafe impl bytemuck::Pod for Pixels {}
214unsafe impl bytemuck::Zeroable for Pixels {}
215
216impl Debug for Pixels {
217 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
218 write!(f, "{} px", self.0)
219 }
220}
221
222impl From<Pixels> for f32 {
223 fn from(pixels: Pixels) -> Self {
224 pixels.0
225 }
226}
227
228impl From<&Pixels> for f32 {
229 fn from(pixels: &Pixels) -> Self {
230 pixels.0
231 }
232}
233
234#[derive(Clone, Copy, Default, Add, Sub, Mul, Div)]
235pub struct Rems(f32);
236
237impl Mul<Pixels> for Rems {
238 type Output = Pixels;
239
240 fn mul(self, other: Pixels) -> Pixels {
241 Pixels(self.0 * other.0)
242 }
243}
244
245impl Debug for Rems {
246 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
247 write!(f, "{} rem", self.0)
248 }
249}
250
251#[derive(Clone, Copy, Debug)]
252pub enum AbsoluteLength {
253 Pixels(Pixels),
254 Rems(Rems),
255}
256
257impl From<Pixels> for AbsoluteLength {
258 fn from(pixels: Pixels) -> Self {
259 AbsoluteLength::Pixels(pixels)
260 }
261}
262
263impl From<Rems> for AbsoluteLength {
264 fn from(rems: Rems) -> Self {
265 AbsoluteLength::Rems(rems)
266 }
267}
268
269impl AbsoluteLength {
270 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
271 match self {
272 AbsoluteLength::Pixels(pixels) => *pixels,
273 AbsoluteLength::Rems(rems) => *rems * rem_size,
274 }
275 }
276}
277
278impl Default for AbsoluteLength {
279 fn default() -> Self {
280 px(0.).into()
281 }
282}
283
284/// A non-auto length that can be defined in pixels, rems, or percent of parent.
285#[derive(Clone, Copy)]
286pub enum DefiniteLength {
287 Absolute(AbsoluteLength),
288 /// A fraction of the parent's size between 0 and 1.
289 Fraction(f32),
290}
291
292impl Debug for DefiniteLength {
293 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
294 match self {
295 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
296 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
297 }
298 }
299}
300
301impl From<Pixels> for DefiniteLength {
302 fn from(pixels: Pixels) -> Self {
303 Self::Absolute(pixels.into())
304 }
305}
306
307impl From<Rems> for DefiniteLength {
308 fn from(rems: Rems) -> Self {
309 Self::Absolute(rems.into())
310 }
311}
312
313impl From<AbsoluteLength> for DefiniteLength {
314 fn from(length: AbsoluteLength) -> Self {
315 Self::Absolute(length)
316 }
317}
318
319impl Default for DefiniteLength {
320 fn default() -> Self {
321 Self::Absolute(AbsoluteLength::default())
322 }
323}
324
325/// A length that can be defined in pixels, rems, percent of parent, or auto.
326#[derive(Clone, Copy)]
327pub enum Length {
328 Definite(DefiniteLength),
329 Auto,
330}
331
332impl Debug for Length {
333 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
334 match self {
335 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
336 Length::Auto => write!(f, "auto"),
337 }
338 }
339}
340
341pub fn relative<T: From<DefiniteLength>>(fraction: f32) -> T {
342 DefiniteLength::Fraction(fraction).into()
343}
344
345pub fn rems(rems: f32) -> Rems {
346 Rems(rems)
347}
348
349pub fn px(pixels: f32) -> Pixels {
350 Pixels(pixels)
351}
352
353pub fn auto() -> Length {
354 Length::Auto
355}
356
357impl From<Pixels> for Length {
358 fn from(pixels: Pixels) -> Self {
359 Self::Definite(pixels.into())
360 }
361}
362
363impl From<Rems> for Length {
364 fn from(rems: Rems) -> Self {
365 Self::Definite(rems.into())
366 }
367}
368
369impl From<DefiniteLength> for Length {
370 fn from(length: DefiniteLength) -> Self {
371 Self::Definite(length)
372 }
373}
374
375impl From<AbsoluteLength> for Length {
376 fn from(length: AbsoluteLength) -> Self {
377 Self::Definite(length.into())
378 }
379}
380
381impl Default for Length {
382 fn default() -> Self {
383 Self::Definite(DefiniteLength::default())
384 }
385}
386
387impl From<()> for Length {
388 fn from(_: ()) -> Self {
389 Self::Definite(DefiniteLength::default())
390 }
391}