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