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