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<T> Corners<T>
 659where
 660    T: Clone + Default + Debug,
 661{
 662    pub fn all(value: T) -> Self {
 663        Self {
 664            top_left: value.clone(),
 665            top_right: value.clone(),
 666            bottom_right: value.clone(),
 667            bottom_left: value,
 668        }
 669    }
 670}
 671
 672impl Corners<AbsoluteLength> {
 673    pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
 674        let max = size.width.max(size.height) / 2.;
 675        Corners {
 676            top_left: self.top_left.to_pixels(rem_size).min(max),
 677            top_right: self.top_right.to_pixels(rem_size).min(max),
 678            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
 679            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
 680        }
 681    }
 682}
 683
 684impl Corners<Pixels> {
 685    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
 686        Corners {
 687            top_left: self.top_left.scale(factor),
 688            top_right: self.top_right.scale(factor),
 689            bottom_right: self.bottom_right.scale(factor),
 690            bottom_left: self.bottom_left.scale(factor),
 691        }
 692    }
 693}
 694
 695impl<T: Clone + Default + Debug> Corners<T> {
 696    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
 697    where
 698        U: Clone + Default + Debug,
 699    {
 700        Corners {
 701            top_left: f(&self.top_left),
 702            top_right: f(&self.top_right),
 703            bottom_right: f(&self.bottom_right),
 704            bottom_left: f(&self.bottom_left),
 705        }
 706    }
 707}
 708
 709impl<T> Mul for Corners<T>
 710where
 711    T: Mul<Output = T> + Clone + Default + Debug,
 712{
 713    type Output = Self;
 714
 715    fn mul(self, rhs: Self) -> Self::Output {
 716        Self {
 717            top_left: self.top_left.clone() * rhs.top_left,
 718            top_right: self.top_right.clone() * rhs.top_right,
 719            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
 720            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
 721        }
 722    }
 723}
 724
 725impl<T, S> MulAssign<S> for Corners<T>
 726where
 727    T: Mul<S, Output = T> + Clone + Default + Debug,
 728    S: Clone,
 729{
 730    fn mul_assign(&mut self, rhs: S) {
 731        self.top_left = self.top_left.clone() * rhs.clone();
 732        self.top_right = self.top_right.clone() * rhs.clone();
 733        self.bottom_right = self.bottom_right.clone() * rhs.clone();
 734        self.bottom_left = self.bottom_left.clone() * rhs;
 735    }
 736}
 737
 738impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
 739
 740#[derive(
 741    Clone,
 742    Copy,
 743    Default,
 744    Add,
 745    AddAssign,
 746    Sub,
 747    SubAssign,
 748    Neg,
 749    Div,
 750    DivAssign,
 751    PartialEq,
 752    PartialOrd,
 753    Serialize,
 754    Deserialize,
 755)]
 756#[repr(transparent)]
 757pub struct Pixels(pub f32);
 758
 759impl std::ops::Div for Pixels {
 760    type Output = f32;
 761
 762    fn div(self, rhs: Self) -> Self::Output {
 763        self.0 / rhs.0
 764    }
 765}
 766
 767impl std::ops::DivAssign for Pixels {
 768    fn div_assign(&mut self, rhs: Self) {
 769        *self = Self(self.0 / rhs.0);
 770    }
 771}
 772
 773impl std::ops::RemAssign for Pixels {
 774    fn rem_assign(&mut self, rhs: Self) {
 775        self.0 %= rhs.0;
 776    }
 777}
 778
 779impl std::ops::Rem for Pixels {
 780    type Output = Self;
 781
 782    fn rem(self, rhs: Self) -> Self {
 783        Self(self.0 % rhs.0)
 784    }
 785}
 786
 787impl Mul<f32> for Pixels {
 788    type Output = Pixels;
 789
 790    fn mul(self, other: f32) -> Pixels {
 791        Pixels(self.0 * other)
 792    }
 793}
 794
 795impl Mul<usize> for Pixels {
 796    type Output = Pixels;
 797
 798    fn mul(self, other: usize) -> Pixels {
 799        Pixels(self.0 * other as f32)
 800    }
 801}
 802
 803impl Mul<Pixels> for f32 {
 804    type Output = Pixels;
 805
 806    fn mul(self, rhs: Pixels) -> Self::Output {
 807        Pixels(self * rhs.0)
 808    }
 809}
 810
 811impl MulAssign<f32> for Pixels {
 812    fn mul_assign(&mut self, other: f32) {
 813        self.0 *= other;
 814    }
 815}
 816
 817impl Pixels {
 818    pub const ZERO: Pixels = Pixels(0.0);
 819    pub const MAX: Pixels = Pixels(f32::MAX);
 820
 821    pub fn floor(&self) -> Self {
 822        Self(self.0.floor())
 823    }
 824
 825    pub fn round(&self) -> Self {
 826        Self(self.0.round())
 827    }
 828
 829    pub fn ceil(&self) -> Self {
 830        Self(self.0.ceil())
 831    }
 832
 833    pub fn scale(&self, factor: f32) -> ScaledPixels {
 834        ScaledPixels(self.0 * factor)
 835    }
 836
 837    pub fn pow(&self, exponent: f32) -> Self {
 838        Self(self.0.powf(exponent))
 839    }
 840
 841    pub fn abs(&self) -> Self {
 842        Self(self.0.abs())
 843    }
 844}
 845
 846impl Mul<Pixels> for Pixels {
 847    type Output = Pixels;
 848
 849    fn mul(self, rhs: Pixels) -> Self::Output {
 850        Pixels(self.0 * rhs.0)
 851    }
 852}
 853
 854impl Eq for Pixels {}
 855
 856impl Ord for Pixels {
 857    fn cmp(&self, other: &Self) -> cmp::Ordering {
 858        self.0.partial_cmp(&other.0).unwrap()
 859    }
 860}
 861
 862impl std::hash::Hash for Pixels {
 863    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
 864        self.0.to_bits().hash(state);
 865    }
 866}
 867
 868impl From<f64> for Pixels {
 869    fn from(pixels: f64) -> Self {
 870        Pixels(pixels as f32)
 871    }
 872}
 873
 874impl From<f32> for Pixels {
 875    fn from(pixels: f32) -> Self {
 876        Pixels(pixels)
 877    }
 878}
 879
 880impl Debug for Pixels {
 881    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 882        write!(f, "{} px", self.0)
 883    }
 884}
 885
 886impl From<Pixels> for f32 {
 887    fn from(pixels: Pixels) -> Self {
 888        pixels.0
 889    }
 890}
 891
 892impl From<&Pixels> for f32 {
 893    fn from(pixels: &Pixels) -> Self {
 894        pixels.0
 895    }
 896}
 897
 898impl From<Pixels> for f64 {
 899    fn from(pixels: Pixels) -> Self {
 900        pixels.0 as f64
 901    }
 902}
 903
 904impl From<Pixels> for u32 {
 905    fn from(pixels: Pixels) -> Self {
 906        pixels.0 as u32
 907    }
 908}
 909
 910impl From<u32> for Pixels {
 911    fn from(pixels: u32) -> Self {
 912        Pixels(pixels as f32)
 913    }
 914}
 915
 916impl From<Pixels> for usize {
 917    fn from(pixels: Pixels) -> Self {
 918        pixels.0 as usize
 919    }
 920}
 921
 922impl From<usize> for Pixels {
 923    fn from(pixels: usize) -> Self {
 924        Pixels(pixels as f32)
 925    }
 926}
 927
 928#[derive(
 929    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
 930)]
 931#[repr(transparent)]
 932pub struct DevicePixels(pub(crate) i32);
 933
 934impl DevicePixels {
 935    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
 936        self.0 as u32 * bytes_per_pixel as u32
 937    }
 938}
 939
 940impl fmt::Debug for DevicePixels {
 941    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 942        write!(f, "{} px (device)", self.0)
 943    }
 944}
 945
 946impl From<DevicePixels> for i32 {
 947    fn from(device_pixels: DevicePixels) -> Self {
 948        device_pixels.0
 949    }
 950}
 951
 952impl From<i32> for DevicePixels {
 953    fn from(device_pixels: i32) -> Self {
 954        DevicePixels(device_pixels)
 955    }
 956}
 957
 958impl From<u32> for DevicePixels {
 959    fn from(device_pixels: u32) -> Self {
 960        DevicePixels(device_pixels as i32)
 961    }
 962}
 963
 964impl From<DevicePixels> for u32 {
 965    fn from(device_pixels: DevicePixels) -> Self {
 966        device_pixels.0 as u32
 967    }
 968}
 969
 970impl From<DevicePixels> for u64 {
 971    fn from(device_pixels: DevicePixels) -> Self {
 972        device_pixels.0 as u64
 973    }
 974}
 975
 976impl From<u64> for DevicePixels {
 977    fn from(device_pixels: u64) -> Self {
 978        DevicePixels(device_pixels as i32)
 979    }
 980}
 981
 982impl From<DevicePixels> for usize {
 983    fn from(device_pixels: DevicePixels) -> Self {
 984        device_pixels.0 as usize
 985    }
 986}
 987
 988impl From<usize> for DevicePixels {
 989    fn from(device_pixels: usize) -> Self {
 990        DevicePixels(device_pixels as i32)
 991    }
 992}
 993
 994#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 995#[repr(transparent)]
 996pub struct ScaledPixels(pub(crate) f32);
 997
 998impl ScaledPixels {
 999    pub fn floor(&self) -> Self {
1000        Self(self.0.floor())
1001    }
1002
1003    pub fn ceil(&self) -> Self {
1004        Self(self.0.ceil())
1005    }
1006}
1007
1008impl Eq for ScaledPixels {}
1009
1010impl Debug for ScaledPixels {
1011    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1012        write!(f, "{} px (scaled)", self.0)
1013    }
1014}
1015
1016impl From<ScaledPixels> for DevicePixels {
1017    fn from(scaled: ScaledPixels) -> Self {
1018        DevicePixels(scaled.0.ceil() as i32)
1019    }
1020}
1021
1022impl From<DevicePixels> for ScaledPixels {
1023    fn from(device: DevicePixels) -> Self {
1024        ScaledPixels(device.0 as f32)
1025    }
1026}
1027
1028impl From<ScaledPixels> for f64 {
1029    fn from(scaled_pixels: ScaledPixels) -> Self {
1030        scaled_pixels.0 as f64
1031    }
1032}
1033
1034#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
1035#[repr(transparent)]
1036pub struct GlobalPixels(pub(crate) f32);
1037
1038impl Debug for GlobalPixels {
1039    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1040        write!(f, "{} px (global coordinate space)", self.0)
1041    }
1042}
1043
1044impl From<GlobalPixels> for f64 {
1045    fn from(global_pixels: GlobalPixels) -> Self {
1046        global_pixels.0 as f64
1047    }
1048}
1049
1050impl From<f64> for GlobalPixels {
1051    fn from(global_pixels: f64) -> Self {
1052        GlobalPixels(global_pixels as f32)
1053    }
1054}
1055
1056impl sqlez::bindable::StaticColumnCount for GlobalPixels {}
1057
1058impl sqlez::bindable::Bind for GlobalPixels {
1059    fn bind(
1060        &self,
1061        statement: &sqlez::statement::Statement,
1062        start_index: i32,
1063    ) -> anyhow::Result<i32> {
1064        self.0.bind(statement, start_index)
1065    }
1066}
1067
1068#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
1069pub struct Rems(pub f32);
1070
1071impl Mul<Pixels> for Rems {
1072    type Output = Pixels;
1073
1074    fn mul(self, other: Pixels) -> Pixels {
1075        Pixels(self.0 * other.0)
1076    }
1077}
1078
1079impl Debug for Rems {
1080    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1081        write!(f, "{} rem", self.0)
1082    }
1083}
1084
1085#[derive(Clone, Copy, Debug, Neg)]
1086pub enum AbsoluteLength {
1087    Pixels(Pixels),
1088    Rems(Rems),
1089}
1090
1091impl AbsoluteLength {
1092    pub fn is_zero(&self) -> bool {
1093        match self {
1094            AbsoluteLength::Pixels(px) => px.0 == 0.,
1095            AbsoluteLength::Rems(rems) => rems.0 == 0.,
1096        }
1097    }
1098}
1099
1100impl From<Pixels> for AbsoluteLength {
1101    fn from(pixels: Pixels) -> Self {
1102        AbsoluteLength::Pixels(pixels)
1103    }
1104}
1105
1106impl From<Rems> for AbsoluteLength {
1107    fn from(rems: Rems) -> Self {
1108        AbsoluteLength::Rems(rems)
1109    }
1110}
1111
1112impl AbsoluteLength {
1113    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
1114        match self {
1115            AbsoluteLength::Pixels(pixels) => *pixels,
1116            AbsoluteLength::Rems(rems) => *rems * rem_size,
1117        }
1118    }
1119}
1120
1121impl Default for AbsoluteLength {
1122    fn default() -> Self {
1123        px(0.).into()
1124    }
1125}
1126
1127/// A non-auto length that can be defined in pixels, rems, or percent of parent.
1128#[derive(Clone, Copy, Neg)]
1129pub enum DefiniteLength {
1130    Absolute(AbsoluteLength),
1131    /// A fraction of the parent's size between 0 and 1.
1132    Fraction(f32),
1133}
1134
1135impl DefiniteLength {
1136    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
1137        match self {
1138            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
1139            DefiniteLength::Fraction(fraction) => match base_size {
1140                AbsoluteLength::Pixels(px) => px * *fraction,
1141                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
1142            },
1143        }
1144    }
1145}
1146
1147impl Debug for DefiniteLength {
1148    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1149        match self {
1150            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
1151            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
1152        }
1153    }
1154}
1155
1156impl From<Pixels> for DefiniteLength {
1157    fn from(pixels: Pixels) -> Self {
1158        Self::Absolute(pixels.into())
1159    }
1160}
1161
1162impl From<Rems> for DefiniteLength {
1163    fn from(rems: Rems) -> Self {
1164        Self::Absolute(rems.into())
1165    }
1166}
1167
1168impl From<AbsoluteLength> for DefiniteLength {
1169    fn from(length: AbsoluteLength) -> Self {
1170        Self::Absolute(length)
1171    }
1172}
1173
1174impl Default for DefiniteLength {
1175    fn default() -> Self {
1176        Self::Absolute(AbsoluteLength::default())
1177    }
1178}
1179
1180/// A length that can be defined in pixels, rems, percent of parent, or auto.
1181#[derive(Clone, Copy)]
1182pub enum Length {
1183    Definite(DefiniteLength),
1184    Auto,
1185}
1186
1187impl Debug for Length {
1188    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1189        match self {
1190            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
1191            Length::Auto => write!(f, "auto"),
1192        }
1193    }
1194}
1195
1196pub fn relative(fraction: f32) -> DefiniteLength {
1197    DefiniteLength::Fraction(fraction).into()
1198}
1199
1200/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1201pub fn phi() -> DefiniteLength {
1202    relative(1.61803398875)
1203}
1204
1205pub fn rems(rems: f32) -> Rems {
1206    Rems(rems)
1207}
1208
1209pub const fn px(pixels: f32) -> Pixels {
1210    Pixels(pixels)
1211}
1212
1213pub fn auto() -> Length {
1214    Length::Auto
1215}
1216
1217impl From<Pixels> for Length {
1218    fn from(pixels: Pixels) -> Self {
1219        Self::Definite(pixels.into())
1220    }
1221}
1222
1223impl From<Rems> for Length {
1224    fn from(rems: Rems) -> Self {
1225        Self::Definite(rems.into())
1226    }
1227}
1228
1229impl From<DefiniteLength> for Length {
1230    fn from(length: DefiniteLength) -> Self {
1231        Self::Definite(length)
1232    }
1233}
1234
1235impl From<AbsoluteLength> for Length {
1236    fn from(length: AbsoluteLength) -> Self {
1237        Self::Definite(length.into())
1238    }
1239}
1240
1241impl Default for Length {
1242    fn default() -> Self {
1243        Self::Definite(DefiniteLength::default())
1244    }
1245}
1246
1247impl From<()> for Length {
1248    fn from(_: ()) -> Self {
1249        Self::Definite(DefiniteLength::default())
1250    }
1251}
1252
1253pub trait Half {
1254    fn half(&self) -> Self;
1255}
1256
1257impl Half for f32 {
1258    fn half(&self) -> Self {
1259        self / 2.
1260    }
1261}
1262
1263impl Half for DevicePixels {
1264    fn half(&self) -> Self {
1265        Self(self.0 / 2)
1266    }
1267}
1268
1269impl Half for ScaledPixels {
1270    fn half(&self) -> Self {
1271        Self(self.0 / 2.)
1272    }
1273}
1274
1275impl Half for Pixels {
1276    fn half(&self) -> Self {
1277        Self(self.0 / 2.)
1278    }
1279}
1280
1281impl Half for Rems {
1282    fn half(&self) -> Self {
1283        Self(self.0 / 2.)
1284    }
1285}
1286
1287impl Half for GlobalPixels {
1288    fn half(&self) -> Self {
1289        Self(self.0 / 2.)
1290    }
1291}
1292
1293pub trait IsZero {
1294    fn is_zero(&self) -> bool;
1295}
1296
1297impl IsZero for DevicePixels {
1298    fn is_zero(&self) -> bool {
1299        self.0 == 0
1300    }
1301}
1302
1303impl IsZero for ScaledPixels {
1304    fn is_zero(&self) -> bool {
1305        self.0 == 0.
1306    }
1307}
1308
1309impl IsZero for Pixels {
1310    fn is_zero(&self) -> bool {
1311        self.0 == 0.
1312    }
1313}
1314
1315impl IsZero for Rems {
1316    fn is_zero(&self) -> bool {
1317        self.0 == 0.
1318    }
1319}
1320
1321impl IsZero for AbsoluteLength {
1322    fn is_zero(&self) -> bool {
1323        match self {
1324            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1325            AbsoluteLength::Rems(rems) => rems.is_zero(),
1326        }
1327    }
1328}
1329
1330impl IsZero for DefiniteLength {
1331    fn is_zero(&self) -> bool {
1332        match self {
1333            DefiniteLength::Absolute(length) => length.is_zero(),
1334            DefiniteLength::Fraction(fraction) => *fraction == 0.,
1335        }
1336    }
1337}
1338
1339impl IsZero for Length {
1340    fn is_zero(&self) -> bool {
1341        match self {
1342            Length::Definite(length) => length.is_zero(),
1343            Length::Auto => false,
1344        }
1345    }
1346}
1347
1348impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1349    fn is_zero(&self) -> bool {
1350        self.x.is_zero() && self.y.is_zero()
1351    }
1352}
1353
1354impl<T> IsZero for Size<T>
1355where
1356    T: IsZero + Default + Debug + Clone,
1357{
1358    fn is_zero(&self) -> bool {
1359        self.width.is_zero() || self.height.is_zero()
1360    }
1361}
1362
1363impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1364    fn is_zero(&self) -> bool {
1365        self.size.is_zero()
1366    }
1367}
1368
1369impl<T> IsZero for Corners<T>
1370where
1371    T: IsZero + Clone + Default + Debug,
1372{
1373    fn is_zero(&self) -> bool {
1374        self.top_left.is_zero()
1375            && self.top_right.is_zero()
1376            && self.bottom_right.is_zero()
1377            && self.bottom_left.is_zero()
1378    }
1379}
1380
1381#[cfg(test)]
1382mod tests {
1383    use super::*;
1384
1385    #[test]
1386    fn test_bounds_intersects() {
1387        let bounds1 = Bounds {
1388            origin: Point { x: 0.0, y: 0.0 },
1389            size: Size {
1390                width: 5.0,
1391                height: 5.0,
1392            },
1393        };
1394        let bounds2 = Bounds {
1395            origin: Point { x: 4.0, y: 4.0 },
1396            size: Size {
1397                width: 5.0,
1398                height: 5.0,
1399            },
1400        };
1401        let bounds3 = Bounds {
1402            origin: Point { x: 10.0, y: 10.0 },
1403            size: Size {
1404                width: 5.0,
1405                height: 5.0,
1406            },
1407        };
1408
1409        // Test Case 1: Intersecting bounds
1410        assert_eq!(bounds1.intersects(&bounds2), true);
1411
1412        // Test Case 2: Non-Intersecting bounds
1413        assert_eq!(bounds1.intersects(&bounds3), false);
1414
1415        // Test Case 3: Bounds intersecting with themselves
1416        assert_eq!(bounds1.intersects(&bounds1), true);
1417    }
1418}