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 ceil(&self) -> Self {
 789        Self(self.0.ceil())
 790    }
 791
 792    pub fn scale(&self, factor: f32) -> ScaledPixels {
 793        ScaledPixels(self.0 * factor)
 794    }
 795
 796    pub fn pow(&self, exponent: f32) -> Self {
 797        Self(self.0.powf(exponent))
 798    }
 799
 800    pub fn abs(&self) -> Self {
 801        Self(self.0.abs())
 802    }
 803}
 804
 805impl Mul<Pixels> for Pixels {
 806    type Output = Pixels;
 807
 808    fn mul(self, rhs: Pixels) -> Self::Output {
 809        Pixels(self.0 * rhs.0)
 810    }
 811}
 812
 813impl Eq for Pixels {}
 814
 815impl Ord for Pixels {
 816    fn cmp(&self, other: &Self) -> cmp::Ordering {
 817        self.0.partial_cmp(&other.0).unwrap()
 818    }
 819}
 820
 821impl std::hash::Hash for Pixels {
 822    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
 823        self.0.to_bits().hash(state);
 824    }
 825}
 826
 827impl From<f64> for Pixels {
 828    fn from(pixels: f64) -> Self {
 829        Pixels(pixels as f32)
 830    }
 831}
 832
 833impl From<f32> for Pixels {
 834    fn from(pixels: f32) -> Self {
 835        Pixels(pixels)
 836    }
 837}
 838
 839impl Debug for Pixels {
 840    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 841        write!(f, "{} px", self.0)
 842    }
 843}
 844
 845impl From<Pixels> for f32 {
 846    fn from(pixels: Pixels) -> Self {
 847        pixels.0
 848    }
 849}
 850
 851impl From<&Pixels> for f32 {
 852    fn from(pixels: &Pixels) -> Self {
 853        pixels.0
 854    }
 855}
 856
 857impl From<Pixels> for f64 {
 858    fn from(pixels: Pixels) -> Self {
 859        pixels.0 as f64
 860    }
 861}
 862
 863impl From<Pixels> for u32 {
 864    fn from(pixels: Pixels) -> Self {
 865        pixels.0 as u32
 866    }
 867}
 868
 869impl From<u32> for Pixels {
 870    fn from(pixels: u32) -> Self {
 871        Pixels(pixels as f32)
 872    }
 873}
 874
 875impl From<Pixels> for usize {
 876    fn from(pixels: Pixels) -> Self {
 877        pixels.0 as usize
 878    }
 879}
 880
 881#[derive(
 882    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
 883)]
 884#[repr(transparent)]
 885pub struct DevicePixels(pub(crate) i32);
 886
 887impl DevicePixels {
 888    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
 889        self.0 as u32 * bytes_per_pixel as u32
 890    }
 891}
 892
 893impl fmt::Debug for DevicePixels {
 894    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 895        write!(f, "{} px (device)", self.0)
 896    }
 897}
 898
 899impl From<DevicePixels> for i32 {
 900    fn from(device_pixels: DevicePixels) -> Self {
 901        device_pixels.0
 902    }
 903}
 904
 905impl From<i32> for DevicePixels {
 906    fn from(device_pixels: i32) -> Self {
 907        DevicePixels(device_pixels)
 908    }
 909}
 910
 911impl From<u32> for DevicePixels {
 912    fn from(device_pixels: u32) -> Self {
 913        DevicePixels(device_pixels as i32)
 914    }
 915}
 916
 917impl From<DevicePixels> for u32 {
 918    fn from(device_pixels: DevicePixels) -> Self {
 919        device_pixels.0 as u32
 920    }
 921}
 922
 923impl From<DevicePixels> for u64 {
 924    fn from(device_pixels: DevicePixels) -> Self {
 925        device_pixels.0 as u64
 926    }
 927}
 928
 929impl From<u64> for DevicePixels {
 930    fn from(device_pixels: u64) -> Self {
 931        DevicePixels(device_pixels as i32)
 932    }
 933}
 934
 935#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 936#[repr(transparent)]
 937pub struct ScaledPixels(pub(crate) f32);
 938
 939impl ScaledPixels {
 940    pub fn floor(&self) -> Self {
 941        Self(self.0.floor())
 942    }
 943
 944    pub fn ceil(&self) -> Self {
 945        Self(self.0.ceil())
 946    }
 947}
 948
 949impl Eq for ScaledPixels {}
 950
 951impl Debug for ScaledPixels {
 952    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 953        write!(f, "{} px (scaled)", self.0)
 954    }
 955}
 956
 957impl From<ScaledPixels> for DevicePixels {
 958    fn from(scaled: ScaledPixels) -> Self {
 959        DevicePixels(scaled.0.ceil() as i32)
 960    }
 961}
 962
 963impl From<DevicePixels> for ScaledPixels {
 964    fn from(device: DevicePixels) -> Self {
 965        ScaledPixels(device.0 as f32)
 966    }
 967}
 968
 969impl From<ScaledPixels> for f64 {
 970    fn from(scaled_pixels: ScaledPixels) -> Self {
 971        scaled_pixels.0 as f64
 972    }
 973}
 974
 975#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 976#[repr(transparent)]
 977pub struct GlobalPixels(pub(crate) f32);
 978
 979impl Debug for GlobalPixels {
 980    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 981        write!(f, "{} px (global coordinate space)", self.0)
 982    }
 983}
 984
 985impl From<GlobalPixels> for f64 {
 986    fn from(global_pixels: GlobalPixels) -> Self {
 987        global_pixels.0 as f64
 988    }
 989}
 990
 991impl From<f64> for GlobalPixels {
 992    fn from(global_pixels: f64) -> Self {
 993        GlobalPixels(global_pixels as f32)
 994    }
 995}
 996
 997impl sqlez::bindable::StaticColumnCount for GlobalPixels {}
 998
 999impl sqlez::bindable::Bind for GlobalPixels {
1000    fn bind(
1001        &self,
1002        statement: &sqlez::statement::Statement,
1003        start_index: i32,
1004    ) -> anyhow::Result<i32> {
1005        self.0.bind(statement, start_index)
1006    }
1007}
1008
1009#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
1010pub struct Rems(f32);
1011
1012impl Mul<Pixels> for Rems {
1013    type Output = Pixels;
1014
1015    fn mul(self, other: Pixels) -> Pixels {
1016        Pixels(self.0 * other.0)
1017    }
1018}
1019
1020impl Debug for Rems {
1021    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1022        write!(f, "{} rem", self.0)
1023    }
1024}
1025
1026#[derive(Clone, Copy, Debug, Neg)]
1027pub enum AbsoluteLength {
1028    Pixels(Pixels),
1029    Rems(Rems),
1030}
1031
1032impl AbsoluteLength {
1033    pub fn is_zero(&self) -> bool {
1034        match self {
1035            AbsoluteLength::Pixels(px) => px.0 == 0.,
1036            AbsoluteLength::Rems(rems) => rems.0 == 0.,
1037        }
1038    }
1039}
1040
1041impl From<Pixels> for AbsoluteLength {
1042    fn from(pixels: Pixels) -> Self {
1043        AbsoluteLength::Pixels(pixels)
1044    }
1045}
1046
1047impl From<Rems> for AbsoluteLength {
1048    fn from(rems: Rems) -> Self {
1049        AbsoluteLength::Rems(rems)
1050    }
1051}
1052
1053impl AbsoluteLength {
1054    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
1055        match self {
1056            AbsoluteLength::Pixels(pixels) => *pixels,
1057            AbsoluteLength::Rems(rems) => *rems * rem_size,
1058        }
1059    }
1060}
1061
1062impl Default for AbsoluteLength {
1063    fn default() -> Self {
1064        px(0.).into()
1065    }
1066}
1067
1068/// A non-auto length that can be defined in pixels, rems, or percent of parent.
1069#[derive(Clone, Copy, Neg)]
1070pub enum DefiniteLength {
1071    Absolute(AbsoluteLength),
1072    /// A fraction of the parent's size between 0 and 1.
1073    Fraction(f32),
1074}
1075
1076impl DefiniteLength {
1077    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
1078        match self {
1079            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
1080            DefiniteLength::Fraction(fraction) => match base_size {
1081                AbsoluteLength::Pixels(px) => px * *fraction,
1082                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
1083            },
1084        }
1085    }
1086}
1087
1088impl Debug for DefiniteLength {
1089    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1090        match self {
1091            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
1092            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
1093        }
1094    }
1095}
1096
1097impl From<Pixels> for DefiniteLength {
1098    fn from(pixels: Pixels) -> Self {
1099        Self::Absolute(pixels.into())
1100    }
1101}
1102
1103impl From<Rems> for DefiniteLength {
1104    fn from(rems: Rems) -> Self {
1105        Self::Absolute(rems.into())
1106    }
1107}
1108
1109impl From<AbsoluteLength> for DefiniteLength {
1110    fn from(length: AbsoluteLength) -> Self {
1111        Self::Absolute(length)
1112    }
1113}
1114
1115impl Default for DefiniteLength {
1116    fn default() -> Self {
1117        Self::Absolute(AbsoluteLength::default())
1118    }
1119}
1120
1121/// A length that can be defined in pixels, rems, percent of parent, or auto.
1122#[derive(Clone, Copy)]
1123pub enum Length {
1124    Definite(DefiniteLength),
1125    Auto,
1126}
1127
1128impl Debug for Length {
1129    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1130        match self {
1131            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
1132            Length::Auto => write!(f, "auto"),
1133        }
1134    }
1135}
1136
1137pub fn relative(fraction: f32) -> DefiniteLength {
1138    DefiniteLength::Fraction(fraction).into()
1139}
1140
1141/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1142pub fn phi() -> DefiniteLength {
1143    relative(1.61803398875)
1144}
1145
1146pub fn rems(rems: f32) -> Rems {
1147    Rems(rems)
1148}
1149
1150pub const fn px(pixels: f32) -> Pixels {
1151    Pixels(pixels)
1152}
1153
1154pub fn auto() -> Length {
1155    Length::Auto
1156}
1157
1158impl From<Pixels> for Length {
1159    fn from(pixels: Pixels) -> Self {
1160        Self::Definite(pixels.into())
1161    }
1162}
1163
1164impl From<Rems> for Length {
1165    fn from(rems: Rems) -> Self {
1166        Self::Definite(rems.into())
1167    }
1168}
1169
1170impl From<DefiniteLength> for Length {
1171    fn from(length: DefiniteLength) -> Self {
1172        Self::Definite(length)
1173    }
1174}
1175
1176impl From<AbsoluteLength> for Length {
1177    fn from(length: AbsoluteLength) -> Self {
1178        Self::Definite(length.into())
1179    }
1180}
1181
1182impl Default for Length {
1183    fn default() -> Self {
1184        Self::Definite(DefiniteLength::default())
1185    }
1186}
1187
1188impl From<()> for Length {
1189    fn from(_: ()) -> Self {
1190        Self::Definite(DefiniteLength::default())
1191    }
1192}
1193
1194pub trait IsZero {
1195    fn is_zero(&self) -> bool;
1196}
1197
1198impl IsZero for DevicePixels {
1199    fn is_zero(&self) -> bool {
1200        self.0 == 0
1201    }
1202}
1203
1204impl IsZero for ScaledPixels {
1205    fn is_zero(&self) -> bool {
1206        self.0 == 0.
1207    }
1208}
1209
1210impl IsZero for Pixels {
1211    fn is_zero(&self) -> bool {
1212        self.0 == 0.
1213    }
1214}
1215
1216impl IsZero for Rems {
1217    fn is_zero(&self) -> bool {
1218        self.0 == 0.
1219    }
1220}
1221
1222impl IsZero for AbsoluteLength {
1223    fn is_zero(&self) -> bool {
1224        match self {
1225            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1226            AbsoluteLength::Rems(rems) => rems.is_zero(),
1227        }
1228    }
1229}
1230
1231impl IsZero for DefiniteLength {
1232    fn is_zero(&self) -> bool {
1233        match self {
1234            DefiniteLength::Absolute(length) => length.is_zero(),
1235            DefiniteLength::Fraction(fraction) => *fraction == 0.,
1236        }
1237    }
1238}
1239
1240impl IsZero for Length {
1241    fn is_zero(&self) -> bool {
1242        match self {
1243            Length::Definite(length) => length.is_zero(),
1244            Length::Auto => false,
1245        }
1246    }
1247}
1248
1249impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1250    fn is_zero(&self) -> bool {
1251        self.x.is_zero() && self.y.is_zero()
1252    }
1253}
1254
1255impl<T> IsZero for Size<T>
1256where
1257    T: IsZero + Default + Debug + Clone,
1258{
1259    fn is_zero(&self) -> bool {
1260        self.width.is_zero() || self.height.is_zero()
1261    }
1262}
1263
1264impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1265    fn is_zero(&self) -> bool {
1266        self.size.is_zero()
1267    }
1268}
1269
1270impl<T> IsZero for Corners<T>
1271where
1272    T: IsZero + Clone + Default + Debug,
1273{
1274    fn is_zero(&self) -> bool {
1275        self.top_left.is_zero()
1276            && self.top_right.is_zero()
1277            && self.bottom_right.is_zero()
1278            && self.bottom_left.is_zero()
1279    }
1280}
1281
1282#[cfg(test)]
1283mod tests {
1284    use super::*;
1285
1286    #[test]
1287    fn test_bounds_intersects() {
1288        let bounds1 = Bounds {
1289            origin: Point { x: 0.0, y: 0.0 },
1290            size: Size {
1291                width: 5.0,
1292                height: 5.0,
1293            },
1294        };
1295        let bounds2 = Bounds {
1296            origin: Point { x: 4.0, y: 4.0 },
1297            size: Size {
1298                width: 5.0,
1299                height: 5.0,
1300            },
1301        };
1302        let bounds3 = Bounds {
1303            origin: Point { x: 10.0, y: 10.0 },
1304            size: Size {
1305                width: 5.0,
1306                height: 5.0,
1307            },
1308        };
1309
1310        // Test Case 1: Intersecting bounds
1311        assert_eq!(bounds1.intersects(&bounds2), true);
1312
1313        // Test Case 2: Non-Intersecting bounds
1314        assert_eq!(bounds1.intersects(&bounds3), false);
1315
1316        // Test Case 3: Bounds intersecting with themselves
1317        assert_eq!(bounds1.intersects(&bounds1), true);
1318    }
1319}