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