geometry.rs

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