1use core::fmt::Debug;
2use derive_more::{Add, AddAssign, Div, DivAssign, Mul, Neg, Sub, SubAssign};
3use refineable::Refineable;
4use serde_derive::{Deserialize, Serialize};
5use std::{
6 cmp::{self, PartialOrd},
7 fmt,
8 ops::{Add, Div, Mul, MulAssign, Sub},
9};
10
11#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
12#[refineable(Debug)]
13#[repr(C)]
14pub struct Point<T: Default + Clone + Debug> {
15 pub x: T,
16 pub y: T,
17}
18
19pub fn point<T: Clone + Debug + Default>(x: T, y: T) -> Point<T> {
20 Point { x, y }
21}
22
23impl<T: Clone + Debug + Default> Point<T> {
24 pub const fn new(x: T, y: T) -> Self {
25 Self { x, y }
26 }
27
28 pub fn zero() -> Self {
29 Self::new(T::default(), T::default())
30 }
31
32 pub fn map<U: Clone + Default + Debug>(&self, f: impl Fn(T) -> U) -> Point<U> {
33 Point {
34 x: f(self.x.clone()),
35 y: f(self.y.clone()),
36 }
37 }
38}
39
40impl Point<Pixels> {
41 pub fn scale(&self, factor: f32) -> Point<ScaledPixels> {
42 Point {
43 x: self.x.scale(factor),
44 y: self.y.scale(factor),
45 }
46 }
47
48 pub fn magnitude(&self) -> f64 {
49 ((self.x.0.powi(2) + self.y.0.powi(2)) as f64).sqrt()
50 }
51}
52
53impl<T, Rhs> Mul<Rhs> for Point<T>
54where
55 T: Mul<Rhs, Output = T> + Clone + Default + Debug,
56 Rhs: Clone + Debug,
57{
58 type Output = Point<T>;
59
60 fn mul(self, rhs: Rhs) -> Self::Output {
61 Point {
62 x: self.x * rhs.clone(),
63 y: self.y * rhs,
64 }
65 }
66}
67
68impl<T, S> MulAssign<S> for Point<T>
69where
70 T: Clone + Mul<S, Output = T> + Default + Debug,
71 S: Clone,
72{
73 fn mul_assign(&mut self, rhs: S) {
74 self.x = self.x.clone() * rhs.clone();
75 self.y = self.y.clone() * rhs;
76 }
77}
78
79impl<T, S> Div<S> for Point<T>
80where
81 T: Div<S, Output = T> + Clone + Default + Debug,
82 S: Clone,
83{
84 type Output = Self;
85
86 fn div(self, rhs: S) -> Self::Output {
87 Self {
88 x: self.x / rhs.clone(),
89 y: self.y / rhs,
90 }
91 }
92}
93
94impl<T> Point<T>
95where
96 T: PartialOrd + Clone + Default + Debug,
97{
98 pub fn max(&self, other: &Self) -> Self {
99 Point {
100 x: if self.x >= other.x {
101 self.x.clone()
102 } else {
103 other.x.clone()
104 },
105 y: if self.y >= other.y {
106 self.y.clone()
107 } else {
108 other.y.clone()
109 },
110 }
111 }
112
113 pub fn min(&self, other: &Self) -> Self {
114 Point {
115 x: if self.x <= other.x {
116 self.x.clone()
117 } else {
118 other.x.clone()
119 },
120 y: if self.y <= other.y {
121 self.y.clone()
122 } else {
123 other.y.clone()
124 },
125 }
126 }
127
128 pub fn clamp(&self, min: &Self, max: &Self) -> Self {
129 self.max(min).min(max)
130 }
131}
132
133impl<T: Clone + Default + Debug> Clone for Point<T> {
134 fn clone(&self) -> Self {
135 Self {
136 x: self.x.clone(),
137 y: self.y.clone(),
138 }
139 }
140}
141
142#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash, Serialize, Deserialize)]
143#[refineable(Debug)]
144#[repr(C)]
145pub struct Size<T: Clone + Default + Debug> {
146 pub width: T,
147 pub height: T,
148}
149
150pub fn size<T>(width: T, height: T) -> Size<T>
151where
152 T: Clone + Default + Debug,
153{
154 Size { width, height }
155}
156
157impl<T> Size<T>
158where
159 T: Clone + Default + Debug,
160{
161 pub fn map<U>(&self, f: impl Fn(T) -> U) -> Size<U>
162 where
163 U: Clone + Default + Debug,
164 {
165 Size {
166 width: f(self.width.clone()),
167 height: f(self.height.clone()),
168 }
169 }
170}
171
172impl Size<Pixels> {
173 pub fn scale(&self, factor: f32) -> Size<ScaledPixels> {
174 Size {
175 width: self.width.scale(factor),
176 height: self.height.scale(factor),
177 }
178 }
179}
180
181impl<T> Size<T>
182where
183 T: PartialOrd + Clone + Default + Debug,
184{
185 pub fn max(&self, other: &Self) -> Self {
186 Size {
187 width: if self.width >= other.width {
188 self.width.clone()
189 } else {
190 other.width.clone()
191 },
192 height: if self.height >= other.height {
193 self.height.clone()
194 } else {
195 other.height.clone()
196 },
197 }
198 }
199}
200
201impl<T> Sub for Size<T>
202where
203 T: Sub<Output = T> + Clone + Default + Debug,
204{
205 type Output = Size<T>;
206
207 fn sub(self, rhs: Self) -> Self::Output {
208 Size {
209 width: self.width - rhs.width,
210 height: self.height - rhs.height,
211 }
212 }
213}
214
215impl<T, Rhs> Mul<Rhs> for Size<T>
216where
217 T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
218 Rhs: Clone + Default + Debug,
219{
220 type Output = Size<Rhs>;
221
222 fn mul(self, rhs: Rhs) -> Self::Output {
223 Size {
224 width: self.width * rhs.clone(),
225 height: self.height * rhs,
226 }
227 }
228}
229
230impl<T, S> MulAssign<S> for Size<T>
231where
232 T: Mul<S, Output = T> + Clone + Default + Debug,
233 S: Clone,
234{
235 fn mul_assign(&mut self, rhs: S) {
236 self.width = self.width.clone() * rhs.clone();
237 self.height = self.height.clone() * rhs;
238 }
239}
240
241impl<T> Eq for Size<T> where T: Eq + Default + Debug + Clone {}
242
243impl<T> Debug for Size<T>
244where
245 T: Clone + Default + Debug,
246{
247 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
248 write!(f, "Size {{ {:?} × {:?} }}", self.width, self.height)
249 }
250}
251
252impl<T: Clone + Default + Debug> From<Point<T>> for Size<T> {
253 fn from(point: Point<T>) -> Self {
254 Self {
255 width: point.x,
256 height: point.y,
257 }
258 }
259}
260
261impl From<Size<Pixels>> for Size<GlobalPixels> {
262 fn from(size: Size<Pixels>) -> Self {
263 Size {
264 width: GlobalPixels(size.width.0),
265 height: GlobalPixels(size.height.0),
266 }
267 }
268}
269
270impl From<Size<Pixels>> for Size<DefiniteLength> {
271 fn from(size: Size<Pixels>) -> Self {
272 Size {
273 width: size.width.into(),
274 height: size.height.into(),
275 }
276 }
277}
278
279impl From<Size<Pixels>> for Size<AbsoluteLength> {
280 fn from(size: Size<Pixels>) -> Self {
281 Size {
282 width: size.width.into(),
283 height: size.height.into(),
284 }
285 }
286}
287
288impl Size<Length> {
289 pub fn full() -> Self {
290 Self {
291 width: relative(1.).into(),
292 height: relative(1.).into(),
293 }
294 }
295}
296
297impl Size<DefiniteLength> {
298 pub fn zero() -> Self {
299 Self {
300 width: px(0.).into(),
301 height: px(0.).into(),
302 }
303 }
304}
305
306impl Size<Length> {
307 pub fn auto() -> Self {
308 Self {
309 width: Length::Auto,
310 height: Length::Auto,
311 }
312 }
313}
314
315#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
316#[refineable(Debug)]
317#[repr(C)]
318pub struct Bounds<T: Clone + Default + Debug> {
319 pub origin: Point<T>,
320 pub size: Size<T>,
321}
322
323impl<T> Bounds<T>
324where
325 T: Clone + Debug + Sub<Output = T> + Default,
326{
327 pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
328 let origin = Point {
329 x: upper_left.x.clone(),
330 y: upper_left.y.clone(),
331 };
332 let size = Size {
333 width: lower_right.x - upper_left.x,
334 height: lower_right.y - upper_left.y,
335 };
336 Bounds { origin, size }
337 }
338
339 pub fn new(origin: Point<T>, size: Size<T>) -> Self {
340 Bounds { origin, size }
341 }
342}
343
344impl<T> Bounds<T>
345where
346 T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default + Half,
347{
348 pub fn intersects(&self, other: &Bounds<T>) -> bool {
349 let my_lower_right = self.lower_right();
350 let their_lower_right = other.lower_right();
351
352 self.origin.x < their_lower_right.x
353 && my_lower_right.x > other.origin.x
354 && self.origin.y < their_lower_right.y
355 && my_lower_right.y > other.origin.y
356 }
357
358 pub fn dilate(&mut self, amount: T) {
359 self.origin.x = self.origin.x.clone() - amount.clone();
360 self.origin.y = self.origin.y.clone() - amount.clone();
361 let double_amount = amount.clone() + amount;
362 self.size.width = self.size.width.clone() + double_amount.clone();
363 self.size.height = self.size.height.clone() + double_amount;
364 }
365
366 pub fn center(&self) -> Point<T> {
367 Point {
368 x: self.origin.x.clone() + self.size.width.clone().half(),
369 y: self.origin.y.clone() + self.size.height.clone().half(),
370 }
371 }
372}
373
374impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
375 pub fn intersect(&self, other: &Self) -> Self {
376 let upper_left = self.origin.max(&other.origin);
377 let lower_right = self.lower_right().min(&other.lower_right());
378 Self::from_corners(upper_left, lower_right)
379 }
380
381 pub fn union(&self, other: &Self) -> Self {
382 let top_left = self.origin.min(&other.origin);
383 let bottom_right = self.lower_right().max(&other.lower_right());
384 Bounds::from_corners(top_left, bottom_right)
385 }
386}
387
388impl<T, Rhs> Mul<Rhs> for Bounds<T>
389where
390 T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
391 Point<T>: Mul<Rhs, Output = Point<Rhs>>,
392 Rhs: Clone + Default + Debug,
393{
394 type Output = Bounds<Rhs>;
395
396 fn mul(self, rhs: Rhs) -> Self::Output {
397 Bounds {
398 origin: self.origin * rhs.clone(),
399 size: self.size * rhs,
400 }
401 }
402}
403
404impl<T, S> MulAssign<S> for Bounds<T>
405where
406 T: Mul<S, Output = T> + Clone + Default + Debug,
407 S: Clone,
408{
409 fn mul_assign(&mut self, rhs: S) {
410 self.origin *= rhs.clone();
411 self.size *= rhs;
412 }
413}
414
415impl<T, S> Div<S> for Bounds<T>
416where
417 Size<T>: Div<S, Output = Size<T>>,
418 T: Div<S, Output = T> + Default + Clone + Debug,
419 S: Clone,
420{
421 type Output = Self;
422
423 fn div(self, rhs: S) -> Self {
424 Self {
425 origin: self.origin / rhs.clone(),
426 size: self.size / rhs,
427 }
428 }
429}
430
431impl<T> Bounds<T>
432where
433 T: Add<T, Output = T> + Clone + Default + Debug,
434{
435 pub fn top(&self) -> T {
436 self.origin.y.clone()
437 }
438
439 pub fn bottom(&self) -> T {
440 self.origin.y.clone() + self.size.height.clone()
441 }
442
443 pub fn left(&self) -> T {
444 self.origin.x.clone()
445 }
446
447 pub fn right(&self) -> T {
448 self.origin.x.clone() + self.size.width.clone()
449 }
450
451 pub fn upper_right(&self) -> Point<T> {
452 Point {
453 x: self.origin.x.clone() + self.size.width.clone(),
454 y: self.origin.y.clone(),
455 }
456 }
457
458 pub fn lower_right(&self) -> Point<T> {
459 Point {
460 x: self.origin.x.clone() + self.size.width.clone(),
461 y: self.origin.y.clone() + self.size.height.clone(),
462 }
463 }
464
465 pub fn lower_left(&self) -> Point<T> {
466 Point {
467 x: self.origin.x.clone(),
468 y: self.origin.y.clone() + self.size.height.clone(),
469 }
470 }
471}
472
473impl<T> Bounds<T>
474where
475 T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
476{
477 pub fn contains_point(&self, point: &Point<T>) -> bool {
478 point.x >= self.origin.x
479 && point.x <= self.origin.x.clone() + self.size.width.clone()
480 && point.y >= self.origin.y
481 && point.y <= self.origin.y.clone() + self.size.height.clone()
482 }
483
484 pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
485 where
486 U: Clone + Default + Debug,
487 {
488 Bounds {
489 origin: self.origin.map(&f),
490 size: self.size.map(f),
491 }
492 }
493}
494
495impl Bounds<Pixels> {
496 pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
497 Bounds {
498 origin: self.origin.scale(factor),
499 size: self.size.scale(factor),
500 }
501 }
502}
503
504impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
505
506#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
507#[refineable(Debug)]
508#[repr(C)]
509pub struct Edges<T: Clone + Default + Debug> {
510 pub top: T,
511 pub right: T,
512 pub bottom: T,
513 pub left: T,
514}
515
516impl<T> Mul for Edges<T>
517where
518 T: Mul<Output = T> + Clone + Default + Debug,
519{
520 type Output = Self;
521
522 fn mul(self, rhs: Self) -> Self::Output {
523 Self {
524 top: self.top.clone() * rhs.top,
525 right: self.right.clone() * rhs.right,
526 bottom: self.bottom.clone() * rhs.bottom,
527 left: self.left.clone() * rhs.left,
528 }
529 }
530}
531
532impl<T, S> MulAssign<S> for Edges<T>
533where
534 T: Mul<S, Output = T> + Clone + Default + Debug,
535 S: Clone,
536{
537 fn mul_assign(&mut self, rhs: S) {
538 self.top = self.top.clone() * rhs.clone();
539 self.right = self.right.clone() * rhs.clone();
540 self.bottom = self.bottom.clone() * rhs.clone();
541 self.left = self.left.clone() * rhs;
542 }
543}
544
545impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
546
547impl<T: Clone + Default + Debug> Edges<T> {
548 pub fn all(value: T) -> Self {
549 Self {
550 top: value.clone(),
551 right: value.clone(),
552 bottom: value.clone(),
553 left: value,
554 }
555 }
556
557 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
558 where
559 U: Clone + Default + Debug,
560 {
561 Edges {
562 top: f(&self.top),
563 right: f(&self.right),
564 bottom: f(&self.bottom),
565 left: f(&self.left),
566 }
567 }
568
569 pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
570 predicate(&self.top)
571 || predicate(&self.right)
572 || predicate(&self.bottom)
573 || predicate(&self.left)
574 }
575}
576
577impl Edges<Length> {
578 pub fn auto() -> Self {
579 Self {
580 top: Length::Auto,
581 right: Length::Auto,
582 bottom: Length::Auto,
583 left: Length::Auto,
584 }
585 }
586
587 pub fn zero() -> Self {
588 Self {
589 top: px(0.).into(),
590 right: px(0.).into(),
591 bottom: px(0.).into(),
592 left: px(0.).into(),
593 }
594 }
595}
596
597impl Edges<DefiniteLength> {
598 pub fn zero() -> Self {
599 Self {
600 top: px(0.).into(),
601 right: px(0.).into(),
602 bottom: px(0.).into(),
603 left: px(0.).into(),
604 }
605 }
606
607 pub fn to_pixels(&self, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
608 Edges {
609 top: self.top.to_pixels(parent_size.height, rem_size),
610 right: self.right.to_pixels(parent_size.width, rem_size),
611 bottom: self.bottom.to_pixels(parent_size.height, rem_size),
612 left: self.left.to_pixels(parent_size.width, rem_size),
613 }
614 }
615}
616
617impl Edges<AbsoluteLength> {
618 pub fn zero() -> Self {
619 Self {
620 top: px(0.).into(),
621 right: px(0.).into(),
622 bottom: px(0.).into(),
623 left: px(0.).into(),
624 }
625 }
626
627 pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
628 Edges {
629 top: self.top.to_pixels(rem_size),
630 right: self.right.to_pixels(rem_size),
631 bottom: self.bottom.to_pixels(rem_size),
632 left: self.left.to_pixels(rem_size),
633 }
634 }
635}
636
637impl Edges<Pixels> {
638 pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
639 Edges {
640 top: self.top.scale(factor),
641 right: self.right.scale(factor),
642 bottom: self.bottom.scale(factor),
643 left: self.left.scale(factor),
644 }
645 }
646}
647
648#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
649#[refineable(Debug)]
650#[repr(C)]
651pub struct Corners<T: Clone + Default + Debug> {
652 pub top_left: T,
653 pub top_right: T,
654 pub bottom_right: T,
655 pub bottom_left: T,
656}
657
658impl<T> Corners<T>
659where
660 T: Clone + Default + Debug,
661{
662 pub fn all(value: T) -> Self {
663 Self {
664 top_left: value.clone(),
665 top_right: value.clone(),
666 bottom_right: value.clone(),
667 bottom_left: value,
668 }
669 }
670}
671
672impl Corners<AbsoluteLength> {
673 pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
674 let max = size.width.max(size.height) / 2.;
675 Corners {
676 top_left: self.top_left.to_pixels(rem_size).min(max),
677 top_right: self.top_right.to_pixels(rem_size).min(max),
678 bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
679 bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
680 }
681 }
682}
683
684impl Corners<Pixels> {
685 pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
686 Corners {
687 top_left: self.top_left.scale(factor),
688 top_right: self.top_right.scale(factor),
689 bottom_right: self.bottom_right.scale(factor),
690 bottom_left: self.bottom_left.scale(factor),
691 }
692 }
693}
694
695impl<T: Clone + Default + Debug> Corners<T> {
696 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
697 where
698 U: Clone + Default + Debug,
699 {
700 Corners {
701 top_left: f(&self.top_left),
702 top_right: f(&self.top_right),
703 bottom_right: f(&self.bottom_right),
704 bottom_left: f(&self.bottom_left),
705 }
706 }
707}
708
709impl<T> Mul for Corners<T>
710where
711 T: Mul<Output = T> + Clone + Default + Debug,
712{
713 type Output = Self;
714
715 fn mul(self, rhs: Self) -> Self::Output {
716 Self {
717 top_left: self.top_left.clone() * rhs.top_left,
718 top_right: self.top_right.clone() * rhs.top_right,
719 bottom_right: self.bottom_right.clone() * rhs.bottom_right,
720 bottom_left: self.bottom_left.clone() * rhs.bottom_left,
721 }
722 }
723}
724
725impl<T, S> MulAssign<S> for Corners<T>
726where
727 T: Mul<S, Output = T> + Clone + Default + Debug,
728 S: Clone,
729{
730 fn mul_assign(&mut self, rhs: S) {
731 self.top_left = self.top_left.clone() * rhs.clone();
732 self.top_right = self.top_right.clone() * rhs.clone();
733 self.bottom_right = self.bottom_right.clone() * rhs.clone();
734 self.bottom_left = self.bottom_left.clone() * rhs;
735 }
736}
737
738impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
739
740#[derive(
741 Clone,
742 Copy,
743 Default,
744 Add,
745 AddAssign,
746 Sub,
747 SubAssign,
748 Neg,
749 Div,
750 DivAssign,
751 PartialEq,
752 PartialOrd,
753 Serialize,
754 Deserialize,
755)]
756#[repr(transparent)]
757pub struct Pixels(pub f32);
758
759impl std::ops::Div for Pixels {
760 type Output = f32;
761
762 fn div(self, rhs: Self) -> Self::Output {
763 self.0 / rhs.0
764 }
765}
766
767impl std::ops::DivAssign for Pixels {
768 fn div_assign(&mut self, rhs: Self) {
769 *self = Self(self.0 / rhs.0);
770 }
771}
772
773impl std::ops::RemAssign for Pixels {
774 fn rem_assign(&mut self, rhs: Self) {
775 self.0 %= rhs.0;
776 }
777}
778
779impl std::ops::Rem for Pixels {
780 type Output = Self;
781
782 fn rem(self, rhs: Self) -> Self {
783 Self(self.0 % rhs.0)
784 }
785}
786
787impl Mul<f32> for Pixels {
788 type Output = Pixels;
789
790 fn mul(self, other: f32) -> Pixels {
791 Pixels(self.0 * other)
792 }
793}
794
795impl Mul<usize> for Pixels {
796 type Output = Pixels;
797
798 fn mul(self, other: usize) -> Pixels {
799 Pixels(self.0 * other as f32)
800 }
801}
802
803impl Mul<Pixels> for f32 {
804 type Output = Pixels;
805
806 fn mul(self, rhs: Pixels) -> Self::Output {
807 Pixels(self * rhs.0)
808 }
809}
810
811impl MulAssign<f32> for Pixels {
812 fn mul_assign(&mut self, other: f32) {
813 self.0 *= other;
814 }
815}
816
817impl Pixels {
818 pub const ZERO: Pixels = Pixels(0.0);
819 pub const MAX: Pixels = Pixels(f32::MAX);
820
821 pub fn floor(&self) -> Self {
822 Self(self.0.floor())
823 }
824
825 pub fn round(&self) -> Self {
826 Self(self.0.round())
827 }
828
829 pub fn ceil(&self) -> Self {
830 Self(self.0.ceil())
831 }
832
833 pub fn scale(&self, factor: f32) -> ScaledPixels {
834 ScaledPixels(self.0 * factor)
835 }
836
837 pub fn pow(&self, exponent: f32) -> Self {
838 Self(self.0.powf(exponent))
839 }
840
841 pub fn abs(&self) -> Self {
842 Self(self.0.abs())
843 }
844}
845
846impl Mul<Pixels> for Pixels {
847 type Output = Pixels;
848
849 fn mul(self, rhs: Pixels) -> Self::Output {
850 Pixels(self.0 * rhs.0)
851 }
852}
853
854impl Eq for Pixels {}
855
856impl Ord for Pixels {
857 fn cmp(&self, other: &Self) -> cmp::Ordering {
858 self.0.partial_cmp(&other.0).unwrap()
859 }
860}
861
862impl std::hash::Hash for Pixels {
863 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
864 self.0.to_bits().hash(state);
865 }
866}
867
868impl From<f64> for Pixels {
869 fn from(pixels: f64) -> Self {
870 Pixels(pixels as f32)
871 }
872}
873
874impl From<f32> for Pixels {
875 fn from(pixels: f32) -> Self {
876 Pixels(pixels)
877 }
878}
879
880impl Debug for Pixels {
881 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
882 write!(f, "{} px", self.0)
883 }
884}
885
886impl From<Pixels> for f32 {
887 fn from(pixels: Pixels) -> Self {
888 pixels.0
889 }
890}
891
892impl From<&Pixels> for f32 {
893 fn from(pixels: &Pixels) -> Self {
894 pixels.0
895 }
896}
897
898impl From<Pixels> for f64 {
899 fn from(pixels: Pixels) -> Self {
900 pixels.0 as f64
901 }
902}
903
904impl From<Pixels> for u32 {
905 fn from(pixels: Pixels) -> Self {
906 pixels.0 as u32
907 }
908}
909
910impl From<u32> for Pixels {
911 fn from(pixels: u32) -> Self {
912 Pixels(pixels as f32)
913 }
914}
915
916impl From<Pixels> for usize {
917 fn from(pixels: Pixels) -> Self {
918 pixels.0 as usize
919 }
920}
921
922impl From<usize> for Pixels {
923 fn from(pixels: usize) -> Self {
924 Pixels(pixels as f32)
925 }
926}
927
928#[derive(
929 Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
930)]
931#[repr(transparent)]
932pub struct DevicePixels(pub(crate) i32);
933
934impl DevicePixels {
935 pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
936 self.0 as u32 * bytes_per_pixel as u32
937 }
938}
939
940impl fmt::Debug for DevicePixels {
941 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
942 write!(f, "{} px (device)", self.0)
943 }
944}
945
946impl From<DevicePixels> for i32 {
947 fn from(device_pixels: DevicePixels) -> Self {
948 device_pixels.0
949 }
950}
951
952impl From<i32> for DevicePixels {
953 fn from(device_pixels: i32) -> Self {
954 DevicePixels(device_pixels)
955 }
956}
957
958impl From<u32> for DevicePixels {
959 fn from(device_pixels: u32) -> Self {
960 DevicePixels(device_pixels as i32)
961 }
962}
963
964impl From<DevicePixels> for u32 {
965 fn from(device_pixels: DevicePixels) -> Self {
966 device_pixels.0 as u32
967 }
968}
969
970impl From<DevicePixels> for u64 {
971 fn from(device_pixels: DevicePixels) -> Self {
972 device_pixels.0 as u64
973 }
974}
975
976impl From<u64> for DevicePixels {
977 fn from(device_pixels: u64) -> Self {
978 DevicePixels(device_pixels as i32)
979 }
980}
981
982impl From<DevicePixels> for usize {
983 fn from(device_pixels: DevicePixels) -> Self {
984 device_pixels.0 as usize
985 }
986}
987
988impl From<usize> for DevicePixels {
989 fn from(device_pixels: usize) -> Self {
990 DevicePixels(device_pixels as i32)
991 }
992}
993
994#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
995#[repr(transparent)]
996pub struct ScaledPixels(pub(crate) f32);
997
998impl ScaledPixels {
999 pub fn floor(&self) -> Self {
1000 Self(self.0.floor())
1001 }
1002
1003 pub fn ceil(&self) -> Self {
1004 Self(self.0.ceil())
1005 }
1006}
1007
1008impl Eq for ScaledPixels {}
1009
1010impl Debug for ScaledPixels {
1011 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1012 write!(f, "{} px (scaled)", self.0)
1013 }
1014}
1015
1016impl From<ScaledPixels> for DevicePixels {
1017 fn from(scaled: ScaledPixels) -> Self {
1018 DevicePixels(scaled.0.ceil() as i32)
1019 }
1020}
1021
1022impl From<DevicePixels> for ScaledPixels {
1023 fn from(device: DevicePixels) -> Self {
1024 ScaledPixels(device.0 as f32)
1025 }
1026}
1027
1028impl From<ScaledPixels> for f64 {
1029 fn from(scaled_pixels: ScaledPixels) -> Self {
1030 scaled_pixels.0 as f64
1031 }
1032}
1033
1034#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
1035#[repr(transparent)]
1036pub struct GlobalPixels(pub(crate) f32);
1037
1038impl Debug for GlobalPixels {
1039 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1040 write!(f, "{} px (global coordinate space)", self.0)
1041 }
1042}
1043
1044impl From<GlobalPixels> for f64 {
1045 fn from(global_pixels: GlobalPixels) -> Self {
1046 global_pixels.0 as f64
1047 }
1048}
1049
1050impl From<f64> for GlobalPixels {
1051 fn from(global_pixels: f64) -> Self {
1052 GlobalPixels(global_pixels as f32)
1053 }
1054}
1055
1056impl sqlez::bindable::StaticColumnCount for GlobalPixels {}
1057
1058impl sqlez::bindable::Bind for GlobalPixels {
1059 fn bind(
1060 &self,
1061 statement: &sqlez::statement::Statement,
1062 start_index: i32,
1063 ) -> anyhow::Result<i32> {
1064 self.0.bind(statement, start_index)
1065 }
1066}
1067
1068#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
1069pub struct Rems(pub f32);
1070
1071impl Mul<Pixels> for Rems {
1072 type Output = Pixels;
1073
1074 fn mul(self, other: Pixels) -> Pixels {
1075 Pixels(self.0 * other.0)
1076 }
1077}
1078
1079impl Debug for Rems {
1080 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1081 write!(f, "{} rem", self.0)
1082 }
1083}
1084
1085#[derive(Clone, Copy, Debug, Neg)]
1086pub enum AbsoluteLength {
1087 Pixels(Pixels),
1088 Rems(Rems),
1089}
1090
1091impl AbsoluteLength {
1092 pub fn is_zero(&self) -> bool {
1093 match self {
1094 AbsoluteLength::Pixels(px) => px.0 == 0.,
1095 AbsoluteLength::Rems(rems) => rems.0 == 0.,
1096 }
1097 }
1098}
1099
1100impl From<Pixels> for AbsoluteLength {
1101 fn from(pixels: Pixels) -> Self {
1102 AbsoluteLength::Pixels(pixels)
1103 }
1104}
1105
1106impl From<Rems> for AbsoluteLength {
1107 fn from(rems: Rems) -> Self {
1108 AbsoluteLength::Rems(rems)
1109 }
1110}
1111
1112impl AbsoluteLength {
1113 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
1114 match self {
1115 AbsoluteLength::Pixels(pixels) => *pixels,
1116 AbsoluteLength::Rems(rems) => *rems * rem_size,
1117 }
1118 }
1119}
1120
1121impl Default for AbsoluteLength {
1122 fn default() -> Self {
1123 px(0.).into()
1124 }
1125}
1126
1127/// A non-auto length that can be defined in pixels, rems, or percent of parent.
1128#[derive(Clone, Copy, Neg)]
1129pub enum DefiniteLength {
1130 Absolute(AbsoluteLength),
1131 /// A fraction of the parent's size between 0 and 1.
1132 Fraction(f32),
1133}
1134
1135impl DefiniteLength {
1136 pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
1137 match self {
1138 DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
1139 DefiniteLength::Fraction(fraction) => match base_size {
1140 AbsoluteLength::Pixels(px) => px * *fraction,
1141 AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
1142 },
1143 }
1144 }
1145}
1146
1147impl Debug for DefiniteLength {
1148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1149 match self {
1150 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
1151 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
1152 }
1153 }
1154}
1155
1156impl From<Pixels> for DefiniteLength {
1157 fn from(pixels: Pixels) -> Self {
1158 Self::Absolute(pixels.into())
1159 }
1160}
1161
1162impl From<Rems> for DefiniteLength {
1163 fn from(rems: Rems) -> Self {
1164 Self::Absolute(rems.into())
1165 }
1166}
1167
1168impl From<AbsoluteLength> for DefiniteLength {
1169 fn from(length: AbsoluteLength) -> Self {
1170 Self::Absolute(length)
1171 }
1172}
1173
1174impl Default for DefiniteLength {
1175 fn default() -> Self {
1176 Self::Absolute(AbsoluteLength::default())
1177 }
1178}
1179
1180/// A length that can be defined in pixels, rems, percent of parent, or auto.
1181#[derive(Clone, Copy)]
1182pub enum Length {
1183 Definite(DefiniteLength),
1184 Auto,
1185}
1186
1187impl Debug for Length {
1188 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1189 match self {
1190 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
1191 Length::Auto => write!(f, "auto"),
1192 }
1193 }
1194}
1195
1196pub fn relative(fraction: f32) -> DefiniteLength {
1197 DefiniteLength::Fraction(fraction).into()
1198}
1199
1200/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1201pub fn phi() -> DefiniteLength {
1202 relative(1.61803398875)
1203}
1204
1205pub fn rems(rems: f32) -> Rems {
1206 Rems(rems)
1207}
1208
1209pub const fn px(pixels: f32) -> Pixels {
1210 Pixels(pixels)
1211}
1212
1213pub fn auto() -> Length {
1214 Length::Auto
1215}
1216
1217impl From<Pixels> for Length {
1218 fn from(pixels: Pixels) -> Self {
1219 Self::Definite(pixels.into())
1220 }
1221}
1222
1223impl From<Rems> for Length {
1224 fn from(rems: Rems) -> Self {
1225 Self::Definite(rems.into())
1226 }
1227}
1228
1229impl From<DefiniteLength> for Length {
1230 fn from(length: DefiniteLength) -> Self {
1231 Self::Definite(length)
1232 }
1233}
1234
1235impl From<AbsoluteLength> for Length {
1236 fn from(length: AbsoluteLength) -> Self {
1237 Self::Definite(length.into())
1238 }
1239}
1240
1241impl Default for Length {
1242 fn default() -> Self {
1243 Self::Definite(DefiniteLength::default())
1244 }
1245}
1246
1247impl From<()> for Length {
1248 fn from(_: ()) -> Self {
1249 Self::Definite(DefiniteLength::default())
1250 }
1251}
1252
1253pub trait Half {
1254 fn half(&self) -> Self;
1255}
1256
1257impl Half for f32 {
1258 fn half(&self) -> Self {
1259 self / 2.
1260 }
1261}
1262
1263impl Half for DevicePixels {
1264 fn half(&self) -> Self {
1265 Self(self.0 / 2)
1266 }
1267}
1268
1269impl Half for ScaledPixels {
1270 fn half(&self) -> Self {
1271 Self(self.0 / 2.)
1272 }
1273}
1274
1275impl Half for Pixels {
1276 fn half(&self) -> Self {
1277 Self(self.0 / 2.)
1278 }
1279}
1280
1281impl Half for Rems {
1282 fn half(&self) -> Self {
1283 Self(self.0 / 2.)
1284 }
1285}
1286
1287impl Half for GlobalPixels {
1288 fn half(&self) -> Self {
1289 Self(self.0 / 2.)
1290 }
1291}
1292
1293pub trait IsZero {
1294 fn is_zero(&self) -> bool;
1295}
1296
1297impl IsZero for DevicePixels {
1298 fn is_zero(&self) -> bool {
1299 self.0 == 0
1300 }
1301}
1302
1303impl IsZero for ScaledPixels {
1304 fn is_zero(&self) -> bool {
1305 self.0 == 0.
1306 }
1307}
1308
1309impl IsZero for Pixels {
1310 fn is_zero(&self) -> bool {
1311 self.0 == 0.
1312 }
1313}
1314
1315impl IsZero for Rems {
1316 fn is_zero(&self) -> bool {
1317 self.0 == 0.
1318 }
1319}
1320
1321impl IsZero for AbsoluteLength {
1322 fn is_zero(&self) -> bool {
1323 match self {
1324 AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1325 AbsoluteLength::Rems(rems) => rems.is_zero(),
1326 }
1327 }
1328}
1329
1330impl IsZero for DefiniteLength {
1331 fn is_zero(&self) -> bool {
1332 match self {
1333 DefiniteLength::Absolute(length) => length.is_zero(),
1334 DefiniteLength::Fraction(fraction) => *fraction == 0.,
1335 }
1336 }
1337}
1338
1339impl IsZero for Length {
1340 fn is_zero(&self) -> bool {
1341 match self {
1342 Length::Definite(length) => length.is_zero(),
1343 Length::Auto => false,
1344 }
1345 }
1346}
1347
1348impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1349 fn is_zero(&self) -> bool {
1350 self.x.is_zero() && self.y.is_zero()
1351 }
1352}
1353
1354impl<T> IsZero for Size<T>
1355where
1356 T: IsZero + Default + Debug + Clone,
1357{
1358 fn is_zero(&self) -> bool {
1359 self.width.is_zero() || self.height.is_zero()
1360 }
1361}
1362
1363impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1364 fn is_zero(&self) -> bool {
1365 self.size.is_zero()
1366 }
1367}
1368
1369impl<T> IsZero for Corners<T>
1370where
1371 T: IsZero + Clone + Default + Debug,
1372{
1373 fn is_zero(&self) -> bool {
1374 self.top_left.is_zero()
1375 && self.top_right.is_zero()
1376 && self.bottom_right.is_zero()
1377 && self.bottom_left.is_zero()
1378 }
1379}
1380
1381#[cfg(test)]
1382mod tests {
1383 use super::*;
1384
1385 #[test]
1386 fn test_bounds_intersects() {
1387 let bounds1 = Bounds {
1388 origin: Point { x: 0.0, y: 0.0 },
1389 size: Size {
1390 width: 5.0,
1391 height: 5.0,
1392 },
1393 };
1394 let bounds2 = Bounds {
1395 origin: Point { x: 4.0, y: 4.0 },
1396 size: Size {
1397 width: 5.0,
1398 height: 5.0,
1399 },
1400 };
1401 let bounds3 = Bounds {
1402 origin: Point { x: 10.0, y: 10.0 },
1403 size: Size {
1404 width: 5.0,
1405 height: 5.0,
1406 },
1407 };
1408
1409 // Test Case 1: Intersecting bounds
1410 assert_eq!(bounds1.intersects(&bounds2), true);
1411
1412 // Test Case 2: Non-Intersecting bounds
1413 assert_eq!(bounds1.intersects(&bounds3), false);
1414
1415 // Test Case 3: Bounds intersecting with themselves
1416 assert_eq!(bounds1.intersects(&bounds1), true);
1417 }
1418}