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