1use bytemuck::{Pod, Zeroable};
2use core::fmt::Debug;
3use derive_more::{Add, AddAssign, Div, Mul, Sub, SubAssign};
4use refineable::Refineable;
5use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign};
6
7#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, 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, Rhs> Mul<Rhs> for Point<T>
33where
34 T: Mul<Rhs, Output = Rhs> + Clone + Debug,
35 Rhs: Clone + Debug,
36{
37 type Output = Point<Rhs>;
38
39 fn mul(self, rhs: Rhs) -> Self::Output {
40 Point {
41 x: self.x * rhs.clone(),
42 y: self.y * rhs,
43 }
44 }
45}
46
47impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Point<T> {
48 fn mul_assign(&mut self, rhs: S) {
49 self.x = self.x.clone() * rhs.clone();
50 self.y = self.y.clone() * rhs;
51 }
52}
53
54impl<T: Clone + Debug + Sub<Output = T>> SubAssign<Size<T>> for Point<T> {
55 fn sub_assign(&mut self, rhs: Size<T>) {
56 self.x = self.x.clone() - rhs.width;
57 self.y = self.y.clone() - rhs.height;
58 }
59}
60
61impl<T: Clone + Debug + Add<Output = T> + Copy> AddAssign<T> for Point<T> {
62 fn add_assign(&mut self, rhs: T) {
63 self.x = self.x.clone() + rhs;
64 self.y = self.y.clone() + rhs;
65 }
66}
67
68impl<T: Clone + Debug + Div<S, Output = T>, S: Clone> Div<S> for Point<T> {
69 type Output = Self;
70
71 fn div(self, rhs: S) -> Self::Output {
72 Self {
73 x: self.x / rhs.clone(),
74 y: self.y / rhs,
75 }
76 }
77}
78
79impl<T: Clone + Debug + std::cmp::PartialOrd> Point<T> {
80 pub fn max(&self, other: &Self) -> Self {
81 Point {
82 x: if self.x >= other.x {
83 self.x.clone()
84 } else {
85 other.x.clone()
86 },
87 y: if self.y >= other.y {
88 self.y.clone()
89 } else {
90 other.y.clone()
91 },
92 }
93 }
94}
95
96impl<T: Clone + Debug> Clone for Point<T> {
97 fn clone(&self) -> Self {
98 Self {
99 x: self.x.clone(),
100 y: self.y.clone(),
101 }
102 }
103}
104
105unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Point<T> {}
106unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Point<T> {}
107
108#[derive(Refineable, Default, Clone, Copy, Debug, PartialEq, Div)]
109#[refineable(debug)]
110#[repr(C)]
111pub struct Size<T: Clone + Debug> {
112 pub width: T,
113 pub height: T,
114}
115
116unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Size<T> {}
117unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Size<T> {}
118
119pub fn size<T: Clone + Debug>(width: T, height: T) -> Size<T> {
120 Size { width, height }
121}
122
123impl<T: Clone + Debug> Size<T> {
124 pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Size<U> {
125 Size {
126 width: f(self.width.clone()),
127 height: f(self.height.clone()),
128 }
129 }
130}
131
132impl<T, Rhs> Mul<Rhs> for Size<T>
133where
134 T: Mul<Rhs, Output = Rhs> + Debug + Clone,
135 Rhs: Debug + Clone,
136{
137 type Output = Size<Rhs>;
138
139 fn mul(self, rhs: Rhs) -> Self::Output {
140 Size {
141 width: self.width * rhs.clone(),
142 height: self.height * rhs,
143 }
144 }
145}
146
147impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Size<T> {
148 fn mul_assign(&mut self, rhs: S) {
149 self.width = self.width.clone() * rhs.clone();
150 self.height = self.height.clone() * rhs;
151 }
152}
153
154impl From<Size<Option<Pixels>>> for Size<Option<f32>> {
155 fn from(val: Size<Option<Pixels>>) -> Self {
156 Size {
157 width: val.width.map(|p| p.0 as f32),
158 height: val.height.map(|p| p.0 as f32),
159 }
160 }
161}
162
163impl Size<Length> {
164 pub fn full() -> Self {
165 Self {
166 width: relative(1.).into(),
167 height: relative(1.).into(),
168 }
169 }
170}
171
172impl Size<DefiniteLength> {
173 pub fn zero() -> Self {
174 Self {
175 width: px(0.).into(),
176 height: px(0.).into(),
177 }
178 }
179}
180
181impl Size<Length> {
182 pub fn auto() -> Self {
183 Self {
184 width: Length::Auto,
185 height: Length::Auto,
186 }
187 }
188}
189
190#[derive(Refineable, Clone, Default, Debug, PartialEq)]
191#[refineable(debug)]
192#[repr(C)]
193pub struct Bounds<T: Clone + Debug> {
194 pub origin: Point<T>,
195 pub size: Size<T>,
196}
197
198unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Bounds<T> {}
199unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Bounds<T> {}
200
201// Bounds<f32> * Pixels = Bounds<Pixels>
202impl<T, Rhs> Mul<Rhs> for Bounds<T>
203where
204 T: Mul<Rhs, Output = Rhs> + Clone + Debug,
205 Rhs: Clone + Debug,
206{
207 type Output = Bounds<Rhs>;
208
209 fn mul(self, rhs: Rhs) -> Self::Output {
210 Bounds {
211 origin: self.origin * rhs.clone(),
212 size: self.size * rhs,
213 }
214 }
215}
216
217impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Bounds<T> {
218 fn mul_assign(&mut self, rhs: S) {
219 self.origin *= rhs.clone();
220 self.size *= rhs;
221 }
222}
223
224impl<T: Clone + Debug + Div<S, Output = T>, S: Clone> Div<S> for Bounds<T>
225where
226 Size<T>: Div<S, Output = Size<T>>,
227{
228 type Output = Self;
229
230 fn div(self, rhs: S) -> Self {
231 Self {
232 origin: self.origin / rhs.clone(),
233 size: self.size / rhs,
234 }
235 }
236}
237
238impl<T: Clone + Debug + Add<T, Output = T>> Bounds<T> {
239 pub fn upper_right(&self) -> Point<T> {
240 Point {
241 x: self.origin.x.clone() + self.size.width.clone(),
242 y: self.origin.y.clone(),
243 }
244 }
245
246 pub fn lower_right(&self) -> Point<T> {
247 Point {
248 x: self.origin.x.clone() + self.size.width.clone(),
249 y: self.origin.y.clone() + self.size.height.clone(),
250 }
251 }
252}
253
254impl<T: Clone + Debug + PartialOrd + Add<T, Output = T>> Bounds<T> {
255 pub fn contains_point(&self, point: Point<T>) -> bool {
256 point.x >= self.origin.x
257 && point.x <= self.origin.x.clone() + self.size.width.clone()
258 && point.y >= self.origin.y
259 && point.y <= self.origin.y.clone() + self.size.height.clone()
260 }
261
262 pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Bounds<U> {
263 Bounds {
264 origin: self.origin.map(&f),
265 size: self.size.map(f),
266 }
267 }
268}
269
270impl<T: Clone + Debug + Copy> Copy for Bounds<T> {}
271
272#[derive(Refineable, Clone, Default, Debug)]
273#[refineable(debug)]
274#[repr(C)]
275pub struct Edges<T: Clone + Debug> {
276 pub top: T,
277 pub right: T,
278 pub bottom: T,
279 pub left: T,
280}
281
282impl<T: Clone + Debug + Mul<Output = T>> Mul for Edges<T> {
283 type Output = Self;
284
285 fn mul(self, rhs: Self) -> Self::Output {
286 Self {
287 top: self.top.clone() * rhs.top,
288 right: self.right.clone() * rhs.right,
289 bottom: self.bottom.clone() * rhs.bottom,
290 left: self.left.clone() * rhs.left,
291 }
292 }
293}
294
295impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Edges<T> {
296 fn mul_assign(&mut self, rhs: S) {
297 self.top = self.top.clone() * rhs.clone();
298 self.right = self.right.clone() * rhs.clone();
299 self.bottom = self.bottom.clone() * rhs.clone();
300 self.left = self.left.clone() * rhs.clone();
301 }
302}
303
304impl<T: Clone + Debug + Copy> Copy for Edges<T> {}
305
306unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Edges<T> {}
307
308unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Edges<T> {}
309
310impl<T: Clone + Debug> Edges<T> {
311 pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Edges<U> {
312 Edges {
313 top: f(&self.top),
314 right: f(&self.right),
315 bottom: f(&self.bottom),
316 left: f(&self.left),
317 }
318 }
319
320 pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
321 predicate(&self.top)
322 || predicate(&self.right)
323 || predicate(&self.bottom)
324 || predicate(&self.left)
325 }
326}
327
328impl Edges<Length> {
329 pub fn auto() -> Self {
330 Self {
331 top: Length::Auto,
332 right: Length::Auto,
333 bottom: Length::Auto,
334 left: Length::Auto,
335 }
336 }
337
338 pub fn zero() -> Self {
339 Self {
340 top: px(0.).into(),
341 right: px(0.).into(),
342 bottom: px(0.).into(),
343 left: px(0.).into(),
344 }
345 }
346}
347
348impl Edges<DefiniteLength> {
349 pub fn zero() -> Self {
350 Self {
351 top: px(0.).into(),
352 right: px(0.).into(),
353 bottom: px(0.).into(),
354 left: px(0.).into(),
355 }
356 }
357}
358
359impl Edges<AbsoluteLength> {
360 pub fn zero() -> Self {
361 Self {
362 top: px(0.).into(),
363 right: px(0.).into(),
364 bottom: px(0.).into(),
365 left: px(0.).into(),
366 }
367 }
368
369 pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
370 Edges {
371 top: self.top.to_pixels(rem_size),
372 right: self.right.to_pixels(rem_size),
373 bottom: self.bottom.to_pixels(rem_size),
374 left: self.left.to_pixels(rem_size),
375 }
376 }
377}
378
379#[derive(Refineable, Clone, Default, Debug)]
380#[refineable(debug)]
381#[repr(C)]
382pub struct Corners<T: Clone + Debug> {
383 pub top_left: T,
384 pub top_right: T,
385 pub bottom_right: T,
386 pub bottom_left: T,
387}
388
389impl<T: Clone + Debug> Corners<T> {
390 pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Corners<U> {
391 Corners {
392 top_left: f(&self.top_left),
393 top_right: f(&self.top_right),
394 bottom_right: f(&self.bottom_right),
395 bottom_left: f(&self.bottom_left),
396 }
397 }
398}
399
400impl<T: Clone + Debug + Mul<Output = T>> Mul for Corners<T> {
401 type Output = Self;
402
403 fn mul(self, rhs: Self) -> Self::Output {
404 Self {
405 top_left: self.top_left.clone() * rhs.top_left,
406 top_right: self.top_right.clone() * rhs.top_right,
407 bottom_right: self.bottom_right.clone() * rhs.bottom_right,
408 bottom_left: self.bottom_left.clone() * rhs.bottom_left,
409 }
410 }
411}
412
413impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Corners<T> {
414 fn mul_assign(&mut self, rhs: S) {
415 self.top_left = self.top_left.clone() * rhs.clone();
416 self.top_right = self.top_right.clone() * rhs.clone();
417 self.bottom_right = self.bottom_right.clone() * rhs.clone();
418 self.bottom_left = self.bottom_left.clone() * rhs;
419 }
420}
421
422impl<T: Clone + Debug + Copy> Copy for Corners<T> {}
423
424unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Corners<T> {}
425
426unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Corners<T> {}
427
428#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
429#[repr(transparent)]
430pub struct Pixels(pub(crate) f32);
431
432impl Mul<f32> for Pixels {
433 type Output = Pixels;
434
435 fn mul(self, other: f32) -> Pixels {
436 Pixels(self.0 * other)
437 }
438}
439
440impl Mul<Pixels> for f32 {
441 type Output = Pixels;
442
443 fn mul(self, rhs: Pixels) -> Self::Output {
444 Pixels(self * rhs.0)
445 }
446}
447
448impl Pixels {
449 pub fn round(&self) -> Self {
450 Self(self.0.round())
451 }
452
453 pub fn to_device_pixels(&self, scale: f32) -> DevicePixels {
454 DevicePixels((self.0 * scale).ceil() as u32)
455 }
456}
457
458impl Mul<Pixels> for Pixels {
459 type Output = Pixels;
460
461 fn mul(self, rhs: Pixels) -> Self::Output {
462 Pixels(self.0 * rhs.0)
463 }
464}
465
466impl Eq for Pixels {}
467
468impl Ord for Pixels {
469 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
470 self.0.partial_cmp(&other.0).unwrap()
471 }
472}
473
474impl std::hash::Hash for Pixels {
475 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
476 self.0.to_bits().hash(state);
477 }
478}
479
480impl From<f64> for Pixels {
481 fn from(val: f64) -> Self {
482 Pixels(val as f32)
483 }
484}
485
486impl From<f32> for Pixels {
487 fn from(val: f32) -> Self {
488 Pixels(val)
489 }
490}
491
492unsafe impl bytemuck::Pod for Pixels {}
493unsafe impl bytemuck::Zeroable for Pixels {}
494
495impl Debug for Pixels {
496 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
497 write!(f, "{} px", self.0)
498 }
499}
500
501impl From<Pixels> for f32 {
502 fn from(pixels: Pixels) -> Self {
503 pixels.0
504 }
505}
506
507impl From<&Pixels> for f32 {
508 fn from(pixels: &Pixels) -> Self {
509 pixels.0
510 }
511}
512
513impl From<Pixels> for f64 {
514 fn from(pixels: Pixels) -> Self {
515 pixels.0 as f64
516 }
517}
518
519#[derive(
520 Clone, Copy, Debug, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd,
521)]
522#[repr(transparent)]
523pub struct DevicePixels(pub(crate) u32);
524
525unsafe impl bytemuck::Pod for DevicePixels {}
526unsafe impl bytemuck::Zeroable for DevicePixels {}
527
528impl From<DevicePixels> for u32 {
529 fn from(device_pixels: DevicePixels) -> Self {
530 device_pixels.0
531 }
532}
533
534impl From<u32> for DevicePixels {
535 fn from(val: u32) -> Self {
536 DevicePixels(val)
537 }
538}
539
540#[derive(Clone, Copy, Default, Add, Sub, Mul, Div)]
541pub struct Rems(f32);
542
543impl Mul<Pixels> for Rems {
544 type Output = Pixels;
545
546 fn mul(self, other: Pixels) -> Pixels {
547 Pixels(self.0 * other.0)
548 }
549}
550
551impl Debug for Rems {
552 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
553 write!(f, "{} rem", self.0)
554 }
555}
556
557#[derive(Clone, Copy, Debug)]
558pub enum AbsoluteLength {
559 Pixels(Pixels),
560 Rems(Rems),
561}
562
563impl AbsoluteLength {
564 pub fn is_zero(&self) -> bool {
565 match self {
566 AbsoluteLength::Pixels(px) => px.0 == 0.,
567 AbsoluteLength::Rems(rems) => rems.0 == 0.,
568 }
569 }
570}
571
572impl From<Pixels> for AbsoluteLength {
573 fn from(pixels: Pixels) -> Self {
574 AbsoluteLength::Pixels(pixels)
575 }
576}
577
578impl From<Rems> for AbsoluteLength {
579 fn from(rems: Rems) -> Self {
580 AbsoluteLength::Rems(rems)
581 }
582}
583
584impl AbsoluteLength {
585 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
586 match self {
587 AbsoluteLength::Pixels(pixels) => *pixels,
588 AbsoluteLength::Rems(rems) => *rems * rem_size,
589 }
590 }
591}
592
593impl Default for AbsoluteLength {
594 fn default() -> Self {
595 px(0.).into()
596 }
597}
598
599/// A non-auto length that can be defined in pixels, rems, or percent of parent.
600#[derive(Clone, Copy)]
601pub enum DefiniteLength {
602 Absolute(AbsoluteLength),
603 /// A fraction of the parent's size between 0 and 1.
604 Fraction(f32),
605}
606
607impl DefiniteLength {
608 pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
609 match self {
610 DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
611 DefiniteLength::Fraction(fraction) => match base_size {
612 AbsoluteLength::Pixels(px) => px * *fraction,
613 AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
614 },
615 }
616 }
617}
618
619impl Debug for DefiniteLength {
620 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
621 match self {
622 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
623 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
624 }
625 }
626}
627
628impl From<Pixels> for DefiniteLength {
629 fn from(pixels: Pixels) -> Self {
630 Self::Absolute(pixels.into())
631 }
632}
633
634impl From<Rems> for DefiniteLength {
635 fn from(rems: Rems) -> Self {
636 Self::Absolute(rems.into())
637 }
638}
639
640impl From<AbsoluteLength> for DefiniteLength {
641 fn from(length: AbsoluteLength) -> Self {
642 Self::Absolute(length)
643 }
644}
645
646impl Default for DefiniteLength {
647 fn default() -> Self {
648 Self::Absolute(AbsoluteLength::default())
649 }
650}
651
652/// A length that can be defined in pixels, rems, percent of parent, or auto.
653#[derive(Clone, Copy)]
654pub enum Length {
655 Definite(DefiniteLength),
656 Auto,
657}
658
659impl Debug for Length {
660 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
661 match self {
662 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
663 Length::Auto => write!(f, "auto"),
664 }
665 }
666}
667
668pub fn relative(fraction: f32) -> DefiniteLength {
669 DefiniteLength::Fraction(fraction).into()
670}
671
672/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
673pub fn phi() -> DefiniteLength {
674 relative(1.61803398875)
675}
676
677pub fn rems(rems: f32) -> Rems {
678 Rems(rems)
679}
680
681pub fn px(pixels: f32) -> Pixels {
682 Pixels(pixels)
683}
684
685pub fn auto() -> Length {
686 Length::Auto
687}
688
689impl From<Pixels> for Length {
690 fn from(pixels: Pixels) -> Self {
691 Self::Definite(pixels.into())
692 }
693}
694
695impl From<Rems> for Length {
696 fn from(rems: Rems) -> Self {
697 Self::Definite(rems.into())
698 }
699}
700
701impl From<DefiniteLength> for Length {
702 fn from(length: DefiniteLength) -> Self {
703 Self::Definite(length)
704 }
705}
706
707impl From<AbsoluteLength> for Length {
708 fn from(length: AbsoluteLength) -> Self {
709 Self::Definite(length.into())
710 }
711}
712
713impl Default for Length {
714 fn default() -> Self {
715 Self::Definite(DefiniteLength::default())
716 }
717}
718
719impl From<()> for Length {
720 fn from(_: ()) -> Self {
721 Self::Definite(DefiniteLength::default())
722 }
723}