geometry.rs

   1//! The GPUI geometry module is a collection of types and traits that
   2//! can be used to describe common units, concepts, and the relationships
   3//! between them.
   4
   5use core::fmt::Debug;
   6use derive_more::{Add, AddAssign, Div, DivAssign, Mul, Neg, Sub, SubAssign};
   7use refineable::Refineable;
   8use serde_derive::{Deserialize, Serialize};
   9use std::{
  10    cmp::{self, PartialOrd},
  11    fmt,
  12    hash::Hash,
  13    ops::{Add, Div, Mul, MulAssign, Sub},
  14};
  15
  16use crate::{AppContext, DisplayId};
  17
  18/// An axis along which a measurement can be made.
  19#[derive(Copy, Clone, PartialEq, Eq, Debug)]
  20pub enum Axis {
  21    /// The y axis, or up and down
  22    Vertical,
  23    /// The x axis, or left and right
  24    Horizontal,
  25}
  26
  27impl Axis {
  28    /// Swap this axis to the opposite axis.
  29    pub fn invert(self) -> Self {
  30        match self {
  31            Axis::Vertical => Axis::Horizontal,
  32            Axis::Horizontal => Axis::Vertical,
  33        }
  34    }
  35}
  36
  37/// A trait for accessing the given unit along a certain axis.
  38pub trait Along {
  39    /// The unit associated with this type
  40    type Unit;
  41
  42    /// Returns the unit along the given axis.
  43    fn along(&self, axis: Axis) -> Self::Unit;
  44
  45    /// Applies the given function to the unit along the given axis and returns a new value.
  46    fn apply_along(&self, axis: Axis, f: impl FnOnce(Self::Unit) -> Self::Unit) -> Self;
  47}
  48
  49/// Describes a location in a 2D cartesian coordinate space.
  50///
  51/// It holds two public fields, `x` and `y`, which represent the coordinates in the space.
  52/// The type `T` for the coordinates can be any type that implements `Default`, `Clone`, and `Debug`.
  53///
  54/// # Examples
  55///
  56/// ```
  57/// # use zed::Point;
  58/// let point = Point { x: 10, y: 20 };
  59/// println!("{:?}", point); // Outputs: Point { x: 10, y: 20 }
  60/// ```
  61#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
  62#[refineable(Debug)]
  63#[repr(C)]
  64pub struct Point<T: Default + Clone + Debug> {
  65    /// The x coordinate of the point.
  66    pub x: T,
  67    /// The y coordinate of the point.
  68    pub y: T,
  69}
  70
  71/// Constructs a new `Point<T>` with the given x and y coordinates.
  72///
  73/// # Arguments
  74///
  75/// * `x` - The x coordinate of the point.
  76/// * `y` - The y coordinate of the point.
  77///
  78/// # Returns
  79///
  80/// Returns a `Point<T>` with the specified coordinates.
  81///
  82/// # Examples
  83///
  84/// ```
  85/// # use zed::Point;
  86/// let p = point(10, 20);
  87/// assert_eq!(p.x, 10);
  88/// assert_eq!(p.y, 20);
  89/// ```
  90pub const fn point<T: Clone + Debug + Default>(x: T, y: T) -> Point<T> {
  91    Point { x, y }
  92}
  93
  94impl<T: Clone + Debug + Default> Point<T> {
  95    /// Creates a new `Point` with the specified `x` and `y` coordinates.
  96    ///
  97    /// # Arguments
  98    ///
  99    /// * `x` - The horizontal coordinate of the point.
 100    /// * `y` - The vertical coordinate of the point.
 101    ///
 102    /// # Examples
 103    ///
 104    /// ```
 105    /// let p = Point::new(10, 20);
 106    /// assert_eq!(p.x, 10);
 107    /// assert_eq!(p.y, 20);
 108    /// ```
 109    pub const fn new(x: T, y: T) -> Self {
 110        Self { x, y }
 111    }
 112
 113    /// Transforms the point to a `Point<U>` by applying the given function to both coordinates.
 114    ///
 115    /// This method allows for converting a `Point<T>` to a `Point<U>` by specifying a closure
 116    /// that defines how to convert between the two types. The closure is applied to both the `x`
 117    /// and `y` coordinates, resulting in a new point of the desired type.
 118    ///
 119    /// # Arguments
 120    ///
 121    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
 122    ///
 123    /// # Examples
 124    ///
 125    /// ```
 126    /// # use zed::Point;
 127    /// let p = Point { x: 3, y: 4 };
 128    /// let p_float = p.map(|coord| coord as f32);
 129    /// assert_eq!(p_float, Point { x: 3.0, y: 4.0 });
 130    /// ```
 131    pub fn map<U: Clone + Default + Debug>(&self, f: impl Fn(T) -> U) -> Point<U> {
 132        Point {
 133            x: f(self.x.clone()),
 134            y: f(self.y.clone()),
 135        }
 136    }
 137}
 138
 139impl<T: Clone + Debug + Default> Along for Point<T> {
 140    type Unit = T;
 141
 142    fn along(&self, axis: Axis) -> T {
 143        match axis {
 144            Axis::Horizontal => self.x.clone(),
 145            Axis::Vertical => self.y.clone(),
 146        }
 147    }
 148
 149    fn apply_along(&self, axis: Axis, f: impl FnOnce(T) -> T) -> Point<T> {
 150        match axis {
 151            Axis::Horizontal => Point {
 152                x: f(self.x.clone()),
 153                y: self.y.clone(),
 154            },
 155            Axis::Vertical => Point {
 156                x: self.x.clone(),
 157                y: f(self.y.clone()),
 158            },
 159        }
 160    }
 161}
 162
 163impl<T: Clone + Debug + Default + Negate> Negate for Point<T> {
 164    fn negate(self) -> Self {
 165        self.map(Negate::negate)
 166    }
 167}
 168
 169impl Point<Pixels> {
 170    /// Scales the point by a given factor, which is typically derived from the resolution
 171    /// of a target display to ensure proper sizing of UI elements.
 172    ///
 173    /// # Arguments
 174    ///
 175    /// * `factor` - The scaling factor to apply to both the x and y coordinates.
 176    ///
 177    /// # Examples
 178    ///
 179    /// ```
 180    /// # use zed::{Point, Pixels, ScaledPixels};
 181    /// let p = Point { x: Pixels(10.0), y: Pixels(20.0) };
 182    /// let scaled_p = p.scale(1.5);
 183    /// assert_eq!(scaled_p, Point { x: ScaledPixels(15.0), y: ScaledPixels(30.0) });
 184    /// ```
 185    pub fn scale(&self, factor: f32) -> Point<ScaledPixels> {
 186        Point {
 187            x: self.x.scale(factor),
 188            y: self.y.scale(factor),
 189        }
 190    }
 191
 192    /// Calculates the Euclidean distance from the origin (0, 0) to this point.
 193    ///
 194    /// # Examples
 195    ///
 196    /// ```
 197    /// # use zed::Point;
 198    /// # use zed::Pixels;
 199    /// let p = Point { x: Pixels(3.0), y: Pixels(4.0) };
 200    /// assert_eq!(p.magnitude(), 5.0);
 201    /// ```
 202    pub fn magnitude(&self) -> f64 {
 203        ((self.x.0.powi(2) + self.y.0.powi(2)) as f64).sqrt()
 204    }
 205}
 206
 207impl<T, Rhs> Mul<Rhs> for Point<T>
 208where
 209    T: Mul<Rhs, Output = T> + Clone + Default + Debug,
 210    Rhs: Clone + Debug,
 211{
 212    type Output = Point<T>;
 213
 214    fn mul(self, rhs: Rhs) -> Self::Output {
 215        Point {
 216            x: self.x * rhs.clone(),
 217            y: self.y * rhs,
 218        }
 219    }
 220}
 221
 222impl<T, S> MulAssign<S> for Point<T>
 223where
 224    T: Clone + Mul<S, Output = T> + Default + Debug,
 225    S: Clone,
 226{
 227    fn mul_assign(&mut self, rhs: S) {
 228        self.x = self.x.clone() * rhs.clone();
 229        self.y = self.y.clone() * rhs;
 230    }
 231}
 232
 233impl<T, S> Div<S> for Point<T>
 234where
 235    T: Div<S, Output = T> + Clone + Default + Debug,
 236    S: Clone,
 237{
 238    type Output = Self;
 239
 240    fn div(self, rhs: S) -> Self::Output {
 241        Self {
 242            x: self.x / rhs.clone(),
 243            y: self.y / rhs,
 244        }
 245    }
 246}
 247
 248impl<T> Point<T>
 249where
 250    T: PartialOrd + Clone + Default + Debug,
 251{
 252    /// Returns a new point with the maximum values of each dimension from `self` and `other`.
 253    ///
 254    /// # Arguments
 255    ///
 256    /// * `other` - A reference to another `Point` to compare with `self`.
 257    ///
 258    /// # Examples
 259    ///
 260    /// ```
 261    /// # use zed::Point;
 262    /// let p1 = Point { x: 3, y: 7 };
 263    /// let p2 = Point { x: 5, y: 2 };
 264    /// let max_point = p1.max(&p2);
 265    /// assert_eq!(max_point, Point { x: 5, y: 7 });
 266    /// ```
 267    pub fn max(&self, other: &Self) -> Self {
 268        Point {
 269            x: if self.x > other.x {
 270                self.x.clone()
 271            } else {
 272                other.x.clone()
 273            },
 274            y: if self.y > other.y {
 275                self.y.clone()
 276            } else {
 277                other.y.clone()
 278            },
 279        }
 280    }
 281
 282    /// Returns a new point with the minimum values of each dimension from `self` and `other`.
 283    ///
 284    /// # Arguments
 285    ///
 286    /// * `other` - A reference to another `Point` to compare with `self`.
 287    ///
 288    /// # Examples
 289    ///
 290    /// ```
 291    /// # use zed::Point;
 292    /// let p1 = Point { x: 3, y: 7 };
 293    /// let p2 = Point { x: 5, y: 2 };
 294    /// let min_point = p1.min(&p2);
 295    /// assert_eq!(min_point, Point { x: 3, y: 2 });
 296    /// ```
 297    pub fn min(&self, other: &Self) -> Self {
 298        Point {
 299            x: if self.x <= other.x {
 300                self.x.clone()
 301            } else {
 302                other.x.clone()
 303            },
 304            y: if self.y <= other.y {
 305                self.y.clone()
 306            } else {
 307                other.y.clone()
 308            },
 309        }
 310    }
 311
 312    /// Clamps the point to a specified range.
 313    ///
 314    /// Given a minimum point and a maximum point, this method constrains the current point
 315    /// such that its coordinates do not exceed the range defined by the minimum and maximum points.
 316    /// If the current point's coordinates are less than the minimum, they are set to the minimum.
 317    /// If they are greater than the maximum, they are set to the maximum.
 318    ///
 319    /// # Arguments
 320    ///
 321    /// * `min` - A reference to a `Point` representing the minimum allowable coordinates.
 322    /// * `max` - A reference to a `Point` representing the maximum allowable coordinates.
 323    ///
 324    /// # Examples
 325    ///
 326    /// ```
 327    /// # use zed::Point;
 328    /// let p = Point { x: 10, y: 20 };
 329    /// let min = Point { x: 0, y: 5 };
 330    /// let max = Point { x: 15, y: 25 };
 331    /// let clamped_p = p.clamp(&min, &max);
 332    /// assert_eq!(clamped_p, Point { x: 10, y: 20 });
 333    ///
 334    /// let p_out_of_bounds = Point { x: -5, y: 30 };
 335    /// let clamped_p_out_of_bounds = p_out_of_bounds.clamp(&min, &max);
 336    /// assert_eq!(clamped_p_out_of_bounds, Point { x: 0, y: 25 });
 337    /// ```
 338    pub fn clamp(&self, min: &Self, max: &Self) -> Self {
 339        self.max(min).min(max)
 340    }
 341}
 342
 343impl<T: Clone + Default + Debug> Clone for Point<T> {
 344    fn clone(&self) -> Self {
 345        Self {
 346            x: self.x.clone(),
 347            y: self.y.clone(),
 348        }
 349    }
 350}
 351
 352/// A structure representing a two-dimensional size with width and height in a given unit.
 353///
 354/// This struct is generic over the type `T`, which can be any type that implements `Clone`, `Default`, and `Debug`.
 355/// It is commonly used to specify dimensions for elements in a UI, such as a window or element.
 356#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash, Serialize, Deserialize)]
 357#[refineable(Debug)]
 358#[repr(C)]
 359pub struct Size<T: Clone + Default + Debug> {
 360    /// The width component of the size.
 361    pub width: T,
 362    /// The height component of the size.
 363    pub height: T,
 364}
 365
 366/// Constructs a new `Size<T>` with the provided width and height.
 367///
 368/// # Arguments
 369///
 370/// * `width` - The width component of the `Size`.
 371/// * `height` - The height component of the `Size`.
 372///
 373/// # Examples
 374///
 375/// ```
 376/// # use zed::Size;
 377/// let my_size = size(10, 20);
 378/// assert_eq!(my_size.width, 10);
 379/// assert_eq!(my_size.height, 20);
 380/// ```
 381pub const fn size<T>(width: T, height: T) -> Size<T>
 382where
 383    T: Clone + Default + Debug,
 384{
 385    Size { width, height }
 386}
 387
 388impl<T> Size<T>
 389where
 390    T: Clone + Default + Debug,
 391{
 392    /// Applies a function to the width and height of the size, producing a new `Size<U>`.
 393    ///
 394    /// This method allows for converting a `Size<T>` to a `Size<U>` by specifying a closure
 395    /// that defines how to convert between the two types. The closure is applied to both the `width`
 396    /// and `height`, resulting in a new size of the desired type.
 397    ///
 398    /// # Arguments
 399    ///
 400    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
 401    ///
 402    /// # Examples
 403    ///
 404    /// ```
 405    /// # use zed::Size;
 406    /// let my_size = Size { width: 10, height: 20 };
 407    /// let my_new_size = my_size.map(|dimension| dimension as f32 * 1.5);
 408    /// assert_eq!(my_new_size, Size { width: 15.0, height: 30.0 });
 409    /// ```
 410    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Size<U>
 411    where
 412        U: Clone + Default + Debug,
 413    {
 414        Size {
 415            width: f(self.width.clone()),
 416            height: f(self.height.clone()),
 417        }
 418    }
 419}
 420
 421impl<T> Size<T>
 422where
 423    T: Clone + Default + Debug + Half,
 424{
 425    /// Compute the center point of the size.g
 426    pub fn center(&self) -> Point<T> {
 427        Point {
 428            x: self.width.half(),
 429            y: self.height.half(),
 430        }
 431    }
 432}
 433
 434impl Size<Pixels> {
 435    /// Scales the size by a given factor.
 436    ///
 437    /// This method multiplies both the width and height by the provided scaling factor,
 438    /// resulting in a new `Size<ScaledPixels>` that is proportionally larger or smaller
 439    /// depending on the factor.
 440    ///
 441    /// # Arguments
 442    ///
 443    /// * `factor` - The scaling factor to apply to the width and height.
 444    ///
 445    /// # Examples
 446    ///
 447    /// ```
 448    /// # use zed::{Size, Pixels, ScaledPixels};
 449    /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
 450    /// let scaled_size = size.scale(2.0);
 451    /// assert_eq!(scaled_size, Size { width: ScaledPixels(200.0), height: ScaledPixels(100.0) });
 452    /// ```
 453    pub fn scale(&self, factor: f32) -> Size<ScaledPixels> {
 454        Size {
 455            width: self.width.scale(factor),
 456            height: self.height.scale(factor),
 457        }
 458    }
 459}
 460
 461impl<T> Along for Size<T>
 462where
 463    T: Clone + Default + Debug,
 464{
 465    type Unit = T;
 466
 467    fn along(&self, axis: Axis) -> T {
 468        match axis {
 469            Axis::Horizontal => self.width.clone(),
 470            Axis::Vertical => self.height.clone(),
 471        }
 472    }
 473
 474    /// Returns the value of this size along the given axis.
 475    fn apply_along(&self, axis: Axis, f: impl FnOnce(T) -> T) -> Self {
 476        match axis {
 477            Axis::Horizontal => Size {
 478                width: f(self.width.clone()),
 479                height: self.height.clone(),
 480            },
 481            Axis::Vertical => Size {
 482                width: self.width.clone(),
 483                height: f(self.height.clone()),
 484            },
 485        }
 486    }
 487}
 488
 489impl<T> Size<T>
 490where
 491    T: PartialOrd + Clone + Default + Debug,
 492{
 493    /// Returns a new `Size` with the maximum width and height from `self` and `other`.
 494    ///
 495    /// # Arguments
 496    ///
 497    /// * `other` - A reference to another `Size` to compare with `self`.
 498    ///
 499    /// # Examples
 500    ///
 501    /// ```
 502    /// # use zed::Size;
 503    /// let size1 = Size { width: 30, height: 40 };
 504    /// let size2 = Size { width: 50, height: 20 };
 505    /// let max_size = size1.max(&size2);
 506    /// assert_eq!(max_size, Size { width: 50, height: 40 });
 507    /// ```
 508    pub fn max(&self, other: &Self) -> Self {
 509        Size {
 510            width: if self.width >= other.width {
 511                self.width.clone()
 512            } else {
 513                other.width.clone()
 514            },
 515            height: if self.height >= other.height {
 516                self.height.clone()
 517            } else {
 518                other.height.clone()
 519            },
 520        }
 521    }
 522    /// Returns a new `Size` with the minimum width and height from `self` and `other`.
 523    ///
 524    /// # Arguments
 525    ///
 526    /// * `other` - A reference to another `Size` to compare with `self`.
 527    ///
 528    /// # Examples
 529    ///
 530    /// ```
 531    /// # use zed::Size;
 532    /// let size1 = Size { width: 30, height: 40 };
 533    /// let size2 = Size { width: 50, height: 20 };
 534    /// let min_size = size1.min(&size2);
 535    /// assert_eq!(min_size, Size { width: 30, height: 20 });
 536    /// ```
 537    pub fn min(&self, other: &Self) -> Self {
 538        Size {
 539            width: if self.width >= other.width {
 540                other.width.clone()
 541            } else {
 542                self.width.clone()
 543            },
 544            height: if self.height >= other.height {
 545                other.height.clone()
 546            } else {
 547                self.height.clone()
 548            },
 549        }
 550    }
 551}
 552
 553impl<T> Sub for Size<T>
 554where
 555    T: Sub<Output = T> + Clone + Default + Debug,
 556{
 557    type Output = Size<T>;
 558
 559    fn sub(self, rhs: Self) -> Self::Output {
 560        Size {
 561            width: self.width - rhs.width,
 562            height: self.height - rhs.height,
 563        }
 564    }
 565}
 566
 567impl<T> Add for Size<T>
 568where
 569    T: Add<Output = T> + Clone + Default + Debug,
 570{
 571    type Output = Size<T>;
 572
 573    fn add(self, rhs: Self) -> Self::Output {
 574        Size {
 575            width: self.width + rhs.width,
 576            height: self.height + rhs.height,
 577        }
 578    }
 579}
 580
 581impl<T, Rhs> Mul<Rhs> for Size<T>
 582where
 583    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
 584    Rhs: Clone + Default + Debug,
 585{
 586    type Output = Size<Rhs>;
 587
 588    fn mul(self, rhs: Rhs) -> Self::Output {
 589        Size {
 590            width: self.width * rhs.clone(),
 591            height: self.height * rhs,
 592        }
 593    }
 594}
 595
 596impl<T, S> MulAssign<S> for Size<T>
 597where
 598    T: Mul<S, Output = T> + Clone + Default + Debug,
 599    S: Clone,
 600{
 601    fn mul_assign(&mut self, rhs: S) {
 602        self.width = self.width.clone() * rhs.clone();
 603        self.height = self.height.clone() * rhs;
 604    }
 605}
 606
 607impl<T> Eq for Size<T> where T: Eq + Default + Debug + Clone {}
 608
 609impl<T> Debug for Size<T>
 610where
 611    T: Clone + Default + Debug,
 612{
 613    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 614        write!(f, "Size {{ {:?} × {:?} }}", self.width, self.height)
 615    }
 616}
 617
 618impl<T: Clone + Default + Debug> From<Point<T>> for Size<T> {
 619    fn from(point: Point<T>) -> Self {
 620        Self {
 621            width: point.x,
 622            height: point.y,
 623        }
 624    }
 625}
 626
 627impl From<Size<Pixels>> for Size<DefiniteLength> {
 628    fn from(size: Size<Pixels>) -> Self {
 629        Size {
 630            width: size.width.into(),
 631            height: size.height.into(),
 632        }
 633    }
 634}
 635
 636impl From<Size<Pixels>> for Size<AbsoluteLength> {
 637    fn from(size: Size<Pixels>) -> Self {
 638        Size {
 639            width: size.width.into(),
 640            height: size.height.into(),
 641        }
 642    }
 643}
 644
 645impl Size<Length> {
 646    /// Returns a `Size` with both width and height set to fill the available space.
 647    ///
 648    /// This function creates a `Size` instance where both the width and height are set to `Length::Definite(DefiniteLength::Fraction(1.0))`,
 649    /// which represents 100% of the available space in both dimensions.
 650    ///
 651    /// # Returns
 652    ///
 653    /// A `Size<Length>` that will fill the available space when used in a layout.
 654    pub fn full() -> Self {
 655        Self {
 656            width: relative(1.).into(),
 657            height: relative(1.).into(),
 658        }
 659    }
 660}
 661
 662impl Size<Length> {
 663    /// Returns a `Size` with both width and height set to `auto`, which allows the layout engine to determine the size.
 664    ///
 665    /// This function creates a `Size` instance where both the width and height are set to `Length::Auto`,
 666    /// indicating that their size should be computed based on the layout context, such as the content size or
 667    /// available space.
 668    ///
 669    /// # Returns
 670    ///
 671    /// A `Size<Length>` with width and height set to `Length::Auto`.
 672    pub fn auto() -> Self {
 673        Self {
 674            width: Length::Auto,
 675            height: Length::Auto,
 676        }
 677    }
 678}
 679
 680/// Represents a rectangular area in a 2D space with an origin point and a size.
 681///
 682/// The `Bounds` struct is generic over a type `T` which represents the type of the coordinate system.
 683/// The origin is represented as a `Point<T>` which defines the upper-left corner of the rectangle,
 684/// and the size is represented as a `Size<T>` which defines the width and height of the rectangle.
 685///
 686/// # Examples
 687///
 688/// ```
 689/// # use zed::{Bounds, Point, Size};
 690/// let origin = Point { x: 0, y: 0 };
 691/// let size = Size { width: 10, height: 20 };
 692/// let bounds = Bounds::new(origin, size);
 693///
 694/// assert_eq!(bounds.origin, origin);
 695/// assert_eq!(bounds.size, size);
 696/// ```
 697#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq, Hash)]
 698#[refineable(Debug)]
 699#[repr(C)]
 700pub struct Bounds<T: Clone + Default + Debug> {
 701    /// The origin point of this area.
 702    pub origin: Point<T>,
 703    /// The size of the rectangle.
 704    pub size: Size<T>,
 705}
 706
 707impl Bounds<Pixels> {
 708    /// Generate a centered bounds for the given display or primary display if none is provided
 709    pub fn centered(
 710        display_id: Option<DisplayId>,
 711        size: Size<Pixels>,
 712        cx: &mut AppContext,
 713    ) -> Self {
 714        let display = display_id
 715            .and_then(|id| cx.find_display(id))
 716            .or_else(|| cx.primary_display());
 717
 718        display
 719            .map(|display| {
 720                let center = display.bounds().center();
 721                Bounds {
 722                    origin: point(center.x - size.width / 2., center.y - size.height / 2.),
 723                    size,
 724                }
 725            })
 726            .unwrap_or_else(|| Bounds {
 727                origin: point(px(0.), px(0.)),
 728                size,
 729            })
 730    }
 731
 732    /// Generate maximized bounds for the given display or primary display if none is provided
 733    pub fn maximized(display_id: Option<DisplayId>, cx: &mut AppContext) -> Self {
 734        let display = display_id
 735            .and_then(|id| cx.find_display(id))
 736            .or_else(|| cx.primary_display());
 737
 738        display
 739            .map(|display| display.bounds())
 740            .unwrap_or_else(|| Bounds {
 741                origin: point(px(0.), px(0.)),
 742                size: size(px(1024.), px(768.)),
 743            })
 744    }
 745}
 746
 747impl<T> Bounds<T>
 748where
 749    T: Clone + Debug + Sub<Output = T> + Default,
 750{
 751    /// Constructs a `Bounds` from two corner points: the upper-left and lower-right corners.
 752    ///
 753    /// This function calculates the origin and size of the `Bounds` based on the provided corner points.
 754    /// The origin is set to the upper-left corner, and the size is determined by the difference between
 755    /// the x and y coordinates of the lower-right and upper-left points.
 756    ///
 757    /// # Arguments
 758    ///
 759    /// * `upper_left` - A `Point<T>` representing the upper-left corner of the rectangle.
 760    /// * `lower_right` - A `Point<T>` representing the lower-right corner of the rectangle.
 761    ///
 762    /// # Returns
 763    ///
 764    /// Returns a `Bounds<T>` that encompasses the area defined by the two corner points.
 765    ///
 766    /// # Examples
 767    ///
 768    /// ```
 769    /// # use zed::{Bounds, Point};
 770    /// let upper_left = Point { x: 0, y: 0 };
 771    /// let lower_right = Point { x: 10, y: 10 };
 772    /// let bounds = Bounds::from_corners(upper_left, lower_right);
 773    ///
 774    /// assert_eq!(bounds.origin, upper_left);
 775    /// assert_eq!(bounds.size.width, 10);
 776    /// assert_eq!(bounds.size.height, 10);
 777    /// ```
 778    pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
 779        let origin = Point {
 780            x: upper_left.x.clone(),
 781            y: upper_left.y.clone(),
 782        };
 783        let size = Size {
 784            width: lower_right.x - upper_left.x,
 785            height: lower_right.y - upper_left.y,
 786        };
 787        Bounds { origin, size }
 788    }
 789
 790    /// Creates a new `Bounds` with the specified origin and size.
 791    ///
 792    /// # Arguments
 793    ///
 794    /// * `origin` - A `Point<T>` representing the origin of the bounds.
 795    /// * `size` - A `Size<T>` representing the size of the bounds.
 796    ///
 797    /// # Returns
 798    ///
 799    /// Returns a `Bounds<T>` that has the given origin and size.
 800    pub fn new(origin: Point<T>, size: Size<T>) -> Self {
 801        Bounds { origin, size }
 802    }
 803}
 804
 805impl<T> Bounds<T>
 806where
 807    T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default + Half,
 808{
 809    /// Checks if this `Bounds` intersects with another `Bounds`.
 810    ///
 811    /// Two `Bounds` instances intersect if they overlap in the 2D space they occupy.
 812    /// This method checks if there is any overlapping area between the two bounds.
 813    ///
 814    /// # Arguments
 815    ///
 816    /// * `other` - A reference to another `Bounds` to check for intersection with.
 817    ///
 818    /// # Returns
 819    ///
 820    /// Returns `true` if there is any intersection between the two bounds, `false` otherwise.
 821    ///
 822    /// # Examples
 823    ///
 824    /// ```
 825    /// # use zed::{Bounds, Point, Size};
 826    /// let bounds1 = Bounds {
 827    ///     origin: Point { x: 0, y: 0 },
 828    ///     size: Size { width: 10, height: 10 },
 829    /// };
 830    /// let bounds2 = Bounds {
 831    ///     origin: Point { x: 5, y: 5 },
 832    ///     size: Size { width: 10, height: 10 },
 833    /// };
 834    /// let bounds3 = Bounds {
 835    ///     origin: Point { x: 20, y: 20 },
 836    ///     size: Size { width: 10, height: 10 },
 837    /// };
 838    ///
 839    /// assert_eq!(bounds1.intersects(&bounds2), true); // Overlapping bounds
 840    /// assert_eq!(bounds1.intersects(&bounds3), false); // Non-overlapping bounds
 841    /// ```
 842    pub fn intersects(&self, other: &Bounds<T>) -> bool {
 843        let my_lower_right = self.lower_right();
 844        let their_lower_right = other.lower_right();
 845
 846        self.origin.x < their_lower_right.x
 847            && my_lower_right.x > other.origin.x
 848            && self.origin.y < their_lower_right.y
 849            && my_lower_right.y > other.origin.y
 850    }
 851
 852    /// Dilates the bounds by a specified amount in all directions.
 853    ///
 854    /// This method expands the bounds by the given `amount`, increasing the size
 855    /// and adjusting the origin so that the bounds grow outwards equally in all directions.
 856    /// The resulting bounds will have its width and height increased by twice the `amount`
 857    /// (since it grows in both directions), and the origin will be moved by `-amount`
 858    /// in both the x and y directions.
 859    ///
 860    /// # Arguments
 861    ///
 862    /// * `amount` - The amount by which to dilate the bounds.
 863    ///
 864    /// # Examples
 865    ///
 866    /// ```
 867    /// # use zed::{Bounds, Point, Size};
 868    /// let mut bounds = Bounds {
 869    ///     origin: Point { x: 10, y: 10 },
 870    ///     size: Size { width: 10, height: 10 },
 871    /// };
 872    /// bounds.dilate(5);
 873    /// assert_eq!(bounds, Bounds {
 874    ///     origin: Point { x: 5, y: 5 },
 875    ///     size: Size { width: 20, height: 20 },
 876    /// });
 877    /// ```
 878    pub fn dilate(&mut self, amount: T) {
 879        self.origin.x = self.origin.x.clone() - amount.clone();
 880        self.origin.y = self.origin.y.clone() - amount.clone();
 881        let double_amount = amount.clone() + amount;
 882        self.size.width = self.size.width.clone() + double_amount.clone();
 883        self.size.height = self.size.height.clone() + double_amount;
 884    }
 885
 886    /// Returns the center point of the bounds.
 887    ///
 888    /// Calculates the center by taking the origin's x and y coordinates and adding half the width and height
 889    /// of the bounds, respectively. The center is represented as a `Point<T>` where `T` is the type of the
 890    /// coordinate system.
 891    ///
 892    /// # Returns
 893    ///
 894    /// A `Point<T>` representing the center of the bounds.
 895    ///
 896    /// # Examples
 897    ///
 898    /// ```
 899    /// # use zed::{Bounds, Point, Size};
 900    /// let bounds = Bounds {
 901    ///     origin: Point { x: 0, y: 0 },
 902    ///     size: Size { width: 10, height: 20 },
 903    /// };
 904    /// let center = bounds.center();
 905    /// assert_eq!(center, Point { x: 5, y: 10 });
 906    /// ```
 907    pub fn center(&self) -> Point<T> {
 908        Point {
 909            x: self.origin.x.clone() + self.size.width.clone().half(),
 910            y: self.origin.y.clone() + self.size.height.clone().half(),
 911        }
 912    }
 913
 914    /// Calculates the half perimeter of a rectangle defined by the bounds.
 915    ///
 916    /// The half perimeter is calculated as the sum of the width and the height of the rectangle.
 917    /// This method is generic over the type `T` which must implement the `Sub` trait to allow
 918    /// calculation of the width and height from the bounds' origin and size, as well as the `Add` trait
 919    /// to sum the width and height for the half perimeter.
 920    ///
 921    /// # Examples
 922    ///
 923    /// ```
 924    /// # use zed::{Bounds, Point, Size};
 925    /// let bounds = Bounds {
 926    ///     origin: Point { x: 0, y: 0 },
 927    ///     size: Size { width: 10, height: 20 },
 928    /// };
 929    /// let half_perimeter = bounds.half_perimeter();
 930    /// assert_eq!(half_perimeter, 30);
 931    /// ```
 932    pub fn half_perimeter(&self) -> T {
 933        self.size.width.clone() + self.size.height.clone()
 934    }
 935}
 936
 937impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
 938    /// Calculates the intersection of two `Bounds` objects.
 939    ///
 940    /// This method computes the overlapping region of two `Bounds`. If the bounds do not intersect,
 941    /// the resulting `Bounds` will have a size with width and height of zero.
 942    ///
 943    /// # Arguments
 944    ///
 945    /// * `other` - A reference to another `Bounds` to intersect with.
 946    ///
 947    /// # Returns
 948    ///
 949    /// Returns a `Bounds` representing the intersection area. If there is no intersection,
 950    /// the returned `Bounds` will have a size with width and height of zero.
 951    ///
 952    /// # Examples
 953    ///
 954    /// ```
 955    /// # use zed::{Bounds, Point, Size};
 956    /// let bounds1 = Bounds {
 957    ///     origin: Point { x: 0, y: 0 },
 958    ///     size: Size { width: 10, height: 10 },
 959    /// };
 960    /// let bounds2 = Bounds {
 961    ///     origin: Point { x: 5, y: 5 },
 962    ///     size: Size { width: 10, height: 10 },
 963    /// };
 964    /// let intersection = bounds1.intersect(&bounds2);
 965    ///
 966    /// assert_eq!(intersection, Bounds {
 967    ///     origin: Point { x: 5, y: 5 },
 968    ///     size: Size { width: 5, height: 5 },
 969    /// });
 970    /// ```
 971    pub fn intersect(&self, other: &Self) -> Self {
 972        let upper_left = self.origin.max(&other.origin);
 973        let lower_right = self.lower_right().min(&other.lower_right());
 974        Self::from_corners(upper_left, lower_right)
 975    }
 976
 977    /// Computes the union of two `Bounds`.
 978    ///
 979    /// This method calculates the smallest `Bounds` that contains both the current `Bounds` and the `other` `Bounds`.
 980    /// The resulting `Bounds` will have an origin that is the minimum of the origins of the two `Bounds`,
 981    /// and a size that encompasses the furthest extents of both `Bounds`.
 982    ///
 983    /// # Arguments
 984    ///
 985    /// * `other` - A reference to another `Bounds` to create a union with.
 986    ///
 987    /// # Returns
 988    ///
 989    /// Returns a `Bounds` representing the union of the two `Bounds`.
 990    ///
 991    /// # Examples
 992    ///
 993    /// ```
 994    /// # use zed::{Bounds, Point, Size};
 995    /// let bounds1 = Bounds {
 996    ///     origin: Point { x: 0, y: 0 },
 997    ///     size: Size { width: 10, height: 10 },
 998    /// };
 999    /// let bounds2 = Bounds {
1000    ///     origin: Point { x: 5, y: 5 },
1001    ///     size: Size { width: 15, height: 15 },
1002    /// };
1003    /// let union_bounds = bounds1.union(&bounds2);
1004    ///
1005    /// assert_eq!(union_bounds, Bounds {
1006    ///     origin: Point { x: 0, y: 0 },
1007    ///     size: Size { width: 20, height: 20 },
1008    /// });
1009    /// ```
1010    pub fn union(&self, other: &Self) -> Self {
1011        let top_left = self.origin.min(&other.origin);
1012        let bottom_right = self.lower_right().max(&other.lower_right());
1013        Bounds::from_corners(top_left, bottom_right)
1014    }
1015}
1016
1017impl<T, Rhs> Mul<Rhs> for Bounds<T>
1018where
1019    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
1020    Point<T>: Mul<Rhs, Output = Point<Rhs>>,
1021    Rhs: Clone + Default + Debug,
1022{
1023    type Output = Bounds<Rhs>;
1024
1025    fn mul(self, rhs: Rhs) -> Self::Output {
1026        Bounds {
1027            origin: self.origin * rhs.clone(),
1028            size: self.size * rhs,
1029        }
1030    }
1031}
1032
1033impl<T, S> MulAssign<S> for Bounds<T>
1034where
1035    T: Mul<S, Output = T> + Clone + Default + Debug,
1036    S: Clone,
1037{
1038    fn mul_assign(&mut self, rhs: S) {
1039        self.origin *= rhs.clone();
1040        self.size *= rhs;
1041    }
1042}
1043
1044impl<T, S> Div<S> for Bounds<T>
1045where
1046    Size<T>: Div<S, Output = Size<T>>,
1047    T: Div<S, Output = T> + Default + Clone + Debug,
1048    S: Clone,
1049{
1050    type Output = Self;
1051
1052    fn div(self, rhs: S) -> Self {
1053        Self {
1054            origin: self.origin / rhs.clone(),
1055            size: self.size / rhs,
1056        }
1057    }
1058}
1059
1060impl<T> Bounds<T>
1061where
1062    T: Add<T, Output = T> + Clone + Default + Debug,
1063{
1064    /// Returns the top edge of the bounds.
1065    ///
1066    /// # Returns
1067    ///
1068    /// A value of type `T` representing the y-coordinate of the top edge of the bounds.
1069    pub fn top(&self) -> T {
1070        self.origin.y.clone()
1071    }
1072
1073    /// Returns the bottom edge of the bounds.
1074    ///
1075    /// # Returns
1076    ///
1077    /// A value of type `T` representing the y-coordinate of the bottom edge of the bounds.
1078    pub fn bottom(&self) -> T {
1079        self.origin.y.clone() + self.size.height.clone()
1080    }
1081
1082    /// Returns the left edge of the bounds.
1083    ///
1084    /// # Returns
1085    ///
1086    /// A value of type `T` representing the x-coordinate of the left edge of the bounds.
1087    pub fn left(&self) -> T {
1088        self.origin.x.clone()
1089    }
1090
1091    /// Returns the right edge of the bounds.
1092    ///
1093    /// # Returns
1094    ///
1095    /// A value of type `T` representing the x-coordinate of the right edge of the bounds.
1096    pub fn right(&self) -> T {
1097        self.origin.x.clone() + self.size.width.clone()
1098    }
1099
1100    /// Returns the upper-right corner point of the bounds.
1101    ///
1102    /// # Returns
1103    ///
1104    /// A `Point<T>` representing the upper-right corner of the bounds.
1105    ///
1106    /// # Examples
1107    ///
1108    /// ```
1109    /// # use zed::{Bounds, Point, Size};
1110    /// let bounds = Bounds {
1111    ///     origin: Point { x: 0, y: 0 },
1112    ///     size: Size { width: 10, height: 20 },
1113    /// };
1114    /// let upper_right = bounds.upper_right();
1115    /// assert_eq!(upper_right, Point { x: 10, y: 0 });
1116    /// ```
1117    pub fn upper_right(&self) -> Point<T> {
1118        Point {
1119            x: self.origin.x.clone() + self.size.width.clone(),
1120            y: self.origin.y.clone(),
1121        }
1122    }
1123
1124    /// Returns the lower-right corner point of the bounds.
1125    ///
1126    /// # Returns
1127    ///
1128    /// A `Point<T>` representing the lower-right corner of the bounds.
1129    ///
1130    /// # Examples
1131    ///
1132    /// ```
1133    /// # use zed::{Bounds, Point, Size};
1134    /// let bounds = Bounds {
1135    ///     origin: Point { x: 0, y: 0 },
1136    ///     size: Size { width: 10, height: 20 },
1137    /// };
1138    /// let lower_right = bounds.lower_right();
1139    /// assert_eq!(lower_right, Point { x: 10, y: 20 });
1140    /// ```
1141    pub fn lower_right(&self) -> Point<T> {
1142        Point {
1143            x: self.origin.x.clone() + self.size.width.clone(),
1144            y: self.origin.y.clone() + self.size.height.clone(),
1145        }
1146    }
1147
1148    /// Returns the lower-left corner point of the bounds.
1149    ///
1150    /// # Returns
1151    ///
1152    /// A `Point<T>` representing the lower-left corner of the bounds.
1153    ///
1154    /// # Examples
1155    ///
1156    /// ```
1157    /// # use zed::{Bounds, Point, Size};
1158    /// let bounds = Bounds {
1159    ///     origin: Point { x: 0, y: 0 },
1160    ///     size: Size { width: 10, height: 20 },
1161    /// };
1162    /// let lower_left = bounds.lower_left();
1163    /// assert_eq!(lower_left, Point { x: 0, y: 20 });
1164    /// ```
1165    pub fn lower_left(&self) -> Point<T> {
1166        Point {
1167            x: self.origin.x.clone(),
1168            y: self.origin.y.clone() + self.size.height.clone(),
1169        }
1170    }
1171}
1172
1173impl<T> Bounds<T>
1174where
1175    T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
1176{
1177    /// Checks if the given point is within the bounds.
1178    ///
1179    /// This method determines whether a point lies inside the rectangle defined by the bounds,
1180    /// including the edges. The point is considered inside if its x-coordinate is greater than
1181    /// or equal to the left edge and less than or equal to the right edge, and its y-coordinate
1182    /// is greater than or equal to the top edge and less than or equal to the bottom edge of the bounds.
1183    ///
1184    /// # Arguments
1185    ///
1186    /// * `point` - A reference to a `Point<T>` that represents the point to check.
1187    ///
1188    /// # Returns
1189    ///
1190    /// Returns `true` if the point is within the bounds, `false` otherwise.
1191    ///
1192    /// # Examples
1193    ///
1194    /// ```
1195    /// # use zed::{Point, Bounds};
1196    /// let bounds = Bounds {
1197    ///     origin: Point { x: 0, y: 0 },
1198    ///     size: Size { width: 10, height: 10 },
1199    /// };
1200    /// let inside_point = Point { x: 5, y: 5 };
1201    /// let outside_point = Point { x: 15, y: 15 };
1202    ///
1203    /// assert!(bounds.contains_point(&inside_point));
1204    /// assert!(!bounds.contains_point(&outside_point));
1205    /// ```
1206    pub fn contains(&self, point: &Point<T>) -> bool {
1207        point.x >= self.origin.x
1208            && point.x <= self.origin.x.clone() + self.size.width.clone()
1209            && point.y >= self.origin.y
1210            && point.y <= self.origin.y.clone() + self.size.height.clone()
1211    }
1212
1213    /// Applies a function to the origin and size of the bounds, producing a new `Bounds<U>`.
1214    ///
1215    /// This method allows for converting a `Bounds<T>` to a `Bounds<U>` by specifying a closure
1216    /// that defines how to convert between the two types. The closure is applied to the `origin` and
1217    /// `size` fields, resulting in new bounds of the desired type.
1218    ///
1219    /// # Arguments
1220    ///
1221    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
1222    ///
1223    /// # Returns
1224    ///
1225    /// Returns a new `Bounds<U>` with the origin and size mapped by the provided function.
1226    ///
1227    /// # Examples
1228    ///
1229    /// ```
1230    /// # use zed::{Bounds, Point, Size};
1231    /// let bounds = Bounds {
1232    ///     origin: Point { x: 10.0, y: 10.0 },
1233    ///     size: Size { width: 10.0, height: 20.0 },
1234    /// };
1235    /// let new_bounds = bounds.map(|value| value as f64 * 1.5);
1236    ///
1237    /// assert_eq!(new_bounds, Bounds {
1238    ///     origin: Point { x: 15.0, y: 15.0 },
1239    ///     size: Size { width: 15.0, height: 30.0 },
1240    /// });
1241    /// ```
1242    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
1243    where
1244        U: Clone + Default + Debug,
1245    {
1246        Bounds {
1247            origin: self.origin.map(&f),
1248            size: self.size.map(f),
1249        }
1250    }
1251
1252    /// Applies a function to the origin  of the bounds, producing a new `Bounds` with the new origin
1253    ///
1254    /// # Examples
1255    ///
1256    /// ```
1257    /// # use zed::{Bounds, Point, Size};
1258    /// let bounds = Bounds {
1259    ///     origin: Point { x: 10.0, y: 10.0 },
1260    ///     size: Size { width: 10.0, height: 20.0 },
1261    /// };
1262    /// let new_bounds = bounds.map_origin(|value| value * 1.5);
1263    ///
1264    /// assert_eq!(new_bounds, Bounds {
1265    ///     origin: Point { x: 15.0, y: 15.0 },
1266    ///     size: Size { width: 10.0, height: 20.0 },
1267    /// });
1268    /// ```
1269    pub fn map_origin(self, f: impl Fn(Point<T>) -> Point<T>) -> Bounds<T> {
1270        Bounds {
1271            origin: f(self.origin),
1272            size: self.size,
1273        }
1274    }
1275}
1276
1277/// Checks if the bounds represent an empty area.
1278///
1279/// # Returns
1280///
1281/// Returns `true` if either the width or the height of the bounds is less than or equal to zero, indicating an empty area.
1282impl<T: PartialOrd + Default + Debug + Clone> Bounds<T> {
1283    /// Checks if the bounds represent an empty area.
1284    ///
1285    /// # Returns
1286    ///
1287    /// Returns `true` if either the width or the height of the bounds is less than or equal to zero, indicating an empty area.
1288    pub fn is_empty(&self) -> bool {
1289        self.size.width <= T::default() || self.size.height <= T::default()
1290    }
1291}
1292
1293impl Size<DevicePixels> {
1294    /// Converts the size from physical to logical pixels.
1295    pub(crate) fn to_pixels(self, scale_factor: f32) -> Size<Pixels> {
1296        size(
1297            px(self.width.0 as f32 / scale_factor),
1298            px(self.height.0 as f32 / scale_factor),
1299        )
1300    }
1301}
1302
1303impl Size<Pixels> {
1304    /// Converts the size from physical to logical pixels.
1305    pub(crate) fn to_device_pixels(self, scale_factor: f32) -> Size<DevicePixels> {
1306        size(
1307            DevicePixels((self.width.0 * scale_factor) as i32),
1308            DevicePixels((self.height.0 * scale_factor) as i32),
1309        )
1310    }
1311}
1312
1313impl Bounds<Pixels> {
1314    /// Scales the bounds by a given factor, typically used to adjust for display scaling.
1315    ///
1316    /// This method multiplies the origin and size of the bounds by the provided scaling factor,
1317    /// resulting in a new `Bounds<ScaledPixels>` that is proportionally larger or smaller
1318    /// depending on the scaling factor. This can be used to ensure that the bounds are properly
1319    /// scaled for different display densities.
1320    ///
1321    /// # Arguments
1322    ///
1323    /// * `factor` - The scaling factor to apply to the origin and size, typically the display's scaling factor.
1324    ///
1325    /// # Returns
1326    ///
1327    /// Returns a new `Bounds<ScaledPixels>` that represents the scaled bounds.
1328    ///
1329    /// # Examples
1330    ///
1331    /// ```
1332    /// # use zed::{Bounds, Point, Size, Pixels};
1333    /// let bounds = Bounds {
1334    ///     origin: Point { x: Pixels(10.0), y: Pixels(20.0) },
1335    ///     size: Size { width: Pixels(30.0), height: Pixels(40.0) },
1336    /// };
1337    /// let display_scale_factor = 2.0;
1338    /// let scaled_bounds = bounds.scale(display_scale_factor);
1339    /// assert_eq!(scaled_bounds, Bounds {
1340    ///     origin: Point { x: ScaledPixels(20.0), y: ScaledPixels(40.0) },
1341    ///     size: Size { width: ScaledPixels(60.0), height: ScaledPixels(80.0) },
1342    /// });
1343    /// ```
1344    pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
1345        Bounds {
1346            origin: self.origin.scale(factor),
1347            size: self.size.scale(factor),
1348        }
1349    }
1350
1351    /// Convert the bounds from logical pixels to physical pixels
1352    pub fn to_device_pixels(&self, factor: f32) -> Bounds<DevicePixels> {
1353        Bounds {
1354            origin: point(
1355                DevicePixels((self.origin.x.0 * factor) as i32),
1356                DevicePixels((self.origin.y.0 * factor) as i32),
1357            ),
1358            size: self.size.to_device_pixels(factor),
1359        }
1360    }
1361}
1362
1363impl Bounds<DevicePixels> {
1364    /// Convert the bounds from physical pixels to logical pixels
1365    pub fn to_pixels(self, scale_factor: f32) -> Bounds<Pixels> {
1366        Bounds {
1367            origin: point(
1368                px(self.origin.x.0 as f32 / scale_factor),
1369                px(self.origin.y.0 as f32 / scale_factor),
1370            ),
1371            size: self.size.to_pixels(scale_factor),
1372        }
1373    }
1374}
1375
1376impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
1377
1378/// Represents the edges of a box in a 2D space, such as padding or margin.
1379///
1380/// Each field represents the size of the edge on one side of the box: `top`, `right`, `bottom`, and `left`.
1381///
1382/// # Examples
1383///
1384/// ```
1385/// # use zed::Edges;
1386/// let edges = Edges {
1387///     top: 10.0,
1388///     right: 20.0,
1389///     bottom: 30.0,
1390///     left: 40.0,
1391/// };
1392///
1393/// assert_eq!(edges.top, 10.0);
1394/// assert_eq!(edges.right, 20.0);
1395/// assert_eq!(edges.bottom, 30.0);
1396/// assert_eq!(edges.left, 40.0);
1397/// ```
1398#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1399#[refineable(Debug)]
1400#[repr(C)]
1401pub struct Edges<T: Clone + Default + Debug> {
1402    /// The size of the top edge.
1403    pub top: T,
1404    /// The size of the right edge.
1405    pub right: T,
1406    /// The size of the bottom edge.
1407    pub bottom: T,
1408    /// The size of the left edge.
1409    pub left: T,
1410}
1411
1412impl<T> Mul for Edges<T>
1413where
1414    T: Mul<Output = T> + Clone + Default + Debug,
1415{
1416    type Output = Self;
1417
1418    fn mul(self, rhs: Self) -> Self::Output {
1419        Self {
1420            top: self.top.clone() * rhs.top,
1421            right: self.right.clone() * rhs.right,
1422            bottom: self.bottom.clone() * rhs.bottom,
1423            left: self.left.clone() * rhs.left,
1424        }
1425    }
1426}
1427
1428impl<T, S> MulAssign<S> for Edges<T>
1429where
1430    T: Mul<S, Output = T> + Clone + Default + Debug,
1431    S: Clone,
1432{
1433    fn mul_assign(&mut self, rhs: S) {
1434        self.top = self.top.clone() * rhs.clone();
1435        self.right = self.right.clone() * rhs.clone();
1436        self.bottom = self.bottom.clone() * rhs.clone();
1437        self.left = self.left.clone() * rhs;
1438    }
1439}
1440
1441impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
1442
1443impl<T: Clone + Default + Debug> Edges<T> {
1444    /// Constructs `Edges` where all sides are set to the same specified value.
1445    ///
1446    /// This function creates an `Edges` instance with the `top`, `right`, `bottom`, and `left` fields all initialized
1447    /// to the same value provided as an argument. This is useful when you want to have uniform edges around a box,
1448    /// such as padding or margin with the same size on all sides.
1449    ///
1450    /// # Arguments
1451    ///
1452    /// * `value` - The value to set for all four sides of the edges.
1453    ///
1454    /// # Returns
1455    ///
1456    /// An `Edges` instance with all sides set to the given value.
1457    ///
1458    /// # Examples
1459    ///
1460    /// ```
1461    /// # use zed::Edges;
1462    /// let uniform_edges = Edges::all(10.0);
1463    /// assert_eq!(uniform_edges.top, 10.0);
1464    /// assert_eq!(uniform_edges.right, 10.0);
1465    /// assert_eq!(uniform_edges.bottom, 10.0);
1466    /// assert_eq!(uniform_edges.left, 10.0);
1467    /// ```
1468    pub fn all(value: T) -> Self {
1469        Self {
1470            top: value.clone(),
1471            right: value.clone(),
1472            bottom: value.clone(),
1473            left: value,
1474        }
1475    }
1476
1477    /// Applies a function to each field of the `Edges`, producing a new `Edges<U>`.
1478    ///
1479    /// This method allows for converting an `Edges<T>` to an `Edges<U>` by specifying a closure
1480    /// that defines how to convert between the two types. The closure is applied to each field
1481    /// (`top`, `right`, `bottom`, `left`), resulting in new edges of the desired type.
1482    ///
1483    /// # Arguments
1484    ///
1485    /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1486    ///
1487    /// # Returns
1488    ///
1489    /// Returns a new `Edges<U>` with each field mapped by the provided function.
1490    ///
1491    /// # Examples
1492    ///
1493    /// ```
1494    /// # use zed::Edges;
1495    /// let edges = Edges { top: 10, right: 20, bottom: 30, left: 40 };
1496    /// let edges_float = edges.map(|&value| value as f32 * 1.1);
1497    /// assert_eq!(edges_float, Edges { top: 11.0, right: 22.0, bottom: 33.0, left: 44.0 });
1498    /// ```
1499    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
1500    where
1501        U: Clone + Default + Debug,
1502    {
1503        Edges {
1504            top: f(&self.top),
1505            right: f(&self.right),
1506            bottom: f(&self.bottom),
1507            left: f(&self.left),
1508        }
1509    }
1510
1511    /// Checks if any of the edges satisfy a given predicate.
1512    ///
1513    /// This method applies a predicate function to each field of the `Edges` and returns `true` if any field satisfies the predicate.
1514    ///
1515    /// # Arguments
1516    ///
1517    /// * `predicate` - A closure that takes a reference to a value of type `T` and returns a `bool`.
1518    ///
1519    /// # Returns
1520    ///
1521    /// Returns `true` if the predicate returns `true` for any of the edge values, `false` otherwise.
1522    ///
1523    /// # Examples
1524    ///
1525    /// ```
1526    /// # use zed::Edges;
1527    /// let edges = Edges {
1528    ///     top: 10,
1529    ///     right: 0,
1530    ///     bottom: 5,
1531    ///     left: 0,
1532    /// };
1533    ///
1534    /// assert!(edges.any(|value| *value == 0));
1535    /// assert!(edges.any(|value| *value > 0));
1536    /// assert!(!edges.any(|value| *value > 10));
1537    /// ```
1538    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
1539        predicate(&self.top)
1540            || predicate(&self.right)
1541            || predicate(&self.bottom)
1542            || predicate(&self.left)
1543    }
1544}
1545
1546impl Edges<Length> {
1547    /// Sets the edges of the `Edges` struct to `auto`, which is a special value that allows the layout engine to automatically determine the size of the edges.
1548    ///
1549    /// This is typically used in layout contexts where the exact size of the edges is not important, or when the size should be calculated based on the content or container.
1550    ///
1551    /// # Returns
1552    ///
1553    /// Returns an `Edges<Length>` with all edges set to `Length::Auto`.
1554    ///
1555    /// # Examples
1556    ///
1557    /// ```
1558    /// # use zed::Edges;
1559    /// let auto_edges = Edges::auto();
1560    /// assert_eq!(auto_edges.top, Length::Auto);
1561    /// assert_eq!(auto_edges.right, Length::Auto);
1562    /// assert_eq!(auto_edges.bottom, Length::Auto);
1563    /// assert_eq!(auto_edges.left, Length::Auto);
1564    /// ```
1565    pub fn auto() -> Self {
1566        Self {
1567            top: Length::Auto,
1568            right: Length::Auto,
1569            bottom: Length::Auto,
1570            left: Length::Auto,
1571        }
1572    }
1573
1574    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1575    ///
1576    /// This is typically used when you want to specify that a box (like a padding or margin area)
1577    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1578    ///
1579    /// # Returns
1580    ///
1581    /// Returns an `Edges<Length>` with all edges set to zero length.
1582    ///
1583    /// # Examples
1584    ///
1585    /// ```
1586    /// # use zed::Edges;
1587    /// let no_edges = Edges::zero();
1588    /// assert_eq!(no_edges.top, Length::Definite(DefiniteLength::from(Pixels(0.))));
1589    /// assert_eq!(no_edges.right, Length::Definite(DefiniteLength::from(Pixels(0.))));
1590    /// assert_eq!(no_edges.bottom, Length::Definite(DefiniteLength::from(Pixels(0.))));
1591    /// assert_eq!(no_edges.left, Length::Definite(DefiniteLength::from(Pixels(0.))));
1592    /// ```
1593    pub fn zero() -> Self {
1594        Self {
1595            top: px(0.).into(),
1596            right: px(0.).into(),
1597            bottom: px(0.).into(),
1598            left: px(0.).into(),
1599        }
1600    }
1601}
1602
1603impl Edges<DefiniteLength> {
1604    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1605    ///
1606    /// This is typically used when you want to specify that a box (like a padding or margin area)
1607    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1608    ///
1609    /// # Returns
1610    ///
1611    /// Returns an `Edges<DefiniteLength>` with all edges set to zero length.
1612    ///
1613    /// # Examples
1614    ///
1615    /// ```
1616    /// # use zed::Edges;
1617    /// let no_edges = Edges::zero();
1618    /// assert_eq!(no_edges.top, DefiniteLength::from(zed::px(0.)));
1619    /// assert_eq!(no_edges.right, DefiniteLength::from(zed::px(0.)));
1620    /// assert_eq!(no_edges.bottom, DefiniteLength::from(zed::px(0.)));
1621    /// assert_eq!(no_edges.left, DefiniteLength::from(zed::px(0.)));
1622    /// ```
1623    pub fn zero() -> Self {
1624        Self {
1625            top: px(0.).into(),
1626            right: px(0.).into(),
1627            bottom: px(0.).into(),
1628            left: px(0.).into(),
1629        }
1630    }
1631
1632    /// Converts the `DefiniteLength` to `Pixels` based on the parent size and the REM size.
1633    ///
1634    /// This method allows for a `DefiniteLength` value to be converted into pixels, taking into account
1635    /// the size of the parent element (for percentage-based lengths) and the size of a rem unit (for rem-based lengths).
1636    ///
1637    /// # Arguments
1638    ///
1639    /// * `parent_size` - `Size<AbsoluteLength>` representing the size of the parent element.
1640    /// * `rem_size` - `Pixels` representing the size of one REM unit.
1641    ///
1642    /// # Returns
1643    ///
1644    /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1645    ///
1646    /// # Examples
1647    ///
1648    /// ```
1649    /// # use zed::{Edges, DefiniteLength, px, AbsoluteLength, Size};
1650    /// let edges = Edges {
1651    ///     top: DefiniteLength::Absolute(AbsoluteLength::Pixels(px(10.0))),
1652    ///     right: DefiniteLength::Fraction(0.5),
1653    ///     bottom: DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0))),
1654    ///     left: DefiniteLength::Fraction(0.25),
1655    /// };
1656    /// let parent_size = Size {
1657    ///     width: AbsoluteLength::Pixels(px(200.0)),
1658    ///     height: AbsoluteLength::Pixels(px(100.0)),
1659    /// };
1660    /// let rem_size = px(16.0);
1661    /// let edges_in_pixels = edges.to_pixels(parent_size, rem_size);
1662    ///
1663    /// assert_eq!(edges_in_pixels.top, px(10.0)); // Absolute length in pixels
1664    /// assert_eq!(edges_in_pixels.right, px(100.0)); // 50% of parent width
1665    /// assert_eq!(edges_in_pixels.bottom, px(32.0)); // 2 rems
1666    /// assert_eq!(edges_in_pixels.left, px(50.0)); // 25% of parent width
1667    /// ```
1668    pub fn to_pixels(&self, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
1669        Edges {
1670            top: self.top.to_pixels(parent_size.height, rem_size),
1671            right: self.right.to_pixels(parent_size.width, rem_size),
1672            bottom: self.bottom.to_pixels(parent_size.height, rem_size),
1673            left: self.left.to_pixels(parent_size.width, rem_size),
1674        }
1675    }
1676}
1677
1678impl Edges<AbsoluteLength> {
1679    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1680    ///
1681    /// This is typically used when you want to specify that a box (like a padding or margin area)
1682    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1683    ///
1684    /// # Returns
1685    ///
1686    /// Returns an `Edges<AbsoluteLength>` with all edges set to zero length.
1687    ///
1688    /// # Examples
1689    ///
1690    /// ```
1691    /// # use zed::Edges;
1692    /// let no_edges = Edges::zero();
1693    /// assert_eq!(no_edges.top, AbsoluteLength::Pixels(Pixels(0.0)));
1694    /// assert_eq!(no_edges.right, AbsoluteLength::Pixels(Pixels(0.0)));
1695    /// assert_eq!(no_edges.bottom, AbsoluteLength::Pixels(Pixels(0.0)));
1696    /// assert_eq!(no_edges.left, AbsoluteLength::Pixels(Pixels(0.0)));
1697    /// ```
1698    pub fn zero() -> Self {
1699        Self {
1700            top: px(0.).into(),
1701            right: px(0.).into(),
1702            bottom: px(0.).into(),
1703            left: px(0.).into(),
1704        }
1705    }
1706
1707    /// Converts the `AbsoluteLength` to `Pixels` based on the `rem_size`.
1708    ///
1709    /// If the `AbsoluteLength` is already in pixels, it simply returns the corresponding `Pixels` value.
1710    /// If the `AbsoluteLength` is in rems, it multiplies the number of rems by the `rem_size` to convert it to pixels.
1711    ///
1712    /// # Arguments
1713    ///
1714    /// * `rem_size` - The size of one rem unit in pixels.
1715    ///
1716    /// # Returns
1717    ///
1718    /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1719    ///
1720    /// # Examples
1721    ///
1722    /// ```
1723    /// # use zed::{Edges, AbsoluteLength, Pixels, px};
1724    /// let edges = Edges {
1725    ///     top: AbsoluteLength::Pixels(px(10.0)),
1726    ///     right: AbsoluteLength::Rems(rems(1.0)),
1727    ///     bottom: AbsoluteLength::Pixels(px(20.0)),
1728    ///     left: AbsoluteLength::Rems(rems(2.0)),
1729    /// };
1730    /// let rem_size = px(16.0);
1731    /// let edges_in_pixels = edges.to_pixels(rem_size);
1732    ///
1733    /// assert_eq!(edges_in_pixels.top, px(10.0)); // Already in pixels
1734    /// assert_eq!(edges_in_pixels.right, px(16.0)); // 1 rem converted to pixels
1735    /// assert_eq!(edges_in_pixels.bottom, px(20.0)); // Already in pixels
1736    /// assert_eq!(edges_in_pixels.left, px(32.0)); // 2 rems converted to pixels
1737    /// ```
1738    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
1739        Edges {
1740            top: self.top.to_pixels(rem_size),
1741            right: self.right.to_pixels(rem_size),
1742            bottom: self.bottom.to_pixels(rem_size),
1743            left: self.left.to_pixels(rem_size),
1744        }
1745    }
1746}
1747
1748impl Edges<Pixels> {
1749    /// Scales the `Edges<Pixels>` by a given factor, returning `Edges<ScaledPixels>`.
1750    ///
1751    /// This method is typically used for adjusting the edge sizes for different display densities or scaling factors.
1752    ///
1753    /// # Arguments
1754    ///
1755    /// * `factor` - The scaling factor to apply to each edge.
1756    ///
1757    /// # Returns
1758    ///
1759    /// Returns a new `Edges<ScaledPixels>` where each edge is the result of scaling the original edge by the given factor.
1760    ///
1761    /// # Examples
1762    ///
1763    /// ```
1764    /// # use zed::{Edges, Pixels};
1765    /// let edges = Edges {
1766    ///     top: Pixels(10.0),
1767    ///     right: Pixels(20.0),
1768    ///     bottom: Pixels(30.0),
1769    ///     left: Pixels(40.0),
1770    /// };
1771    /// let scaled_edges = edges.scale(2.0);
1772    /// assert_eq!(scaled_edges.top, ScaledPixels(20.0));
1773    /// assert_eq!(scaled_edges.right, ScaledPixels(40.0));
1774    /// assert_eq!(scaled_edges.bottom, ScaledPixels(60.0));
1775    /// assert_eq!(scaled_edges.left, ScaledPixels(80.0));
1776    /// ```
1777    pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
1778        Edges {
1779            top: self.top.scale(factor),
1780            right: self.right.scale(factor),
1781            bottom: self.bottom.scale(factor),
1782            left: self.left.scale(factor),
1783        }
1784    }
1785
1786    /// Returns the maximum value of any edge.
1787    ///
1788    /// # Returns
1789    ///
1790    /// The maximum `Pixels` value among all four edges.
1791    pub fn max(&self) -> Pixels {
1792        self.top.max(self.right).max(self.bottom).max(self.left)
1793    }
1794}
1795
1796impl From<f32> for Edges<Pixels> {
1797    fn from(val: f32) -> Self {
1798        Edges {
1799            top: val.into(),
1800            right: val.into(),
1801            bottom: val.into(),
1802            left: val.into(),
1803        }
1804    }
1805}
1806
1807/// Represents the corners of a box in a 2D space, such as border radius.
1808///
1809/// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`.
1810#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1811#[refineable(Debug)]
1812#[repr(C)]
1813pub struct Corners<T: Clone + Default + Debug> {
1814    /// The value associated with the top left corner.
1815    pub top_left: T,
1816    /// The value associated with the top right corner.
1817    pub top_right: T,
1818    /// The value associated with the bottom right corner.
1819    pub bottom_right: T,
1820    /// The value associated with the bottom left corner.
1821    pub bottom_left: T,
1822}
1823
1824impl<T> Corners<T>
1825where
1826    T: Clone + Default + Debug,
1827{
1828    /// Constructs `Corners` where all sides are set to the same specified value.
1829    ///
1830    /// This function creates a `Corners` instance with the `top_left`, `top_right`, `bottom_right`, and `bottom_left` fields all initialized
1831    /// to the same value provided as an argument. This is useful when you want to have uniform corners around a box,
1832    /// such as a uniform border radius on a rectangle.
1833    ///
1834    /// # Arguments
1835    ///
1836    /// * `value` - The value to set for all four corners.
1837    ///
1838    /// # Returns
1839    ///
1840    /// An `Corners` instance with all corners set to the given value.
1841    ///
1842    /// # Examples
1843    ///
1844    /// ```
1845    /// # use zed::Corners;
1846    /// let uniform_corners = Corners::all(5.0);
1847    /// assert_eq!(uniform_corners.top_left, 5.0);
1848    /// assert_eq!(uniform_corners.top_right, 5.0);
1849    /// assert_eq!(uniform_corners.bottom_right, 5.0);
1850    /// assert_eq!(uniform_corners.bottom_left, 5.0);
1851    /// ```
1852    pub fn all(value: T) -> Self {
1853        Self {
1854            top_left: value.clone(),
1855            top_right: value.clone(),
1856            bottom_right: value.clone(),
1857            bottom_left: value,
1858        }
1859    }
1860}
1861
1862impl Corners<AbsoluteLength> {
1863    /// Converts the `AbsoluteLength` to `Pixels` based on the provided size and rem size, ensuring the resulting
1864    /// `Pixels` do not exceed half of the maximum of the provided size's width and height.
1865    ///
1866    /// This method is particularly useful when dealing with corner radii, where the radius in pixels should not
1867    /// exceed half the size of the box it applies to, to avoid the corners overlapping.
1868    ///
1869    /// # Arguments
1870    ///
1871    /// * `size` - The `Size<Pixels>` against which the maximum allowable radius is determined.
1872    /// * `rem_size` - The size of one REM unit in pixels, used for conversion if the `AbsoluteLength` is in REMs.
1873    ///
1874    /// # Returns
1875    ///
1876    /// Returns a `Corners<Pixels>` instance with each corner's length converted to pixels and clamped to the
1877    /// maximum allowable radius based on the provided size.
1878    ///
1879    /// # Examples
1880    ///
1881    /// ```
1882    /// # use zed::{Corners, AbsoluteLength, Pixels, Size};
1883    /// let corners = Corners {
1884    ///     top_left: AbsoluteLength::Pixels(Pixels(15.0)),
1885    ///     top_right: AbsoluteLength::Rems(Rems(1.0)),
1886    ///     bottom_right: AbsoluteLength::Pixels(Pixels(20.0)),
1887    ///     bottom_left: AbsoluteLength::Rems(Rems(2.0)),
1888    /// };
1889    /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
1890    /// let rem_size = Pixels(16.0);
1891    /// let corners_in_pixels = corners.to_pixels(size, rem_size);
1892    ///
1893    /// // The resulting corners should not exceed half the size of the smallest dimension (50.0 / 2.0 = 25.0).
1894    /// assert_eq!(corners_in_pixels.top_left, Pixels(15.0));
1895    /// assert_eq!(corners_in_pixels.top_right, Pixels(16.0)); // 1 rem converted to pixels
1896    /// assert_eq!(corners_in_pixels.bottom_right, Pixels(20.0).min(Pixels(25.0))); // Clamped to 25.0
1897    /// assert_eq!(corners_in_pixels.bottom_left, Pixels(32.0).min(Pixels(25.0))); // 2 rems converted to pixels and clamped
1898    /// ```
1899    pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
1900        let max = size.width.max(size.height) / 2.;
1901        Corners {
1902            top_left: self.top_left.to_pixels(rem_size).min(max),
1903            top_right: self.top_right.to_pixels(rem_size).min(max),
1904            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
1905            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
1906        }
1907    }
1908}
1909
1910impl Corners<Pixels> {
1911    /// Scales the `Corners<Pixels>` by a given factor, returning `Corners<ScaledPixels>`.
1912    ///
1913    /// This method is typically used for adjusting the corner sizes for different display densities or scaling factors.
1914    ///
1915    /// # Arguments
1916    ///
1917    /// * `factor` - The scaling factor to apply to each corner.
1918    ///
1919    /// # Returns
1920    ///
1921    /// Returns a new `Corners<ScaledPixels>` where each corner is the result of scaling the original corner by the given factor.
1922    ///
1923    /// # Examples
1924    ///
1925    /// ```
1926    /// # use zed::{Corners, Pixels};
1927    /// let corners = Corners {
1928    ///     top_left: Pixels(10.0),
1929    ///     top_right: Pixels(20.0),
1930    ///     bottom_right: Pixels(30.0),
1931    ///     bottom_left: Pixels(40.0),
1932    /// };
1933    /// let scaled_corners = corners.scale(2.0);
1934    /// assert_eq!(scaled_corners.top_left, ScaledPixels(20.0));
1935    /// assert_eq!(scaled_corners.top_right, ScaledPixels(40.0));
1936    /// assert_eq!(scaled_corners.bottom_right, ScaledPixels(60.0));
1937    /// assert_eq!(scaled_corners.bottom_left, ScaledPixels(80.0));
1938    /// ```
1939    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
1940        Corners {
1941            top_left: self.top_left.scale(factor),
1942            top_right: self.top_right.scale(factor),
1943            bottom_right: self.bottom_right.scale(factor),
1944            bottom_left: self.bottom_left.scale(factor),
1945        }
1946    }
1947
1948    /// Returns the maximum value of any corner.
1949    ///
1950    /// # Returns
1951    ///
1952    /// The maximum `Pixels` value among all four corners.
1953    pub fn max(&self) -> Pixels {
1954        self.top_left
1955            .max(self.top_right)
1956            .max(self.bottom_right)
1957            .max(self.bottom_left)
1958    }
1959}
1960
1961impl<T: Clone + Default + Debug> Corners<T> {
1962    /// Applies a function to each field of the `Corners`, producing a new `Corners<U>`.
1963    ///
1964    /// This method allows for converting a `Corners<T>` to a `Corners<U>` by specifying a closure
1965    /// that defines how to convert between the two types. The closure is applied to each field
1966    /// (`top_left`, `top_right`, `bottom_right`, `bottom_left`), resulting in new corners of the desired type.
1967    ///
1968    /// # Arguments
1969    ///
1970    /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1971    ///
1972    /// # Returns
1973    ///
1974    /// Returns a new `Corners<U>` with each field mapped by the provided function.
1975    ///
1976    /// # Examples
1977    ///
1978    /// ```
1979    /// # use zed::{Corners, Pixels};
1980    /// let corners = Corners {
1981    ///     top_left: Pixels(10.0),
1982    ///     top_right: Pixels(20.0),
1983    ///     bottom_right: Pixels(30.0),
1984    ///     bottom_left: Pixels(40.0),
1985    /// };
1986    /// let corners_in_rems = corners.map(|&px| Rems(px.0 / 16.0));
1987    /// assert_eq!(corners_in_rems, Corners {
1988    ///     top_left: Rems(0.625),
1989    ///     top_right: Rems(1.25),
1990    ///     bottom_right: Rems(1.875),
1991    ///     bottom_left: Rems(2.5),
1992    /// });
1993    /// ```
1994    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
1995    where
1996        U: Clone + Default + Debug,
1997    {
1998        Corners {
1999            top_left: f(&self.top_left),
2000            top_right: f(&self.top_right),
2001            bottom_right: f(&self.bottom_right),
2002            bottom_left: f(&self.bottom_left),
2003        }
2004    }
2005}
2006
2007impl<T> Mul for Corners<T>
2008where
2009    T: Mul<Output = T> + Clone + Default + Debug,
2010{
2011    type Output = Self;
2012
2013    fn mul(self, rhs: Self) -> Self::Output {
2014        Self {
2015            top_left: self.top_left.clone() * rhs.top_left,
2016            top_right: self.top_right.clone() * rhs.top_right,
2017            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
2018            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
2019        }
2020    }
2021}
2022
2023impl<T, S> MulAssign<S> for Corners<T>
2024where
2025    T: Mul<S, Output = T> + Clone + Default + Debug,
2026    S: Clone,
2027{
2028    fn mul_assign(&mut self, rhs: S) {
2029        self.top_left = self.top_left.clone() * rhs.clone();
2030        self.top_right = self.top_right.clone() * rhs.clone();
2031        self.bottom_right = self.bottom_right.clone() * rhs.clone();
2032        self.bottom_left = self.bottom_left.clone() * rhs;
2033    }
2034}
2035
2036impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
2037
2038impl From<f32> for Corners<Pixels> {
2039    fn from(val: f32) -> Self {
2040        Corners {
2041            top_left: val.into(),
2042            top_right: val.into(),
2043            bottom_right: val.into(),
2044            bottom_left: val.into(),
2045        }
2046    }
2047}
2048
2049impl From<Pixels> for Corners<Pixels> {
2050    fn from(val: Pixels) -> Self {
2051        Corners {
2052            top_left: val,
2053            top_right: val,
2054            bottom_right: val,
2055            bottom_left: val,
2056        }
2057    }
2058}
2059
2060/// Represents an angle in Radians
2061#[derive(
2062    Clone,
2063    Copy,
2064    Default,
2065    Add,
2066    AddAssign,
2067    Sub,
2068    SubAssign,
2069    Neg,
2070    Div,
2071    DivAssign,
2072    PartialEq,
2073    Serialize,
2074    Deserialize,
2075    Debug,
2076)]
2077#[repr(transparent)]
2078pub struct Radians(pub f32);
2079
2080/// Create a `Radian` from a raw value
2081pub fn radians(value: f32) -> Radians {
2082    Radians(value)
2083}
2084
2085/// A type representing a percentage value.
2086#[derive(
2087    Clone,
2088    Copy,
2089    Default,
2090    Add,
2091    AddAssign,
2092    Sub,
2093    SubAssign,
2094    Neg,
2095    Div,
2096    DivAssign,
2097    PartialEq,
2098    Serialize,
2099    Deserialize,
2100    Debug,
2101)]
2102#[repr(transparent)]
2103pub struct Percentage(pub f32);
2104
2105/// Generate a `Radian` from a percentage of a full circle.
2106pub fn percentage(value: f32) -> Percentage {
2107    debug_assert!(
2108        value >= 0.0 && value <= 1.0,
2109        "Percentage must be between 0 and 1"
2110    );
2111    Percentage(value)
2112}
2113
2114impl From<Percentage> for Radians {
2115    fn from(value: Percentage) -> Self {
2116        radians(value.0 * std::f32::consts::PI * 2.0)
2117    }
2118}
2119
2120/// Represents a length in pixels, the base unit of measurement in the UI framework.
2121///
2122/// `Pixels` is a value type that represents an absolute length in pixels, which is used
2123/// for specifying sizes, positions, and distances in the UI. It is the fundamental unit
2124/// of measurement for all visual elements and layout calculations.
2125///
2126/// The inner value is an `f32`, allowing for sub-pixel precision which can be useful for
2127/// anti-aliasing and animations. However, when applied to actual pixel grids, the value
2128/// is typically rounded to the nearest integer.
2129///
2130/// # Examples
2131///
2132/// ```
2133/// use zed::Pixels;
2134///
2135/// // Define a length of 10 pixels
2136/// let length = Pixels(10.0);
2137///
2138/// // Define a length and scale it by a factor of 2
2139/// let scaled_length = length.scale(2.0);
2140/// assert_eq!(scaled_length, Pixels(20.0));
2141/// ```
2142#[derive(
2143    Clone,
2144    Copy,
2145    Default,
2146    Add,
2147    AddAssign,
2148    Sub,
2149    SubAssign,
2150    Neg,
2151    Div,
2152    DivAssign,
2153    PartialEq,
2154    Serialize,
2155    Deserialize,
2156)]
2157#[repr(transparent)]
2158pub struct Pixels(pub f32);
2159
2160impl std::fmt::Display for Pixels {
2161    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2162        f.write_fmt(format_args!("{}px", self.0))
2163    }
2164}
2165
2166impl std::ops::Div for Pixels {
2167    type Output = f32;
2168
2169    fn div(self, rhs: Self) -> Self::Output {
2170        self.0 / rhs.0
2171    }
2172}
2173
2174impl std::ops::DivAssign for Pixels {
2175    fn div_assign(&mut self, rhs: Self) {
2176        *self = Self(self.0 / rhs.0);
2177    }
2178}
2179
2180impl std::ops::RemAssign for Pixels {
2181    fn rem_assign(&mut self, rhs: Self) {
2182        self.0 %= rhs.0;
2183    }
2184}
2185
2186impl std::ops::Rem for Pixels {
2187    type Output = Self;
2188
2189    fn rem(self, rhs: Self) -> Self {
2190        Self(self.0 % rhs.0)
2191    }
2192}
2193
2194impl Mul<f32> for Pixels {
2195    type Output = Pixels;
2196
2197    fn mul(self, other: f32) -> Pixels {
2198        Pixels(self.0 * other)
2199    }
2200}
2201
2202impl Mul<usize> for Pixels {
2203    type Output = Pixels;
2204
2205    fn mul(self, other: usize) -> Pixels {
2206        Pixels(self.0 * other as f32)
2207    }
2208}
2209
2210impl Mul<Pixels> for f32 {
2211    type Output = Pixels;
2212
2213    fn mul(self, rhs: Pixels) -> Self::Output {
2214        Pixels(self * rhs.0)
2215    }
2216}
2217
2218impl MulAssign<f32> for Pixels {
2219    fn mul_assign(&mut self, other: f32) {
2220        self.0 *= other;
2221    }
2222}
2223
2224impl Pixels {
2225    /// Represents zero pixels.
2226    pub const ZERO: Pixels = Pixels(0.0);
2227    /// The maximum value that can be represented by `Pixels`.
2228    pub const MAX: Pixels = Pixels(f32::MAX);
2229
2230    /// Floors the `Pixels` value to the nearest whole number.
2231    ///
2232    /// # Returns
2233    ///
2234    /// Returns a new `Pixels` instance with the floored value.
2235    pub fn floor(&self) -> Self {
2236        Self(self.0.floor())
2237    }
2238
2239    /// Rounds the `Pixels` value to the nearest whole number.
2240    ///
2241    /// # Returns
2242    ///
2243    /// Returns a new `Pixels` instance with the rounded value.
2244    pub fn round(&self) -> Self {
2245        Self(self.0.round())
2246    }
2247
2248    /// Returns the ceiling of the `Pixels` value to the nearest whole number.
2249    ///
2250    /// # Returns
2251    ///
2252    /// Returns a new `Pixels` instance with the ceiling value.
2253    pub fn ceil(&self) -> Self {
2254        Self(self.0.ceil())
2255    }
2256
2257    /// Scales the `Pixels` value by a given factor, producing `ScaledPixels`.
2258    ///
2259    /// This method is used when adjusting pixel values for display scaling factors,
2260    /// such as high DPI (dots per inch) or Retina displays, where the pixel density is higher and
2261    /// thus requires scaling to maintain visual consistency and readability.
2262    ///
2263    /// The resulting `ScaledPixels` represent the scaled value which can be used for rendering
2264    /// calculations where display scaling is considered.
2265    pub fn scale(&self, factor: f32) -> ScaledPixels {
2266        ScaledPixels(self.0 * factor)
2267    }
2268
2269    /// Raises the `Pixels` value to a given power.
2270    ///
2271    /// # Arguments
2272    ///
2273    /// * `exponent` - The exponent to raise the `Pixels` value by.
2274    ///
2275    /// # Returns
2276    ///
2277    /// Returns a new `Pixels` instance with the value raised to the given exponent.
2278    pub fn pow(&self, exponent: f32) -> Self {
2279        Self(self.0.powf(exponent))
2280    }
2281
2282    /// Returns the absolute value of the `Pixels`.
2283    ///
2284    /// # Returns
2285    ///
2286    /// A new `Pixels` instance with the absolute value of the original `Pixels`.
2287    pub fn abs(&self) -> Self {
2288        Self(self.0.abs())
2289    }
2290
2291    /// Returns the f64 value of `Pixels`.
2292    ///
2293    /// # Returns
2294    ///
2295    /// A f64 value of the `Pixels`.
2296    pub fn to_f64(self) -> f64 {
2297        self.0 as f64
2298    }
2299}
2300
2301impl Mul<Pixels> for Pixels {
2302    type Output = Pixels;
2303
2304    fn mul(self, rhs: Pixels) -> Self::Output {
2305        Pixels(self.0 * rhs.0)
2306    }
2307}
2308
2309impl Eq for Pixels {}
2310
2311impl PartialOrd for Pixels {
2312    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
2313        Some(self.cmp(other))
2314    }
2315}
2316
2317impl Ord for Pixels {
2318    fn cmp(&self, other: &Self) -> cmp::Ordering {
2319        self.0.total_cmp(&other.0)
2320    }
2321}
2322
2323impl std::hash::Hash for Pixels {
2324    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2325        self.0.to_bits().hash(state);
2326    }
2327}
2328
2329impl From<f64> for Pixels {
2330    fn from(pixels: f64) -> Self {
2331        Pixels(pixels as f32)
2332    }
2333}
2334
2335impl From<f32> for Pixels {
2336    fn from(pixels: f32) -> Self {
2337        Pixels(pixels)
2338    }
2339}
2340
2341impl Debug for Pixels {
2342    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2343        write!(f, "{} px", self.0)
2344    }
2345}
2346
2347impl From<Pixels> for f32 {
2348    fn from(pixels: Pixels) -> Self {
2349        pixels.0
2350    }
2351}
2352
2353impl From<&Pixels> for f32 {
2354    fn from(pixels: &Pixels) -> Self {
2355        pixels.0
2356    }
2357}
2358
2359impl From<Pixels> for f64 {
2360    fn from(pixels: Pixels) -> Self {
2361        pixels.0 as f64
2362    }
2363}
2364
2365impl From<Pixels> for u32 {
2366    fn from(pixels: Pixels) -> Self {
2367        pixels.0 as u32
2368    }
2369}
2370
2371impl From<u32> for Pixels {
2372    fn from(pixels: u32) -> Self {
2373        Pixels(pixels as f32)
2374    }
2375}
2376
2377impl From<Pixels> for usize {
2378    fn from(pixels: Pixels) -> Self {
2379        pixels.0 as usize
2380    }
2381}
2382
2383impl From<usize> for Pixels {
2384    fn from(pixels: usize) -> Self {
2385        Pixels(pixels as f32)
2386    }
2387}
2388
2389/// Represents physical pixels on the display.
2390///
2391/// `DevicePixels` is a unit of measurement that refers to the actual pixels on a device's screen.
2392/// This type is used when precise pixel manipulation is required, such as rendering graphics or
2393/// interfacing with hardware that operates on the pixel level. Unlike logical pixels that may be
2394/// affected by the device's scale factor, `DevicePixels` always correspond to real pixels on the
2395/// display.
2396#[derive(
2397    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
2398)]
2399#[repr(transparent)]
2400pub struct DevicePixels(pub(crate) i32);
2401
2402impl DevicePixels {
2403    /// Converts the `DevicePixels` value to the number of bytes needed to represent it in memory.
2404    ///
2405    /// This function is useful when working with graphical data that needs to be stored in a buffer,
2406    /// such as images or framebuffers, where each pixel may be represented by a specific number of bytes.
2407    ///
2408    /// # Arguments
2409    ///
2410    /// * `bytes_per_pixel` - The number of bytes used to represent a single pixel.
2411    ///
2412    /// # Returns
2413    ///
2414    /// The number of bytes required to represent the `DevicePixels` value in memory.
2415    ///
2416    /// # Examples
2417    ///
2418    /// ```
2419    /// # use zed::DevicePixels;
2420    /// let pixels = DevicePixels(10); // 10 device pixels
2421    /// let bytes_per_pixel = 4; // Assume each pixel is represented by 4 bytes (e.g., RGBA)
2422    /// let total_bytes = pixels.to_bytes(bytes_per_pixel);
2423    /// assert_eq!(total_bytes, 40); // 10 pixels * 4 bytes/pixel = 40 bytes
2424    /// ```
2425    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
2426        self.0 as u32 * bytes_per_pixel as u32
2427    }
2428}
2429
2430impl fmt::Debug for DevicePixels {
2431    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2432        write!(f, "{} px (device)", self.0)
2433    }
2434}
2435
2436impl From<DevicePixels> for i32 {
2437    fn from(device_pixels: DevicePixels) -> Self {
2438        device_pixels.0
2439    }
2440}
2441
2442impl From<i32> for DevicePixels {
2443    fn from(device_pixels: i32) -> Self {
2444        DevicePixels(device_pixels)
2445    }
2446}
2447
2448impl From<u32> for DevicePixels {
2449    fn from(device_pixels: u32) -> Self {
2450        DevicePixels(device_pixels as i32)
2451    }
2452}
2453
2454impl From<DevicePixels> for u32 {
2455    fn from(device_pixels: DevicePixels) -> Self {
2456        device_pixels.0 as u32
2457    }
2458}
2459
2460impl From<DevicePixels> for u64 {
2461    fn from(device_pixels: DevicePixels) -> Self {
2462        device_pixels.0 as u64
2463    }
2464}
2465
2466impl From<u64> for DevicePixels {
2467    fn from(device_pixels: u64) -> Self {
2468        DevicePixels(device_pixels as i32)
2469    }
2470}
2471
2472impl From<DevicePixels> for usize {
2473    fn from(device_pixels: DevicePixels) -> Self {
2474        device_pixels.0 as usize
2475    }
2476}
2477
2478impl From<usize> for DevicePixels {
2479    fn from(device_pixels: usize) -> Self {
2480        DevicePixels(device_pixels as i32)
2481    }
2482}
2483
2484/// Represents scaled pixels that take into account the device's scale factor.
2485///
2486/// `ScaledPixels` are used to ensure that UI elements appear at the correct size on devices
2487/// with different pixel densities. When a device has a higher scale factor (such as Retina displays),
2488/// a single logical pixel may correspond to multiple physical pixels. By using `ScaledPixels`,
2489/// dimensions and positions can be specified in a way that scales appropriately across different
2490/// display resolutions.
2491#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2492#[repr(transparent)]
2493pub struct ScaledPixels(pub(crate) f32);
2494
2495impl ScaledPixels {
2496    /// Floors the `ScaledPixels` value to the nearest whole number.
2497    ///
2498    /// # Returns
2499    ///
2500    /// Returns a new `ScaledPixels` instance with the floored value.
2501    pub fn floor(&self) -> Self {
2502        Self(self.0.floor())
2503    }
2504
2505    /// Rounds the `ScaledPixels` value to the nearest whole number.
2506    ///
2507    /// # Returns
2508    ///
2509    /// Returns a new `ScaledPixels` instance with the rounded value.
2510    pub fn ceil(&self) -> Self {
2511        Self(self.0.ceil())
2512    }
2513}
2514
2515impl Eq for ScaledPixels {}
2516
2517impl Debug for ScaledPixels {
2518    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2519        write!(f, "{} px (scaled)", self.0)
2520    }
2521}
2522
2523impl From<ScaledPixels> for DevicePixels {
2524    fn from(scaled: ScaledPixels) -> Self {
2525        DevicePixels(scaled.0.ceil() as i32)
2526    }
2527}
2528
2529impl From<DevicePixels> for ScaledPixels {
2530    fn from(device: DevicePixels) -> Self {
2531        ScaledPixels(device.0 as f32)
2532    }
2533}
2534
2535impl From<ScaledPixels> for f64 {
2536    fn from(scaled_pixels: ScaledPixels) -> Self {
2537        scaled_pixels.0 as f64
2538    }
2539}
2540
2541/// Represents a length in rems, a unit based on the font-size of the window, which can be assigned with [`WindowContext::set_rem_size`][set_rem_size].
2542///
2543/// Rems are used for defining lengths that are scalable and consistent across different UI elements.
2544/// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers),
2545/// making it a flexible unit that adapts to the user's text size preferences. In this framework, `rems` serve a similar
2546/// purpose, allowing for scalable and accessible design that can adjust to different display settings or user preferences.
2547///
2548/// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`.
2549///
2550/// [set_rem_size]: crate::WindowContext::set_rem_size
2551#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
2552pub struct Rems(pub f32);
2553
2554impl Rems {
2555    /// Convert this Rem value to pixels.
2556    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2557        *self * rem_size
2558    }
2559}
2560
2561impl Mul<Pixels> for Rems {
2562    type Output = Pixels;
2563
2564    fn mul(self, other: Pixels) -> Pixels {
2565        Pixels(self.0 * other.0)
2566    }
2567}
2568
2569impl Debug for Rems {
2570    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2571        write!(f, "{} rem", self.0)
2572    }
2573}
2574
2575/// Represents an absolute length in pixels or rems.
2576///
2577/// `AbsoluteLength` can be either a fixed number of pixels, which is an absolute measurement not
2578/// affected by the current font size, or a number of rems, which is relative to the font size of
2579/// the root element. It is used for specifying dimensions that are either independent of or
2580/// related to the typographic scale.
2581#[derive(Clone, Copy, Debug, Neg, PartialEq)]
2582pub enum AbsoluteLength {
2583    /// A length in pixels.
2584    Pixels(Pixels),
2585    /// A length in rems.
2586    Rems(Rems),
2587}
2588
2589impl AbsoluteLength {
2590    /// Checks if the absolute length is zero.
2591    pub fn is_zero(&self) -> bool {
2592        match self {
2593            AbsoluteLength::Pixels(px) => px.0 == 0.0,
2594            AbsoluteLength::Rems(rems) => rems.0 == 0.0,
2595        }
2596    }
2597}
2598
2599impl From<Pixels> for AbsoluteLength {
2600    fn from(pixels: Pixels) -> Self {
2601        AbsoluteLength::Pixels(pixels)
2602    }
2603}
2604
2605impl From<Rems> for AbsoluteLength {
2606    fn from(rems: Rems) -> Self {
2607        AbsoluteLength::Rems(rems)
2608    }
2609}
2610
2611impl AbsoluteLength {
2612    /// Converts an `AbsoluteLength` to `Pixels` based on a given `rem_size`.
2613    ///
2614    /// # Arguments
2615    ///
2616    /// * `rem_size` - The size of one rem in pixels.
2617    ///
2618    /// # Returns
2619    ///
2620    /// Returns the `AbsoluteLength` as `Pixels`.
2621    ///
2622    /// # Examples
2623    ///
2624    /// ```
2625    /// # use zed::{AbsoluteLength, Pixels};
2626    /// let length_in_pixels = AbsoluteLength::Pixels(Pixels(42.0));
2627    /// let length_in_rems = AbsoluteLength::Rems(Rems(2.0));
2628    /// let rem_size = Pixels(16.0);
2629    ///
2630    /// assert_eq!(length_in_pixels.to_pixels(rem_size), Pixels(42.0));
2631    /// assert_eq!(length_in_rems.to_pixels(rem_size), Pixels(32.0));
2632    /// ```
2633    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2634        match self {
2635            AbsoluteLength::Pixels(pixels) => *pixels,
2636            AbsoluteLength::Rems(rems) => rems.to_pixels(rem_size),
2637        }
2638    }
2639}
2640
2641impl Default for AbsoluteLength {
2642    fn default() -> Self {
2643        px(0.).into()
2644    }
2645}
2646
2647/// A non-auto length that can be defined in pixels, rems, or percent of parent.
2648///
2649/// This enum represents lengths that have a specific value, as opposed to lengths that are automatically
2650/// determined by the context. It includes absolute lengths in pixels or rems, and relative lengths as a
2651/// fraction of the parent's size.
2652#[derive(Clone, Copy, Neg, PartialEq)]
2653pub enum DefiniteLength {
2654    /// An absolute length specified in pixels or rems.
2655    Absolute(AbsoluteLength),
2656    /// A relative length specified as a fraction of the parent's size, between 0 and 1.
2657    Fraction(f32),
2658}
2659
2660impl DefiniteLength {
2661    /// Converts the `DefiniteLength` to `Pixels` based on a given `base_size` and `rem_size`.
2662    ///
2663    /// If the `DefiniteLength` is an absolute length, it will be directly converted to `Pixels`.
2664    /// If it is a fraction, the fraction will be multiplied by the `base_size` to get the length in pixels.
2665    ///
2666    /// # Arguments
2667    ///
2668    /// * `base_size` - The base size in `AbsoluteLength` to which the fraction will be applied.
2669    /// * `rem_size` - The size of one rem in pixels, used to convert rems to pixels.
2670    ///
2671    /// # Returns
2672    ///
2673    /// Returns the `DefiniteLength` as `Pixels`.
2674    ///
2675    /// # Examples
2676    ///
2677    /// ```
2678    /// # use zed::{DefiniteLength, AbsoluteLength, Pixels, px, rems};
2679    /// let length_in_pixels = DefiniteLength::Absolute(AbsoluteLength::Pixels(px(42.0)));
2680    /// let length_in_rems = DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0)));
2681    /// let length_as_fraction = DefiniteLength::Fraction(0.5);
2682    /// let base_size = AbsoluteLength::Pixels(px(100.0));
2683    /// let rem_size = px(16.0);
2684    ///
2685    /// assert_eq!(length_in_pixels.to_pixels(base_size, rem_size), Pixels(42.0));
2686    /// assert_eq!(length_in_rems.to_pixels(base_size, rem_size), Pixels(32.0));
2687    /// assert_eq!(length_as_fraction.to_pixels(base_size, rem_size), Pixels(50.0));
2688    /// ```
2689    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
2690        match self {
2691            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
2692            DefiniteLength::Fraction(fraction) => match base_size {
2693                AbsoluteLength::Pixels(px) => px * *fraction,
2694                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
2695            },
2696        }
2697    }
2698}
2699
2700impl Debug for DefiniteLength {
2701    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2702        match self {
2703            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
2704            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
2705        }
2706    }
2707}
2708
2709impl From<Pixels> for DefiniteLength {
2710    fn from(pixels: Pixels) -> Self {
2711        Self::Absolute(pixels.into())
2712    }
2713}
2714
2715impl From<Rems> for DefiniteLength {
2716    fn from(rems: Rems) -> Self {
2717        Self::Absolute(rems.into())
2718    }
2719}
2720
2721impl From<AbsoluteLength> for DefiniteLength {
2722    fn from(length: AbsoluteLength) -> Self {
2723        Self::Absolute(length)
2724    }
2725}
2726
2727impl Default for DefiniteLength {
2728    fn default() -> Self {
2729        Self::Absolute(AbsoluteLength::default())
2730    }
2731}
2732
2733/// A length that can be defined in pixels, rems, percent of parent, or auto.
2734#[derive(Clone, Copy)]
2735pub enum Length {
2736    /// A definite length specified either in pixels, rems, or as a fraction of the parent's size.
2737    Definite(DefiniteLength),
2738    /// An automatic length that is determined by the context in which it is used.
2739    Auto,
2740}
2741
2742impl Debug for Length {
2743    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2744        match self {
2745            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
2746            Length::Auto => write!(f, "auto"),
2747        }
2748    }
2749}
2750
2751/// Constructs a `DefiniteLength` representing a relative fraction of a parent size.
2752///
2753/// This function creates a `DefiniteLength` that is a specified fraction of a parent's dimension.
2754/// The fraction should be a floating-point number between 0.0 and 1.0, where 1.0 represents 100% of the parent's size.
2755///
2756/// # Arguments
2757///
2758/// * `fraction` - The fraction of the parent's size, between 0.0 and 1.0.
2759///
2760/// # Returns
2761///
2762/// A `DefiniteLength` representing the relative length as a fraction of the parent's size.
2763pub fn relative(fraction: f32) -> DefiniteLength {
2764    DefiniteLength::Fraction(fraction)
2765}
2766
2767/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
2768pub fn phi() -> DefiniteLength {
2769    relative(1.618_034)
2770}
2771
2772/// Constructs a `Rems` value representing a length in rems.
2773///
2774/// # Arguments
2775///
2776/// * `rems` - The number of rems for the length.
2777///
2778/// # Returns
2779///
2780/// A `Rems` representing the specified number of rems.
2781pub fn rems(rems: f32) -> Rems {
2782    Rems(rems)
2783}
2784
2785/// Constructs a `Pixels` value representing a length in pixels.
2786///
2787/// # Arguments
2788///
2789/// * `pixels` - The number of pixels for the length.
2790///
2791/// # Returns
2792///
2793/// A `Pixels` representing the specified number of pixels.
2794pub const fn px(pixels: f32) -> Pixels {
2795    Pixels(pixels)
2796}
2797
2798/// Returns a `Length` representing an automatic length.
2799///
2800/// The `auto` length is often used in layout calculations where the length should be determined
2801/// by the layout context itself rather than being explicitly set. This is commonly used in CSS
2802/// for properties like `width`, `height`, `margin`, `padding`, etc., where `auto` can be used
2803/// to instruct the layout engine to calculate the size based on other factors like the size of the
2804/// container or the intrinsic size of the content.
2805///
2806/// # Returns
2807///
2808/// A `Length` variant set to `Auto`.
2809pub fn auto() -> Length {
2810    Length::Auto
2811}
2812
2813impl From<Pixels> for Length {
2814    fn from(pixels: Pixels) -> Self {
2815        Self::Definite(pixels.into())
2816    }
2817}
2818
2819impl From<Rems> for Length {
2820    fn from(rems: Rems) -> Self {
2821        Self::Definite(rems.into())
2822    }
2823}
2824
2825impl From<DefiniteLength> for Length {
2826    fn from(length: DefiniteLength) -> Self {
2827        Self::Definite(length)
2828    }
2829}
2830
2831impl From<AbsoluteLength> for Length {
2832    fn from(length: AbsoluteLength) -> Self {
2833        Self::Definite(length.into())
2834    }
2835}
2836
2837impl Default for Length {
2838    fn default() -> Self {
2839        Self::Definite(DefiniteLength::default())
2840    }
2841}
2842
2843impl From<()> for Length {
2844    fn from(_: ()) -> Self {
2845        Self::Definite(DefiniteLength::default())
2846    }
2847}
2848
2849/// Provides a trait for types that can calculate half of their value.
2850///
2851/// The `Half` trait is used for types that can be evenly divided, returning a new instance of the same type
2852/// representing half of the original value. This is commonly used for types that represent measurements or sizes,
2853/// such as lengths or pixels, where halving is a frequent operation during layout calculations or animations.
2854pub trait Half {
2855    /// Returns half of the current value.
2856    ///
2857    /// # Returns
2858    ///
2859    /// A new instance of the implementing type, representing half of the original value.
2860    fn half(&self) -> Self;
2861}
2862
2863impl Half for i32 {
2864    fn half(&self) -> Self {
2865        self / 2
2866    }
2867}
2868
2869impl Half for f32 {
2870    fn half(&self) -> Self {
2871        self / 2.
2872    }
2873}
2874
2875impl Half for DevicePixels {
2876    fn half(&self) -> Self {
2877        Self(self.0 / 2)
2878    }
2879}
2880
2881impl Half for ScaledPixels {
2882    fn half(&self) -> Self {
2883        Self(self.0 / 2.)
2884    }
2885}
2886
2887impl Half for Pixels {
2888    fn half(&self) -> Self {
2889        Self(self.0 / 2.)
2890    }
2891}
2892
2893impl Half for Rems {
2894    fn half(&self) -> Self {
2895        Self(self.0 / 2.)
2896    }
2897}
2898
2899/// Provides a trait for types that can negate their values.
2900pub trait Negate {
2901    /// Returns the negation of the given value
2902    fn negate(self) -> Self;
2903}
2904
2905impl Negate for i32 {
2906    fn negate(self) -> Self {
2907        -self
2908    }
2909}
2910
2911impl Negate for f32 {
2912    fn negate(self) -> Self {
2913        -self
2914    }
2915}
2916
2917impl Negate for DevicePixels {
2918    fn negate(self) -> Self {
2919        Self(-self.0)
2920    }
2921}
2922
2923impl Negate for ScaledPixels {
2924    fn negate(self) -> Self {
2925        Self(-self.0)
2926    }
2927}
2928
2929impl Negate for Pixels {
2930    fn negate(self) -> Self {
2931        Self(-self.0)
2932    }
2933}
2934
2935impl Negate for Rems {
2936    fn negate(self) -> Self {
2937        Self(-self.0)
2938    }
2939}
2940
2941/// A trait for checking if a value is zero.
2942///
2943/// This trait provides a method to determine if a value is considered to be zero.
2944/// It is implemented for various numeric and length-related types where the concept
2945/// of zero is applicable. This can be useful for comparisons, optimizations, or
2946/// determining if an operation has a neutral effect.
2947pub trait IsZero {
2948    /// Determines if the value is zero.
2949    ///
2950    /// # Returns
2951    ///
2952    /// Returns `true` if the value is zero, `false` otherwise.
2953    fn is_zero(&self) -> bool;
2954}
2955
2956impl IsZero for DevicePixels {
2957    fn is_zero(&self) -> bool {
2958        self.0 == 0
2959    }
2960}
2961
2962impl IsZero for ScaledPixels {
2963    fn is_zero(&self) -> bool {
2964        self.0 == 0.
2965    }
2966}
2967
2968impl IsZero for Pixels {
2969    fn is_zero(&self) -> bool {
2970        self.0 == 0.
2971    }
2972}
2973
2974impl IsZero for Rems {
2975    fn is_zero(&self) -> bool {
2976        self.0 == 0.
2977    }
2978}
2979
2980impl IsZero for AbsoluteLength {
2981    fn is_zero(&self) -> bool {
2982        match self {
2983            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
2984            AbsoluteLength::Rems(rems) => rems.is_zero(),
2985        }
2986    }
2987}
2988
2989impl IsZero for DefiniteLength {
2990    fn is_zero(&self) -> bool {
2991        match self {
2992            DefiniteLength::Absolute(length) => length.is_zero(),
2993            DefiniteLength::Fraction(fraction) => *fraction == 0.,
2994        }
2995    }
2996}
2997
2998impl IsZero for Length {
2999    fn is_zero(&self) -> bool {
3000        match self {
3001            Length::Definite(length) => length.is_zero(),
3002            Length::Auto => false,
3003        }
3004    }
3005}
3006
3007impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
3008    fn is_zero(&self) -> bool {
3009        self.x.is_zero() && self.y.is_zero()
3010    }
3011}
3012
3013impl<T> IsZero for Size<T>
3014where
3015    T: IsZero + Default + Debug + Clone,
3016{
3017    fn is_zero(&self) -> bool {
3018        self.width.is_zero() || self.height.is_zero()
3019    }
3020}
3021
3022impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
3023    fn is_zero(&self) -> bool {
3024        self.size.is_zero()
3025    }
3026}
3027
3028impl<T> IsZero for Corners<T>
3029where
3030    T: IsZero + Clone + Default + Debug,
3031{
3032    fn is_zero(&self) -> bool {
3033        self.top_left.is_zero()
3034            && self.top_right.is_zero()
3035            && self.bottom_right.is_zero()
3036            && self.bottom_left.is_zero()
3037    }
3038}
3039
3040#[cfg(test)]
3041mod tests {
3042    use super::*;
3043
3044    #[test]
3045    fn test_bounds_intersects() {
3046        let bounds1 = Bounds {
3047            origin: Point { x: 0.0, y: 0.0 },
3048            size: Size {
3049                width: 5.0,
3050                height: 5.0,
3051            },
3052        };
3053        let bounds2 = Bounds {
3054            origin: Point { x: 4.0, y: 4.0 },
3055            size: Size {
3056                width: 5.0,
3057                height: 5.0,
3058            },
3059        };
3060        let bounds3 = Bounds {
3061            origin: Point { x: 10.0, y: 10.0 },
3062            size: Size {
3063                width: 5.0,
3064                height: 5.0,
3065            },
3066        };
3067
3068        // Test Case 1: Intersecting bounds
3069        assert_eq!(bounds1.intersects(&bounds2), true);
3070
3071        // Test Case 2: Non-Intersecting bounds
3072        assert_eq!(bounds1.intersects(&bounds3), false);
3073
3074        // Test Case 3: Bounds intersecting with themselves
3075        assert_eq!(bounds1.intersects(&bounds1), true);
3076    }
3077}