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 map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
 496    where
 497        U: Clone + Default + Debug,
 498    {
 499        Edges {
 500            top: f(&self.top),
 501            right: f(&self.right),
 502            bottom: f(&self.bottom),
 503            left: f(&self.left),
 504        }
 505    }
 506
 507    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
 508        predicate(&self.top)
 509            || predicate(&self.right)
 510            || predicate(&self.bottom)
 511            || predicate(&self.left)
 512    }
 513}
 514
 515impl Edges<Length> {
 516    pub fn auto() -> Self {
 517        Self {
 518            top: Length::Auto,
 519            right: Length::Auto,
 520            bottom: Length::Auto,
 521            left: Length::Auto,
 522        }
 523    }
 524
 525    pub fn zero() -> Self {
 526        Self {
 527            top: px(0.).into(),
 528            right: px(0.).into(),
 529            bottom: px(0.).into(),
 530            left: px(0.).into(),
 531        }
 532    }
 533}
 534
 535impl Edges<DefiniteLength> {
 536    pub fn zero() -> Self {
 537        Self {
 538            top: px(0.).into(),
 539            right: px(0.).into(),
 540            bottom: px(0.).into(),
 541            left: px(0.).into(),
 542        }
 543    }
 544}
 545
 546impl Edges<AbsoluteLength> {
 547    pub fn zero() -> Self {
 548        Self {
 549            top: px(0.).into(),
 550            right: px(0.).into(),
 551            bottom: px(0.).into(),
 552            left: px(0.).into(),
 553        }
 554    }
 555
 556    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
 557        Edges {
 558            top: self.top.to_pixels(rem_size),
 559            right: self.right.to_pixels(rem_size),
 560            bottom: self.bottom.to_pixels(rem_size),
 561            left: self.left.to_pixels(rem_size),
 562        }
 563    }
 564}
 565
 566impl Edges<Pixels> {
 567    pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
 568        Edges {
 569            top: self.top.scale(factor),
 570            right: self.right.scale(factor),
 571            bottom: self.bottom.scale(factor),
 572            left: self.left.scale(factor),
 573        }
 574    }
 575}
 576
 577#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 578#[refineable(debug)]
 579#[repr(C)]
 580pub struct Corners<T: Clone + Default + Debug> {
 581    pub top_left: T,
 582    pub top_right: T,
 583    pub bottom_right: T,
 584    pub bottom_left: T,
 585}
 586
 587impl Corners<AbsoluteLength> {
 588    pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
 589        let max = size.width.max(size.height) / 2.;
 590        Corners {
 591            top_left: self.top_left.to_pixels(rem_size).min(max),
 592            top_right: self.top_right.to_pixels(rem_size).min(max),
 593            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
 594            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
 595        }
 596    }
 597}
 598
 599impl Corners<Pixels> {
 600    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
 601        Corners {
 602            top_left: self.top_left.scale(factor),
 603            top_right: self.top_right.scale(factor),
 604            bottom_right: self.bottom_right.scale(factor),
 605            bottom_left: self.bottom_left.scale(factor),
 606        }
 607    }
 608}
 609
 610impl<T: Clone + Default + Debug> Corners<T> {
 611    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
 612    where
 613        U: Clone + Default + Debug,
 614    {
 615        Corners {
 616            top_left: f(&self.top_left),
 617            top_right: f(&self.top_right),
 618            bottom_right: f(&self.bottom_right),
 619            bottom_left: f(&self.bottom_left),
 620        }
 621    }
 622}
 623
 624impl<T> Mul for Corners<T>
 625where
 626    T: Mul<Output = T> + Clone + Default + Debug,
 627{
 628    type Output = Self;
 629
 630    fn mul(self, rhs: Self) -> Self::Output {
 631        Self {
 632            top_left: self.top_left.clone() * rhs.top_left,
 633            top_right: self.top_right.clone() * rhs.top_right,
 634            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
 635            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
 636        }
 637    }
 638}
 639
 640impl<T, S> MulAssign<S> for Corners<T>
 641where
 642    T: Mul<S, Output = T> + Clone + Default + Debug,
 643    S: Clone,
 644{
 645    fn mul_assign(&mut self, rhs: S) {
 646        self.top_left = self.top_left.clone() * rhs.clone();
 647        self.top_right = self.top_right.clone() * rhs.clone();
 648        self.bottom_right = self.bottom_right.clone() * rhs.clone();
 649        self.bottom_left = self.bottom_left.clone() * rhs;
 650    }
 651}
 652
 653impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
 654
 655#[derive(
 656    Clone,
 657    Copy,
 658    Default,
 659    Add,
 660    AddAssign,
 661    Sub,
 662    SubAssign,
 663    Neg,
 664    Div,
 665    DivAssign,
 666    PartialEq,
 667    PartialOrd,
 668    Serialize,
 669    Deserialize,
 670)]
 671#[repr(transparent)]
 672pub struct Pixels(pub(crate) f32);
 673
 674impl std::ops::Div for Pixels {
 675    type Output = Self;
 676
 677    fn div(self, rhs: Self) -> Self::Output {
 678        Self(self.0 / rhs.0)
 679    }
 680}
 681
 682impl std::ops::DivAssign for Pixels {
 683    fn div_assign(&mut self, rhs: Self) {
 684        self.0 /= rhs.0;
 685    }
 686}
 687
 688impl std::ops::RemAssign for Pixels {
 689    fn rem_assign(&mut self, rhs: Self) {
 690        self.0 %= rhs.0;
 691    }
 692}
 693
 694impl std::ops::Rem for Pixels {
 695    type Output = Self;
 696
 697    fn rem(self, rhs: Self) -> Self {
 698        Self(self.0 % rhs.0)
 699    }
 700}
 701
 702impl Mul<f32> for Pixels {
 703    type Output = Pixels;
 704
 705    fn mul(self, other: f32) -> Pixels {
 706        Pixels(self.0 * other)
 707    }
 708}
 709
 710impl Mul<usize> for Pixels {
 711    type Output = Pixels;
 712
 713    fn mul(self, other: usize) -> Pixels {
 714        Pixels(self.0 * other as f32)
 715    }
 716}
 717
 718impl Mul<Pixels> for f32 {
 719    type Output = Pixels;
 720
 721    fn mul(self, rhs: Pixels) -> Self::Output {
 722        Pixels(self * rhs.0)
 723    }
 724}
 725
 726impl MulAssign<f32> for Pixels {
 727    fn mul_assign(&mut self, other: f32) {
 728        self.0 *= other;
 729    }
 730}
 731
 732impl Pixels {
 733    pub const MAX: Pixels = Pixels(f32::MAX);
 734
 735    pub fn as_usize(&self) -> usize {
 736        self.0 as usize
 737    }
 738
 739    pub fn as_isize(&self) -> isize {
 740        self.0 as isize
 741    }
 742
 743    pub fn floor(&self) -> Self {
 744        Self(self.0.floor())
 745    }
 746
 747    pub fn round(&self) -> Self {
 748        Self(self.0.round())
 749    }
 750
 751    pub fn scale(&self, factor: f32) -> ScaledPixels {
 752        ScaledPixels(self.0 * factor)
 753    }
 754
 755    pub fn pow(&self, exponent: f32) -> Self {
 756        Self(self.0.powf(exponent))
 757    }
 758
 759    pub fn abs(&self) -> Self {
 760        Self(self.0.abs())
 761    }
 762}
 763
 764impl Mul<Pixels> for Pixels {
 765    type Output = Pixels;
 766
 767    fn mul(self, rhs: Pixels) -> Self::Output {
 768        Pixels(self.0 * rhs.0)
 769    }
 770}
 771
 772impl Eq for Pixels {}
 773
 774impl Ord for Pixels {
 775    fn cmp(&self, other: &Self) -> cmp::Ordering {
 776        self.0.partial_cmp(&other.0).unwrap()
 777    }
 778}
 779
 780impl std::hash::Hash for Pixels {
 781    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
 782        self.0.to_bits().hash(state);
 783    }
 784}
 785
 786impl From<f64> for Pixels {
 787    fn from(pixels: f64) -> Self {
 788        Pixels(pixels as f32)
 789    }
 790}
 791
 792impl From<f32> for Pixels {
 793    fn from(pixels: f32) -> Self {
 794        Pixels(pixels)
 795    }
 796}
 797
 798impl Debug for Pixels {
 799    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 800        write!(f, "{} px", self.0)
 801    }
 802}
 803
 804impl From<Pixels> for f32 {
 805    fn from(pixels: Pixels) -> Self {
 806        pixels.0
 807    }
 808}
 809
 810impl From<&Pixels> for f32 {
 811    fn from(pixels: &Pixels) -> Self {
 812        pixels.0
 813    }
 814}
 815
 816impl From<Pixels> for f64 {
 817    fn from(pixels: Pixels) -> Self {
 818        pixels.0 as f64
 819    }
 820}
 821
 822impl From<Pixels> for u32 {
 823    fn from(pixels: Pixels) -> Self {
 824        pixels.0 as u32
 825    }
 826}
 827
 828impl From<Pixels> for usize {
 829    fn from(pixels: Pixels) -> Self {
 830        pixels.0 as usize
 831    }
 832}
 833
 834#[derive(
 835    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
 836)]
 837#[repr(transparent)]
 838pub struct DevicePixels(pub(crate) i32);
 839
 840impl DevicePixels {
 841    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
 842        self.0 as u32 * bytes_per_pixel as u32
 843    }
 844}
 845
 846impl fmt::Debug for DevicePixels {
 847    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 848        write!(f, "{} px (device)", self.0)
 849    }
 850}
 851
 852impl From<DevicePixels> for i32 {
 853    fn from(device_pixels: DevicePixels) -> Self {
 854        device_pixels.0
 855    }
 856}
 857
 858impl From<i32> for DevicePixels {
 859    fn from(device_pixels: i32) -> Self {
 860        DevicePixels(device_pixels)
 861    }
 862}
 863
 864impl From<u32> for DevicePixels {
 865    fn from(device_pixels: u32) -> Self {
 866        DevicePixels(device_pixels as i32)
 867    }
 868}
 869
 870impl From<DevicePixels> for u32 {
 871    fn from(device_pixels: DevicePixels) -> Self {
 872        device_pixels.0 as u32
 873    }
 874}
 875
 876impl From<DevicePixels> for u64 {
 877    fn from(device_pixels: DevicePixels) -> Self {
 878        device_pixels.0 as u64
 879    }
 880}
 881
 882impl From<u64> for DevicePixels {
 883    fn from(device_pixels: u64) -> Self {
 884        DevicePixels(device_pixels as i32)
 885    }
 886}
 887
 888#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 889#[repr(transparent)]
 890pub struct ScaledPixels(pub(crate) f32);
 891
 892impl ScaledPixels {
 893    pub fn floor(&self) -> Self {
 894        Self(self.0.floor())
 895    }
 896
 897    pub fn ceil(&self) -> Self {
 898        Self(self.0.ceil())
 899    }
 900}
 901
 902impl Eq for ScaledPixels {}
 903
 904impl Debug for ScaledPixels {
 905    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 906        write!(f, "{} px (scaled)", self.0)
 907    }
 908}
 909
 910impl From<ScaledPixels> for DevicePixels {
 911    fn from(scaled: ScaledPixels) -> Self {
 912        DevicePixels(scaled.0.ceil() as i32)
 913    }
 914}
 915
 916impl From<DevicePixels> for ScaledPixels {
 917    fn from(device: DevicePixels) -> Self {
 918        ScaledPixels(device.0 as f32)
 919    }
 920}
 921
 922impl From<ScaledPixels> for f64 {
 923    fn from(scaled_pixels: ScaledPixels) -> Self {
 924        scaled_pixels.0 as f64
 925    }
 926}
 927
 928#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 929#[repr(transparent)]
 930pub struct GlobalPixels(pub(crate) f32);
 931
 932impl Debug for GlobalPixels {
 933    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 934        write!(f, "{} px (global coordinate space)", self.0)
 935    }
 936}
 937
 938impl From<GlobalPixels> for f64 {
 939    fn from(global_pixels: GlobalPixels) -> Self {
 940        global_pixels.0 as f64
 941    }
 942}
 943
 944impl From<f64> for GlobalPixels {
 945    fn from(global_pixels: f64) -> Self {
 946        GlobalPixels(global_pixels as f32)
 947    }
 948}
 949
 950impl sqlez::bindable::StaticColumnCount for GlobalPixels {}
 951
 952impl sqlez::bindable::Bind for GlobalPixels {
 953    fn bind(
 954        &self,
 955        statement: &sqlez::statement::Statement,
 956        start_index: i32,
 957    ) -> anyhow::Result<i32> {
 958        self.0.bind(statement, start_index)
 959    }
 960}
 961
 962#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
 963pub struct Rems(f32);
 964
 965impl Mul<Pixels> for Rems {
 966    type Output = Pixels;
 967
 968    fn mul(self, other: Pixels) -> Pixels {
 969        Pixels(self.0 * other.0)
 970    }
 971}
 972
 973impl Debug for Rems {
 974    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 975        write!(f, "{} rem", self.0)
 976    }
 977}
 978
 979#[derive(Clone, Copy, Debug, Neg)]
 980pub enum AbsoluteLength {
 981    Pixels(Pixels),
 982    Rems(Rems),
 983}
 984
 985impl AbsoluteLength {
 986    pub fn is_zero(&self) -> bool {
 987        match self {
 988            AbsoluteLength::Pixels(px) => px.0 == 0.,
 989            AbsoluteLength::Rems(rems) => rems.0 == 0.,
 990        }
 991    }
 992}
 993
 994impl From<Pixels> for AbsoluteLength {
 995    fn from(pixels: Pixels) -> Self {
 996        AbsoluteLength::Pixels(pixels)
 997    }
 998}
 999
1000impl From<Rems> for AbsoluteLength {
1001    fn from(rems: Rems) -> Self {
1002        AbsoluteLength::Rems(rems)
1003    }
1004}
1005
1006impl AbsoluteLength {
1007    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
1008        match self {
1009            AbsoluteLength::Pixels(pixels) => *pixels,
1010            AbsoluteLength::Rems(rems) => *rems * rem_size,
1011        }
1012    }
1013}
1014
1015impl Default for AbsoluteLength {
1016    fn default() -> Self {
1017        px(0.).into()
1018    }
1019}
1020
1021/// A non-auto length that can be defined in pixels, rems, or percent of parent.
1022#[derive(Clone, Copy, Neg)]
1023pub enum DefiniteLength {
1024    Absolute(AbsoluteLength),
1025    /// A fraction of the parent's size between 0 and 1.
1026    Fraction(f32),
1027}
1028
1029impl DefiniteLength {
1030    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
1031        match self {
1032            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
1033            DefiniteLength::Fraction(fraction) => match base_size {
1034                AbsoluteLength::Pixels(px) => px * *fraction,
1035                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
1036            },
1037        }
1038    }
1039}
1040
1041impl Debug for DefiniteLength {
1042    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1043        match self {
1044            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
1045            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
1046        }
1047    }
1048}
1049
1050impl From<Pixels> for DefiniteLength {
1051    fn from(pixels: Pixels) -> Self {
1052        Self::Absolute(pixels.into())
1053    }
1054}
1055
1056impl From<Rems> for DefiniteLength {
1057    fn from(rems: Rems) -> Self {
1058        Self::Absolute(rems.into())
1059    }
1060}
1061
1062impl From<AbsoluteLength> for DefiniteLength {
1063    fn from(length: AbsoluteLength) -> Self {
1064        Self::Absolute(length)
1065    }
1066}
1067
1068impl Default for DefiniteLength {
1069    fn default() -> Self {
1070        Self::Absolute(AbsoluteLength::default())
1071    }
1072}
1073
1074/// A length that can be defined in pixels, rems, percent of parent, or auto.
1075#[derive(Clone, Copy)]
1076pub enum Length {
1077    Definite(DefiniteLength),
1078    Auto,
1079}
1080
1081impl Debug for Length {
1082    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1083        match self {
1084            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
1085            Length::Auto => write!(f, "auto"),
1086        }
1087    }
1088}
1089
1090pub fn relative(fraction: f32) -> DefiniteLength {
1091    DefiniteLength::Fraction(fraction).into()
1092}
1093
1094/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1095pub fn phi() -> DefiniteLength {
1096    relative(1.61803398875)
1097}
1098
1099pub fn rems(rems: f32) -> Rems {
1100    Rems(rems)
1101}
1102
1103pub const fn px(pixels: f32) -> Pixels {
1104    Pixels(pixels)
1105}
1106
1107pub fn auto() -> Length {
1108    Length::Auto
1109}
1110
1111impl From<Pixels> for Length {
1112    fn from(pixels: Pixels) -> Self {
1113        Self::Definite(pixels.into())
1114    }
1115}
1116
1117impl From<Rems> for Length {
1118    fn from(rems: Rems) -> Self {
1119        Self::Definite(rems.into())
1120    }
1121}
1122
1123impl From<DefiniteLength> for Length {
1124    fn from(length: DefiniteLength) -> Self {
1125        Self::Definite(length)
1126    }
1127}
1128
1129impl From<AbsoluteLength> for Length {
1130    fn from(length: AbsoluteLength) -> Self {
1131        Self::Definite(length.into())
1132    }
1133}
1134
1135impl Default for Length {
1136    fn default() -> Self {
1137        Self::Definite(DefiniteLength::default())
1138    }
1139}
1140
1141impl From<()> for Length {
1142    fn from(_: ()) -> Self {
1143        Self::Definite(DefiniteLength::default())
1144    }
1145}
1146
1147pub trait IsZero {
1148    fn is_zero(&self) -> bool;
1149}
1150
1151impl IsZero for DevicePixels {
1152    fn is_zero(&self) -> bool {
1153        self.0 == 0
1154    }
1155}
1156
1157impl IsZero for ScaledPixels {
1158    fn is_zero(&self) -> bool {
1159        self.0 == 0.
1160    }
1161}
1162
1163impl IsZero for Pixels {
1164    fn is_zero(&self) -> bool {
1165        self.0 == 0.
1166    }
1167}
1168
1169impl IsZero for Rems {
1170    fn is_zero(&self) -> bool {
1171        self.0 == 0.
1172    }
1173}
1174
1175impl IsZero for AbsoluteLength {
1176    fn is_zero(&self) -> bool {
1177        match self {
1178            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1179            AbsoluteLength::Rems(rems) => rems.is_zero(),
1180        }
1181    }
1182}
1183
1184impl IsZero for DefiniteLength {
1185    fn is_zero(&self) -> bool {
1186        match self {
1187            DefiniteLength::Absolute(length) => length.is_zero(),
1188            DefiniteLength::Fraction(fraction) => *fraction == 0.,
1189        }
1190    }
1191}
1192
1193impl IsZero for Length {
1194    fn is_zero(&self) -> bool {
1195        match self {
1196            Length::Definite(length) => length.is_zero(),
1197            Length::Auto => false,
1198        }
1199    }
1200}
1201
1202impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1203    fn is_zero(&self) -> bool {
1204        self.x.is_zero() && self.y.is_zero()
1205    }
1206}
1207
1208impl<T> IsZero for Size<T>
1209where
1210    T: IsZero + Default + Debug + Clone,
1211{
1212    fn is_zero(&self) -> bool {
1213        self.width.is_zero() || self.height.is_zero()
1214    }
1215}
1216
1217impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1218    fn is_zero(&self) -> bool {
1219        self.size.is_zero()
1220    }
1221}
1222
1223impl<T> IsZero for Corners<T>
1224where
1225    T: IsZero + Clone + Default + Debug,
1226{
1227    fn is_zero(&self) -> bool {
1228        self.top_left.is_zero()
1229            && self.top_right.is_zero()
1230            && self.bottom_right.is_zero()
1231            && self.bottom_left.is_zero()
1232    }
1233}
1234
1235#[cfg(test)]
1236mod tests {
1237    use super::*;
1238
1239    #[test]
1240    fn test_bounds_intersects() {
1241        let bounds1 = Bounds {
1242            origin: Point { x: 0.0, y: 0.0 },
1243            size: Size {
1244                width: 5.0,
1245                height: 5.0,
1246            },
1247        };
1248        let bounds2 = Bounds {
1249            origin: Point { x: 4.0, y: 4.0 },
1250            size: Size {
1251                width: 5.0,
1252                height: 5.0,
1253            },
1254        };
1255        let bounds3 = Bounds {
1256            origin: Point { x: 10.0, y: 10.0 },
1257            size: Size {
1258                width: 5.0,
1259                height: 5.0,
1260            },
1261        };
1262
1263        // Test Case 1: Intersecting bounds
1264        assert_eq!(bounds1.intersects(&bounds2), true);
1265
1266        // Test Case 2: Non-Intersecting bounds
1267        assert_eq!(bounds1.intersects(&bounds3), false);
1268
1269        // Test Case 3: Bounds intersecting with themselves
1270        assert_eq!(bounds1.intersects(&bounds1), true);
1271    }
1272}