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