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