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
 822#[derive(
 823    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
 824)]
 825#[repr(transparent)]
 826pub struct DevicePixels(pub(crate) i32);
 827
 828impl DevicePixels {
 829    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
 830        self.0 as u32 * bytes_per_pixel as u32
 831    }
 832}
 833
 834impl fmt::Debug for DevicePixels {
 835    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 836        write!(f, "{} px (device)", self.0)
 837    }
 838}
 839
 840impl From<DevicePixels> for i32 {
 841    fn from(device_pixels: DevicePixels) -> Self {
 842        device_pixels.0
 843    }
 844}
 845
 846impl From<i32> for DevicePixels {
 847    fn from(device_pixels: i32) -> Self {
 848        DevicePixels(device_pixels)
 849    }
 850}
 851
 852impl From<u32> for DevicePixels {
 853    fn from(device_pixels: u32) -> Self {
 854        DevicePixels(device_pixels as i32)
 855    }
 856}
 857
 858impl From<DevicePixels> for u32 {
 859    fn from(device_pixels: DevicePixels) -> Self {
 860        device_pixels.0 as u32
 861    }
 862}
 863
 864impl From<DevicePixels> for u64 {
 865    fn from(device_pixels: DevicePixels) -> Self {
 866        device_pixels.0 as u64
 867    }
 868}
 869
 870impl From<u64> for DevicePixels {
 871    fn from(device_pixels: u64) -> Self {
 872        DevicePixels(device_pixels as i32)
 873    }
 874}
 875
 876#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 877#[repr(transparent)]
 878pub struct ScaledPixels(pub(crate) f32);
 879
 880impl ScaledPixels {
 881    pub fn floor(&self) -> Self {
 882        Self(self.0.floor())
 883    }
 884
 885    pub fn ceil(&self) -> Self {
 886        Self(self.0.ceil())
 887    }
 888}
 889
 890impl Eq for ScaledPixels {}
 891
 892impl Debug for ScaledPixels {
 893    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 894        write!(f, "{} px (scaled)", self.0)
 895    }
 896}
 897
 898impl From<ScaledPixels> for DevicePixels {
 899    fn from(scaled: ScaledPixels) -> Self {
 900        DevicePixels(scaled.0.ceil() as i32)
 901    }
 902}
 903
 904impl From<DevicePixels> for ScaledPixels {
 905    fn from(device: DevicePixels) -> Self {
 906        ScaledPixels(device.0 as f32)
 907    }
 908}
 909
 910impl From<ScaledPixels> for f64 {
 911    fn from(scaled_pixels: ScaledPixels) -> Self {
 912        scaled_pixels.0 as f64
 913    }
 914}
 915
 916#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 917#[repr(transparent)]
 918pub struct GlobalPixels(pub(crate) f32);
 919
 920impl Debug for GlobalPixels {
 921    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 922        write!(f, "{} px (global coordinate space)", self.0)
 923    }
 924}
 925
 926impl From<GlobalPixels> for f64 {
 927    fn from(global_pixels: GlobalPixels) -> Self {
 928        global_pixels.0 as f64
 929    }
 930}
 931
 932impl From<f64> for GlobalPixels {
 933    fn from(global_pixels: f64) -> Self {
 934        GlobalPixels(global_pixels as f32)
 935    }
 936}
 937
 938impl sqlez::bindable::StaticColumnCount for GlobalPixels {}
 939
 940impl sqlez::bindable::Bind for GlobalPixels {
 941    fn bind(
 942        &self,
 943        statement: &sqlez::statement::Statement,
 944        start_index: i32,
 945    ) -> anyhow::Result<i32> {
 946        self.0.bind(statement, start_index)
 947    }
 948}
 949
 950#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
 951pub struct Rems(f32);
 952
 953impl Mul<Pixels> for Rems {
 954    type Output = Pixels;
 955
 956    fn mul(self, other: Pixels) -> Pixels {
 957        Pixels(self.0 * other.0)
 958    }
 959}
 960
 961impl Debug for Rems {
 962    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 963        write!(f, "{} rem", self.0)
 964    }
 965}
 966
 967#[derive(Clone, Copy, Debug, Neg)]
 968pub enum AbsoluteLength {
 969    Pixels(Pixels),
 970    Rems(Rems),
 971}
 972
 973impl AbsoluteLength {
 974    pub fn is_zero(&self) -> bool {
 975        match self {
 976            AbsoluteLength::Pixels(px) => px.0 == 0.,
 977            AbsoluteLength::Rems(rems) => rems.0 == 0.,
 978        }
 979    }
 980}
 981
 982impl From<Pixels> for AbsoluteLength {
 983    fn from(pixels: Pixels) -> Self {
 984        AbsoluteLength::Pixels(pixels)
 985    }
 986}
 987
 988impl From<Rems> for AbsoluteLength {
 989    fn from(rems: Rems) -> Self {
 990        AbsoluteLength::Rems(rems)
 991    }
 992}
 993
 994impl AbsoluteLength {
 995    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
 996        match self {
 997            AbsoluteLength::Pixels(pixels) => *pixels,
 998            AbsoluteLength::Rems(rems) => *rems * rem_size,
 999        }
1000    }
1001}
1002
1003impl Default for AbsoluteLength {
1004    fn default() -> Self {
1005        px(0.).into()
1006    }
1007}
1008
1009/// A non-auto length that can be defined in pixels, rems, or percent of parent.
1010#[derive(Clone, Copy, Neg)]
1011pub enum DefiniteLength {
1012    Absolute(AbsoluteLength),
1013    /// A fraction of the parent's size between 0 and 1.
1014    Fraction(f32),
1015}
1016
1017impl DefiniteLength {
1018    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
1019        match self {
1020            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
1021            DefiniteLength::Fraction(fraction) => match base_size {
1022                AbsoluteLength::Pixels(px) => px * *fraction,
1023                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
1024            },
1025        }
1026    }
1027}
1028
1029impl Debug for DefiniteLength {
1030    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1031        match self {
1032            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
1033            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
1034        }
1035    }
1036}
1037
1038impl From<Pixels> for DefiniteLength {
1039    fn from(pixels: Pixels) -> Self {
1040        Self::Absolute(pixels.into())
1041    }
1042}
1043
1044impl From<Rems> for DefiniteLength {
1045    fn from(rems: Rems) -> Self {
1046        Self::Absolute(rems.into())
1047    }
1048}
1049
1050impl From<AbsoluteLength> for DefiniteLength {
1051    fn from(length: AbsoluteLength) -> Self {
1052        Self::Absolute(length)
1053    }
1054}
1055
1056impl Default for DefiniteLength {
1057    fn default() -> Self {
1058        Self::Absolute(AbsoluteLength::default())
1059    }
1060}
1061
1062/// A length that can be defined in pixels, rems, percent of parent, or auto.
1063#[derive(Clone, Copy)]
1064pub enum Length {
1065    Definite(DefiniteLength),
1066    Auto,
1067}
1068
1069impl Debug for Length {
1070    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1071        match self {
1072            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
1073            Length::Auto => write!(f, "auto"),
1074        }
1075    }
1076}
1077
1078pub fn relative(fraction: f32) -> DefiniteLength {
1079    DefiniteLength::Fraction(fraction).into()
1080}
1081
1082/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1083pub fn phi() -> DefiniteLength {
1084    relative(1.61803398875)
1085}
1086
1087pub fn rems(rems: f32) -> Rems {
1088    Rems(rems)
1089}
1090
1091pub const fn px(pixels: f32) -> Pixels {
1092    Pixels(pixels)
1093}
1094
1095pub fn auto() -> Length {
1096    Length::Auto
1097}
1098
1099impl From<Pixels> for Length {
1100    fn from(pixels: Pixels) -> Self {
1101        Self::Definite(pixels.into())
1102    }
1103}
1104
1105impl From<Rems> for Length {
1106    fn from(rems: Rems) -> Self {
1107        Self::Definite(rems.into())
1108    }
1109}
1110
1111impl From<DefiniteLength> for Length {
1112    fn from(length: DefiniteLength) -> Self {
1113        Self::Definite(length)
1114    }
1115}
1116
1117impl From<AbsoluteLength> for Length {
1118    fn from(length: AbsoluteLength) -> Self {
1119        Self::Definite(length.into())
1120    }
1121}
1122
1123impl Default for Length {
1124    fn default() -> Self {
1125        Self::Definite(DefiniteLength::default())
1126    }
1127}
1128
1129impl From<()> for Length {
1130    fn from(_: ()) -> Self {
1131        Self::Definite(DefiniteLength::default())
1132    }
1133}
1134
1135pub trait IsZero {
1136    fn is_zero(&self) -> bool;
1137}
1138
1139impl IsZero for DevicePixels {
1140    fn is_zero(&self) -> bool {
1141        self.0 == 0
1142    }
1143}
1144
1145impl IsZero for ScaledPixels {
1146    fn is_zero(&self) -> bool {
1147        self.0 == 0.
1148    }
1149}
1150
1151impl IsZero for Pixels {
1152    fn is_zero(&self) -> bool {
1153        self.0 == 0.
1154    }
1155}
1156
1157impl IsZero for Rems {
1158    fn is_zero(&self) -> bool {
1159        self.0 == 0.
1160    }
1161}
1162
1163impl IsZero for AbsoluteLength {
1164    fn is_zero(&self) -> bool {
1165        match self {
1166            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1167            AbsoluteLength::Rems(rems) => rems.is_zero(),
1168        }
1169    }
1170}
1171
1172impl IsZero for DefiniteLength {
1173    fn is_zero(&self) -> bool {
1174        match self {
1175            DefiniteLength::Absolute(length) => length.is_zero(),
1176            DefiniteLength::Fraction(fraction) => *fraction == 0.,
1177        }
1178    }
1179}
1180
1181impl IsZero for Length {
1182    fn is_zero(&self) -> bool {
1183        match self {
1184            Length::Definite(length) => length.is_zero(),
1185            Length::Auto => false,
1186        }
1187    }
1188}
1189
1190impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1191    fn is_zero(&self) -> bool {
1192        self.x.is_zero() && self.y.is_zero()
1193    }
1194}
1195
1196impl<T> IsZero for Size<T>
1197where
1198    T: IsZero + Default + Debug + Clone,
1199{
1200    fn is_zero(&self) -> bool {
1201        self.width.is_zero() || self.height.is_zero()
1202    }
1203}
1204
1205impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1206    fn is_zero(&self) -> bool {
1207        self.size.is_zero()
1208    }
1209}
1210
1211impl<T> IsZero for Corners<T>
1212where
1213    T: IsZero + Clone + Default + Debug,
1214{
1215    fn is_zero(&self) -> bool {
1216        self.top_left.is_zero()
1217            && self.top_right.is_zero()
1218            && self.bottom_right.is_zero()
1219            && self.bottom_left.is_zero()
1220    }
1221}
1222
1223#[cfg(test)]
1224mod tests {
1225    use super::*;
1226
1227    #[test]
1228    fn test_bounds_intersects() {
1229        let bounds1 = Bounds {
1230            origin: Point { x: 0.0, y: 0.0 },
1231            size: Size {
1232                width: 5.0,
1233                height: 5.0,
1234            },
1235        };
1236        let bounds2 = Bounds {
1237            origin: Point { x: 4.0, y: 4.0 },
1238            size: Size {
1239                width: 5.0,
1240                height: 5.0,
1241            },
1242        };
1243        let bounds3 = Bounds {
1244            origin: Point { x: 10.0, y: 10.0 },
1245            size: Size {
1246                width: 5.0,
1247                height: 5.0,
1248            },
1249        };
1250
1251        // Test Case 1: Intersecting bounds
1252        assert_eq!(bounds1.intersects(&bounds2), true);
1253
1254        // Test Case 2: Non-Intersecting bounds
1255        assert_eq!(bounds1.intersects(&bounds3), false);
1256
1257        // Test Case 3: Bounds intersecting with themselves
1258        assert_eq!(bounds1.intersects(&bounds1), true);
1259    }
1260}