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