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
202impl 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 Size<Length> {
212 pub fn full() -> Self {
213 Self {
214 width: relative(1.).into(),
215 height: relative(1.).into(),
216 }
217 }
218}
219
220impl Size<DefiniteLength> {
221 pub fn zero() -> Self {
222 Self {
223 width: px(0.).into(),
224 height: px(0.).into(),
225 }
226 }
227}
228
229impl Size<Length> {
230 pub fn auto() -> Self {
231 Self {
232 width: Length::Auto,
233 height: Length::Auto,
234 }
235 }
236}
237
238#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
239#[refineable(debug)]
240#[repr(C)]
241pub struct Bounds<T: Clone + Debug> {
242 pub origin: Point<T>,
243 pub size: Size<T>,
244}
245
246impl<T: Clone + Debug + Sub<Output = T>> Bounds<T> {
247 pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
248 let origin = Point {
249 x: upper_left.x.clone(),
250 y: upper_left.y.clone(),
251 };
252 let size = Size {
253 width: lower_right.x - upper_left.x,
254 height: lower_right.y - upper_left.y,
255 };
256 Bounds { origin, size }
257 }
258}
259
260impl<T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
261 pub fn intersect(&self, other: &Self) -> Self {
262 let upper_left = self.origin.max(&other.origin);
263 let lower_right = self.lower_right().min(&other.lower_right());
264 Self::from_corners(upper_left, lower_right)
265 }
266}
267
268impl<T, Rhs> Mul<Rhs> for Bounds<T>
269where
270 T: Mul<Rhs, Output = Rhs> + Clone + Debug,
271 Point<T>: Mul<Rhs, Output = Point<Rhs>>,
272 Rhs: Clone + Debug,
273{
274 type Output = Bounds<Rhs>;
275
276 fn mul(self, rhs: Rhs) -> Self::Output {
277 Bounds {
278 origin: self.origin * rhs.clone(),
279 size: self.size * rhs,
280 }
281 }
282}
283
284impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Bounds<T> {
285 fn mul_assign(&mut self, rhs: S) {
286 self.origin *= rhs.clone();
287 self.size *= rhs;
288 }
289}
290
291impl<T: Clone + Debug + Div<S, Output = T>, S: Clone> Div<S> for Bounds<T>
292where
293 Size<T>: Div<S, Output = Size<T>>,
294{
295 type Output = Self;
296
297 fn div(self, rhs: S) -> Self {
298 Self {
299 origin: self.origin / rhs.clone(),
300 size: self.size / rhs,
301 }
302 }
303}
304
305impl<T: Clone + Debug + Add<T, Output = T>> Bounds<T> {
306 pub fn upper_right(&self) -> Point<T> {
307 Point {
308 x: self.origin.x.clone() + self.size.width.clone(),
309 y: self.origin.y.clone(),
310 }
311 }
312
313 pub fn lower_right(&self) -> Point<T> {
314 Point {
315 x: self.origin.x.clone() + self.size.width.clone(),
316 y: self.origin.y.clone() + self.size.height.clone(),
317 }
318 }
319}
320
321impl<T: Clone + Debug + PartialOrd + Add<T, Output = T>> Bounds<T> {
322 pub fn contains_point(&self, point: Point<T>) -> bool {
323 point.x >= self.origin.x
324 && point.x <= self.origin.x.clone() + self.size.width.clone()
325 && point.y >= self.origin.y
326 && point.y <= self.origin.y.clone() + self.size.height.clone()
327 }
328
329 pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Bounds<U> {
330 Bounds {
331 origin: self.origin.map(&f),
332 size: self.size.map(f),
333 }
334 }
335}
336
337impl Bounds<Pixels> {
338 pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
339 Bounds {
340 origin: self.origin.scale(factor),
341 size: self.size.scale(factor),
342 }
343 }
344}
345
346impl<T: Clone + Debug + Copy> Copy for Bounds<T> {}
347
348#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
349#[refineable(debug)]
350#[repr(C)]
351pub struct Edges<T: Clone + Debug> {
352 pub top: T,
353 pub right: T,
354 pub bottom: T,
355 pub left: T,
356}
357
358impl<T: Clone + Debug + Mul<Output = T>> Mul for Edges<T> {
359 type Output = Self;
360
361 fn mul(self, rhs: Self) -> Self::Output {
362 Self {
363 top: self.top.clone() * rhs.top,
364 right: self.right.clone() * rhs.right,
365 bottom: self.bottom.clone() * rhs.bottom,
366 left: self.left.clone() * rhs.left,
367 }
368 }
369}
370
371impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Edges<T> {
372 fn mul_assign(&mut self, rhs: S) {
373 self.top = self.top.clone() * rhs.clone();
374 self.right = self.right.clone() * rhs.clone();
375 self.bottom = self.bottom.clone() * rhs.clone();
376 self.left = self.left.clone() * rhs.clone();
377 }
378}
379
380impl<T: Clone + Debug + Copy> Copy for Edges<T> {}
381
382impl<T: Clone + Debug> Edges<T> {
383 pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Edges<U> {
384 Edges {
385 top: f(&self.top),
386 right: f(&self.right),
387 bottom: f(&self.bottom),
388 left: f(&self.left),
389 }
390 }
391
392 pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
393 predicate(&self.top)
394 || predicate(&self.right)
395 || predicate(&self.bottom)
396 || predicate(&self.left)
397 }
398}
399
400impl Edges<Length> {
401 pub fn auto() -> Self {
402 Self {
403 top: Length::Auto,
404 right: Length::Auto,
405 bottom: Length::Auto,
406 left: Length::Auto,
407 }
408 }
409
410 pub fn zero() -> Self {
411 Self {
412 top: px(0.).into(),
413 right: px(0.).into(),
414 bottom: px(0.).into(),
415 left: px(0.).into(),
416 }
417 }
418}
419
420impl Edges<DefiniteLength> {
421 pub fn zero() -> Self {
422 Self {
423 top: px(0.).into(),
424 right: px(0.).into(),
425 bottom: px(0.).into(),
426 left: px(0.).into(),
427 }
428 }
429}
430
431impl Edges<AbsoluteLength> {
432 pub fn zero() -> Self {
433 Self {
434 top: px(0.).into(),
435 right: px(0.).into(),
436 bottom: px(0.).into(),
437 left: px(0.).into(),
438 }
439 }
440
441 pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
442 Edges {
443 top: self.top.to_pixels(rem_size),
444 right: self.right.to_pixels(rem_size),
445 bottom: self.bottom.to_pixels(rem_size),
446 left: self.left.to_pixels(rem_size),
447 }
448 }
449}
450
451#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
452#[refineable(debug)]
453#[repr(C)]
454pub struct Corners<T: Clone + Debug> {
455 pub top_left: T,
456 pub top_right: T,
457 pub bottom_right: T,
458 pub bottom_left: T,
459}
460
461impl Corners<AbsoluteLength> {
462 pub fn to_pixels(&self, bounds: Bounds<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
463 let max = bounds.size.width.max(bounds.size.height) / 2.;
464 Corners {
465 top_left: self.top_left.to_pixels(rem_size).min(max),
466 top_right: self.top_right.to_pixels(rem_size).min(max),
467 bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
468 bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
469 }
470 }
471}
472
473impl Corners<Pixels> {
474 pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
475 Corners {
476 top_left: self.top_left.scale(factor),
477 top_right: self.top_right.scale(factor),
478 bottom_right: self.bottom_right.scale(factor),
479 bottom_left: self.bottom_left.scale(factor),
480 }
481 }
482}
483
484impl<T: Clone + Debug> Corners<T> {
485 pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Corners<U> {
486 Corners {
487 top_left: f(&self.top_left),
488 top_right: f(&self.top_right),
489 bottom_right: f(&self.bottom_right),
490 bottom_left: f(&self.bottom_left),
491 }
492 }
493}
494
495impl<T: Clone + Debug + Mul<Output = T>> Mul for Corners<T> {
496 type Output = Self;
497
498 fn mul(self, rhs: Self) -> Self::Output {
499 Self {
500 top_left: self.top_left.clone() * rhs.top_left,
501 top_right: self.top_right.clone() * rhs.top_right,
502 bottom_right: self.bottom_right.clone() * rhs.bottom_right,
503 bottom_left: self.bottom_left.clone() * rhs.bottom_left,
504 }
505 }
506}
507
508impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Corners<T> {
509 fn mul_assign(&mut self, rhs: S) {
510 self.top_left = self.top_left.clone() * rhs.clone();
511 self.top_right = self.top_right.clone() * rhs.clone();
512 self.bottom_right = self.bottom_right.clone() * rhs.clone();
513 self.bottom_left = self.bottom_left.clone() * rhs;
514 }
515}
516
517impl<T: Clone + Debug + Copy> Copy for Corners<T> {}
518
519#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
520#[repr(transparent)]
521pub struct Pixels(pub(crate) f32);
522
523impl Mul<f32> for Pixels {
524 type Output = Pixels;
525
526 fn mul(self, other: f32) -> Pixels {
527 Pixels(self.0 * other)
528 }
529}
530
531impl Mul<Pixels> for f32 {
532 type Output = Pixels;
533
534 fn mul(self, rhs: Pixels) -> Self::Output {
535 Pixels(self * rhs.0)
536 }
537}
538
539impl MulAssign<f32> for Pixels {
540 fn mul_assign(&mut self, other: f32) {
541 self.0 *= other;
542 }
543}
544
545impl Pixels {
546 pub fn round(&self) -> Self {
547 Self(self.0.round())
548 }
549
550 pub fn scale(&self, factor: f32) -> ScaledPixels {
551 ScaledPixels(self.0 * factor)
552 }
553}
554
555impl Mul<Pixels> for Pixels {
556 type Output = Pixels;
557
558 fn mul(self, rhs: Pixels) -> Self::Output {
559 Pixels(self.0 * rhs.0)
560 }
561}
562
563impl Eq for Pixels {}
564
565impl Ord for Pixels {
566 fn cmp(&self, other: &Self) -> cmp::Ordering {
567 self.0.partial_cmp(&other.0).unwrap()
568 }
569}
570
571impl std::hash::Hash for Pixels {
572 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
573 self.0.to_bits().hash(state);
574 }
575}
576
577impl From<f64> for Pixels {
578 fn from(pixels: f64) -> Self {
579 Pixels(pixels as f32)
580 }
581}
582
583impl From<f32> for Pixels {
584 fn from(pixels: f32) -> Self {
585 Pixels(pixels)
586 }
587}
588
589impl Debug for Pixels {
590 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
591 write!(f, "{} px", self.0)
592 }
593}
594
595impl From<Pixels> for f32 {
596 fn from(pixels: Pixels) -> Self {
597 pixels.0
598 }
599}
600
601impl From<&Pixels> for f32 {
602 fn from(pixels: &Pixels) -> Self {
603 pixels.0
604 }
605}
606
607impl From<Pixels> for f64 {
608 fn from(pixels: Pixels) -> Self {
609 pixels.0 as f64
610 }
611}
612
613#[derive(
614 Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
615)]
616#[repr(transparent)]
617pub struct DevicePixels(pub(crate) i32);
618
619impl DevicePixels {
620 pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
621 self.0 as u32 * bytes_per_pixel as u32
622 }
623}
624
625impl std::fmt::Debug for DevicePixels {
626 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
627 write!(f, "{} px (device)", self.0)
628 }
629}
630
631impl From<DevicePixels> for i32 {
632 fn from(device_pixels: DevicePixels) -> Self {
633 device_pixels.0
634 }
635}
636
637impl From<i32> for DevicePixels {
638 fn from(device_pixels: i32) -> Self {
639 DevicePixels(device_pixels)
640 }
641}
642
643impl From<u32> for DevicePixels {
644 fn from(device_pixels: u32) -> Self {
645 DevicePixels(device_pixels as i32)
646 }
647}
648
649impl From<DevicePixels> for u32 {
650 fn from(device_pixels: DevicePixels) -> Self {
651 device_pixels.0 as u32
652 }
653}
654
655impl From<DevicePixels> for u64 {
656 fn from(device_pixels: DevicePixels) -> Self {
657 device_pixels.0 as u64
658 }
659}
660
661impl From<u64> for DevicePixels {
662 fn from(device_pixels: u64) -> Self {
663 DevicePixels(device_pixels as i32)
664 }
665}
666
667#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
668#[repr(transparent)]
669pub struct ScaledPixels(pub(crate) f32);
670
671impl ScaledPixels {
672 pub fn floor(&self) -> Self {
673 Self(self.0.floor())
674 }
675
676 pub fn ceil(&self) -> Self {
677 Self(self.0.ceil())
678 }
679}
680
681impl Eq for ScaledPixels {}
682
683impl Debug for ScaledPixels {
684 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
685 write!(f, "{} px (scaled)", self.0)
686 }
687}
688
689impl From<ScaledPixels> for DevicePixels {
690 fn from(scaled: ScaledPixels) -> Self {
691 DevicePixels(scaled.0.ceil() as i32)
692 }
693}
694
695impl From<DevicePixels> for ScaledPixels {
696 fn from(device: DevicePixels) -> Self {
697 ScaledPixels(device.0 as f32)
698 }
699}
700
701#[derive(Clone, Copy, Default, Add, Sub, Mul, Div)]
702pub struct Rems(f32);
703
704impl Mul<Pixels> for Rems {
705 type Output = Pixels;
706
707 fn mul(self, other: Pixels) -> Pixels {
708 Pixels(self.0 * other.0)
709 }
710}
711
712impl Debug for Rems {
713 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
714 write!(f, "{} rem", self.0)
715 }
716}
717
718#[derive(Clone, Copy, Debug)]
719pub enum AbsoluteLength {
720 Pixels(Pixels),
721 Rems(Rems),
722}
723
724impl AbsoluteLength {
725 pub fn is_zero(&self) -> bool {
726 match self {
727 AbsoluteLength::Pixels(px) => px.0 == 0.,
728 AbsoluteLength::Rems(rems) => rems.0 == 0.,
729 }
730 }
731}
732
733impl From<Pixels> for AbsoluteLength {
734 fn from(pixels: Pixels) -> Self {
735 AbsoluteLength::Pixels(pixels)
736 }
737}
738
739impl From<Rems> for AbsoluteLength {
740 fn from(rems: Rems) -> Self {
741 AbsoluteLength::Rems(rems)
742 }
743}
744
745impl AbsoluteLength {
746 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
747 match self {
748 AbsoluteLength::Pixels(pixels) => *pixels,
749 AbsoluteLength::Rems(rems) => *rems * rem_size,
750 }
751 }
752}
753
754impl Default for AbsoluteLength {
755 fn default() -> Self {
756 px(0.).into()
757 }
758}
759
760/// A non-auto length that can be defined in pixels, rems, or percent of parent.
761#[derive(Clone, Copy)]
762pub enum DefiniteLength {
763 Absolute(AbsoluteLength),
764 /// A fraction of the parent's size between 0 and 1.
765 Fraction(f32),
766}
767
768impl DefiniteLength {
769 pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
770 match self {
771 DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
772 DefiniteLength::Fraction(fraction) => match base_size {
773 AbsoluteLength::Pixels(px) => px * *fraction,
774 AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
775 },
776 }
777 }
778}
779
780impl Debug for DefiniteLength {
781 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
782 match self {
783 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
784 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
785 }
786 }
787}
788
789impl From<Pixels> for DefiniteLength {
790 fn from(pixels: Pixels) -> Self {
791 Self::Absolute(pixels.into())
792 }
793}
794
795impl From<Rems> for DefiniteLength {
796 fn from(rems: Rems) -> Self {
797 Self::Absolute(rems.into())
798 }
799}
800
801impl From<AbsoluteLength> for DefiniteLength {
802 fn from(length: AbsoluteLength) -> Self {
803 Self::Absolute(length)
804 }
805}
806
807impl Default for DefiniteLength {
808 fn default() -> Self {
809 Self::Absolute(AbsoluteLength::default())
810 }
811}
812
813/// A length that can be defined in pixels, rems, percent of parent, or auto.
814#[derive(Clone, Copy)]
815pub enum Length {
816 Definite(DefiniteLength),
817 Auto,
818}
819
820impl Debug for Length {
821 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
822 match self {
823 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
824 Length::Auto => write!(f, "auto"),
825 }
826 }
827}
828
829pub fn relative(fraction: f32) -> DefiniteLength {
830 DefiniteLength::Fraction(fraction).into()
831}
832
833/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
834pub fn phi() -> DefiniteLength {
835 relative(1.61803398875)
836}
837
838pub fn rems(rems: f32) -> Rems {
839 Rems(rems)
840}
841
842pub fn px(pixels: f32) -> Pixels {
843 Pixels(pixels)
844}
845
846pub fn auto() -> Length {
847 Length::Auto
848}
849
850impl From<Pixels> for Length {
851 fn from(pixels: Pixels) -> Self {
852 Self::Definite(pixels.into())
853 }
854}
855
856impl From<Rems> for Length {
857 fn from(rems: Rems) -> Self {
858 Self::Definite(rems.into())
859 }
860}
861
862impl From<DefiniteLength> for Length {
863 fn from(length: DefiniteLength) -> Self {
864 Self::Definite(length)
865 }
866}
867
868impl From<AbsoluteLength> for Length {
869 fn from(length: AbsoluteLength) -> Self {
870 Self::Definite(length.into())
871 }
872}
873
874impl Default for Length {
875 fn default() -> Self {
876 Self::Definite(DefiniteLength::default())
877 }
878}
879
880impl From<()> for Length {
881 fn from(_: ()) -> Self {
882 Self::Definite(DefiniteLength::default())
883 }
884}
885
886pub trait IsZero {
887 fn is_zero(&self) -> bool;
888}
889
890impl IsZero for DevicePixels {
891 fn is_zero(&self) -> bool {
892 self.0 == 0
893 }
894}
895
896impl IsZero for ScaledPixels {
897 fn is_zero(&self) -> bool {
898 self.0 == 0.
899 }
900}
901
902impl IsZero for Pixels {
903 fn is_zero(&self) -> bool {
904 self.0 == 0.
905 }
906}
907
908impl IsZero for Rems {
909 fn is_zero(&self) -> bool {
910 self.0 == 0.
911 }
912}
913
914impl IsZero for AbsoluteLength {
915 fn is_zero(&self) -> bool {
916 match self {
917 AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
918 AbsoluteLength::Rems(rems) => rems.is_zero(),
919 }
920 }
921}
922
923impl IsZero for DefiniteLength {
924 fn is_zero(&self) -> bool {
925 match self {
926 DefiniteLength::Absolute(length) => length.is_zero(),
927 DefiniteLength::Fraction(fraction) => *fraction == 0.,
928 }
929 }
930}
931
932impl IsZero for Length {
933 fn is_zero(&self) -> bool {
934 match self {
935 Length::Definite(length) => length.is_zero(),
936 Length::Auto => false,
937 }
938 }
939}
940
941impl<T: IsZero + Debug + Clone> IsZero for Point<T> {
942 fn is_zero(&self) -> bool {
943 self.x.is_zero() && self.y.is_zero()
944 }
945}
946
947impl<T: IsZero + Debug + Clone> IsZero for Size<T> {
948 fn is_zero(&self) -> bool {
949 self.width.is_zero() || self.height.is_zero()
950 }
951}
952
953impl<T: IsZero + Debug + Clone> IsZero for Bounds<T> {
954 fn is_zero(&self) -> bool {
955 self.size.is_zero()
956 }
957}
958
959impl<T: IsZero + Debug + Clone> IsZero for Corners<T> {
960 fn is_zero(&self) -> bool {
961 self.top_left.is_zero()
962 && self.top_right.is_zero()
963 && self.bottom_right.is_zero()
964 && self.bottom_left.is_zero()
965 }
966}