geometry.rs

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