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    pub fn new(origin: Point<T>, size: Size<T>) -> Self {
 340        Bounds { origin, size }
 341    }
 342}
 343
 344impl<T> Bounds<T>
 345where
 346    T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default,
 347{
 348    pub fn intersects(&self, other: &Bounds<T>) -> bool {
 349        let my_lower_right = self.lower_right();
 350        let their_lower_right = other.lower_right();
 351
 352        self.origin.x < their_lower_right.x
 353            && my_lower_right.x > other.origin.x
 354            && self.origin.y < their_lower_right.y
 355            && my_lower_right.y > other.origin.y
 356    }
 357
 358    pub fn dilate(&mut self, amount: T) {
 359        self.origin.x = self.origin.x.clone() - amount.clone();
 360        self.origin.y = self.origin.y.clone() - amount.clone();
 361        let double_amount = amount.clone() + amount;
 362        self.size.width = self.size.width.clone() + double_amount.clone();
 363        self.size.height = self.size.height.clone() + double_amount;
 364    }
 365}
 366
 367impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
 368    pub fn intersect(&self, other: &Self) -> Self {
 369        let upper_left = self.origin.max(&other.origin);
 370        let lower_right = self.lower_right().min(&other.lower_right());
 371        Self::from_corners(upper_left, lower_right)
 372    }
 373
 374    pub fn union(&self, other: &Self) -> Self {
 375        let top_left = self.origin.min(&other.origin);
 376        let bottom_right = self.lower_right().max(&other.lower_right());
 377        Bounds::from_corners(top_left, bottom_right)
 378    }
 379}
 380
 381impl<T, Rhs> Mul<Rhs> for Bounds<T>
 382where
 383    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
 384    Point<T>: Mul<Rhs, Output = Point<Rhs>>,
 385    Rhs: Clone + Default + Debug,
 386{
 387    type Output = Bounds<Rhs>;
 388
 389    fn mul(self, rhs: Rhs) -> Self::Output {
 390        Bounds {
 391            origin: self.origin * rhs.clone(),
 392            size: self.size * rhs,
 393        }
 394    }
 395}
 396
 397impl<T, S> MulAssign<S> for Bounds<T>
 398where
 399    T: Mul<S, Output = T> + Clone + Default + Debug,
 400    S: Clone,
 401{
 402    fn mul_assign(&mut self, rhs: S) {
 403        self.origin *= rhs.clone();
 404        self.size *= rhs;
 405    }
 406}
 407
 408impl<T, S> Div<S> for Bounds<T>
 409where
 410    Size<T>: Div<S, Output = Size<T>>,
 411    T: Div<S, Output = T> + Default + Clone + Debug,
 412    S: Clone,
 413{
 414    type Output = Self;
 415
 416    fn div(self, rhs: S) -> Self {
 417        Self {
 418            origin: self.origin / rhs.clone(),
 419            size: self.size / rhs,
 420        }
 421    }
 422}
 423
 424impl<T> Bounds<T>
 425where
 426    T: Add<T, Output = T> + Clone + Default + Debug,
 427{
 428    pub fn top(&self) -> T {
 429        self.origin.y.clone()
 430    }
 431
 432    pub fn bottom(&self) -> T {
 433        self.origin.y.clone() + self.size.height.clone()
 434    }
 435
 436    pub fn left(&self) -> T {
 437        self.origin.x.clone()
 438    }
 439
 440    pub fn right(&self) -> T {
 441        self.origin.x.clone() + self.size.width.clone()
 442    }
 443
 444    pub fn upper_right(&self) -> Point<T> {
 445        Point {
 446            x: self.origin.x.clone() + self.size.width.clone(),
 447            y: self.origin.y.clone(),
 448        }
 449    }
 450
 451    pub fn lower_right(&self) -> Point<T> {
 452        Point {
 453            x: self.origin.x.clone() + self.size.width.clone(),
 454            y: self.origin.y.clone() + self.size.height.clone(),
 455        }
 456    }
 457
 458    pub fn lower_left(&self) -> Point<T> {
 459        Point {
 460            x: self.origin.x.clone(),
 461            y: self.origin.y.clone() + self.size.height.clone(),
 462        }
 463    }
 464}
 465
 466impl<T> Bounds<T>
 467where
 468    T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
 469{
 470    pub fn contains_point(&self, point: &Point<T>) -> bool {
 471        point.x >= self.origin.x
 472            && point.x <= self.origin.x.clone() + self.size.width.clone()
 473            && point.y >= self.origin.y
 474            && point.y <= self.origin.y.clone() + self.size.height.clone()
 475    }
 476
 477    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
 478    where
 479        U: Clone + Default + Debug,
 480    {
 481        Bounds {
 482            origin: self.origin.map(&f),
 483            size: self.size.map(f),
 484        }
 485    }
 486}
 487
 488impl Bounds<Pixels> {
 489    pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
 490        Bounds {
 491            origin: self.origin.scale(factor),
 492            size: self.size.scale(factor),
 493        }
 494    }
 495}
 496
 497impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
 498
 499#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 500#[refineable(Debug)]
 501#[repr(C)]
 502pub struct Edges<T: Clone + Default + Debug> {
 503    pub top: T,
 504    pub right: T,
 505    pub bottom: T,
 506    pub left: T,
 507}
 508
 509impl<T> Mul for Edges<T>
 510where
 511    T: Mul<Output = T> + Clone + Default + Debug,
 512{
 513    type Output = Self;
 514
 515    fn mul(self, rhs: Self) -> Self::Output {
 516        Self {
 517            top: self.top.clone() * rhs.top,
 518            right: self.right.clone() * rhs.right,
 519            bottom: self.bottom.clone() * rhs.bottom,
 520            left: self.left.clone() * rhs.left,
 521        }
 522    }
 523}
 524
 525impl<T, S> MulAssign<S> for Edges<T>
 526where
 527    T: Mul<S, Output = T> + Clone + Default + Debug,
 528    S: Clone,
 529{
 530    fn mul_assign(&mut self, rhs: S) {
 531        self.top = self.top.clone() * rhs.clone();
 532        self.right = self.right.clone() * rhs.clone();
 533        self.bottom = self.bottom.clone() * rhs.clone();
 534        self.left = self.left.clone() * rhs;
 535    }
 536}
 537
 538impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
 539
 540impl<T: Clone + Default + Debug> Edges<T> {
 541    pub fn all(value: T) -> Self {
 542        Self {
 543            top: value.clone(),
 544            right: value.clone(),
 545            bottom: value.clone(),
 546            left: value,
 547        }
 548    }
 549
 550    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
 551    where
 552        U: Clone + Default + Debug,
 553    {
 554        Edges {
 555            top: f(&self.top),
 556            right: f(&self.right),
 557            bottom: f(&self.bottom),
 558            left: f(&self.left),
 559        }
 560    }
 561
 562    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
 563        predicate(&self.top)
 564            || predicate(&self.right)
 565            || predicate(&self.bottom)
 566            || predicate(&self.left)
 567    }
 568}
 569
 570impl Edges<Length> {
 571    pub fn auto() -> Self {
 572        Self {
 573            top: Length::Auto,
 574            right: Length::Auto,
 575            bottom: Length::Auto,
 576            left: Length::Auto,
 577        }
 578    }
 579
 580    pub fn zero() -> Self {
 581        Self {
 582            top: px(0.).into(),
 583            right: px(0.).into(),
 584            bottom: px(0.).into(),
 585            left: px(0.).into(),
 586        }
 587    }
 588}
 589
 590impl Edges<DefiniteLength> {
 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, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
 601        Edges {
 602            top: self.top.to_pixels(parent_size.height, rem_size),
 603            right: self.right.to_pixels(parent_size.width, rem_size),
 604            bottom: self.bottom.to_pixels(parent_size.height, rem_size),
 605            left: self.left.to_pixels(parent_size.width, rem_size),
 606        }
 607    }
 608}
 609
 610impl Edges<AbsoluteLength> {
 611    pub fn zero() -> Self {
 612        Self {
 613            top: px(0.).into(),
 614            right: px(0.).into(),
 615            bottom: px(0.).into(),
 616            left: px(0.).into(),
 617        }
 618    }
 619
 620    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
 621        Edges {
 622            top: self.top.to_pixels(rem_size),
 623            right: self.right.to_pixels(rem_size),
 624            bottom: self.bottom.to_pixels(rem_size),
 625            left: self.left.to_pixels(rem_size),
 626        }
 627    }
 628}
 629
 630impl Edges<Pixels> {
 631    pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
 632        Edges {
 633            top: self.top.scale(factor),
 634            right: self.right.scale(factor),
 635            bottom: self.bottom.scale(factor),
 636            left: self.left.scale(factor),
 637        }
 638    }
 639}
 640
 641#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 642#[refineable(Debug)]
 643#[repr(C)]
 644pub struct Corners<T: Clone + Default + Debug> {
 645    pub top_left: T,
 646    pub top_right: T,
 647    pub bottom_right: T,
 648    pub bottom_left: T,
 649}
 650
 651impl Corners<AbsoluteLength> {
 652    pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
 653        let max = size.width.max(size.height) / 2.;
 654        Corners {
 655            top_left: self.top_left.to_pixels(rem_size).min(max),
 656            top_right: self.top_right.to_pixels(rem_size).min(max),
 657            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
 658            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
 659        }
 660    }
 661}
 662
 663impl Corners<Pixels> {
 664    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
 665        Corners {
 666            top_left: self.top_left.scale(factor),
 667            top_right: self.top_right.scale(factor),
 668            bottom_right: self.bottom_right.scale(factor),
 669            bottom_left: self.bottom_left.scale(factor),
 670        }
 671    }
 672}
 673
 674impl<T: Clone + Default + Debug> Corners<T> {
 675    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
 676    where
 677        U: Clone + Default + Debug,
 678    {
 679        Corners {
 680            top_left: f(&self.top_left),
 681            top_right: f(&self.top_right),
 682            bottom_right: f(&self.bottom_right),
 683            bottom_left: f(&self.bottom_left),
 684        }
 685    }
 686}
 687
 688impl<T> Mul for Corners<T>
 689where
 690    T: Mul<Output = T> + Clone + Default + Debug,
 691{
 692    type Output = Self;
 693
 694    fn mul(self, rhs: Self) -> Self::Output {
 695        Self {
 696            top_left: self.top_left.clone() * rhs.top_left,
 697            top_right: self.top_right.clone() * rhs.top_right,
 698            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
 699            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
 700        }
 701    }
 702}
 703
 704impl<T, S> MulAssign<S> for Corners<T>
 705where
 706    T: Mul<S, Output = T> + Clone + Default + Debug,
 707    S: Clone,
 708{
 709    fn mul_assign(&mut self, rhs: S) {
 710        self.top_left = self.top_left.clone() * rhs.clone();
 711        self.top_right = self.top_right.clone() * rhs.clone();
 712        self.bottom_right = self.bottom_right.clone() * rhs.clone();
 713        self.bottom_left = self.bottom_left.clone() * rhs;
 714    }
 715}
 716
 717impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
 718
 719#[derive(
 720    Clone,
 721    Copy,
 722    Default,
 723    Add,
 724    AddAssign,
 725    Sub,
 726    SubAssign,
 727    Neg,
 728    Div,
 729    DivAssign,
 730    PartialEq,
 731    PartialOrd,
 732    Serialize,
 733    Deserialize,
 734)]
 735#[repr(transparent)]
 736pub struct Pixels(pub(crate) f32);
 737
 738impl std::ops::Div for Pixels {
 739    type Output = f32;
 740
 741    fn div(self, rhs: Self) -> Self::Output {
 742        self.0 / rhs.0
 743    }
 744}
 745
 746impl std::ops::DivAssign for Pixels {
 747    fn div_assign(&mut self, rhs: Self) {
 748        *self = Self(self.0 / rhs.0);
 749    }
 750}
 751
 752impl std::ops::RemAssign for Pixels {
 753    fn rem_assign(&mut self, rhs: Self) {
 754        self.0 %= rhs.0;
 755    }
 756}
 757
 758impl std::ops::Rem for Pixels {
 759    type Output = Self;
 760
 761    fn rem(self, rhs: Self) -> Self {
 762        Self(self.0 % rhs.0)
 763    }
 764}
 765
 766impl Mul<f32> for Pixels {
 767    type Output = Pixels;
 768
 769    fn mul(self, other: f32) -> Pixels {
 770        Pixels(self.0 * other)
 771    }
 772}
 773
 774impl Mul<usize> for Pixels {
 775    type Output = Pixels;
 776
 777    fn mul(self, other: usize) -> Pixels {
 778        Pixels(self.0 * other as f32)
 779    }
 780}
 781
 782impl Mul<Pixels> for f32 {
 783    type Output = Pixels;
 784
 785    fn mul(self, rhs: Pixels) -> Self::Output {
 786        Pixels(self * rhs.0)
 787    }
 788}
 789
 790impl MulAssign<f32> for Pixels {
 791    fn mul_assign(&mut self, other: f32) {
 792        self.0 *= other;
 793    }
 794}
 795
 796impl Pixels {
 797    pub const ZERO: Pixels = Pixels(0.0);
 798    pub const MAX: Pixels = Pixels(f32::MAX);
 799
 800    pub fn floor(&self) -> Self {
 801        Self(self.0.floor())
 802    }
 803
 804    pub fn round(&self) -> Self {
 805        Self(self.0.round())
 806    }
 807
 808    pub fn ceil(&self) -> Self {
 809        Self(self.0.ceil())
 810    }
 811
 812    pub fn scale(&self, factor: f32) -> ScaledPixels {
 813        ScaledPixels(self.0 * factor)
 814    }
 815
 816    pub fn pow(&self, exponent: f32) -> Self {
 817        Self(self.0.powf(exponent))
 818    }
 819
 820    pub fn abs(&self) -> Self {
 821        Self(self.0.abs())
 822    }
 823}
 824
 825impl Mul<Pixels> for Pixels {
 826    type Output = Pixels;
 827
 828    fn mul(self, rhs: Pixels) -> Self::Output {
 829        Pixels(self.0 * rhs.0)
 830    }
 831}
 832
 833impl Eq for Pixels {}
 834
 835impl Ord for Pixels {
 836    fn cmp(&self, other: &Self) -> cmp::Ordering {
 837        self.0.partial_cmp(&other.0).unwrap()
 838    }
 839}
 840
 841impl std::hash::Hash for Pixels {
 842    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
 843        self.0.to_bits().hash(state);
 844    }
 845}
 846
 847impl From<f64> for Pixels {
 848    fn from(pixels: f64) -> Self {
 849        Pixels(pixels as f32)
 850    }
 851}
 852
 853impl From<f32> for Pixels {
 854    fn from(pixels: f32) -> Self {
 855        Pixels(pixels)
 856    }
 857}
 858
 859impl Debug for Pixels {
 860    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 861        write!(f, "{} px", self.0)
 862    }
 863}
 864
 865impl From<Pixels> for f32 {
 866    fn from(pixels: Pixels) -> Self {
 867        pixels.0
 868    }
 869}
 870
 871impl From<&Pixels> for f32 {
 872    fn from(pixels: &Pixels) -> Self {
 873        pixels.0
 874    }
 875}
 876
 877impl From<Pixels> for f64 {
 878    fn from(pixels: Pixels) -> Self {
 879        pixels.0 as f64
 880    }
 881}
 882
 883impl From<Pixels> for u32 {
 884    fn from(pixels: Pixels) -> Self {
 885        pixels.0 as u32
 886    }
 887}
 888
 889impl From<u32> for Pixels {
 890    fn from(pixels: u32) -> Self {
 891        Pixels(pixels as f32)
 892    }
 893}
 894
 895impl From<Pixels> for usize {
 896    fn from(pixels: Pixels) -> Self {
 897        pixels.0 as usize
 898    }
 899}
 900
 901#[derive(
 902    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
 903)]
 904#[repr(transparent)]
 905pub struct DevicePixels(pub(crate) i32);
 906
 907impl DevicePixels {
 908    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
 909        self.0 as u32 * bytes_per_pixel as u32
 910    }
 911}
 912
 913impl fmt::Debug for DevicePixels {
 914    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 915        write!(f, "{} px (device)", self.0)
 916    }
 917}
 918
 919impl From<DevicePixels> for i32 {
 920    fn from(device_pixels: DevicePixels) -> Self {
 921        device_pixels.0
 922    }
 923}
 924
 925impl From<i32> for DevicePixels {
 926    fn from(device_pixels: i32) -> Self {
 927        DevicePixels(device_pixels)
 928    }
 929}
 930
 931impl From<u32> for DevicePixels {
 932    fn from(device_pixels: u32) -> Self {
 933        DevicePixels(device_pixels as i32)
 934    }
 935}
 936
 937impl From<DevicePixels> for u32 {
 938    fn from(device_pixels: DevicePixels) -> Self {
 939        device_pixels.0 as u32
 940    }
 941}
 942
 943impl From<DevicePixels> for u64 {
 944    fn from(device_pixels: DevicePixels) -> Self {
 945        device_pixels.0 as u64
 946    }
 947}
 948
 949impl From<u64> for DevicePixels {
 950    fn from(device_pixels: u64) -> Self {
 951        DevicePixels(device_pixels as i32)
 952    }
 953}
 954
 955#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 956#[repr(transparent)]
 957pub struct ScaledPixels(pub(crate) f32);
 958
 959impl ScaledPixels {
 960    pub fn floor(&self) -> Self {
 961        Self(self.0.floor())
 962    }
 963
 964    pub fn ceil(&self) -> Self {
 965        Self(self.0.ceil())
 966    }
 967}
 968
 969impl Eq for ScaledPixels {}
 970
 971impl Debug for ScaledPixels {
 972    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 973        write!(f, "{} px (scaled)", self.0)
 974    }
 975}
 976
 977impl From<ScaledPixels> for DevicePixels {
 978    fn from(scaled: ScaledPixels) -> Self {
 979        DevicePixels(scaled.0.ceil() as i32)
 980    }
 981}
 982
 983impl From<DevicePixels> for ScaledPixels {
 984    fn from(device: DevicePixels) -> Self {
 985        ScaledPixels(device.0 as f32)
 986    }
 987}
 988
 989impl From<ScaledPixels> for f64 {
 990    fn from(scaled_pixels: ScaledPixels) -> Self {
 991        scaled_pixels.0 as f64
 992    }
 993}
 994
 995#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 996#[repr(transparent)]
 997pub struct GlobalPixels(pub(crate) f32);
 998
 999impl Debug for GlobalPixels {
1000    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1001        write!(f, "{} px (global coordinate space)", self.0)
1002    }
1003}
1004
1005impl From<GlobalPixels> for f64 {
1006    fn from(global_pixels: GlobalPixels) -> Self {
1007        global_pixels.0 as f64
1008    }
1009}
1010
1011impl From<f64> for GlobalPixels {
1012    fn from(global_pixels: f64) -> Self {
1013        GlobalPixels(global_pixels as f32)
1014    }
1015}
1016
1017impl sqlez::bindable::StaticColumnCount for GlobalPixels {}
1018
1019impl sqlez::bindable::Bind for GlobalPixels {
1020    fn bind(
1021        &self,
1022        statement: &sqlez::statement::Statement,
1023        start_index: i32,
1024    ) -> anyhow::Result<i32> {
1025        self.0.bind(statement, start_index)
1026    }
1027}
1028
1029#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
1030pub struct Rems(f32);
1031
1032impl Mul<Pixels> for Rems {
1033    type Output = Pixels;
1034
1035    fn mul(self, other: Pixels) -> Pixels {
1036        Pixels(self.0 * other.0)
1037    }
1038}
1039
1040impl Debug for Rems {
1041    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1042        write!(f, "{} rem", self.0)
1043    }
1044}
1045
1046#[derive(Clone, Copy, Debug, Neg)]
1047pub enum AbsoluteLength {
1048    Pixels(Pixels),
1049    Rems(Rems),
1050}
1051
1052impl AbsoluteLength {
1053    pub fn is_zero(&self) -> bool {
1054        match self {
1055            AbsoluteLength::Pixels(px) => px.0 == 0.,
1056            AbsoluteLength::Rems(rems) => rems.0 == 0.,
1057        }
1058    }
1059}
1060
1061impl From<Pixels> for AbsoluteLength {
1062    fn from(pixels: Pixels) -> Self {
1063        AbsoluteLength::Pixels(pixels)
1064    }
1065}
1066
1067impl From<Rems> for AbsoluteLength {
1068    fn from(rems: Rems) -> Self {
1069        AbsoluteLength::Rems(rems)
1070    }
1071}
1072
1073impl AbsoluteLength {
1074    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
1075        match self {
1076            AbsoluteLength::Pixels(pixels) => *pixels,
1077            AbsoluteLength::Rems(rems) => *rems * rem_size,
1078        }
1079    }
1080}
1081
1082impl Default for AbsoluteLength {
1083    fn default() -> Self {
1084        px(0.).into()
1085    }
1086}
1087
1088/// A non-auto length that can be defined in pixels, rems, or percent of parent.
1089#[derive(Clone, Copy, Neg)]
1090pub enum DefiniteLength {
1091    Absolute(AbsoluteLength),
1092    /// A fraction of the parent's size between 0 and 1.
1093    Fraction(f32),
1094}
1095
1096impl DefiniteLength {
1097    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
1098        match self {
1099            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
1100            DefiniteLength::Fraction(fraction) => match base_size {
1101                AbsoluteLength::Pixels(px) => px * *fraction,
1102                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
1103            },
1104        }
1105    }
1106}
1107
1108impl Debug for DefiniteLength {
1109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1110        match self {
1111            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
1112            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
1113        }
1114    }
1115}
1116
1117impl From<Pixels> for DefiniteLength {
1118    fn from(pixels: Pixels) -> Self {
1119        Self::Absolute(pixels.into())
1120    }
1121}
1122
1123impl From<Rems> for DefiniteLength {
1124    fn from(rems: Rems) -> Self {
1125        Self::Absolute(rems.into())
1126    }
1127}
1128
1129impl From<AbsoluteLength> for DefiniteLength {
1130    fn from(length: AbsoluteLength) -> Self {
1131        Self::Absolute(length)
1132    }
1133}
1134
1135impl Default for DefiniteLength {
1136    fn default() -> Self {
1137        Self::Absolute(AbsoluteLength::default())
1138    }
1139}
1140
1141/// A length that can be defined in pixels, rems, percent of parent, or auto.
1142#[derive(Clone, Copy)]
1143pub enum Length {
1144    Definite(DefiniteLength),
1145    Auto,
1146}
1147
1148impl Debug for Length {
1149    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1150        match self {
1151            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
1152            Length::Auto => write!(f, "auto"),
1153        }
1154    }
1155}
1156
1157pub fn relative(fraction: f32) -> DefiniteLength {
1158    DefiniteLength::Fraction(fraction).into()
1159}
1160
1161/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1162pub fn phi() -> DefiniteLength {
1163    relative(1.61803398875)
1164}
1165
1166pub fn rems(rems: f32) -> Rems {
1167    Rems(rems)
1168}
1169
1170pub const fn px(pixels: f32) -> Pixels {
1171    Pixels(pixels)
1172}
1173
1174pub fn auto() -> Length {
1175    Length::Auto
1176}
1177
1178impl From<Pixels> for Length {
1179    fn from(pixels: Pixels) -> Self {
1180        Self::Definite(pixels.into())
1181    }
1182}
1183
1184impl From<Rems> for Length {
1185    fn from(rems: Rems) -> Self {
1186        Self::Definite(rems.into())
1187    }
1188}
1189
1190impl From<DefiniteLength> for Length {
1191    fn from(length: DefiniteLength) -> Self {
1192        Self::Definite(length)
1193    }
1194}
1195
1196impl From<AbsoluteLength> for Length {
1197    fn from(length: AbsoluteLength) -> Self {
1198        Self::Definite(length.into())
1199    }
1200}
1201
1202impl Default for Length {
1203    fn default() -> Self {
1204        Self::Definite(DefiniteLength::default())
1205    }
1206}
1207
1208impl From<()> for Length {
1209    fn from(_: ()) -> Self {
1210        Self::Definite(DefiniteLength::default())
1211    }
1212}
1213
1214pub trait IsZero {
1215    fn is_zero(&self) -> bool;
1216}
1217
1218impl IsZero for DevicePixels {
1219    fn is_zero(&self) -> bool {
1220        self.0 == 0
1221    }
1222}
1223
1224impl IsZero for ScaledPixels {
1225    fn is_zero(&self) -> bool {
1226        self.0 == 0.
1227    }
1228}
1229
1230impl IsZero for Pixels {
1231    fn is_zero(&self) -> bool {
1232        self.0 == 0.
1233    }
1234}
1235
1236impl IsZero for Rems {
1237    fn is_zero(&self) -> bool {
1238        self.0 == 0.
1239    }
1240}
1241
1242impl IsZero for AbsoluteLength {
1243    fn is_zero(&self) -> bool {
1244        match self {
1245            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1246            AbsoluteLength::Rems(rems) => rems.is_zero(),
1247        }
1248    }
1249}
1250
1251impl IsZero for DefiniteLength {
1252    fn is_zero(&self) -> bool {
1253        match self {
1254            DefiniteLength::Absolute(length) => length.is_zero(),
1255            DefiniteLength::Fraction(fraction) => *fraction == 0.,
1256        }
1257    }
1258}
1259
1260impl IsZero for Length {
1261    fn is_zero(&self) -> bool {
1262        match self {
1263            Length::Definite(length) => length.is_zero(),
1264            Length::Auto => false,
1265        }
1266    }
1267}
1268
1269impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1270    fn is_zero(&self) -> bool {
1271        self.x.is_zero() && self.y.is_zero()
1272    }
1273}
1274
1275impl<T> IsZero for Size<T>
1276where
1277    T: IsZero + Default + Debug + Clone,
1278{
1279    fn is_zero(&self) -> bool {
1280        self.width.is_zero() || self.height.is_zero()
1281    }
1282}
1283
1284impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1285    fn is_zero(&self) -> bool {
1286        self.size.is_zero()
1287    }
1288}
1289
1290impl<T> IsZero for Corners<T>
1291where
1292    T: IsZero + Clone + Default + Debug,
1293{
1294    fn is_zero(&self) -> bool {
1295        self.top_left.is_zero()
1296            && self.top_right.is_zero()
1297            && self.bottom_right.is_zero()
1298            && self.bottom_left.is_zero()
1299    }
1300}
1301
1302#[cfg(test)]
1303mod tests {
1304    use super::*;
1305
1306    #[test]
1307    fn test_bounds_intersects() {
1308        let bounds1 = Bounds {
1309            origin: Point { x: 0.0, y: 0.0 },
1310            size: Size {
1311                width: 5.0,
1312                height: 5.0,
1313            },
1314        };
1315        let bounds2 = Bounds {
1316            origin: Point { x: 4.0, y: 4.0 },
1317            size: Size {
1318                width: 5.0,
1319                height: 5.0,
1320            },
1321        };
1322        let bounds3 = Bounds {
1323            origin: Point { x: 10.0, y: 10.0 },
1324            size: Size {
1325                width: 5.0,
1326                height: 5.0,
1327            },
1328        };
1329
1330        // Test Case 1: Intersecting bounds
1331        assert_eq!(bounds1.intersects(&bounds2), true);
1332
1333        // Test Case 2: Non-Intersecting bounds
1334        assert_eq!(bounds1.intersects(&bounds3), false);
1335
1336        // Test Case 3: Bounds intersecting with themselves
1337        assert_eq!(bounds1.intersects(&bounds1), true);
1338    }
1339}