geometry.rs

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