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