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