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