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