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<Pixels> for f32 {
 660    type Output = Pixels;
 661
 662    fn mul(self, rhs: Pixels) -> Self::Output {
 663        Pixels(self * rhs.0)
 664    }
 665}
 666
 667impl MulAssign<f32> for Pixels {
 668    fn mul_assign(&mut self, other: f32) {
 669        self.0 *= other;
 670    }
 671}
 672
 673impl Pixels {
 674    pub fn round(&self) -> Self {
 675        Self(self.0.round())
 676    }
 677
 678    pub fn scale(&self, factor: f32) -> ScaledPixels {
 679        ScaledPixels(self.0 * factor)
 680    }
 681}
 682
 683impl Mul<Pixels> for Pixels {
 684    type Output = Pixels;
 685
 686    fn mul(self, rhs: Pixels) -> Self::Output {
 687        Pixels(self.0 * rhs.0)
 688    }
 689}
 690
 691impl Eq for Pixels {}
 692
 693impl Ord for Pixels {
 694    fn cmp(&self, other: &Self) -> cmp::Ordering {
 695        self.0.partial_cmp(&other.0).unwrap()
 696    }
 697}
 698
 699impl std::hash::Hash for Pixels {
 700    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
 701        self.0.to_bits().hash(state);
 702    }
 703}
 704
 705impl From<f64> for Pixels {
 706    fn from(pixels: f64) -> Self {
 707        Pixels(pixels as f32)
 708    }
 709}
 710
 711impl From<f32> for Pixels {
 712    fn from(pixels: f32) -> Self {
 713        Pixels(pixels)
 714    }
 715}
 716
 717impl Debug for Pixels {
 718    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 719        write!(f, "{} px", self.0)
 720    }
 721}
 722
 723impl From<Pixels> for f32 {
 724    fn from(pixels: Pixels) -> Self {
 725        pixels.0
 726    }
 727}
 728
 729impl From<&Pixels> for f32 {
 730    fn from(pixels: &Pixels) -> Self {
 731        pixels.0
 732    }
 733}
 734
 735impl From<Pixels> for f64 {
 736    fn from(pixels: Pixels) -> Self {
 737        pixels.0 as f64
 738    }
 739}
 740
 741#[derive(
 742    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
 743)]
 744#[repr(transparent)]
 745pub struct DevicePixels(pub(crate) i32);
 746
 747impl DevicePixels {
 748    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
 749        self.0 as u32 * bytes_per_pixel as u32
 750    }
 751}
 752
 753impl fmt::Debug for DevicePixels {
 754    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 755        write!(f, "{} px (device)", self.0)
 756    }
 757}
 758
 759impl From<DevicePixels> for i32 {
 760    fn from(device_pixels: DevicePixels) -> Self {
 761        device_pixels.0
 762    }
 763}
 764
 765impl From<i32> for DevicePixels {
 766    fn from(device_pixels: i32) -> Self {
 767        DevicePixels(device_pixels)
 768    }
 769}
 770
 771impl From<u32> for DevicePixels {
 772    fn from(device_pixels: u32) -> Self {
 773        DevicePixels(device_pixels as i32)
 774    }
 775}
 776
 777impl From<DevicePixels> for u32 {
 778    fn from(device_pixels: DevicePixels) -> Self {
 779        device_pixels.0 as u32
 780    }
 781}
 782
 783impl From<DevicePixels> for u64 {
 784    fn from(device_pixels: DevicePixels) -> Self {
 785        device_pixels.0 as u64
 786    }
 787}
 788
 789impl From<u64> for DevicePixels {
 790    fn from(device_pixels: u64) -> Self {
 791        DevicePixels(device_pixels as i32)
 792    }
 793}
 794
 795#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 796#[repr(transparent)]
 797pub struct ScaledPixels(pub(crate) f32);
 798
 799impl ScaledPixels {
 800    pub fn floor(&self) -> Self {
 801        Self(self.0.floor())
 802    }
 803
 804    pub fn ceil(&self) -> Self {
 805        Self(self.0.ceil())
 806    }
 807}
 808
 809impl Eq for ScaledPixels {}
 810
 811impl Debug for ScaledPixels {
 812    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 813        write!(f, "{} px (scaled)", self.0)
 814    }
 815}
 816
 817impl From<ScaledPixels> for DevicePixels {
 818    fn from(scaled: ScaledPixels) -> Self {
 819        DevicePixels(scaled.0.ceil() as i32)
 820    }
 821}
 822
 823impl From<DevicePixels> for ScaledPixels {
 824    fn from(device: DevicePixels) -> Self {
 825        ScaledPixels(device.0 as f32)
 826    }
 827}
 828
 829impl From<ScaledPixels> for f64 {
 830    fn from(scaled_pixels: ScaledPixels) -> Self {
 831        scaled_pixels.0 as f64
 832    }
 833}
 834
 835#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 836#[repr(transparent)]
 837pub struct GlobalPixels(pub(crate) f32);
 838
 839impl Debug for GlobalPixels {
 840    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 841        write!(f, "{} px (global coordinate space)", self.0)
 842    }
 843}
 844
 845impl From<GlobalPixels> for f64 {
 846    fn from(global_pixels: GlobalPixels) -> Self {
 847        global_pixels.0 as f64
 848    }
 849}
 850
 851impl From<f64> for GlobalPixels {
 852    fn from(global_pixels: f64) -> Self {
 853        GlobalPixels(global_pixels as f32)
 854    }
 855}
 856
 857#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
 858pub struct Rems(f32);
 859
 860impl Mul<Pixels> for Rems {
 861    type Output = Pixels;
 862
 863    fn mul(self, other: Pixels) -> Pixels {
 864        Pixels(self.0 * other.0)
 865    }
 866}
 867
 868impl Debug for Rems {
 869    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 870        write!(f, "{} rem", self.0)
 871    }
 872}
 873
 874#[derive(Clone, Copy, Debug, Neg)]
 875pub enum AbsoluteLength {
 876    Pixels(Pixels),
 877    Rems(Rems),
 878}
 879
 880impl AbsoluteLength {
 881    pub fn is_zero(&self) -> bool {
 882        match self {
 883            AbsoluteLength::Pixels(px) => px.0 == 0.,
 884            AbsoluteLength::Rems(rems) => rems.0 == 0.,
 885        }
 886    }
 887}
 888
 889impl From<Pixels> for AbsoluteLength {
 890    fn from(pixels: Pixels) -> Self {
 891        AbsoluteLength::Pixels(pixels)
 892    }
 893}
 894
 895impl From<Rems> for AbsoluteLength {
 896    fn from(rems: Rems) -> Self {
 897        AbsoluteLength::Rems(rems)
 898    }
 899}
 900
 901impl AbsoluteLength {
 902    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
 903        match self {
 904            AbsoluteLength::Pixels(pixels) => *pixels,
 905            AbsoluteLength::Rems(rems) => *rems * rem_size,
 906        }
 907    }
 908}
 909
 910impl Default for AbsoluteLength {
 911    fn default() -> Self {
 912        px(0.).into()
 913    }
 914}
 915
 916/// A non-auto length that can be defined in pixels, rems, or percent of parent.
 917#[derive(Clone, Copy, Neg)]
 918pub enum DefiniteLength {
 919    Absolute(AbsoluteLength),
 920    /// A fraction of the parent's size between 0 and 1.
 921    Fraction(f32),
 922}
 923
 924impl DefiniteLength {
 925    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
 926        match self {
 927            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
 928            DefiniteLength::Fraction(fraction) => match base_size {
 929                AbsoluteLength::Pixels(px) => px * *fraction,
 930                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
 931            },
 932        }
 933    }
 934}
 935
 936impl Debug for DefiniteLength {
 937    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 938        match self {
 939            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
 940            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
 941        }
 942    }
 943}
 944
 945impl From<Pixels> for DefiniteLength {
 946    fn from(pixels: Pixels) -> Self {
 947        Self::Absolute(pixels.into())
 948    }
 949}
 950
 951impl From<Rems> for DefiniteLength {
 952    fn from(rems: Rems) -> Self {
 953        Self::Absolute(rems.into())
 954    }
 955}
 956
 957impl From<AbsoluteLength> for DefiniteLength {
 958    fn from(length: AbsoluteLength) -> Self {
 959        Self::Absolute(length)
 960    }
 961}
 962
 963impl Default for DefiniteLength {
 964    fn default() -> Self {
 965        Self::Absolute(AbsoluteLength::default())
 966    }
 967}
 968
 969/// A length that can be defined in pixels, rems, percent of parent, or auto.
 970#[derive(Clone, Copy)]
 971pub enum Length {
 972    Definite(DefiniteLength),
 973    Auto,
 974}
 975
 976impl Debug for Length {
 977    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 978        match self {
 979            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
 980            Length::Auto => write!(f, "auto"),
 981        }
 982    }
 983}
 984
 985pub fn relative(fraction: f32) -> DefiniteLength {
 986    DefiniteLength::Fraction(fraction).into()
 987}
 988
 989/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
 990pub fn phi() -> DefiniteLength {
 991    relative(1.61803398875)
 992}
 993
 994pub fn rems(rems: f32) -> Rems {
 995    Rems(rems)
 996}
 997
 998pub fn px(pixels: f32) -> Pixels {
 999    Pixels(pixels)
1000}
1001
1002pub fn auto() -> Length {
1003    Length::Auto
1004}
1005
1006impl From<Pixels> for Length {
1007    fn from(pixels: Pixels) -> Self {
1008        Self::Definite(pixels.into())
1009    }
1010}
1011
1012impl From<Rems> for Length {
1013    fn from(rems: Rems) -> Self {
1014        Self::Definite(rems.into())
1015    }
1016}
1017
1018impl From<DefiniteLength> for Length {
1019    fn from(length: DefiniteLength) -> Self {
1020        Self::Definite(length)
1021    }
1022}
1023
1024impl From<AbsoluteLength> for Length {
1025    fn from(length: AbsoluteLength) -> Self {
1026        Self::Definite(length.into())
1027    }
1028}
1029
1030impl Default for Length {
1031    fn default() -> Self {
1032        Self::Definite(DefiniteLength::default())
1033    }
1034}
1035
1036impl From<()> for Length {
1037    fn from(_: ()) -> Self {
1038        Self::Definite(DefiniteLength::default())
1039    }
1040}
1041
1042pub trait IsZero {
1043    fn is_zero(&self) -> bool;
1044}
1045
1046impl IsZero for DevicePixels {
1047    fn is_zero(&self) -> bool {
1048        self.0 == 0
1049    }
1050}
1051
1052impl IsZero for ScaledPixels {
1053    fn is_zero(&self) -> bool {
1054        self.0 == 0.
1055    }
1056}
1057
1058impl IsZero for Pixels {
1059    fn is_zero(&self) -> bool {
1060        self.0 == 0.
1061    }
1062}
1063
1064impl IsZero for Rems {
1065    fn is_zero(&self) -> bool {
1066        self.0 == 0.
1067    }
1068}
1069
1070impl IsZero for AbsoluteLength {
1071    fn is_zero(&self) -> bool {
1072        match self {
1073            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1074            AbsoluteLength::Rems(rems) => rems.is_zero(),
1075        }
1076    }
1077}
1078
1079impl IsZero for DefiniteLength {
1080    fn is_zero(&self) -> bool {
1081        match self {
1082            DefiniteLength::Absolute(length) => length.is_zero(),
1083            DefiniteLength::Fraction(fraction) => *fraction == 0.,
1084        }
1085    }
1086}
1087
1088impl IsZero for Length {
1089    fn is_zero(&self) -> bool {
1090        match self {
1091            Length::Definite(length) => length.is_zero(),
1092            Length::Auto => false,
1093        }
1094    }
1095}
1096
1097impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1098    fn is_zero(&self) -> bool {
1099        self.x.is_zero() && self.y.is_zero()
1100    }
1101}
1102
1103impl<T> IsZero for Size<T>
1104where
1105    T: IsZero + Default + Debug + Clone,
1106{
1107    fn is_zero(&self) -> bool {
1108        self.width.is_zero() || self.height.is_zero()
1109    }
1110}
1111
1112impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1113    fn is_zero(&self) -> bool {
1114        self.size.is_zero()
1115    }
1116}
1117
1118impl<T> IsZero for Corners<T>
1119where
1120    T: IsZero + Clone + Default + Debug,
1121{
1122    fn is_zero(&self) -> bool {
1123        self.top_left.is_zero()
1124            && self.top_right.is_zero()
1125            && self.bottom_right.is_zero()
1126            && self.bottom_left.is_zero()
1127    }
1128}
1129
1130#[cfg(test)]
1131mod tests {
1132    use super::*;
1133
1134    #[test]
1135    fn test_bounds_intersects() {
1136        let bounds1 = Bounds {
1137            origin: Point { x: 0.0, y: 0.0 },
1138            size: Size {
1139                width: 5.0,
1140                height: 5.0,
1141            },
1142        };
1143        let bounds2 = Bounds {
1144            origin: Point { x: 4.0, y: 4.0 },
1145            size: Size {
1146                width: 5.0,
1147                height: 5.0,
1148            },
1149        };
1150        let bounds3 = Bounds {
1151            origin: Point { x: 10.0, y: 10.0 },
1152            size: Size {
1153                width: 5.0,
1154                height: 5.0,
1155            },
1156        };
1157
1158        // Test Case 1: Intersecting bounds
1159        assert_eq!(bounds1.intersects(&bounds2), true);
1160
1161        // Test Case 2: Non-Intersecting bounds
1162        assert_eq!(bounds1.intersects(&bounds3), false);
1163
1164        // Test Case 3: Bounds intersecting with themselves
1165        assert_eq!(bounds1.intersects(&bounds1), true);
1166    }
1167}