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