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