geometry.rs

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