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 Size<Length> {
 271    pub fn full() -> Self {
 272        Self {
 273            width: relative(1.).into(),
 274            height: relative(1.).into(),
 275        }
 276    }
 277}
 278
 279impl Size<DefiniteLength> {
 280    pub fn zero() -> Self {
 281        Self {
 282            width: px(0.).into(),
 283            height: px(0.).into(),
 284        }
 285    }
 286}
 287
 288impl Size<Length> {
 289    pub fn auto() -> Self {
 290        Self {
 291            width: Length::Auto,
 292            height: Length::Auto,
 293        }
 294    }
 295}
 296
 297#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 298#[refineable(Debug)]
 299#[repr(C)]
 300pub struct Bounds<T: Clone + Default + Debug> {
 301    pub origin: Point<T>,
 302    pub size: Size<T>,
 303}
 304
 305impl<T> Bounds<T>
 306where
 307    T: Clone + Debug + Sub<Output = T> + Default,
 308{
 309    pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
 310        let origin = Point {
 311            x: upper_left.x.clone(),
 312            y: upper_left.y.clone(),
 313        };
 314        let size = Size {
 315            width: lower_right.x - upper_left.x,
 316            height: lower_right.y - upper_left.y,
 317        };
 318        Bounds { origin, size }
 319    }
 320}
 321
 322impl<T> Bounds<T>
 323where
 324    T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default,
 325{
 326    pub fn intersects(&self, other: &Bounds<T>) -> bool {
 327        let my_lower_right = self.lower_right();
 328        let their_lower_right = other.lower_right();
 329
 330        self.origin.x < their_lower_right.x
 331            && my_lower_right.x > other.origin.x
 332            && self.origin.y < their_lower_right.y
 333            && my_lower_right.y > other.origin.y
 334    }
 335
 336    pub fn dilate(&mut self, amount: T) {
 337        self.origin.x = self.origin.x.clone() - amount.clone();
 338        self.origin.y = self.origin.y.clone() - amount.clone();
 339        let double_amount = amount.clone() + amount;
 340        self.size.width = self.size.width.clone() + double_amount.clone();
 341        self.size.height = self.size.height.clone() + double_amount;
 342    }
 343}
 344
 345impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
 346    pub fn intersect(&self, other: &Self) -> Self {
 347        let upper_left = self.origin.max(&other.origin);
 348        let lower_right = self.lower_right().min(&other.lower_right());
 349        Self::from_corners(upper_left, lower_right)
 350    }
 351
 352    pub fn union(&self, other: &Self) -> Self {
 353        let top_left = self.origin.min(&other.origin);
 354        let bottom_right = self.lower_right().max(&other.lower_right());
 355        Bounds::from_corners(top_left, bottom_right)
 356    }
 357}
 358
 359impl<T, Rhs> Mul<Rhs> for Bounds<T>
 360where
 361    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
 362    Point<T>: Mul<Rhs, Output = Point<Rhs>>,
 363    Rhs: Clone + Default + Debug,
 364{
 365    type Output = Bounds<Rhs>;
 366
 367    fn mul(self, rhs: Rhs) -> Self::Output {
 368        Bounds {
 369            origin: self.origin * rhs.clone(),
 370            size: self.size * rhs,
 371        }
 372    }
 373}
 374
 375impl<T, S> MulAssign<S> for Bounds<T>
 376where
 377    T: Mul<S, Output = T> + Clone + Default + Debug,
 378    S: Clone,
 379{
 380    fn mul_assign(&mut self, rhs: S) {
 381        self.origin *= rhs.clone();
 382        self.size *= rhs;
 383    }
 384}
 385
 386impl<T, S> Div<S> for Bounds<T>
 387where
 388    Size<T>: Div<S, Output = Size<T>>,
 389    T: Div<S, Output = T> + Default + Clone + Debug,
 390    S: Clone,
 391{
 392    type Output = Self;
 393
 394    fn div(self, rhs: S) -> Self {
 395        Self {
 396            origin: self.origin / rhs.clone(),
 397            size: self.size / rhs,
 398        }
 399    }
 400}
 401
 402impl<T> Bounds<T>
 403where
 404    T: Add<T, Output = T> + Clone + Default + Debug,
 405{
 406    pub fn upper_right(&self) -> Point<T> {
 407        Point {
 408            x: self.origin.x.clone() + self.size.width.clone(),
 409            y: self.origin.y.clone(),
 410        }
 411    }
 412
 413    pub fn lower_right(&self) -> Point<T> {
 414        Point {
 415            x: self.origin.x.clone() + self.size.width.clone(),
 416            y: self.origin.y.clone() + self.size.height.clone(),
 417        }
 418    }
 419
 420    pub fn lower_left(&self) -> Point<T> {
 421        Point {
 422            x: self.origin.x.clone(),
 423            y: self.origin.y.clone() + self.size.height.clone(),
 424        }
 425    }
 426}
 427
 428impl<T> Bounds<T>
 429where
 430    T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
 431{
 432    pub fn contains_point(&self, point: &Point<T>) -> bool {
 433        point.x >= self.origin.x
 434            && point.x <= self.origin.x.clone() + self.size.width.clone()
 435            && point.y >= self.origin.y
 436            && point.y <= self.origin.y.clone() + self.size.height.clone()
 437    }
 438
 439    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
 440    where
 441        U: Clone + Default + Debug,
 442    {
 443        Bounds {
 444            origin: self.origin.map(&f),
 445            size: self.size.map(f),
 446        }
 447    }
 448}
 449
 450impl Bounds<Pixels> {
 451    pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
 452        Bounds {
 453            origin: self.origin.scale(factor),
 454            size: self.size.scale(factor),
 455        }
 456    }
 457}
 458
 459impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
 460
 461#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 462#[refineable(Debug)]
 463#[repr(C)]
 464pub struct Edges<T: Clone + Default + Debug> {
 465    pub top: T,
 466    pub right: T,
 467    pub bottom: T,
 468    pub left: T,
 469}
 470
 471impl<T> Mul for Edges<T>
 472where
 473    T: Mul<Output = T> + Clone + Default + Debug,
 474{
 475    type Output = Self;
 476
 477    fn mul(self, rhs: Self) -> Self::Output {
 478        Self {
 479            top: self.top.clone() * rhs.top,
 480            right: self.right.clone() * rhs.right,
 481            bottom: self.bottom.clone() * rhs.bottom,
 482            left: self.left.clone() * rhs.left,
 483        }
 484    }
 485}
 486
 487impl<T, S> MulAssign<S> for Edges<T>
 488where
 489    T: Mul<S, Output = T> + Clone + Default + Debug,
 490    S: Clone,
 491{
 492    fn mul_assign(&mut self, rhs: S) {
 493        self.top = self.top.clone() * rhs.clone();
 494        self.right = self.right.clone() * rhs.clone();
 495        self.bottom = self.bottom.clone() * rhs.clone();
 496        self.left = self.left.clone() * rhs;
 497    }
 498}
 499
 500impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
 501
 502impl<T: Clone + Default + Debug> Edges<T> {
 503    pub fn all(value: T) -> Self {
 504        Self {
 505            top: value.clone(),
 506            right: value.clone(),
 507            bottom: value.clone(),
 508            left: value,
 509        }
 510    }
 511
 512    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
 513    where
 514        U: Clone + Default + Debug,
 515    {
 516        Edges {
 517            top: f(&self.top),
 518            right: f(&self.right),
 519            bottom: f(&self.bottom),
 520            left: f(&self.left),
 521        }
 522    }
 523
 524    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
 525        predicate(&self.top)
 526            || predicate(&self.right)
 527            || predicate(&self.bottom)
 528            || predicate(&self.left)
 529    }
 530}
 531
 532impl Edges<Length> {
 533    pub fn auto() -> Self {
 534        Self {
 535            top: Length::Auto,
 536            right: Length::Auto,
 537            bottom: Length::Auto,
 538            left: Length::Auto,
 539        }
 540    }
 541
 542    pub fn zero() -> Self {
 543        Self {
 544            top: px(0.).into(),
 545            right: px(0.).into(),
 546            bottom: px(0.).into(),
 547            left: px(0.).into(),
 548        }
 549    }
 550}
 551
 552impl Edges<DefiniteLength> {
 553    pub fn zero() -> Self {
 554        Self {
 555            top: px(0.).into(),
 556            right: px(0.).into(),
 557            bottom: px(0.).into(),
 558            left: px(0.).into(),
 559        }
 560    }
 561}
 562
 563impl Edges<AbsoluteLength> {
 564    pub fn zero() -> Self {
 565        Self {
 566            top: px(0.).into(),
 567            right: px(0.).into(),
 568            bottom: px(0.).into(),
 569            left: px(0.).into(),
 570        }
 571    }
 572
 573    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
 574        Edges {
 575            top: self.top.to_pixels(rem_size),
 576            right: self.right.to_pixels(rem_size),
 577            bottom: self.bottom.to_pixels(rem_size),
 578            left: self.left.to_pixels(rem_size),
 579        }
 580    }
 581}
 582
 583impl Edges<Pixels> {
 584    pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
 585        Edges {
 586            top: self.top.scale(factor),
 587            right: self.right.scale(factor),
 588            bottom: self.bottom.scale(factor),
 589            left: self.left.scale(factor),
 590        }
 591    }
 592}
 593
 594#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 595#[refineable(Debug)]
 596#[repr(C)]
 597pub struct Corners<T: Clone + Default + Debug> {
 598    pub top_left: T,
 599    pub top_right: T,
 600    pub bottom_right: T,
 601    pub bottom_left: T,
 602}
 603
 604impl Corners<AbsoluteLength> {
 605    pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
 606        let max = size.width.max(size.height) / 2.;
 607        Corners {
 608            top_left: self.top_left.to_pixels(rem_size).min(max),
 609            top_right: self.top_right.to_pixels(rem_size).min(max),
 610            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
 611            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
 612        }
 613    }
 614}
 615
 616impl Corners<Pixels> {
 617    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
 618        Corners {
 619            top_left: self.top_left.scale(factor),
 620            top_right: self.top_right.scale(factor),
 621            bottom_right: self.bottom_right.scale(factor),
 622            bottom_left: self.bottom_left.scale(factor),
 623        }
 624    }
 625}
 626
 627impl<T: Clone + Default + Debug> Corners<T> {
 628    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
 629    where
 630        U: Clone + Default + Debug,
 631    {
 632        Corners {
 633            top_left: f(&self.top_left),
 634            top_right: f(&self.top_right),
 635            bottom_right: f(&self.bottom_right),
 636            bottom_left: f(&self.bottom_left),
 637        }
 638    }
 639}
 640
 641impl<T> Mul for Corners<T>
 642where
 643    T: Mul<Output = T> + Clone + Default + Debug,
 644{
 645    type Output = Self;
 646
 647    fn mul(self, rhs: Self) -> Self::Output {
 648        Self {
 649            top_left: self.top_left.clone() * rhs.top_left,
 650            top_right: self.top_right.clone() * rhs.top_right,
 651            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
 652            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
 653        }
 654    }
 655}
 656
 657impl<T, S> MulAssign<S> for Corners<T>
 658where
 659    T: Mul<S, Output = T> + Clone + Default + Debug,
 660    S: Clone,
 661{
 662    fn mul_assign(&mut self, rhs: S) {
 663        self.top_left = self.top_left.clone() * rhs.clone();
 664        self.top_right = self.top_right.clone() * rhs.clone();
 665        self.bottom_right = self.bottom_right.clone() * rhs.clone();
 666        self.bottom_left = self.bottom_left.clone() * rhs;
 667    }
 668}
 669
 670impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
 671
 672#[derive(
 673    Clone,
 674    Copy,
 675    Default,
 676    Add,
 677    AddAssign,
 678    Sub,
 679    SubAssign,
 680    Neg,
 681    Div,
 682    DivAssign,
 683    PartialEq,
 684    PartialOrd,
 685    Serialize,
 686    Deserialize,
 687)]
 688#[repr(transparent)]
 689pub struct Pixels(pub(crate) f32);
 690
 691impl std::ops::Div for Pixels {
 692    type Output = Self;
 693
 694    fn div(self, rhs: Self) -> Self::Output {
 695        Self(self.0 / rhs.0)
 696    }
 697}
 698
 699impl std::ops::DivAssign for Pixels {
 700    fn div_assign(&mut self, rhs: Self) {
 701        self.0 /= rhs.0;
 702    }
 703}
 704
 705impl std::ops::RemAssign for Pixels {
 706    fn rem_assign(&mut self, rhs: Self) {
 707        self.0 %= rhs.0;
 708    }
 709}
 710
 711impl std::ops::Rem for Pixels {
 712    type Output = Self;
 713
 714    fn rem(self, rhs: Self) -> Self {
 715        Self(self.0 % rhs.0)
 716    }
 717}
 718
 719impl Mul<f32> for Pixels {
 720    type Output = Pixels;
 721
 722    fn mul(self, other: f32) -> Pixels {
 723        Pixels(self.0 * other)
 724    }
 725}
 726
 727impl Mul<usize> for Pixels {
 728    type Output = Pixels;
 729
 730    fn mul(self, other: usize) -> Pixels {
 731        Pixels(self.0 * other as f32)
 732    }
 733}
 734
 735impl Mul<Pixels> for f32 {
 736    type Output = Pixels;
 737
 738    fn mul(self, rhs: Pixels) -> Self::Output {
 739        Pixels(self * rhs.0)
 740    }
 741}
 742
 743impl MulAssign<f32> for Pixels {
 744    fn mul_assign(&mut self, other: f32) {
 745        self.0 *= other;
 746    }
 747}
 748
 749impl Pixels {
 750    pub const ZERO: Pixels = Pixels(0.0);
 751    pub const MAX: Pixels = Pixels(f32::MAX);
 752
 753    pub fn as_usize(&self) -> usize {
 754        self.0 as usize
 755    }
 756
 757    pub fn as_isize(&self) -> isize {
 758        self.0 as isize
 759    }
 760
 761    pub fn floor(&self) -> Self {
 762        Self(self.0.floor())
 763    }
 764
 765    pub fn round(&self) -> Self {
 766        Self(self.0.round())
 767    }
 768
 769    pub fn scale(&self, factor: f32) -> ScaledPixels {
 770        ScaledPixels(self.0 * factor)
 771    }
 772
 773    pub fn pow(&self, exponent: f32) -> Self {
 774        Self(self.0.powf(exponent))
 775    }
 776
 777    pub fn abs(&self) -> Self {
 778        Self(self.0.abs())
 779    }
 780}
 781
 782impl Mul<Pixels> for Pixels {
 783    type Output = Pixels;
 784
 785    fn mul(self, rhs: Pixels) -> Self::Output {
 786        Pixels(self.0 * rhs.0)
 787    }
 788}
 789
 790impl Eq for Pixels {}
 791
 792impl Ord for Pixels {
 793    fn cmp(&self, other: &Self) -> cmp::Ordering {
 794        self.0.partial_cmp(&other.0).unwrap()
 795    }
 796}
 797
 798impl std::hash::Hash for Pixels {
 799    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
 800        self.0.to_bits().hash(state);
 801    }
 802}
 803
 804impl From<f64> for Pixels {
 805    fn from(pixels: f64) -> Self {
 806        Pixels(pixels as f32)
 807    }
 808}
 809
 810impl From<f32> for Pixels {
 811    fn from(pixels: f32) -> Self {
 812        Pixels(pixels)
 813    }
 814}
 815
 816impl Debug for Pixels {
 817    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 818        write!(f, "{} px", self.0)
 819    }
 820}
 821
 822impl From<Pixels> for f32 {
 823    fn from(pixels: Pixels) -> Self {
 824        pixels.0
 825    }
 826}
 827
 828impl From<&Pixels> for f32 {
 829    fn from(pixels: &Pixels) -> Self {
 830        pixels.0
 831    }
 832}
 833
 834impl From<Pixels> for f64 {
 835    fn from(pixels: Pixels) -> Self {
 836        pixels.0 as f64
 837    }
 838}
 839
 840impl From<Pixels> for u32 {
 841    fn from(pixels: Pixels) -> Self {
 842        pixels.0 as u32
 843    }
 844}
 845
 846impl From<u32> for Pixels {
 847    fn from(pixels: u32) -> Self {
 848        Pixels(pixels as f32)
 849    }
 850}
 851
 852impl From<Pixels> for usize {
 853    fn from(pixels: Pixels) -> Self {
 854        pixels.0 as usize
 855    }
 856}
 857
 858#[derive(
 859    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
 860)]
 861#[repr(transparent)]
 862pub struct DevicePixels(pub(crate) i32);
 863
 864impl DevicePixels {
 865    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
 866        self.0 as u32 * bytes_per_pixel as u32
 867    }
 868}
 869
 870impl fmt::Debug for DevicePixels {
 871    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 872        write!(f, "{} px (device)", self.0)
 873    }
 874}
 875
 876impl From<DevicePixels> for i32 {
 877    fn from(device_pixels: DevicePixels) -> Self {
 878        device_pixels.0
 879    }
 880}
 881
 882impl From<i32> for DevicePixels {
 883    fn from(device_pixels: i32) -> Self {
 884        DevicePixels(device_pixels)
 885    }
 886}
 887
 888impl From<u32> for DevicePixels {
 889    fn from(device_pixels: u32) -> Self {
 890        DevicePixels(device_pixels as i32)
 891    }
 892}
 893
 894impl From<DevicePixels> for u32 {
 895    fn from(device_pixels: DevicePixels) -> Self {
 896        device_pixels.0 as u32
 897    }
 898}
 899
 900impl From<DevicePixels> for u64 {
 901    fn from(device_pixels: DevicePixels) -> Self {
 902        device_pixels.0 as u64
 903    }
 904}
 905
 906impl From<u64> for DevicePixels {
 907    fn from(device_pixels: u64) -> Self {
 908        DevicePixels(device_pixels as i32)
 909    }
 910}
 911
 912#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 913#[repr(transparent)]
 914pub struct ScaledPixels(pub(crate) f32);
 915
 916impl ScaledPixels {
 917    pub fn floor(&self) -> Self {
 918        Self(self.0.floor())
 919    }
 920
 921    pub fn ceil(&self) -> Self {
 922        Self(self.0.ceil())
 923    }
 924}
 925
 926impl Eq for ScaledPixels {}
 927
 928impl Debug for ScaledPixels {
 929    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 930        write!(f, "{} px (scaled)", self.0)
 931    }
 932}
 933
 934impl From<ScaledPixels> for DevicePixels {
 935    fn from(scaled: ScaledPixels) -> Self {
 936        DevicePixels(scaled.0.ceil() as i32)
 937    }
 938}
 939
 940impl From<DevicePixels> for ScaledPixels {
 941    fn from(device: DevicePixels) -> Self {
 942        ScaledPixels(device.0 as f32)
 943    }
 944}
 945
 946impl From<ScaledPixels> for f64 {
 947    fn from(scaled_pixels: ScaledPixels) -> Self {
 948        scaled_pixels.0 as f64
 949    }
 950}
 951
 952#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
 953#[repr(transparent)]
 954pub struct GlobalPixels(pub(crate) f32);
 955
 956impl Debug for GlobalPixels {
 957    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 958        write!(f, "{} px (global coordinate space)", self.0)
 959    }
 960}
 961
 962impl From<GlobalPixels> for f64 {
 963    fn from(global_pixels: GlobalPixels) -> Self {
 964        global_pixels.0 as f64
 965    }
 966}
 967
 968impl From<f64> for GlobalPixels {
 969    fn from(global_pixels: f64) -> Self {
 970        GlobalPixels(global_pixels as f32)
 971    }
 972}
 973
 974impl sqlez::bindable::StaticColumnCount for GlobalPixels {}
 975
 976impl sqlez::bindable::Bind for GlobalPixels {
 977    fn bind(
 978        &self,
 979        statement: &sqlez::statement::Statement,
 980        start_index: i32,
 981    ) -> anyhow::Result<i32> {
 982        self.0.bind(statement, start_index)
 983    }
 984}
 985
 986#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg)]
 987pub struct Rems(f32);
 988
 989impl Mul<Pixels> for Rems {
 990    type Output = Pixels;
 991
 992    fn mul(self, other: Pixels) -> Pixels {
 993        Pixels(self.0 * other.0)
 994    }
 995}
 996
 997impl Debug for Rems {
 998    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 999        write!(f, "{} rem", self.0)
1000    }
1001}
1002
1003#[derive(Clone, Copy, Debug, Neg)]
1004pub enum AbsoluteLength {
1005    Pixels(Pixels),
1006    Rems(Rems),
1007}
1008
1009impl AbsoluteLength {
1010    pub fn is_zero(&self) -> bool {
1011        match self {
1012            AbsoluteLength::Pixels(px) => px.0 == 0.,
1013            AbsoluteLength::Rems(rems) => rems.0 == 0.,
1014        }
1015    }
1016}
1017
1018impl From<Pixels> for AbsoluteLength {
1019    fn from(pixels: Pixels) -> Self {
1020        AbsoluteLength::Pixels(pixels)
1021    }
1022}
1023
1024impl From<Rems> for AbsoluteLength {
1025    fn from(rems: Rems) -> Self {
1026        AbsoluteLength::Rems(rems)
1027    }
1028}
1029
1030impl AbsoluteLength {
1031    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
1032        match self {
1033            AbsoluteLength::Pixels(pixels) => *pixels,
1034            AbsoluteLength::Rems(rems) => *rems * rem_size,
1035        }
1036    }
1037}
1038
1039impl Default for AbsoluteLength {
1040    fn default() -> Self {
1041        px(0.).into()
1042    }
1043}
1044
1045/// A non-auto length that can be defined in pixels, rems, or percent of parent.
1046#[derive(Clone, Copy, Neg)]
1047pub enum DefiniteLength {
1048    Absolute(AbsoluteLength),
1049    /// A fraction of the parent's size between 0 and 1.
1050    Fraction(f32),
1051}
1052
1053impl DefiniteLength {
1054    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
1055        match self {
1056            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
1057            DefiniteLength::Fraction(fraction) => match base_size {
1058                AbsoluteLength::Pixels(px) => px * *fraction,
1059                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
1060            },
1061        }
1062    }
1063}
1064
1065impl Debug for DefiniteLength {
1066    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1067        match self {
1068            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
1069            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
1070        }
1071    }
1072}
1073
1074impl From<Pixels> for DefiniteLength {
1075    fn from(pixels: Pixels) -> Self {
1076        Self::Absolute(pixels.into())
1077    }
1078}
1079
1080impl From<Rems> for DefiniteLength {
1081    fn from(rems: Rems) -> Self {
1082        Self::Absolute(rems.into())
1083    }
1084}
1085
1086impl From<AbsoluteLength> for DefiniteLength {
1087    fn from(length: AbsoluteLength) -> Self {
1088        Self::Absolute(length)
1089    }
1090}
1091
1092impl Default for DefiniteLength {
1093    fn default() -> Self {
1094        Self::Absolute(AbsoluteLength::default())
1095    }
1096}
1097
1098/// A length that can be defined in pixels, rems, percent of parent, or auto.
1099#[derive(Clone, Copy)]
1100pub enum Length {
1101    Definite(DefiniteLength),
1102    Auto,
1103}
1104
1105impl Debug for Length {
1106    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1107        match self {
1108            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
1109            Length::Auto => write!(f, "auto"),
1110        }
1111    }
1112}
1113
1114pub fn relative(fraction: f32) -> DefiniteLength {
1115    DefiniteLength::Fraction(fraction).into()
1116}
1117
1118/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
1119pub fn phi() -> DefiniteLength {
1120    relative(1.61803398875)
1121}
1122
1123pub fn rems(rems: f32) -> Rems {
1124    Rems(rems)
1125}
1126
1127pub const fn px(pixels: f32) -> Pixels {
1128    Pixels(pixels)
1129}
1130
1131pub fn auto() -> Length {
1132    Length::Auto
1133}
1134
1135impl From<Pixels> for Length {
1136    fn from(pixels: Pixels) -> Self {
1137        Self::Definite(pixels.into())
1138    }
1139}
1140
1141impl From<Rems> for Length {
1142    fn from(rems: Rems) -> Self {
1143        Self::Definite(rems.into())
1144    }
1145}
1146
1147impl From<DefiniteLength> for Length {
1148    fn from(length: DefiniteLength) -> Self {
1149        Self::Definite(length)
1150    }
1151}
1152
1153impl From<AbsoluteLength> for Length {
1154    fn from(length: AbsoluteLength) -> Self {
1155        Self::Definite(length.into())
1156    }
1157}
1158
1159impl Default for Length {
1160    fn default() -> Self {
1161        Self::Definite(DefiniteLength::default())
1162    }
1163}
1164
1165impl From<()> for Length {
1166    fn from(_: ()) -> Self {
1167        Self::Definite(DefiniteLength::default())
1168    }
1169}
1170
1171pub trait IsZero {
1172    fn is_zero(&self) -> bool;
1173}
1174
1175impl IsZero for DevicePixels {
1176    fn is_zero(&self) -> bool {
1177        self.0 == 0
1178    }
1179}
1180
1181impl IsZero for ScaledPixels {
1182    fn is_zero(&self) -> bool {
1183        self.0 == 0.
1184    }
1185}
1186
1187impl IsZero for Pixels {
1188    fn is_zero(&self) -> bool {
1189        self.0 == 0.
1190    }
1191}
1192
1193impl IsZero for Rems {
1194    fn is_zero(&self) -> bool {
1195        self.0 == 0.
1196    }
1197}
1198
1199impl IsZero for AbsoluteLength {
1200    fn is_zero(&self) -> bool {
1201        match self {
1202            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
1203            AbsoluteLength::Rems(rems) => rems.is_zero(),
1204        }
1205    }
1206}
1207
1208impl IsZero for DefiniteLength {
1209    fn is_zero(&self) -> bool {
1210        match self {
1211            DefiniteLength::Absolute(length) => length.is_zero(),
1212            DefiniteLength::Fraction(fraction) => *fraction == 0.,
1213        }
1214    }
1215}
1216
1217impl IsZero for Length {
1218    fn is_zero(&self) -> bool {
1219        match self {
1220            Length::Definite(length) => length.is_zero(),
1221            Length::Auto => false,
1222        }
1223    }
1224}
1225
1226impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
1227    fn is_zero(&self) -> bool {
1228        self.x.is_zero() && self.y.is_zero()
1229    }
1230}
1231
1232impl<T> IsZero for Size<T>
1233where
1234    T: IsZero + Default + Debug + Clone,
1235{
1236    fn is_zero(&self) -> bool {
1237        self.width.is_zero() || self.height.is_zero()
1238    }
1239}
1240
1241impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
1242    fn is_zero(&self) -> bool {
1243        self.size.is_zero()
1244    }
1245}
1246
1247impl<T> IsZero for Corners<T>
1248where
1249    T: IsZero + Clone + Default + Debug,
1250{
1251    fn is_zero(&self) -> bool {
1252        self.top_left.is_zero()
1253            && self.top_right.is_zero()
1254            && self.bottom_right.is_zero()
1255            && self.bottom_left.is_zero()
1256    }
1257}
1258
1259#[cfg(test)]
1260mod tests {
1261    use super::*;
1262
1263    #[test]
1264    fn test_bounds_intersects() {
1265        let bounds1 = Bounds {
1266            origin: Point { x: 0.0, y: 0.0 },
1267            size: Size {
1268                width: 5.0,
1269                height: 5.0,
1270            },
1271        };
1272        let bounds2 = Bounds {
1273            origin: Point { x: 4.0, y: 4.0 },
1274            size: Size {
1275                width: 5.0,
1276                height: 5.0,
1277            },
1278        };
1279        let bounds3 = Bounds {
1280            origin: Point { x: 10.0, y: 10.0 },
1281            size: Size {
1282                width: 5.0,
1283                height: 5.0,
1284            },
1285        };
1286
1287        // Test Case 1: Intersecting bounds
1288        assert_eq!(bounds1.intersects(&bounds2), true);
1289
1290        // Test Case 2: Non-Intersecting bounds
1291        assert_eq!(bounds1.intersects(&bounds3), false);
1292
1293        // Test Case 3: Bounds intersecting with themselves
1294        assert_eq!(bounds1.intersects(&bounds1), true);
1295    }
1296}