geometry.rs

   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}