geometry.rs

  1use core::fmt::Debug;
  2use derive_more::{Add, AddAssign, Div, Mul, Sub, SubAssign};
  3use refineable::Refineable;
  4use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign};
  5
  6#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
  7#[refineable(debug)]
  8#[repr(C)]
  9pub struct Point<T: Clone + Debug> {
 10    pub x: T,
 11    pub y: T,
 12}
 13
 14pub fn point<T: Clone + Debug>(x: T, y: T) -> Point<T> {
 15    Point { x, y }
 16}
 17
 18impl<T: Clone + Debug> Point<T> {
 19    pub fn new(x: T, y: T) -> Self {
 20        Self { x, y }
 21    }
 22
 23    pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Point<U> {
 24        Point {
 25            x: f(self.x.clone()),
 26            y: f(self.y.clone()),
 27        }
 28    }
 29}
 30
 31impl<T, Rhs> Mul<Rhs> for Point<T>
 32where
 33    T: Mul<Rhs, Output = T> + Clone + Debug,
 34    Rhs: Clone + Debug,
 35{
 36    type Output = Point<T>;
 37
 38    fn mul(self, rhs: Rhs) -> Self::Output {
 39        Point {
 40            x: self.x * rhs.clone(),
 41            y: self.y * rhs,
 42        }
 43    }
 44}
 45
 46impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Point<T> {
 47    fn mul_assign(&mut self, rhs: S) {
 48        self.x = self.x.clone() * rhs.clone();
 49        self.y = self.y.clone() * rhs;
 50    }
 51}
 52
 53impl<T: Clone + Debug + Sub<Output = T>> SubAssign<Size<T>> for Point<T> {
 54    fn sub_assign(&mut self, rhs: Size<T>) {
 55        self.x = self.x.clone() - rhs.width;
 56        self.y = self.y.clone() - rhs.height;
 57    }
 58}
 59
 60impl<T: Clone + Debug + Add<Output = T> + Copy> AddAssign<T> for Point<T> {
 61    fn add_assign(&mut self, rhs: T) {
 62        self.x = self.x.clone() + rhs;
 63        self.y = self.y.clone() + rhs;
 64    }
 65}
 66
 67impl<T: Clone + Debug + Div<S, Output = T>, S: Clone> Div<S> for Point<T> {
 68    type Output = Self;
 69
 70    fn div(self, rhs: S) -> Self::Output {
 71        Self {
 72            x: self.x / rhs.clone(),
 73            y: self.y / rhs,
 74        }
 75    }
 76}
 77
 78impl<T: Clone + Debug + std::cmp::PartialOrd> Point<T> {
 79    pub fn max(&self, other: &Self) -> Self {
 80        Point {
 81            x: if self.x >= other.x {
 82                self.x.clone()
 83            } else {
 84                other.x.clone()
 85            },
 86            y: if self.y >= other.y {
 87                self.y.clone()
 88            } else {
 89                other.y.clone()
 90            },
 91        }
 92    }
 93}
 94
 95impl<T: Clone + Debug> Clone for Point<T> {
 96    fn clone(&self) -> Self {
 97        Self {
 98            x: self.x.clone(),
 99            y: self.y.clone(),
100        }
101    }
102}
103
104#[derive(Refineable, Default, Clone, Copy, Debug, PartialEq, Div, Hash)]
105#[refineable(debug)]
106#[repr(C)]
107pub struct Size<T: Clone + Debug> {
108    pub width: T,
109    pub height: T,
110}
111
112pub fn size<T: Clone + Debug>(width: T, height: T) -> Size<T> {
113    Size { width, height }
114}
115
116impl<T: Clone + Debug> Size<T> {
117    pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Size<U> {
118        Size {
119            width: f(self.width.clone()),
120            height: f(self.height.clone()),
121        }
122    }
123}
124
125impl<T: Clone + Debug + Ord> Size<T> {
126    pub fn max(&self, other: &Self) -> Self {
127        Size {
128            width: if self.width >= other.width {
129                self.width.clone()
130            } else {
131                other.width.clone()
132            },
133            height: if self.height >= other.height {
134                self.height.clone()
135            } else {
136                other.height.clone()
137            },
138        }
139    }
140}
141
142impl<T, Rhs> Mul<Rhs> for Size<T>
143where
144    T: Mul<Rhs, Output = Rhs> + Debug + Clone,
145    Rhs: Debug + Clone,
146{
147    type Output = Size<Rhs>;
148
149    fn mul(self, rhs: Rhs) -> Self::Output {
150        Size {
151            width: self.width * rhs.clone(),
152            height: self.height * rhs,
153        }
154    }
155}
156
157impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Size<T> {
158    fn mul_assign(&mut self, rhs: S) {
159        self.width = self.width.clone() * rhs.clone();
160        self.height = self.height.clone() * rhs;
161    }
162}
163
164impl<T: Eq + Debug + Clone> Eq for Size<T> {}
165
166impl From<Size<Option<Pixels>>> for Size<Option<f32>> {
167    fn from(val: Size<Option<Pixels>>) -> Self {
168        Size {
169            width: val.width.map(|p| p.0 as f32),
170            height: val.height.map(|p| p.0 as f32),
171        }
172    }
173}
174
175impl Size<Length> {
176    pub fn full() -> Self {
177        Self {
178            width: relative(1.).into(),
179            height: relative(1.).into(),
180        }
181    }
182}
183
184impl Size<DefiniteLength> {
185    pub fn zero() -> Self {
186        Self {
187            width: px(0.).into(),
188            height: px(0.).into(),
189        }
190    }
191}
192
193impl Size<Length> {
194    pub fn auto() -> Self {
195        Self {
196            width: Length::Auto,
197            height: Length::Auto,
198        }
199    }
200}
201
202#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
203#[refineable(debug)]
204#[repr(C)]
205pub struct Bounds<T: Clone + Debug> {
206    pub origin: Point<T>,
207    pub size: Size<T>,
208}
209
210// Bounds<f32> * Pixels = Bounds<Pixels>
211impl<T, Rhs> Mul<Rhs> for Bounds<T>
212where
213    T: Mul<Rhs, Output = Rhs> + Clone + Debug,
214    Point<T>: Mul<Rhs, Output = Point<Rhs>>,
215    Rhs: Clone + Debug,
216{
217    type Output = Bounds<Rhs>;
218
219    fn mul(self, rhs: Rhs) -> Self::Output {
220        Bounds {
221            origin: self.origin * rhs.clone(),
222            size: self.size * rhs,
223        }
224    }
225}
226
227impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Bounds<T> {
228    fn mul_assign(&mut self, rhs: S) {
229        self.origin *= rhs.clone();
230        self.size *= rhs;
231    }
232}
233
234impl<T: Clone + Debug + Div<S, Output = T>, S: Clone> Div<S> for Bounds<T>
235where
236    Size<T>: Div<S, Output = Size<T>>,
237{
238    type Output = Self;
239
240    fn div(self, rhs: S) -> Self {
241        Self {
242            origin: self.origin / rhs.clone(),
243            size: self.size / rhs,
244        }
245    }
246}
247
248impl<T: Clone + Debug + Add<T, Output = T>> Bounds<T> {
249    pub fn upper_right(&self) -> Point<T> {
250        Point {
251            x: self.origin.x.clone() + self.size.width.clone(),
252            y: self.origin.y.clone(),
253        }
254    }
255
256    pub fn lower_right(&self) -> Point<T> {
257        Point {
258            x: self.origin.x.clone() + self.size.width.clone(),
259            y: self.origin.y.clone() + self.size.height.clone(),
260        }
261    }
262}
263
264impl<T: Clone + Debug + PartialOrd + Add<T, Output = T>> Bounds<T> {
265    pub fn contains_point(&self, point: Point<T>) -> bool {
266        point.x >= self.origin.x
267            && point.x <= self.origin.x.clone() + self.size.width.clone()
268            && point.y >= self.origin.y
269            && point.y <= self.origin.y.clone() + self.size.height.clone()
270    }
271
272    pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Bounds<U> {
273        Bounds {
274            origin: self.origin.map(&f),
275            size: self.size.map(f),
276        }
277    }
278}
279
280impl<T: Clone + Debug + Copy> Copy for Bounds<T> {}
281
282#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
283#[refineable(debug)]
284#[repr(C)]
285pub struct Edges<T: Clone + Debug> {
286    pub top: T,
287    pub right: T,
288    pub bottom: T,
289    pub left: T,
290}
291
292impl<T: Clone + Debug + Mul<Output = T>> Mul for Edges<T> {
293    type Output = Self;
294
295    fn mul(self, rhs: Self) -> Self::Output {
296        Self {
297            top: self.top.clone() * rhs.top,
298            right: self.right.clone() * rhs.right,
299            bottom: self.bottom.clone() * rhs.bottom,
300            left: self.left.clone() * rhs.left,
301        }
302    }
303}
304
305impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Edges<T> {
306    fn mul_assign(&mut self, rhs: S) {
307        self.top = self.top.clone() * rhs.clone();
308        self.right = self.right.clone() * rhs.clone();
309        self.bottom = self.bottom.clone() * rhs.clone();
310        self.left = self.left.clone() * rhs.clone();
311    }
312}
313
314impl<T: Clone + Debug + Copy> Copy for Edges<T> {}
315
316impl<T: Clone + Debug> Edges<T> {
317    pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Edges<U> {
318        Edges {
319            top: f(&self.top),
320            right: f(&self.right),
321            bottom: f(&self.bottom),
322            left: f(&self.left),
323        }
324    }
325
326    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
327        predicate(&self.top)
328            || predicate(&self.right)
329            || predicate(&self.bottom)
330            || predicate(&self.left)
331    }
332}
333
334impl Edges<Length> {
335    pub fn auto() -> Self {
336        Self {
337            top: Length::Auto,
338            right: Length::Auto,
339            bottom: Length::Auto,
340            left: Length::Auto,
341        }
342    }
343
344    pub fn zero() -> Self {
345        Self {
346            top: px(0.).into(),
347            right: px(0.).into(),
348            bottom: px(0.).into(),
349            left: px(0.).into(),
350        }
351    }
352}
353
354impl Edges<DefiniteLength> {
355    pub fn zero() -> Self {
356        Self {
357            top: px(0.).into(),
358            right: px(0.).into(),
359            bottom: px(0.).into(),
360            left: px(0.).into(),
361        }
362    }
363}
364
365impl Edges<AbsoluteLength> {
366    pub fn zero() -> Self {
367        Self {
368            top: px(0.).into(),
369            right: px(0.).into(),
370            bottom: px(0.).into(),
371            left: px(0.).into(),
372        }
373    }
374
375    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
376        Edges {
377            top: self.top.to_pixels(rem_size),
378            right: self.right.to_pixels(rem_size),
379            bottom: self.bottom.to_pixels(rem_size),
380            left: self.left.to_pixels(rem_size),
381        }
382    }
383}
384
385#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
386#[refineable(debug)]
387#[repr(C)]
388pub struct Corners<T: Clone + Debug> {
389    pub top_left: T,
390    pub top_right: T,
391    pub bottom_right: T,
392    pub bottom_left: T,
393}
394
395impl<T: Clone + Debug> Corners<T> {
396    pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Corners<U> {
397        Corners {
398            top_left: f(&self.top_left),
399            top_right: f(&self.top_right),
400            bottom_right: f(&self.bottom_right),
401            bottom_left: f(&self.bottom_left),
402        }
403    }
404}
405
406impl<T: Clone + Debug + Mul<Output = T>> Mul for Corners<T> {
407    type Output = Self;
408
409    fn mul(self, rhs: Self) -> Self::Output {
410        Self {
411            top_left: self.top_left.clone() * rhs.top_left,
412            top_right: self.top_right.clone() * rhs.top_right,
413            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
414            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
415        }
416    }
417}
418
419impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Corners<T> {
420    fn mul_assign(&mut self, rhs: S) {
421        self.top_left = self.top_left.clone() * rhs.clone();
422        self.top_right = self.top_right.clone() * rhs.clone();
423        self.bottom_right = self.bottom_right.clone() * rhs.clone();
424        self.bottom_left = self.bottom_left.clone() * rhs;
425    }
426}
427
428impl<T: Clone + Debug + Copy> Copy for Corners<T> {}
429
430#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
431#[repr(transparent)]
432pub struct Pixels(pub(crate) f32);
433
434impl Mul<f32> for Pixels {
435    type Output = Pixels;
436
437    fn mul(self, other: f32) -> Pixels {
438        Pixels(self.0 * other)
439    }
440}
441
442impl Mul<Pixels> for f32 {
443    type Output = Pixels;
444
445    fn mul(self, rhs: Pixels) -> Self::Output {
446        Pixels(self * rhs.0)
447    }
448}
449
450impl MulAssign<f32> for Pixels {
451    fn mul_assign(&mut self, other: f32) {
452        self.0 *= other;
453    }
454}
455
456impl Pixels {
457    pub fn round(&self) -> Self {
458        Self(self.0.round())
459    }
460
461    pub fn floor(&self) -> Self {
462        Self(self.0.floor())
463    }
464
465    pub fn to_device_pixels(&self, scale: f32) -> DevicePixels {
466        DevicePixels((self.0 * scale).ceil() as u32)
467    }
468}
469
470impl Mul<Pixels> for Pixels {
471    type Output = Pixels;
472
473    fn mul(self, rhs: Pixels) -> Self::Output {
474        Pixels(self.0 * rhs.0)
475    }
476}
477
478impl Eq for Pixels {}
479
480impl Ord for Pixels {
481    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
482        self.0.partial_cmp(&other.0).unwrap()
483    }
484}
485
486impl std::hash::Hash for Pixels {
487    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
488        self.0.to_bits().hash(state);
489    }
490}
491
492impl From<f64> for Pixels {
493    fn from(val: f64) -> Self {
494        Pixels(val as f32)
495    }
496}
497
498impl From<f32> for Pixels {
499    fn from(val: f32) -> Self {
500        Pixels(val)
501    }
502}
503
504impl Debug for Pixels {
505    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
506        write!(f, "{} px", self.0)
507    }
508}
509
510impl From<Pixels> for f32 {
511    fn from(pixels: Pixels) -> Self {
512        pixels.0
513    }
514}
515
516impl From<&Pixels> for f32 {
517    fn from(pixels: &Pixels) -> Self {
518        pixels.0
519    }
520}
521
522impl From<Pixels> for f64 {
523    fn from(pixels: Pixels) -> Self {
524        pixels.0 as f64
525    }
526}
527
528#[derive(
529    Add,
530    AddAssign,
531    Clone,
532    Copy,
533    Debug,
534    Default,
535    Div,
536    Eq,
537    Hash,
538    Ord,
539    PartialEq,
540    PartialOrd,
541    Sub,
542    SubAssign,
543)]
544#[repr(transparent)]
545pub struct DevicePixels(pub(crate) u32);
546
547impl DevicePixels {
548    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
549        self.0 * bytes_per_pixel as u32
550    }
551}
552
553impl From<DevicePixels> for u32 {
554    fn from(device_pixels: DevicePixels) -> Self {
555        device_pixels.0
556    }
557}
558
559impl From<u32> for DevicePixels {
560    fn from(val: u32) -> Self {
561        DevicePixels(val)
562    }
563}
564
565impl From<DevicePixels> for u64 {
566    fn from(device_pixels: DevicePixels) -> Self {
567        device_pixels.0 as u64
568    }
569}
570
571impl From<u64> for DevicePixels {
572    fn from(val: u64) -> Self {
573        DevicePixels(val as u32)
574    }
575}
576
577#[derive(Clone, Copy, Default, Add, Sub, Mul, Div)]
578pub struct Rems(f32);
579
580impl Mul<Pixels> for Rems {
581    type Output = Pixels;
582
583    fn mul(self, other: Pixels) -> Pixels {
584        Pixels(self.0 * other.0)
585    }
586}
587
588impl Debug for Rems {
589    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
590        write!(f, "{} rem", self.0)
591    }
592}
593
594#[derive(Clone, Copy, Debug)]
595pub enum AbsoluteLength {
596    Pixels(Pixels),
597    Rems(Rems),
598}
599
600impl AbsoluteLength {
601    pub fn is_zero(&self) -> bool {
602        match self {
603            AbsoluteLength::Pixels(px) => px.0 == 0.,
604            AbsoluteLength::Rems(rems) => rems.0 == 0.,
605        }
606    }
607}
608
609impl From<Pixels> for AbsoluteLength {
610    fn from(pixels: Pixels) -> Self {
611        AbsoluteLength::Pixels(pixels)
612    }
613}
614
615impl From<Rems> for AbsoluteLength {
616    fn from(rems: Rems) -> Self {
617        AbsoluteLength::Rems(rems)
618    }
619}
620
621impl AbsoluteLength {
622    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
623        match self {
624            AbsoluteLength::Pixels(pixels) => *pixels,
625            AbsoluteLength::Rems(rems) => *rems * rem_size,
626        }
627    }
628}
629
630impl Default for AbsoluteLength {
631    fn default() -> Self {
632        px(0.).into()
633    }
634}
635
636/// A non-auto length that can be defined in pixels, rems, or percent of parent.
637#[derive(Clone, Copy)]
638pub enum DefiniteLength {
639    Absolute(AbsoluteLength),
640    /// A fraction of the parent's size between 0 and 1.
641    Fraction(f32),
642}
643
644impl DefiniteLength {
645    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
646        match self {
647            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
648            DefiniteLength::Fraction(fraction) => match base_size {
649                AbsoluteLength::Pixels(px) => px * *fraction,
650                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
651            },
652        }
653    }
654}
655
656impl Debug for DefiniteLength {
657    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
658        match self {
659            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
660            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
661        }
662    }
663}
664
665impl From<Pixels> for DefiniteLength {
666    fn from(pixels: Pixels) -> Self {
667        Self::Absolute(pixels.into())
668    }
669}
670
671impl From<Rems> for DefiniteLength {
672    fn from(rems: Rems) -> Self {
673        Self::Absolute(rems.into())
674    }
675}
676
677impl From<AbsoluteLength> for DefiniteLength {
678    fn from(length: AbsoluteLength) -> Self {
679        Self::Absolute(length)
680    }
681}
682
683impl Default for DefiniteLength {
684    fn default() -> Self {
685        Self::Absolute(AbsoluteLength::default())
686    }
687}
688
689/// A length that can be defined in pixels, rems, percent of parent, or auto.
690#[derive(Clone, Copy)]
691pub enum Length {
692    Definite(DefiniteLength),
693    Auto,
694}
695
696impl Debug for Length {
697    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
698        match self {
699            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
700            Length::Auto => write!(f, "auto"),
701        }
702    }
703}
704
705pub fn relative(fraction: f32) -> DefiniteLength {
706    DefiniteLength::Fraction(fraction).into()
707}
708
709/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
710pub fn phi() -> DefiniteLength {
711    relative(1.61803398875)
712}
713
714pub fn rems(rems: f32) -> Rems {
715    Rems(rems)
716}
717
718pub fn px(pixels: f32) -> Pixels {
719    Pixels(pixels)
720}
721
722pub fn auto() -> Length {
723    Length::Auto
724}
725
726impl From<Pixels> for Length {
727    fn from(pixels: Pixels) -> Self {
728        Self::Definite(pixels.into())
729    }
730}
731
732impl From<Rems> for Length {
733    fn from(rems: Rems) -> Self {
734        Self::Definite(rems.into())
735    }
736}
737
738impl From<DefiniteLength> for Length {
739    fn from(length: DefiniteLength) -> Self {
740        Self::Definite(length)
741    }
742}
743
744impl From<AbsoluteLength> for Length {
745    fn from(length: AbsoluteLength) -> Self {
746        Self::Definite(length.into())
747    }
748}
749
750impl Default for Length {
751    fn default() -> Self {
752        Self::Definite(DefiniteLength::default())
753    }
754}
755
756impl From<()> for Length {
757    fn from(_: ()) -> Self {
758        Self::Definite(DefiniteLength::default())
759    }
760}