geometry.rs

   1use core::fmt::Debug;
   2use derive_more::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign};
   3use refineable::Refineable;
   4use std::{
   5    cmp::{self, PartialOrd},
   6    fmt,
   7    ops::{Add, Div, Mul, MulAssign, Sub},
   8};
   9
  10#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
  11#[refineable(debug)]
  12#[repr(C)]
  13pub struct Point<T: Default + Clone + Debug> {
  14    pub x: T,
  15    pub y: T,
  16}
  17
  18pub fn point<T: Clone + Debug + Default>(x: T, y: T) -> Point<T> {
  19    Point { x, y }
  20}
  21
  22impl<T: Clone + Debug + Default> Point<T> {
  23    pub fn new(x: T, y: T) -> Self {
  24        Self { x, y }
  25    }
  26
  27    pub fn map<U: Clone + Default + Debug>(&self, f: impl Fn(T) -> U) -> Point<U> {
  28        Point {
  29            x: f(self.x.clone()),
  30            y: f(self.y.clone()),
  31        }
  32    }
  33}
  34
  35impl Point<Pixels> {
  36    pub fn scale(&self, factor: f32) -> Point<ScaledPixels> {
  37        Point {
  38            x: self.x.scale(factor),
  39            y: self.y.scale(factor),
  40        }
  41    }
  42}
  43
  44impl<T, Rhs> Mul<Rhs> for Point<T>
  45where
  46    T: Mul<Rhs, Output = T> + Clone + Default + Debug,
  47    Rhs: Clone + Debug,
  48{
  49    type Output = Point<T>;
  50
  51    fn mul(self, rhs: Rhs) -> Self::Output {
  52        Point {
  53            x: self.x * rhs.clone(),
  54            y: self.y * rhs,
  55        }
  56    }
  57}
  58
  59impl<T, S> MulAssign<S> for Point<T>
  60where
  61    T: Clone + Mul<S, Output = T> + Default + Debug,
  62    S: Clone,
  63{
  64    fn mul_assign(&mut self, rhs: S) {
  65        self.x = self.x.clone() * rhs.clone();
  66        self.y = self.y.clone() * rhs;
  67    }
  68}
  69
  70impl<T, S> Div<S> for Point<T>
  71where
  72    T: Div<S, Output = T> + Clone + Default + Debug,
  73    S: Clone,
  74{
  75    type Output = Self;
  76
  77    fn div(self, rhs: S) -> Self::Output {
  78        Self {
  79            x: self.x / rhs.clone(),
  80            y: self.y / rhs,
  81        }
  82    }
  83}
  84
  85impl<T> Point<T>
  86where
  87    T: PartialOrd + Clone + Default + Debug,
  88{
  89    pub fn max(&self, other: &Self) -> Self {
  90        Point {
  91            x: if self.x >= other.x {
  92                self.x.clone()
  93            } else {
  94                other.x.clone()
  95            },
  96            y: if self.y >= other.y {
  97                self.y.clone()
  98            } else {
  99                other.y.clone()
 100            },
 101        }
 102    }
 103
 104    pub fn min(&self, other: &Self) -> Self {
 105        Point {
 106            x: if self.x <= other.x {
 107                self.x.clone()
 108            } else {
 109                other.x.clone()
 110            },
 111            y: if self.y <= other.y {
 112                self.y.clone()
 113            } else {
 114                other.y.clone()
 115            },
 116        }
 117    }
 118}
 119
 120impl<T: Clone + Default + Debug> Clone for Point<T> {
 121    fn clone(&self) -> Self {
 122        Self {
 123            x: self.x.clone(),
 124            y: self.y.clone(),
 125        }
 126    }
 127}
 128
 129#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash)]
 130#[refineable(debug)]
 131#[repr(C)]
 132pub struct Size<T: Clone + Default + Debug> {
 133    pub width: T,
 134    pub height: T,
 135}
 136
 137pub fn size<T>(width: T, height: T) -> Size<T>
 138where
 139    T: Clone + Default + Debug,
 140{
 141    Size { width, height }
 142}
 143
 144impl<T> Size<T>
 145where
 146    T: Clone + Default + Debug,
 147{
 148    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Size<U>
 149    where
 150        U: Clone + Default + Debug,
 151    {
 152        Size {
 153            width: f(self.width.clone()),
 154            height: f(self.height.clone()),
 155        }
 156    }
 157}
 158
 159impl Size<Pixels> {
 160    pub fn scale(&self, factor: f32) -> Size<ScaledPixels> {
 161        Size {
 162            width: self.width.scale(factor),
 163            height: self.height.scale(factor),
 164        }
 165    }
 166}
 167
 168impl<T> Size<T>
 169where
 170    T: PartialOrd + Clone + Default + Debug,
 171{
 172    pub fn max(&self, other: &Self) -> Self {
 173        Size {
 174            width: if self.width >= other.width {
 175                self.width.clone()
 176            } else {
 177                other.width.clone()
 178            },
 179            height: if self.height >= other.height {
 180                self.height.clone()
 181            } else {
 182                other.height.clone()
 183            },
 184        }
 185    }
 186}
 187
 188impl<T> Sub for Size<T>
 189where
 190    T: Sub<Output = T> + Clone + Default + Debug,
 191{
 192    type Output = Size<T>;
 193
 194    fn sub(self, rhs: Self) -> Self::Output {
 195        Size {
 196            width: self.width - rhs.width,
 197            height: self.height - rhs.height,
 198        }
 199    }
 200}
 201
 202impl<T, Rhs> Mul<Rhs> for Size<T>
 203where
 204    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
 205    Rhs: Clone + Default + Debug,
 206{
 207    type Output = Size<Rhs>;
 208
 209    fn mul(self, rhs: Rhs) -> Self::Output {
 210        Size {
 211            width: self.width * rhs.clone(),
 212            height: self.height * rhs,
 213        }
 214    }
 215}
 216
 217impl<T, S> MulAssign<S> for Size<T>
 218where
 219    T: Mul<S, Output = T> + Clone + Default + Debug,
 220    S: Clone,
 221{
 222    fn mul_assign(&mut self, rhs: S) {
 223        self.width = self.width.clone() * rhs.clone();
 224        self.height = self.height.clone() * rhs;
 225    }
 226}
 227
 228impl<T> Eq for Size<T> where T: Eq + Default + Debug + Clone {}
 229
 230impl<T> Debug for Size<T>
 231where
 232    T: Clone + Default + Debug,
 233{
 234    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 235        write!(f, "Size {{ {:?} × {:?} }}", self.width, self.height)
 236    }
 237}
 238
 239impl<T: Clone + Default + Debug> From<Point<T>> for Size<T> {
 240    fn from(point: Point<T>) -> Self {
 241        Self {
 242            width: point.x,
 243            height: point.y,
 244        }
 245    }
 246}
 247
 248impl From<Size<Pixels>> for Size<GlobalPixels> {
 249    fn from(size: Size<Pixels>) -> Self {
 250        Size {
 251            width: GlobalPixels(size.width.0),
 252            height: GlobalPixels(size.height.0),
 253        }
 254    }
 255}
 256
 257impl Size<Length> {
 258    pub fn full() -> Self {
 259        Self {
 260            width: relative(1.).into(),
 261            height: relative(1.).into(),
 262        }
 263    }
 264}
 265
 266impl Size<DefiniteLength> {
 267    pub fn zero() -> Self {
 268        Self {
 269            width: px(0.).into(),
 270            height: px(0.).into(),
 271        }
 272    }
 273}
 274
 275impl Size<Length> {
 276    pub fn auto() -> Self {
 277        Self {
 278            width: Length::Auto,
 279            height: Length::Auto,
 280        }
 281    }
 282}
 283
 284#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 285#[refineable(debug)]
 286#[repr(C)]
 287pub struct Bounds<T: Clone + Default + Debug> {
 288    pub origin: Point<T>,
 289    pub size: Size<T>,
 290}
 291
 292impl<T> Bounds<T>
 293where
 294    T: Clone + Debug + Sub<Output = T> + Default,
 295{
 296    pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
 297        let origin = Point {
 298            x: upper_left.x.clone(),
 299            y: upper_left.y.clone(),
 300        };
 301        let size = Size {
 302            width: lower_right.x - upper_left.x,
 303            height: lower_right.y - upper_left.y,
 304        };
 305        Bounds { origin, size }
 306    }
 307}
 308
 309impl<T> Bounds<T>
 310where
 311    T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default,
 312{
 313    pub fn intersects(&self, other: &Bounds<T>) -> bool {
 314        let my_lower_right = self.lower_right();
 315        let their_lower_right = other.lower_right();
 316
 317        self.origin.x < their_lower_right.x
 318            && my_lower_right.x > other.origin.x
 319            && self.origin.y < their_lower_right.y
 320            && my_lower_right.y > other.origin.y
 321    }
 322
 323    pub fn dilate(&mut self, amount: T) {
 324        self.origin.x = self.origin.x.clone() - amount.clone();
 325        self.origin.y = self.origin.y.clone() - amount.clone();
 326        let double_amount = amount.clone() + amount;
 327        self.size.width = self.size.width.clone() + double_amount.clone();
 328        self.size.height = self.size.height.clone() + double_amount;
 329    }
 330}
 331
 332impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
 333    pub fn intersect(&self, other: &Self) -> Self {
 334        let upper_left = self.origin.max(&other.origin);
 335        let lower_right = self.lower_right().min(&other.lower_right());
 336        Self::from_corners(upper_left, lower_right)
 337    }
 338
 339    pub fn union(&self, other: &Self) -> Self {
 340        let top_left = self.origin.min(&other.origin);
 341        let bottom_right = self.lower_right().max(&other.lower_right());
 342        Bounds::from_corners(top_left, bottom_right)
 343    }
 344}
 345
 346impl<T, Rhs> Mul<Rhs> for Bounds<T>
 347where
 348    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
 349    Point<T>: Mul<Rhs, Output = Point<Rhs>>,
 350    Rhs: Clone + Default + Debug,
 351{
 352    type Output = Bounds<Rhs>;
 353
 354    fn mul(self, rhs: Rhs) -> Self::Output {
 355        Bounds {
 356            origin: self.origin * rhs.clone(),
 357            size: self.size * rhs,
 358        }
 359    }
 360}
 361
 362impl<T, S> MulAssign<S> for Bounds<T>
 363where
 364    T: Mul<S, Output = T> + Clone + Default + Debug,
 365    S: Clone,
 366{
 367    fn mul_assign(&mut self, rhs: S) {
 368        self.origin *= rhs.clone();
 369        self.size *= rhs;
 370    }
 371}
 372
 373impl<T, S> Div<S> for Bounds<T>
 374where
 375    Size<T>: Div<S, Output = Size<T>>,
 376    T: Div<S, Output = T> + Default + Clone + Debug,
 377    S: Clone,
 378{
 379    type Output = Self;
 380
 381    fn div(self, rhs: S) -> Self {
 382        Self {
 383            origin: self.origin / rhs.clone(),
 384            size: self.size / rhs,
 385        }
 386    }
 387}
 388
 389impl<T> Bounds<T>
 390where
 391    T: Add<T, Output = T> + Clone + Default + Debug,
 392{
 393    pub fn upper_right(&self) -> Point<T> {
 394        Point {
 395            x: self.origin.x.clone() + self.size.width.clone(),
 396            y: self.origin.y.clone(),
 397        }
 398    }
 399
 400    pub fn lower_right(&self) -> Point<T> {
 401        Point {
 402            x: self.origin.x.clone() + self.size.width.clone(),
 403            y: self.origin.y.clone() + self.size.height.clone(),
 404        }
 405    }
 406
 407    pub fn lower_left(&self) -> Point<T> {
 408        Point {
 409            x: self.origin.x.clone(),
 410            y: self.origin.y.clone() + self.size.height.clone(),
 411        }
 412    }
 413}
 414
 415impl<T> Bounds<T>
 416where
 417    T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
 418{
 419    pub fn contains_point(&self, point: &Point<T>) -> bool {
 420        point.x >= self.origin.x
 421            && point.x <= self.origin.x.clone() + self.size.width.clone()
 422            && point.y >= self.origin.y
 423            && point.y <= self.origin.y.clone() + self.size.height.clone()
 424    }
 425
 426    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
 427    where
 428        U: Clone + Default + Debug,
 429    {
 430        Bounds {
 431            origin: self.origin.map(&f),
 432            size: self.size.map(f),
 433        }
 434    }
 435}
 436
 437impl Bounds<Pixels> {
 438    pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
 439        Bounds {
 440            origin: self.origin.scale(factor),
 441            size: self.size.scale(factor),
 442        }
 443    }
 444}
 445
 446impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
 447
 448#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 449#[refineable(debug)]
 450#[repr(C)]
 451pub struct Edges<T: Clone + Default + Debug> {
 452    pub top: T,
 453    pub right: T,
 454    pub bottom: T,
 455    pub left: T,
 456}
 457
 458impl<T> Mul for Edges<T>
 459where
 460    T: Mul<Output = T> + Clone + Default + Debug,
 461{
 462    type Output = Self;
 463
 464    fn mul(self, rhs: Self) -> Self::Output {
 465        Self {
 466            top: self.top.clone() * rhs.top,
 467            right: self.right.clone() * rhs.right,
 468            bottom: self.bottom.clone() * rhs.bottom,
 469            left: self.left.clone() * rhs.left,
 470        }
 471    }
 472}
 473
 474impl<T, S> MulAssign<S> for Edges<T>
 475where
 476    T: Mul<S, Output = T> + Clone + Default + Debug,
 477    S: Clone,
 478{
 479    fn mul_assign(&mut self, rhs: S) {
 480        self.top = self.top.clone() * rhs.clone();
 481        self.right = self.right.clone() * rhs.clone();
 482        self.bottom = self.bottom.clone() * rhs.clone();
 483        self.left = self.left.clone() * rhs;
 484    }
 485}
 486
 487impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
 488
 489impl<T: Clone + Default + Debug> Edges<T> {
 490    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
 491    where
 492        U: Clone + Default + Debug,
 493    {
 494        Edges {
 495            top: f(&self.top),
 496            right: f(&self.right),
 497            bottom: f(&self.bottom),
 498            left: f(&self.left),
 499        }
 500    }
 501
 502    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
 503        predicate(&self.top)
 504            || predicate(&self.right)
 505            || predicate(&self.bottom)
 506            || predicate(&self.left)
 507    }
 508}
 509
 510impl Edges<Length> {
 511    pub fn auto() -> Self {
 512        Self {
 513            top: Length::Auto,
 514            right: Length::Auto,
 515            bottom: Length::Auto,
 516            left: Length::Auto,
 517        }
 518    }
 519
 520    pub fn zero() -> Self {
 521        Self {
 522            top: px(0.).into(),
 523            right: px(0.).into(),
 524            bottom: px(0.).into(),
 525            left: px(0.).into(),
 526        }
 527    }
 528}
 529
 530impl Edges<DefiniteLength> {
 531    pub fn zero() -> Self {
 532        Self {
 533            top: px(0.).into(),
 534            right: px(0.).into(),
 535            bottom: px(0.).into(),
 536            left: px(0.).into(),
 537        }
 538    }
 539}
 540
 541impl Edges<AbsoluteLength> {
 542    pub fn zero() -> Self {
 543        Self {
 544            top: px(0.).into(),
 545            right: px(0.).into(),
 546            bottom: px(0.).into(),
 547            left: px(0.).into(),
 548        }
 549    }
 550
 551    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
 552        Edges {
 553            top: self.top.to_pixels(rem_size),
 554            right: self.right.to_pixels(rem_size),
 555            bottom: self.bottom.to_pixels(rem_size),
 556            left: self.left.to_pixels(rem_size),
 557        }
 558    }
 559}
 560
 561impl Edges<Pixels> {
 562    pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
 563        Edges {
 564            top: self.top.scale(factor),
 565            right: self.right.scale(factor),
 566            bottom: self.bottom.scale(factor),
 567            left: self.left.scale(factor),
 568        }
 569    }
 570}
 571
 572#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 573#[refineable(debug)]
 574#[repr(C)]
 575pub struct Corners<T: Clone + Default + Debug> {
 576    pub top_left: T,
 577    pub top_right: T,
 578    pub bottom_right: T,
 579    pub bottom_left: T,
 580}
 581
 582impl Corners<AbsoluteLength> {
 583    pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
 584        let max = size.width.max(size.height) / 2.;
 585        Corners {
 586            top_left: self.top_left.to_pixels(rem_size).min(max),
 587            top_right: self.top_right.to_pixels(rem_size).min(max),
 588            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
 589            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
 590        }
 591    }
 592}
 593
 594impl Corners<Pixels> {
 595    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
 596        Corners {
 597            top_left: self.top_left.scale(factor),
 598            top_right: self.top_right.scale(factor),
 599            bottom_right: self.bottom_right.scale(factor),
 600            bottom_left: self.bottom_left.scale(factor),
 601        }
 602    }
 603}
 604
 605impl<T: Clone + Default + Debug> Corners<T> {
 606    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
 607    where
 608        U: Clone + Default + Debug,
 609    {
 610        Corners {
 611            top_left: f(&self.top_left),
 612            top_right: f(&self.top_right),
 613            bottom_right: f(&self.bottom_right),
 614            bottom_left: f(&self.bottom_left),
 615        }
 616    }
 617}
 618
 619impl<T> Mul for Corners<T>
 620where
 621    T: Mul<Output = T> + Clone + Default + Debug,
 622{
 623    type Output = Self;
 624
 625    fn mul(self, rhs: Self) -> Self::Output {
 626        Self {
 627            top_left: self.top_left.clone() * rhs.top_left,
 628            top_right: self.top_right.clone() * rhs.top_right,
 629            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
 630            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
 631        }
 632    }
 633}
 634
 635impl<T, S> MulAssign<S> for Corners<T>
 636where
 637    T: Mul<S, Output = T> + Clone + Default + Debug,
 638    S: Clone,
 639{
 640    fn mul_assign(&mut self, rhs: S) {
 641        self.top_left = self.top_left.clone() * rhs.clone();
 642        self.top_right = self.top_right.clone() * rhs.clone();
 643        self.bottom_right = self.bottom_right.clone() * rhs.clone();
 644        self.bottom_left = self.bottom_left.clone() * rhs;
 645    }
 646}
 647
 648impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
 649
 650#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, Neg, PartialEq, PartialOrd)]
 651#[repr(transparent)]
 652pub struct Pixels(pub(crate) f32);
 653
 654impl Mul<f32> for Pixels {
 655    type Output = Pixels;
 656
 657    fn mul(self, other: f32) -> Pixels {
 658        Pixels(self.0 * other)
 659    }
 660}
 661
 662impl Mul<usize> for Pixels {
 663    type Output = Pixels;
 664
 665    fn mul(self, other: usize) -> Pixels {
 666        Pixels(self.0 * other as f32)
 667    }
 668}
 669
 670impl Mul<Pixels> for f32 {
 671    type Output = Pixels;
 672
 673    fn mul(self, rhs: Pixels) -> Self::Output {
 674        Pixels(self * rhs.0)
 675    }
 676}
 677
 678impl MulAssign<f32> for Pixels {
 679    fn mul_assign(&mut self, other: f32) {
 680        self.0 *= other;
 681    }
 682}
 683
 684impl Pixels {
 685    pub const MAX: Pixels = Pixels(f32::MAX);
 686
 687    pub fn round(&self) -> Self {
 688        Self(self.0.round())
 689    }
 690
 691    pub fn scale(&self, factor: f32) -> ScaledPixels {
 692        ScaledPixels(self.0 * factor)
 693    }
 694}
 695
 696impl Mul<Pixels> for Pixels {
 697    type Output = Pixels;
 698
 699    fn mul(self, rhs: Pixels) -> Self::Output {
 700        Pixels(self.0 * rhs.0)
 701    }
 702}
 703
 704impl Eq for Pixels {}
 705
 706impl Ord for Pixels {
 707    fn cmp(&self, other: &Self) -> cmp::Ordering {
 708        self.0.partial_cmp(&other.0).unwrap()
 709    }
 710}
 711
 712impl std::hash::Hash for Pixels {
 713    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
 714        self.0.to_bits().hash(state);
 715    }
 716}
 717
 718impl From<f64> for Pixels {
 719    fn from(pixels: f64) -> Self {
 720        Pixels(pixels as f32)
 721    }
 722}
 723
 724impl From<f32> for Pixels {
 725    fn from(pixels: f32) -> Self {
 726        Pixels(pixels)
 727    }
 728}
 729
 730impl Debug for Pixels {
 731    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 732        write!(f, "{} px", self.0)
 733    }
 734}
 735
 736impl From<Pixels> for f32 {
 737    fn from(pixels: Pixels) -> Self {
 738        pixels.0
 739    }
 740}
 741
 742impl From<&Pixels> for f32 {
 743    fn from(pixels: &Pixels) -> Self {
 744        pixels.0
 745    }
 746}
 747
 748impl From<Pixels> for f64 {
 749    fn from(pixels: Pixels) -> Self {
 750        pixels.0 as f64
 751    }
 752}
 753
 754#[derive(
 755    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
 756)]
 757#[repr(transparent)]
 758pub struct DevicePixels(pub(crate) i32);
 759
 760impl DevicePixels {
 761    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
 762        self.0 as u32 * bytes_per_pixel as u32
 763    }
 764}
 765
 766impl fmt::Debug for DevicePixels {
 767    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 768        write!(f, "{} px (device)", self.0)
 769    }
 770}
 771
 772impl From<DevicePixels> for i32 {
 773    fn from(device_pixels: DevicePixels) -> Self {
 774        device_pixels.0
 775    }
 776}
 777
 778impl From<i32> for DevicePixels {
 779    fn from(device_pixels: i32) -> Self {
 780        DevicePixels(device_pixels)
 781    }
 782}
 783
 784impl From<u32> for DevicePixels {
 785    fn from(device_pixels: u32) -> Self {
 786        DevicePixels(device_pixels as i32)
 787    }
 788}
 789
 790impl From<DevicePixels> for u32 {
 791    fn from(device_pixels: DevicePixels) -> Self {
 792        device_pixels.0 as u32
 793    }
 794}
 795
 796impl From<DevicePixels> for u64 {
 797    fn from(device_pixels: DevicePixels) -> Self {
 798        device_pixels.0 as u64
 799    }
 800}
 801
 802impl From<u64> for DevicePixels {
 803    fn from(device_pixels: u64) -> Self {
 804        DevicePixels(device_pixels as i32)
 805    }
 806}
 807
 808#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 809#[repr(transparent)]
 810pub struct ScaledPixels(pub(crate) f32);
 811
 812impl ScaledPixels {
 813    pub fn floor(&self) -> Self {
 814        Self(self.0.floor())
 815    }
 816
 817    pub fn ceil(&self) -> Self {
 818        Self(self.0.ceil())
 819    }
 820}
 821
 822impl Eq for ScaledPixels {}
 823
 824impl Debug for ScaledPixels {
 825    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 826        write!(f, "{} px (scaled)", self.0)
 827    }
 828}
 829
 830impl From<ScaledPixels> for DevicePixels {
 831    fn from(scaled: ScaledPixels) -> Self {
 832        DevicePixels(scaled.0.ceil() as i32)
 833    }
 834}
 835
 836impl From<DevicePixels> for ScaledPixels {
 837    fn from(device: DevicePixels) -> Self {
 838        ScaledPixels(device.0 as f32)
 839    }
 840}
 841
 842impl From<ScaledPixels> for f64 {
 843    fn from(scaled_pixels: ScaledPixels) -> Self {
 844        scaled_pixels.0 as f64
 845    }
 846}
 847
 848#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 849#[repr(transparent)]
 850pub struct GlobalPixels(pub(crate) f32);
 851
 852impl Debug for GlobalPixels {
 853    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 854        write!(f, "{} px (global coordinate space)", self.0)
 855    }
 856}
 857
 858impl From<GlobalPixels> for f64 {
 859    fn from(global_pixels: GlobalPixels) -> Self {
 860        global_pixels.0 as f64
 861    }
 862}
 863
 864impl From<f64> for GlobalPixels {
 865    fn from(global_pixels: f64) -> Self {
 866        GlobalPixels(global_pixels as f32)
 867    }
 868}
 869
 870#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
 871pub struct Rems(f32);
 872
 873impl Mul<Pixels> for Rems {
 874    type Output = Pixels;
 875
 876    fn mul(self, other: Pixels) -> Pixels {
 877        Pixels(self.0 * other.0)
 878    }
 879}
 880
 881impl Debug for Rems {
 882    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 883        write!(f, "{} rem", self.0)
 884    }
 885}
 886
 887#[derive(Clone, Copy, Debug, Neg)]
 888pub enum AbsoluteLength {
 889    Pixels(Pixels),
 890    Rems(Rems),
 891}
 892
 893impl AbsoluteLength {
 894    pub fn is_zero(&self) -> bool {
 895        match self {
 896            AbsoluteLength::Pixels(px) => px.0 == 0.,
 897            AbsoluteLength::Rems(rems) => rems.0 == 0.,
 898        }
 899    }
 900}
 901
 902impl From<Pixels> for AbsoluteLength {
 903    fn from(pixels: Pixels) -> Self {
 904        AbsoluteLength::Pixels(pixels)
 905    }
 906}
 907
 908impl From<Rems> for AbsoluteLength {
 909    fn from(rems: Rems) -> Self {
 910        AbsoluteLength::Rems(rems)
 911    }
 912}
 913
 914impl AbsoluteLength {
 915    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
 916        match self {
 917            AbsoluteLength::Pixels(pixels) => *pixels,
 918            AbsoluteLength::Rems(rems) => *rems * rem_size,
 919        }
 920    }
 921}
 922
 923impl Default for AbsoluteLength {
 924    fn default() -> Self {
 925        px(0.).into()
 926    }
 927}
 928
 929/// A non-auto length that can be defined in pixels, rems, or percent of parent.
 930#[derive(Clone, Copy, Neg)]
 931pub enum DefiniteLength {
 932    Absolute(AbsoluteLength),
 933    /// A fraction of the parent's size between 0 and 1.
 934    Fraction(f32),
 935}
 936
 937impl DefiniteLength {
 938    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
 939        match self {
 940            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
 941            DefiniteLength::Fraction(fraction) => match base_size {
 942                AbsoluteLength::Pixels(px) => px * *fraction,
 943                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
 944            },
 945        }
 946    }
 947}
 948
 949impl Debug for DefiniteLength {
 950    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 951        match self {
 952            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
 953            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
 954        }
 955    }
 956}
 957
 958impl From<Pixels> for DefiniteLength {
 959    fn from(pixels: Pixels) -> Self {
 960        Self::Absolute(pixels.into())
 961    }
 962}
 963
 964impl From<Rems> for DefiniteLength {
 965    fn from(rems: Rems) -> Self {
 966        Self::Absolute(rems.into())
 967    }
 968}
 969
 970impl From<AbsoluteLength> for DefiniteLength {
 971    fn from(length: AbsoluteLength) -> Self {
 972        Self::Absolute(length)
 973    }
 974}
 975
 976impl Default for DefiniteLength {
 977    fn default() -> Self {
 978        Self::Absolute(AbsoluteLength::default())
 979    }
 980}
 981
 982/// A length that can be defined in pixels, rems, percent of parent, or auto.
 983#[derive(Clone, Copy)]
 984pub enum Length {
 985    Definite(DefiniteLength),
 986    Auto,
 987}
 988
 989impl Debug for Length {
 990    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 991        match self {
 992            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
 993            Length::Auto => write!(f, "auto"),
 994        }
 995    }
 996}
 997
 998pub fn relative(fraction: f32) -> DefiniteLength {
 999    DefiniteLength::Fraction(fraction).into()
1000}
1001
1002/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1003pub fn phi() -> DefiniteLength {
1004    relative(1.61803398875)
1005}
1006
1007pub fn rems(rems: f32) -> Rems {
1008    Rems(rems)
1009}
1010
1011pub fn px(pixels: f32) -> Pixels {
1012    Pixels(pixels)
1013}
1014
1015pub fn auto() -> Length {
1016    Length::Auto
1017}
1018
1019impl From<Pixels> for Length {
1020    fn from(pixels: Pixels) -> Self {
1021        Self::Definite(pixels.into())
1022    }
1023}
1024
1025impl From<Rems> for Length {
1026    fn from(rems: Rems) -> Self {
1027        Self::Definite(rems.into())
1028    }
1029}
1030
1031impl From<DefiniteLength> for Length {
1032    fn from(length: DefiniteLength) -> Self {
1033        Self::Definite(length)
1034    }
1035}
1036
1037impl From<AbsoluteLength> for Length {
1038    fn from(length: AbsoluteLength) -> Self {
1039        Self::Definite(length.into())
1040    }
1041}
1042
1043impl Default for Length {
1044    fn default() -> Self {
1045        Self::Definite(DefiniteLength::default())
1046    }
1047}
1048
1049impl From<()> for Length {
1050    fn from(_: ()) -> Self {
1051        Self::Definite(DefiniteLength::default())
1052    }
1053}
1054
1055pub trait IsZero {
1056    fn is_zero(&self) -> bool;
1057}
1058
1059impl IsZero for DevicePixels {
1060    fn is_zero(&self) -> bool {
1061        self.0 == 0
1062    }
1063}
1064
1065impl IsZero for ScaledPixels {
1066    fn is_zero(&self) -> bool {
1067        self.0 == 0.
1068    }
1069}
1070
1071impl IsZero for Pixels {
1072    fn is_zero(&self) -> bool {
1073        self.0 == 0.
1074    }
1075}
1076
1077impl IsZero for Rems {
1078    fn is_zero(&self) -> bool {
1079        self.0 == 0.
1080    }
1081}
1082
1083impl IsZero for AbsoluteLength {
1084    fn is_zero(&self) -> bool {
1085        match self {
1086            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1087            AbsoluteLength::Rems(rems) => rems.is_zero(),
1088        }
1089    }
1090}
1091
1092impl IsZero for DefiniteLength {
1093    fn is_zero(&self) -> bool {
1094        match self {
1095            DefiniteLength::Absolute(length) => length.is_zero(),
1096            DefiniteLength::Fraction(fraction) => *fraction == 0.,
1097        }
1098    }
1099}
1100
1101impl IsZero for Length {
1102    fn is_zero(&self) -> bool {
1103        match self {
1104            Length::Definite(length) => length.is_zero(),
1105            Length::Auto => false,
1106        }
1107    }
1108}
1109
1110impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1111    fn is_zero(&self) -> bool {
1112        self.x.is_zero() && self.y.is_zero()
1113    }
1114}
1115
1116impl<T> IsZero for Size<T>
1117where
1118    T: IsZero + Default + Debug + Clone,
1119{
1120    fn is_zero(&self) -> bool {
1121        self.width.is_zero() || self.height.is_zero()
1122    }
1123}
1124
1125impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1126    fn is_zero(&self) -> bool {
1127        self.size.is_zero()
1128    }
1129}
1130
1131impl<T> IsZero for Corners<T>
1132where
1133    T: IsZero + Clone + Default + Debug,
1134{
1135    fn is_zero(&self) -> bool {
1136        self.top_left.is_zero()
1137            && self.top_right.is_zero()
1138            && self.bottom_right.is_zero()
1139            && self.bottom_left.is_zero()
1140    }
1141}
1142
1143#[cfg(test)]
1144mod tests {
1145    use super::*;
1146
1147    #[test]
1148    fn test_bounds_intersects() {
1149        let bounds1 = Bounds {
1150            origin: Point { x: 0.0, y: 0.0 },
1151            size: Size {
1152                width: 5.0,
1153                height: 5.0,
1154            },
1155        };
1156        let bounds2 = Bounds {
1157            origin: Point { x: 4.0, y: 4.0 },
1158            size: Size {
1159                width: 5.0,
1160                height: 5.0,
1161            },
1162        };
1163        let bounds3 = Bounds {
1164            origin: Point { x: 10.0, y: 10.0 },
1165            size: Size {
1166                width: 5.0,
1167                height: 5.0,
1168            },
1169        };
1170
1171        // Test Case 1: Intersecting bounds
1172        assert_eq!(bounds1.intersects(&bounds2), true);
1173
1174        // Test Case 2: Non-Intersecting bounds
1175        assert_eq!(bounds1.intersects(&bounds3), false);
1176
1177        // Test Case 3: Bounds intersecting with themselves
1178        assert_eq!(bounds1.intersects(&bounds1), true);
1179    }
1180}