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,
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
367impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
368 pub fn intersect(&self, other: &Self) -> Self {
369 let upper_left = self.origin.max(&other.origin);
370 let lower_right = self.lower_right().min(&other.lower_right());
371 Self::from_corners(upper_left, lower_right)
372 }
373
374 pub fn union(&self, other: &Self) -> Self {
375 let top_left = self.origin.min(&other.origin);
376 let bottom_right = self.lower_right().max(&other.lower_right());
377 Bounds::from_corners(top_left, bottom_right)
378 }
379}
380
381impl<T, Rhs> Mul<Rhs> for Bounds<T>
382where
383 T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
384 Point<T>: Mul<Rhs, Output = Point<Rhs>>,
385 Rhs: Clone + Default + Debug,
386{
387 type Output = Bounds<Rhs>;
388
389 fn mul(self, rhs: Rhs) -> Self::Output {
390 Bounds {
391 origin: self.origin * rhs.clone(),
392 size: self.size * rhs,
393 }
394 }
395}
396
397impl<T, S> MulAssign<S> for Bounds<T>
398where
399 T: Mul<S, Output = T> + Clone + Default + Debug,
400 S: Clone,
401{
402 fn mul_assign(&mut self, rhs: S) {
403 self.origin *= rhs.clone();
404 self.size *= rhs;
405 }
406}
407
408impl<T, S> Div<S> for Bounds<T>
409where
410 Size<T>: Div<S, Output = Size<T>>,
411 T: Div<S, Output = T> + Default + Clone + Debug,
412 S: Clone,
413{
414 type Output = Self;
415
416 fn div(self, rhs: S) -> Self {
417 Self {
418 origin: self.origin / rhs.clone(),
419 size: self.size / rhs,
420 }
421 }
422}
423
424impl<T> Bounds<T>
425where
426 T: Add<T, Output = T> + Clone + Default + Debug,
427{
428 pub fn top(&self) -> T {
429 self.origin.y.clone()
430 }
431
432 pub fn bottom(&self) -> T {
433 self.origin.y.clone() + self.size.height.clone()
434 }
435
436 pub fn left(&self) -> T {
437 self.origin.x.clone()
438 }
439
440 pub fn right(&self) -> T {
441 self.origin.x.clone() + self.size.width.clone()
442 }
443
444 pub fn upper_right(&self) -> Point<T> {
445 Point {
446 x: self.origin.x.clone() + self.size.width.clone(),
447 y: self.origin.y.clone(),
448 }
449 }
450
451 pub fn lower_right(&self) -> Point<T> {
452 Point {
453 x: self.origin.x.clone() + self.size.width.clone(),
454 y: self.origin.y.clone() + self.size.height.clone(),
455 }
456 }
457
458 pub fn lower_left(&self) -> Point<T> {
459 Point {
460 x: self.origin.x.clone(),
461 y: self.origin.y.clone() + self.size.height.clone(),
462 }
463 }
464}
465
466impl<T> Bounds<T>
467where
468 T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
469{
470 pub fn contains_point(&self, point: &Point<T>) -> bool {
471 point.x >= self.origin.x
472 && point.x <= self.origin.x.clone() + self.size.width.clone()
473 && point.y >= self.origin.y
474 && point.y <= self.origin.y.clone() + self.size.height.clone()
475 }
476
477 pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
478 where
479 U: Clone + Default + Debug,
480 {
481 Bounds {
482 origin: self.origin.map(&f),
483 size: self.size.map(f),
484 }
485 }
486}
487
488impl Bounds<Pixels> {
489 pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
490 Bounds {
491 origin: self.origin.scale(factor),
492 size: self.size.scale(factor),
493 }
494 }
495}
496
497impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
498
499#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
500#[refineable(Debug)]
501#[repr(C)]
502pub struct Edges<T: Clone + Default + Debug> {
503 pub top: T,
504 pub right: T,
505 pub bottom: T,
506 pub left: T,
507}
508
509impl<T> Mul for Edges<T>
510where
511 T: Mul<Output = T> + Clone + Default + Debug,
512{
513 type Output = Self;
514
515 fn mul(self, rhs: Self) -> Self::Output {
516 Self {
517 top: self.top.clone() * rhs.top,
518 right: self.right.clone() * rhs.right,
519 bottom: self.bottom.clone() * rhs.bottom,
520 left: self.left.clone() * rhs.left,
521 }
522 }
523}
524
525impl<T, S> MulAssign<S> for Edges<T>
526where
527 T: Mul<S, Output = T> + Clone + Default + Debug,
528 S: Clone,
529{
530 fn mul_assign(&mut self, rhs: S) {
531 self.top = self.top.clone() * rhs.clone();
532 self.right = self.right.clone() * rhs.clone();
533 self.bottom = self.bottom.clone() * rhs.clone();
534 self.left = self.left.clone() * rhs;
535 }
536}
537
538impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
539
540impl<T: Clone + Default + Debug> Edges<T> {
541 pub fn all(value: T) -> Self {
542 Self {
543 top: value.clone(),
544 right: value.clone(),
545 bottom: value.clone(),
546 left: value,
547 }
548 }
549
550 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
551 where
552 U: Clone + Default + Debug,
553 {
554 Edges {
555 top: f(&self.top),
556 right: f(&self.right),
557 bottom: f(&self.bottom),
558 left: f(&self.left),
559 }
560 }
561
562 pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
563 predicate(&self.top)
564 || predicate(&self.right)
565 || predicate(&self.bottom)
566 || predicate(&self.left)
567 }
568}
569
570impl Edges<Length> {
571 pub fn auto() -> Self {
572 Self {
573 top: Length::Auto,
574 right: Length::Auto,
575 bottom: Length::Auto,
576 left: Length::Auto,
577 }
578 }
579
580 pub fn zero() -> Self {
581 Self {
582 top: px(0.).into(),
583 right: px(0.).into(),
584 bottom: px(0.).into(),
585 left: px(0.).into(),
586 }
587 }
588}
589
590impl Edges<DefiniteLength> {
591 pub fn zero() -> Self {
592 Self {
593 top: px(0.).into(),
594 right: px(0.).into(),
595 bottom: px(0.).into(),
596 left: px(0.).into(),
597 }
598 }
599
600 pub fn to_pixels(&self, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
601 Edges {
602 top: self.top.to_pixels(parent_size.height, rem_size),
603 right: self.right.to_pixels(parent_size.width, rem_size),
604 bottom: self.bottom.to_pixels(parent_size.height, rem_size),
605 left: self.left.to_pixels(parent_size.width, rem_size),
606 }
607 }
608}
609
610impl Edges<AbsoluteLength> {
611 pub fn zero() -> Self {
612 Self {
613 top: px(0.).into(),
614 right: px(0.).into(),
615 bottom: px(0.).into(),
616 left: px(0.).into(),
617 }
618 }
619
620 pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
621 Edges {
622 top: self.top.to_pixels(rem_size),
623 right: self.right.to_pixels(rem_size),
624 bottom: self.bottom.to_pixels(rem_size),
625 left: self.left.to_pixels(rem_size),
626 }
627 }
628}
629
630impl Edges<Pixels> {
631 pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
632 Edges {
633 top: self.top.scale(factor),
634 right: self.right.scale(factor),
635 bottom: self.bottom.scale(factor),
636 left: self.left.scale(factor),
637 }
638 }
639}
640
641#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
642#[refineable(Debug)]
643#[repr(C)]
644pub struct Corners<T: Clone + Default + Debug> {
645 pub top_left: T,
646 pub top_right: T,
647 pub bottom_right: T,
648 pub bottom_left: T,
649}
650
651impl Corners<AbsoluteLength> {
652 pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
653 let max = size.width.max(size.height) / 2.;
654 Corners {
655 top_left: self.top_left.to_pixels(rem_size).min(max),
656 top_right: self.top_right.to_pixels(rem_size).min(max),
657 bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
658 bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
659 }
660 }
661}
662
663impl Corners<Pixels> {
664 pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
665 Corners {
666 top_left: self.top_left.scale(factor),
667 top_right: self.top_right.scale(factor),
668 bottom_right: self.bottom_right.scale(factor),
669 bottom_left: self.bottom_left.scale(factor),
670 }
671 }
672}
673
674impl<T: Clone + Default + Debug> Corners<T> {
675 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
676 where
677 U: Clone + Default + Debug,
678 {
679 Corners {
680 top_left: f(&self.top_left),
681 top_right: f(&self.top_right),
682 bottom_right: f(&self.bottom_right),
683 bottom_left: f(&self.bottom_left),
684 }
685 }
686}
687
688impl<T> Mul for Corners<T>
689where
690 T: Mul<Output = T> + Clone + Default + Debug,
691{
692 type Output = Self;
693
694 fn mul(self, rhs: Self) -> Self::Output {
695 Self {
696 top_left: self.top_left.clone() * rhs.top_left,
697 top_right: self.top_right.clone() * rhs.top_right,
698 bottom_right: self.bottom_right.clone() * rhs.bottom_right,
699 bottom_left: self.bottom_left.clone() * rhs.bottom_left,
700 }
701 }
702}
703
704impl<T, S> MulAssign<S> for Corners<T>
705where
706 T: Mul<S, Output = T> + Clone + Default + Debug,
707 S: Clone,
708{
709 fn mul_assign(&mut self, rhs: S) {
710 self.top_left = self.top_left.clone() * rhs.clone();
711 self.top_right = self.top_right.clone() * rhs.clone();
712 self.bottom_right = self.bottom_right.clone() * rhs.clone();
713 self.bottom_left = self.bottom_left.clone() * rhs;
714 }
715}
716
717impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
718
719#[derive(
720 Clone,
721 Copy,
722 Default,
723 Add,
724 AddAssign,
725 Sub,
726 SubAssign,
727 Neg,
728 Div,
729 DivAssign,
730 PartialEq,
731 PartialOrd,
732 Serialize,
733 Deserialize,
734)]
735#[repr(transparent)]
736pub struct Pixels(pub(crate) f32);
737
738impl std::ops::Div for Pixels {
739 type Output = f32;
740
741 fn div(self, rhs: Self) -> Self::Output {
742 self.0 / rhs.0
743 }
744}
745
746impl std::ops::DivAssign for Pixels {
747 fn div_assign(&mut self, rhs: Self) {
748 *self = Self(self.0 / rhs.0);
749 }
750}
751
752impl std::ops::RemAssign for Pixels {
753 fn rem_assign(&mut self, rhs: Self) {
754 self.0 %= rhs.0;
755 }
756}
757
758impl std::ops::Rem for Pixels {
759 type Output = Self;
760
761 fn rem(self, rhs: Self) -> Self {
762 Self(self.0 % rhs.0)
763 }
764}
765
766impl Mul<f32> for Pixels {
767 type Output = Pixels;
768
769 fn mul(self, other: f32) -> Pixels {
770 Pixels(self.0 * other)
771 }
772}
773
774impl Mul<usize> for Pixels {
775 type Output = Pixels;
776
777 fn mul(self, other: usize) -> Pixels {
778 Pixels(self.0 * other as f32)
779 }
780}
781
782impl Mul<Pixels> for f32 {
783 type Output = Pixels;
784
785 fn mul(self, rhs: Pixels) -> Self::Output {
786 Pixels(self * rhs.0)
787 }
788}
789
790impl MulAssign<f32> for Pixels {
791 fn mul_assign(&mut self, other: f32) {
792 self.0 *= other;
793 }
794}
795
796impl Pixels {
797 pub const ZERO: Pixels = Pixels(0.0);
798 pub const MAX: Pixels = Pixels(f32::MAX);
799
800 pub fn floor(&self) -> Self {
801 Self(self.0.floor())
802 }
803
804 pub fn round(&self) -> Self {
805 Self(self.0.round())
806 }
807
808 pub fn ceil(&self) -> Self {
809 Self(self.0.ceil())
810 }
811
812 pub fn scale(&self, factor: f32) -> ScaledPixels {
813 ScaledPixels(self.0 * factor)
814 }
815
816 pub fn pow(&self, exponent: f32) -> Self {
817 Self(self.0.powf(exponent))
818 }
819
820 pub fn abs(&self) -> Self {
821 Self(self.0.abs())
822 }
823}
824
825impl Mul<Pixels> for Pixels {
826 type Output = Pixels;
827
828 fn mul(self, rhs: Pixels) -> Self::Output {
829 Pixels(self.0 * rhs.0)
830 }
831}
832
833impl Eq for Pixels {}
834
835impl Ord for Pixels {
836 fn cmp(&self, other: &Self) -> cmp::Ordering {
837 self.0.partial_cmp(&other.0).unwrap()
838 }
839}
840
841impl std::hash::Hash for Pixels {
842 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
843 self.0.to_bits().hash(state);
844 }
845}
846
847impl From<f64> for Pixels {
848 fn from(pixels: f64) -> Self {
849 Pixels(pixels as f32)
850 }
851}
852
853impl From<f32> for Pixels {
854 fn from(pixels: f32) -> Self {
855 Pixels(pixels)
856 }
857}
858
859impl Debug for Pixels {
860 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
861 write!(f, "{} px", self.0)
862 }
863}
864
865impl From<Pixels> for f32 {
866 fn from(pixels: Pixels) -> Self {
867 pixels.0
868 }
869}
870
871impl From<&Pixels> for f32 {
872 fn from(pixels: &Pixels) -> Self {
873 pixels.0
874 }
875}
876
877impl From<Pixels> for f64 {
878 fn from(pixels: Pixels) -> Self {
879 pixels.0 as f64
880 }
881}
882
883impl From<Pixels> for u32 {
884 fn from(pixels: Pixels) -> Self {
885 pixels.0 as u32
886 }
887}
888
889impl From<u32> for Pixels {
890 fn from(pixels: u32) -> Self {
891 Pixels(pixels as f32)
892 }
893}
894
895impl From<Pixels> for usize {
896 fn from(pixels: Pixels) -> Self {
897 pixels.0 as usize
898 }
899}
900
901#[derive(
902 Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
903)]
904#[repr(transparent)]
905pub struct DevicePixels(pub(crate) i32);
906
907impl DevicePixels {
908 pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
909 self.0 as u32 * bytes_per_pixel as u32
910 }
911}
912
913impl fmt::Debug for DevicePixels {
914 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
915 write!(f, "{} px (device)", self.0)
916 }
917}
918
919impl From<DevicePixels> for i32 {
920 fn from(device_pixels: DevicePixels) -> Self {
921 device_pixels.0
922 }
923}
924
925impl From<i32> for DevicePixels {
926 fn from(device_pixels: i32) -> Self {
927 DevicePixels(device_pixels)
928 }
929}
930
931impl From<u32> for DevicePixels {
932 fn from(device_pixels: u32) -> Self {
933 DevicePixels(device_pixels as i32)
934 }
935}
936
937impl From<DevicePixels> for u32 {
938 fn from(device_pixels: DevicePixels) -> Self {
939 device_pixels.0 as u32
940 }
941}
942
943impl From<DevicePixels> for u64 {
944 fn from(device_pixels: DevicePixels) -> Self {
945 device_pixels.0 as u64
946 }
947}
948
949impl From<u64> for DevicePixels {
950 fn from(device_pixels: u64) -> Self {
951 DevicePixels(device_pixels as i32)
952 }
953}
954
955#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
956#[repr(transparent)]
957pub struct ScaledPixels(pub(crate) f32);
958
959impl ScaledPixels {
960 pub fn floor(&self) -> Self {
961 Self(self.0.floor())
962 }
963
964 pub fn ceil(&self) -> Self {
965 Self(self.0.ceil())
966 }
967}
968
969impl Eq for ScaledPixels {}
970
971impl Debug for ScaledPixels {
972 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
973 write!(f, "{} px (scaled)", self.0)
974 }
975}
976
977impl From<ScaledPixels> for DevicePixels {
978 fn from(scaled: ScaledPixels) -> Self {
979 DevicePixels(scaled.0.ceil() as i32)
980 }
981}
982
983impl From<DevicePixels> for ScaledPixels {
984 fn from(device: DevicePixels) -> Self {
985 ScaledPixels(device.0 as f32)
986 }
987}
988
989impl From<ScaledPixels> for f64 {
990 fn from(scaled_pixels: ScaledPixels) -> Self {
991 scaled_pixels.0 as f64
992 }
993}
994
995#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
996#[repr(transparent)]
997pub struct GlobalPixels(pub(crate) f32);
998
999impl Debug for GlobalPixels {
1000 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1001 write!(f, "{} px (global coordinate space)", self.0)
1002 }
1003}
1004
1005impl From<GlobalPixels> for f64 {
1006 fn from(global_pixels: GlobalPixels) -> Self {
1007 global_pixels.0 as f64
1008 }
1009}
1010
1011impl From<f64> for GlobalPixels {
1012 fn from(global_pixels: f64) -> Self {
1013 GlobalPixels(global_pixels as f32)
1014 }
1015}
1016
1017impl sqlez::bindable::StaticColumnCount for GlobalPixels {}
1018
1019impl sqlez::bindable::Bind for GlobalPixels {
1020 fn bind(
1021 &self,
1022 statement: &sqlez::statement::Statement,
1023 start_index: i32,
1024 ) -> anyhow::Result<i32> {
1025 self.0.bind(statement, start_index)
1026 }
1027}
1028
1029#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
1030pub struct Rems(f32);
1031
1032impl Mul<Pixels> for Rems {
1033 type Output = Pixels;
1034
1035 fn mul(self, other: Pixels) -> Pixels {
1036 Pixels(self.0 * other.0)
1037 }
1038}
1039
1040impl Debug for Rems {
1041 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1042 write!(f, "{} rem", self.0)
1043 }
1044}
1045
1046#[derive(Clone, Copy, Debug, Neg)]
1047pub enum AbsoluteLength {
1048 Pixels(Pixels),
1049 Rems(Rems),
1050}
1051
1052impl AbsoluteLength {
1053 pub fn is_zero(&self) -> bool {
1054 match self {
1055 AbsoluteLength::Pixels(px) => px.0 == 0.,
1056 AbsoluteLength::Rems(rems) => rems.0 == 0.,
1057 }
1058 }
1059}
1060
1061impl From<Pixels> for AbsoluteLength {
1062 fn from(pixels: Pixels) -> Self {
1063 AbsoluteLength::Pixels(pixels)
1064 }
1065}
1066
1067impl From<Rems> for AbsoluteLength {
1068 fn from(rems: Rems) -> Self {
1069 AbsoluteLength::Rems(rems)
1070 }
1071}
1072
1073impl AbsoluteLength {
1074 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
1075 match self {
1076 AbsoluteLength::Pixels(pixels) => *pixels,
1077 AbsoluteLength::Rems(rems) => *rems * rem_size,
1078 }
1079 }
1080}
1081
1082impl Default for AbsoluteLength {
1083 fn default() -> Self {
1084 px(0.).into()
1085 }
1086}
1087
1088/// A non-auto length that can be defined in pixels, rems, or percent of parent.
1089#[derive(Clone, Copy, Neg)]
1090pub enum DefiniteLength {
1091 Absolute(AbsoluteLength),
1092 /// A fraction of the parent's size between 0 and 1.
1093 Fraction(f32),
1094}
1095
1096impl DefiniteLength {
1097 pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
1098 match self {
1099 DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
1100 DefiniteLength::Fraction(fraction) => match base_size {
1101 AbsoluteLength::Pixels(px) => px * *fraction,
1102 AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
1103 },
1104 }
1105 }
1106}
1107
1108impl Debug for DefiniteLength {
1109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1110 match self {
1111 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
1112 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
1113 }
1114 }
1115}
1116
1117impl From<Pixels> for DefiniteLength {
1118 fn from(pixels: Pixels) -> Self {
1119 Self::Absolute(pixels.into())
1120 }
1121}
1122
1123impl From<Rems> for DefiniteLength {
1124 fn from(rems: Rems) -> Self {
1125 Self::Absolute(rems.into())
1126 }
1127}
1128
1129impl From<AbsoluteLength> for DefiniteLength {
1130 fn from(length: AbsoluteLength) -> Self {
1131 Self::Absolute(length)
1132 }
1133}
1134
1135impl Default for DefiniteLength {
1136 fn default() -> Self {
1137 Self::Absolute(AbsoluteLength::default())
1138 }
1139}
1140
1141/// A length that can be defined in pixels, rems, percent of parent, or auto.
1142#[derive(Clone, Copy)]
1143pub enum Length {
1144 Definite(DefiniteLength),
1145 Auto,
1146}
1147
1148impl Debug for Length {
1149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1150 match self {
1151 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
1152 Length::Auto => write!(f, "auto"),
1153 }
1154 }
1155}
1156
1157pub fn relative(fraction: f32) -> DefiniteLength {
1158 DefiniteLength::Fraction(fraction).into()
1159}
1160
1161/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1162pub fn phi() -> DefiniteLength {
1163 relative(1.61803398875)
1164}
1165
1166pub fn rems(rems: f32) -> Rems {
1167 Rems(rems)
1168}
1169
1170pub const fn px(pixels: f32) -> Pixels {
1171 Pixels(pixels)
1172}
1173
1174pub fn auto() -> Length {
1175 Length::Auto
1176}
1177
1178impl From<Pixels> for Length {
1179 fn from(pixels: Pixels) -> Self {
1180 Self::Definite(pixels.into())
1181 }
1182}
1183
1184impl From<Rems> for Length {
1185 fn from(rems: Rems) -> Self {
1186 Self::Definite(rems.into())
1187 }
1188}
1189
1190impl From<DefiniteLength> for Length {
1191 fn from(length: DefiniteLength) -> Self {
1192 Self::Definite(length)
1193 }
1194}
1195
1196impl From<AbsoluteLength> for Length {
1197 fn from(length: AbsoluteLength) -> Self {
1198 Self::Definite(length.into())
1199 }
1200}
1201
1202impl Default for Length {
1203 fn default() -> Self {
1204 Self::Definite(DefiniteLength::default())
1205 }
1206}
1207
1208impl From<()> for Length {
1209 fn from(_: ()) -> Self {
1210 Self::Definite(DefiniteLength::default())
1211 }
1212}
1213
1214pub trait IsZero {
1215 fn is_zero(&self) -> bool;
1216}
1217
1218impl IsZero for DevicePixels {
1219 fn is_zero(&self) -> bool {
1220 self.0 == 0
1221 }
1222}
1223
1224impl IsZero for ScaledPixels {
1225 fn is_zero(&self) -> bool {
1226 self.0 == 0.
1227 }
1228}
1229
1230impl IsZero for Pixels {
1231 fn is_zero(&self) -> bool {
1232 self.0 == 0.
1233 }
1234}
1235
1236impl IsZero for Rems {
1237 fn is_zero(&self) -> bool {
1238 self.0 == 0.
1239 }
1240}
1241
1242impl IsZero for AbsoluteLength {
1243 fn is_zero(&self) -> bool {
1244 match self {
1245 AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1246 AbsoluteLength::Rems(rems) => rems.is_zero(),
1247 }
1248 }
1249}
1250
1251impl IsZero for DefiniteLength {
1252 fn is_zero(&self) -> bool {
1253 match self {
1254 DefiniteLength::Absolute(length) => length.is_zero(),
1255 DefiniteLength::Fraction(fraction) => *fraction == 0.,
1256 }
1257 }
1258}
1259
1260impl IsZero for Length {
1261 fn is_zero(&self) -> bool {
1262 match self {
1263 Length::Definite(length) => length.is_zero(),
1264 Length::Auto => false,
1265 }
1266 }
1267}
1268
1269impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1270 fn is_zero(&self) -> bool {
1271 self.x.is_zero() && self.y.is_zero()
1272 }
1273}
1274
1275impl<T> IsZero for Size<T>
1276where
1277 T: IsZero + Default + Debug + Clone,
1278{
1279 fn is_zero(&self) -> bool {
1280 self.width.is_zero() || self.height.is_zero()
1281 }
1282}
1283
1284impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1285 fn is_zero(&self) -> bool {
1286 self.size.is_zero()
1287 }
1288}
1289
1290impl<T> IsZero for Corners<T>
1291where
1292 T: IsZero + Clone + Default + Debug,
1293{
1294 fn is_zero(&self) -> bool {
1295 self.top_left.is_zero()
1296 && self.top_right.is_zero()
1297 && self.bottom_right.is_zero()
1298 && self.bottom_left.is_zero()
1299 }
1300}
1301
1302#[cfg(test)]
1303mod tests {
1304 use super::*;
1305
1306 #[test]
1307 fn test_bounds_intersects() {
1308 let bounds1 = Bounds {
1309 origin: Point { x: 0.0, y: 0.0 },
1310 size: Size {
1311 width: 5.0,
1312 height: 5.0,
1313 },
1314 };
1315 let bounds2 = Bounds {
1316 origin: Point { x: 4.0, y: 4.0 },
1317 size: Size {
1318 width: 5.0,
1319 height: 5.0,
1320 },
1321 };
1322 let bounds3 = Bounds {
1323 origin: Point { x: 10.0, y: 10.0 },
1324 size: Size {
1325 width: 5.0,
1326 height: 5.0,
1327 },
1328 };
1329
1330 // Test Case 1: Intersecting bounds
1331 assert_eq!(bounds1.intersects(&bounds2), true);
1332
1333 // Test Case 2: Non-Intersecting bounds
1334 assert_eq!(bounds1.intersects(&bounds3), false);
1335
1336 // Test Case 3: Bounds intersecting with themselves
1337 assert_eq!(bounds1.intersects(&bounds1), true);
1338 }
1339}