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