geometry.rs

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