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