geometry.rs

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