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(display_id: Option<DisplayId>, size: Size<Pixels>, cx: &AppContext) -> Self {
 710        let display = display_id
 711            .and_then(|id| cx.find_display(id))
 712            .or_else(|| cx.primary_display());
 713
 714        display
 715            .map(|display| {
 716                let center = display.bounds().center();
 717                Bounds {
 718                    origin: point(center.x - size.width / 2., center.y - size.height / 2.),
 719                    size,
 720                }
 721            })
 722            .unwrap_or_else(|| Bounds {
 723                origin: point(px(0.), px(0.)),
 724                size,
 725            })
 726    }
 727
 728    /// Generate maximized bounds for the given display or primary display if none is provided
 729    pub fn maximized(display_id: Option<DisplayId>, cx: &AppContext) -> Self {
 730        let display = display_id
 731            .and_then(|id| cx.find_display(id))
 732            .or_else(|| cx.primary_display());
 733
 734        display
 735            .map(|display| display.bounds())
 736            .unwrap_or_else(|| Bounds {
 737                origin: point(px(0.), px(0.)),
 738                size: size(px(1024.), px(768.)),
 739            })
 740    }
 741}
 742
 743impl<T> Bounds<T>
 744where
 745    T: Clone + Debug + Sub<Output = T> + Default,
 746{
 747    /// Constructs a `Bounds` from two corner points: the upper-left and lower-right corners.
 748    ///
 749    /// This function calculates the origin and size of the `Bounds` based on the provided corner points.
 750    /// The origin is set to the upper-left corner, and the size is determined by the difference between
 751    /// the x and y coordinates of the lower-right and upper-left points.
 752    ///
 753    /// # Arguments
 754    ///
 755    /// * `upper_left` - A `Point<T>` representing the upper-left corner of the rectangle.
 756    /// * `lower_right` - A `Point<T>` representing the lower-right corner of the rectangle.
 757    ///
 758    /// # Returns
 759    ///
 760    /// Returns a `Bounds<T>` that encompasses the area defined by the two corner points.
 761    ///
 762    /// # Examples
 763    ///
 764    /// ```
 765    /// # use zed::{Bounds, Point};
 766    /// let upper_left = Point { x: 0, y: 0 };
 767    /// let lower_right = Point { x: 10, y: 10 };
 768    /// let bounds = Bounds::from_corners(upper_left, lower_right);
 769    ///
 770    /// assert_eq!(bounds.origin, upper_left);
 771    /// assert_eq!(bounds.size.width, 10);
 772    /// assert_eq!(bounds.size.height, 10);
 773    /// ```
 774    pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
 775        let origin = Point {
 776            x: upper_left.x.clone(),
 777            y: upper_left.y.clone(),
 778        };
 779        let size = Size {
 780            width: lower_right.x - upper_left.x,
 781            height: lower_right.y - upper_left.y,
 782        };
 783        Bounds { origin, size }
 784    }
 785
 786    /// Creates a new `Bounds` with the specified origin and size.
 787    ///
 788    /// # Arguments
 789    ///
 790    /// * `origin` - A `Point<T>` representing the origin of the bounds.
 791    /// * `size` - A `Size<T>` representing the size of the bounds.
 792    ///
 793    /// # Returns
 794    ///
 795    /// Returns a `Bounds<T>` that has the given origin and size.
 796    pub fn new(origin: Point<T>, size: Size<T>) -> Self {
 797        Bounds { origin, size }
 798    }
 799}
 800
 801impl<T> Bounds<T>
 802where
 803    T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default + Half,
 804{
 805    /// Checks if this `Bounds` intersects with another `Bounds`.
 806    ///
 807    /// Two `Bounds` instances intersect if they overlap in the 2D space they occupy.
 808    /// This method checks if there is any overlapping area between the two bounds.
 809    ///
 810    /// # Arguments
 811    ///
 812    /// * `other` - A reference to another `Bounds` to check for intersection with.
 813    ///
 814    /// # Returns
 815    ///
 816    /// Returns `true` if there is any intersection between the two bounds, `false` otherwise.
 817    ///
 818    /// # Examples
 819    ///
 820    /// ```
 821    /// # use zed::{Bounds, Point, Size};
 822    /// let bounds1 = Bounds {
 823    ///     origin: Point { x: 0, y: 0 },
 824    ///     size: Size { width: 10, height: 10 },
 825    /// };
 826    /// let bounds2 = Bounds {
 827    ///     origin: Point { x: 5, y: 5 },
 828    ///     size: Size { width: 10, height: 10 },
 829    /// };
 830    /// let bounds3 = Bounds {
 831    ///     origin: Point { x: 20, y: 20 },
 832    ///     size: Size { width: 10, height: 10 },
 833    /// };
 834    ///
 835    /// assert_eq!(bounds1.intersects(&bounds2), true); // Overlapping bounds
 836    /// assert_eq!(bounds1.intersects(&bounds3), false); // Non-overlapping bounds
 837    /// ```
 838    pub fn intersects(&self, other: &Bounds<T>) -> bool {
 839        let my_lower_right = self.lower_right();
 840        let their_lower_right = other.lower_right();
 841
 842        self.origin.x < their_lower_right.x
 843            && my_lower_right.x > other.origin.x
 844            && self.origin.y < their_lower_right.y
 845            && my_lower_right.y > other.origin.y
 846    }
 847
 848    /// Dilates the bounds by a specified amount in all directions.
 849    ///
 850    /// This method expands the bounds by the given `amount`, increasing the size
 851    /// and adjusting the origin so that the bounds grow outwards equally in all directions.
 852    /// The resulting bounds will have its width and height increased by twice the `amount`
 853    /// (since it grows in both directions), and the origin will be moved by `-amount`
 854    /// in both the x and y directions.
 855    ///
 856    /// # Arguments
 857    ///
 858    /// * `amount` - The amount by which to dilate the bounds.
 859    ///
 860    /// # Examples
 861    ///
 862    /// ```
 863    /// # use zed::{Bounds, Point, Size};
 864    /// let mut bounds = Bounds {
 865    ///     origin: Point { x: 10, y: 10 },
 866    ///     size: Size { width: 10, height: 10 },
 867    /// };
 868    /// bounds.dilate(5);
 869    /// assert_eq!(bounds, Bounds {
 870    ///     origin: Point { x: 5, y: 5 },
 871    ///     size: Size { width: 20, height: 20 },
 872    /// });
 873    /// ```
 874    pub fn dilate(&mut self, amount: T) {
 875        self.origin.x = self.origin.x.clone() - amount.clone();
 876        self.origin.y = self.origin.y.clone() - amount.clone();
 877        let double_amount = amount.clone() + amount;
 878        self.size.width = self.size.width.clone() + double_amount.clone();
 879        self.size.height = self.size.height.clone() + double_amount;
 880    }
 881
 882    /// inset the bounds by a specified amount
 883    /// Note that this may panic if T does not support negative values
 884    pub fn inset(&self, amount: T) -> Self {
 885        let mut result = self.clone();
 886        result.dilate(T::default() - amount);
 887        result
 888    }
 889
 890    /// Returns the center point of the bounds.
 891    ///
 892    /// Calculates the center by taking the origin's x and y coordinates and adding half the width and height
 893    /// of the bounds, respectively. The center is represented as a `Point<T>` where `T` is the type of the
 894    /// coordinate system.
 895    ///
 896    /// # Returns
 897    ///
 898    /// A `Point<T>` representing the center of the bounds.
 899    ///
 900    /// # Examples
 901    ///
 902    /// ```
 903    /// # use zed::{Bounds, Point, Size};
 904    /// let bounds = Bounds {
 905    ///     origin: Point { x: 0, y: 0 },
 906    ///     size: Size { width: 10, height: 20 },
 907    /// };
 908    /// let center = bounds.center();
 909    /// assert_eq!(center, Point { x: 5, y: 10 });
 910    /// ```
 911    pub fn center(&self) -> Point<T> {
 912        Point {
 913            x: self.origin.x.clone() + self.size.width.clone().half(),
 914            y: self.origin.y.clone() + self.size.height.clone().half(),
 915        }
 916    }
 917
 918    /// Calculates the half perimeter of a rectangle defined by the bounds.
 919    ///
 920    /// The half perimeter is calculated as the sum of the width and the height of the rectangle.
 921    /// This method is generic over the type `T` which must implement the `Sub` trait to allow
 922    /// calculation of the width and height from the bounds' origin and size, as well as the `Add` trait
 923    /// to sum the width and height for the half perimeter.
 924    ///
 925    /// # Examples
 926    ///
 927    /// ```
 928    /// # use zed::{Bounds, Point, Size};
 929    /// let bounds = Bounds {
 930    ///     origin: Point { x: 0, y: 0 },
 931    ///     size: Size { width: 10, height: 20 },
 932    /// };
 933    /// let half_perimeter = bounds.half_perimeter();
 934    /// assert_eq!(half_perimeter, 30);
 935    /// ```
 936    pub fn half_perimeter(&self) -> T {
 937        self.size.width.clone() + self.size.height.clone()
 938    }
 939
 940    /// centered_at creates a new bounds centered at the given point.
 941    pub fn centered_at(center: Point<T>, size: Size<T>) -> Self {
 942        let origin = Point {
 943            x: center.x - size.width.half(),
 944            y: center.y - size.height.half(),
 945        };
 946        Self::new(origin, size)
 947    }
 948}
 949
 950impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
 951    /// Calculates the intersection of two `Bounds` objects.
 952    ///
 953    /// This method computes the overlapping region of two `Bounds`. If the bounds do not intersect,
 954    /// the resulting `Bounds` will have a size with width and height of zero.
 955    ///
 956    /// # Arguments
 957    ///
 958    /// * `other` - A reference to another `Bounds` to intersect with.
 959    ///
 960    /// # Returns
 961    ///
 962    /// Returns a `Bounds` representing the intersection area. If there is no intersection,
 963    /// the returned `Bounds` will have a size with width and height of zero.
 964    ///
 965    /// # Examples
 966    ///
 967    /// ```
 968    /// # use zed::{Bounds, Point, Size};
 969    /// let bounds1 = Bounds {
 970    ///     origin: Point { x: 0, y: 0 },
 971    ///     size: Size { width: 10, height: 10 },
 972    /// };
 973    /// let bounds2 = Bounds {
 974    ///     origin: Point { x: 5, y: 5 },
 975    ///     size: Size { width: 10, height: 10 },
 976    /// };
 977    /// let intersection = bounds1.intersect(&bounds2);
 978    ///
 979    /// assert_eq!(intersection, Bounds {
 980    ///     origin: Point { x: 5, y: 5 },
 981    ///     size: Size { width: 5, height: 5 },
 982    /// });
 983    /// ```
 984    pub fn intersect(&self, other: &Self) -> Self {
 985        let upper_left = self.origin.max(&other.origin);
 986        let lower_right = self.lower_right().min(&other.lower_right());
 987        Self::from_corners(upper_left, lower_right)
 988    }
 989
 990    /// Computes the union of two `Bounds`.
 991    ///
 992    /// This method calculates the smallest `Bounds` that contains both the current `Bounds` and the `other` `Bounds`.
 993    /// The resulting `Bounds` will have an origin that is the minimum of the origins of the two `Bounds`,
 994    /// and a size that encompasses the furthest extents of both `Bounds`.
 995    ///
 996    /// # Arguments
 997    ///
 998    /// * `other` - A reference to another `Bounds` to create a union with.
 999    ///
1000    /// # Returns
1001    ///
1002    /// Returns a `Bounds` representing the union of the two `Bounds`.
1003    ///
1004    /// # Examples
1005    ///
1006    /// ```
1007    /// # use zed::{Bounds, Point, Size};
1008    /// let bounds1 = Bounds {
1009    ///     origin: Point { x: 0, y: 0 },
1010    ///     size: Size { width: 10, height: 10 },
1011    /// };
1012    /// let bounds2 = Bounds {
1013    ///     origin: Point { x: 5, y: 5 },
1014    ///     size: Size { width: 15, height: 15 },
1015    /// };
1016    /// let union_bounds = bounds1.union(&bounds2);
1017    ///
1018    /// assert_eq!(union_bounds, Bounds {
1019    ///     origin: Point { x: 0, y: 0 },
1020    ///     size: Size { width: 20, height: 20 },
1021    /// });
1022    /// ```
1023    pub fn union(&self, other: &Self) -> Self {
1024        let top_left = self.origin.min(&other.origin);
1025        let bottom_right = self.lower_right().max(&other.lower_right());
1026        Bounds::from_corners(top_left, bottom_right)
1027    }
1028}
1029
1030impl<T, Rhs> Mul<Rhs> for Bounds<T>
1031where
1032    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
1033    Point<T>: Mul<Rhs, Output = Point<Rhs>>,
1034    Rhs: Clone + Default + Debug,
1035{
1036    type Output = Bounds<Rhs>;
1037
1038    fn mul(self, rhs: Rhs) -> Self::Output {
1039        Bounds {
1040            origin: self.origin * rhs.clone(),
1041            size: self.size * rhs,
1042        }
1043    }
1044}
1045
1046impl<T, S> MulAssign<S> for Bounds<T>
1047where
1048    T: Mul<S, Output = T> + Clone + Default + Debug,
1049    S: Clone,
1050{
1051    fn mul_assign(&mut self, rhs: S) {
1052        self.origin *= rhs.clone();
1053        self.size *= rhs;
1054    }
1055}
1056
1057impl<T, S> Div<S> for Bounds<T>
1058where
1059    Size<T>: Div<S, Output = Size<T>>,
1060    T: Div<S, Output = T> + Default + Clone + Debug,
1061    S: Clone,
1062{
1063    type Output = Self;
1064
1065    fn div(self, rhs: S) -> Self {
1066        Self {
1067            origin: self.origin / rhs.clone(),
1068            size: self.size / rhs,
1069        }
1070    }
1071}
1072
1073impl<T> Bounds<T>
1074where
1075    T: Add<T, Output = T> + Clone + Default + Debug,
1076{
1077    /// Returns the top edge of the bounds.
1078    ///
1079    /// # Returns
1080    ///
1081    /// A value of type `T` representing the y-coordinate of the top edge of the bounds.
1082    pub fn top(&self) -> T {
1083        self.origin.y.clone()
1084    }
1085
1086    /// Returns the bottom edge of the bounds.
1087    ///
1088    /// # Returns
1089    ///
1090    /// A value of type `T` representing the y-coordinate of the bottom edge of the bounds.
1091    pub fn bottom(&self) -> T {
1092        self.origin.y.clone() + self.size.height.clone()
1093    }
1094
1095    /// Returns the left edge of the bounds.
1096    ///
1097    /// # Returns
1098    ///
1099    /// A value of type `T` representing the x-coordinate of the left edge of the bounds.
1100    pub fn left(&self) -> T {
1101        self.origin.x.clone()
1102    }
1103
1104    /// Returns the right edge of the bounds.
1105    ///
1106    /// # Returns
1107    ///
1108    /// A value of type `T` representing the x-coordinate of the right edge of the bounds.
1109    pub fn right(&self) -> T {
1110        self.origin.x.clone() + self.size.width.clone()
1111    }
1112
1113    /// Returns the upper-right corner point of the bounds.
1114    ///
1115    /// # Returns
1116    ///
1117    /// A `Point<T>` representing the upper-right corner of the bounds.
1118    ///
1119    /// # Examples
1120    ///
1121    /// ```
1122    /// # use zed::{Bounds, Point, Size};
1123    /// let bounds = Bounds {
1124    ///     origin: Point { x: 0, y: 0 },
1125    ///     size: Size { width: 10, height: 20 },
1126    /// };
1127    /// let upper_right = bounds.upper_right();
1128    /// assert_eq!(upper_right, Point { x: 10, y: 0 });
1129    /// ```
1130    pub fn upper_right(&self) -> Point<T> {
1131        Point {
1132            x: self.origin.x.clone() + self.size.width.clone(),
1133            y: self.origin.y.clone(),
1134        }
1135    }
1136
1137    /// Returns the lower-right corner point of the bounds.
1138    ///
1139    /// # Returns
1140    ///
1141    /// A `Point<T>` representing the lower-right corner of the bounds.
1142    ///
1143    /// # Examples
1144    ///
1145    /// ```
1146    /// # use zed::{Bounds, Point, Size};
1147    /// let bounds = Bounds {
1148    ///     origin: Point { x: 0, y: 0 },
1149    ///     size: Size { width: 10, height: 20 },
1150    /// };
1151    /// let lower_right = bounds.lower_right();
1152    /// assert_eq!(lower_right, Point { x: 10, y: 20 });
1153    /// ```
1154    pub fn lower_right(&self) -> Point<T> {
1155        Point {
1156            x: self.origin.x.clone() + self.size.width.clone(),
1157            y: self.origin.y.clone() + self.size.height.clone(),
1158        }
1159    }
1160
1161    /// Returns the lower-left corner point of the bounds.
1162    ///
1163    /// # Returns
1164    ///
1165    /// A `Point<T>` representing the lower-left corner of the bounds.
1166    ///
1167    /// # Examples
1168    ///
1169    /// ```
1170    /// # use zed::{Bounds, Point, Size};
1171    /// let bounds = Bounds {
1172    ///     origin: Point { x: 0, y: 0 },
1173    ///     size: Size { width: 10, height: 20 },
1174    /// };
1175    /// let lower_left = bounds.lower_left();
1176    /// assert_eq!(lower_left, Point { x: 0, y: 20 });
1177    /// ```
1178    pub fn lower_left(&self) -> Point<T> {
1179        Point {
1180            x: self.origin.x.clone(),
1181            y: self.origin.y.clone() + self.size.height.clone(),
1182        }
1183    }
1184}
1185
1186impl<T> Bounds<T>
1187where
1188    T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
1189{
1190    /// Checks if the given point is within the bounds.
1191    ///
1192    /// This method determines whether a point lies inside the rectangle defined by the bounds,
1193    /// including the edges. The point is considered inside if its x-coordinate is greater than
1194    /// or equal to the left edge and less than or equal to the right edge, and its y-coordinate
1195    /// is greater than or equal to the top edge and less than or equal to the bottom edge of the bounds.
1196    ///
1197    /// # Arguments
1198    ///
1199    /// * `point` - A reference to a `Point<T>` that represents the point to check.
1200    ///
1201    /// # Returns
1202    ///
1203    /// Returns `true` if the point is within the bounds, `false` otherwise.
1204    ///
1205    /// # Examples
1206    ///
1207    /// ```
1208    /// # use zed::{Point, Bounds};
1209    /// let bounds = Bounds {
1210    ///     origin: Point { x: 0, y: 0 },
1211    ///     size: Size { width: 10, height: 10 },
1212    /// };
1213    /// let inside_point = Point { x: 5, y: 5 };
1214    /// let outside_point = Point { x: 15, y: 15 };
1215    ///
1216    /// assert!(bounds.contains_point(&inside_point));
1217    /// assert!(!bounds.contains_point(&outside_point));
1218    /// ```
1219    pub fn contains(&self, point: &Point<T>) -> bool {
1220        point.x >= self.origin.x
1221            && point.x <= self.origin.x.clone() + self.size.width.clone()
1222            && point.y >= self.origin.y
1223            && point.y <= self.origin.y.clone() + self.size.height.clone()
1224    }
1225
1226    /// Applies a function to the origin and size of the bounds, producing a new `Bounds<U>`.
1227    ///
1228    /// This method allows for converting a `Bounds<T>` to a `Bounds<U>` by specifying a closure
1229    /// that defines how to convert between the two types. The closure is applied to the `origin` and
1230    /// `size` fields, resulting in new bounds of the desired type.
1231    ///
1232    /// # Arguments
1233    ///
1234    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
1235    ///
1236    /// # Returns
1237    ///
1238    /// Returns a new `Bounds<U>` with the origin and size mapped by the provided function.
1239    ///
1240    /// # Examples
1241    ///
1242    /// ```
1243    /// # use zed::{Bounds, Point, Size};
1244    /// let bounds = Bounds {
1245    ///     origin: Point { x: 10.0, y: 10.0 },
1246    ///     size: Size { width: 10.0, height: 20.0 },
1247    /// };
1248    /// let new_bounds = bounds.map(|value| value as f64 * 1.5);
1249    ///
1250    /// assert_eq!(new_bounds, Bounds {
1251    ///     origin: Point { x: 15.0, y: 15.0 },
1252    ///     size: Size { width: 15.0, height: 30.0 },
1253    /// });
1254    /// ```
1255    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
1256    where
1257        U: Clone + Default + Debug,
1258    {
1259        Bounds {
1260            origin: self.origin.map(&f),
1261            size: self.size.map(f),
1262        }
1263    }
1264
1265    /// Applies a function to the origin  of the bounds, producing a new `Bounds` with the new origin
1266    ///
1267    /// # Examples
1268    ///
1269    /// ```
1270    /// # use zed::{Bounds, Point, Size};
1271    /// let bounds = Bounds {
1272    ///     origin: Point { x: 10.0, y: 10.0 },
1273    ///     size: Size { width: 10.0, height: 20.0 },
1274    /// };
1275    /// let new_bounds = bounds.map_origin(|value| value * 1.5);
1276    ///
1277    /// assert_eq!(new_bounds, Bounds {
1278    ///     origin: Point { x: 15.0, y: 15.0 },
1279    ///     size: Size { width: 10.0, height: 20.0 },
1280    /// });
1281    /// ```
1282    pub fn map_origin(self, f: impl Fn(T) -> T) -> Bounds<T> {
1283        Bounds {
1284            origin: self.origin.map(f),
1285            size: self.size,
1286        }
1287    }
1288
1289    /// Applies a function to the origin  of the bounds, producing a new `Bounds` with the new origin
1290    ///
1291    /// # Examples
1292    ///
1293    /// ```
1294    /// # use zed::{Bounds, Point, Size};
1295    /// let bounds = Bounds {
1296    ///     origin: Point { x: 10.0, y: 10.0 },
1297    ///     size: Size { width: 10.0, height: 20.0 },
1298    /// };
1299    /// let new_bounds = bounds.map_size(|value| value * 1.5);
1300    ///
1301    /// assert_eq!(new_bounds, Bounds {
1302    ///     origin: Point { x: 10.0, y: 10.0 },
1303    ///     size: Size { width: 15.0, height: 30.0 },
1304    /// });
1305    /// ```
1306    pub fn map_size(self, f: impl Fn(T) -> T) -> Bounds<T> {
1307        Bounds {
1308            origin: self.origin,
1309            size: self.size.map(f),
1310        }
1311    }
1312}
1313
1314/// Checks if the bounds represent an empty area.
1315///
1316/// # Returns
1317///
1318/// Returns `true` if either the width or the height of the bounds is less than or equal to zero, indicating an empty area.
1319impl<T: PartialOrd + Default + Debug + Clone> Bounds<T> {
1320    /// Checks if the bounds represent an empty area.
1321    ///
1322    /// # Returns
1323    ///
1324    /// Returns `true` if either the width or the height of the bounds is less than or equal to zero, indicating an empty area.
1325    pub fn is_empty(&self) -> bool {
1326        self.size.width <= T::default() || self.size.height <= T::default()
1327    }
1328}
1329
1330impl Size<DevicePixels> {
1331    /// Converts the size from physical to logical pixels.
1332    pub(crate) fn to_pixels(self, scale_factor: f32) -> Size<Pixels> {
1333        size(
1334            px(self.width.0 as f32 / scale_factor),
1335            px(self.height.0 as f32 / scale_factor),
1336        )
1337    }
1338}
1339
1340impl Size<Pixels> {
1341    /// Converts the size from physical to logical pixels.
1342    pub(crate) fn to_device_pixels(self, scale_factor: f32) -> Size<DevicePixels> {
1343        size(
1344            DevicePixels((self.width.0 * scale_factor) as i32),
1345            DevicePixels((self.height.0 * scale_factor) as i32),
1346        )
1347    }
1348}
1349
1350impl Bounds<Pixels> {
1351    /// Scales the bounds by a given factor, typically used to adjust for display scaling.
1352    ///
1353    /// This method multiplies the origin and size of the bounds by the provided scaling factor,
1354    /// resulting in a new `Bounds<ScaledPixels>` that is proportionally larger or smaller
1355    /// depending on the scaling factor. This can be used to ensure that the bounds are properly
1356    /// scaled for different display densities.
1357    ///
1358    /// # Arguments
1359    ///
1360    /// * `factor` - The scaling factor to apply to the origin and size, typically the display's scaling factor.
1361    ///
1362    /// # Returns
1363    ///
1364    /// Returns a new `Bounds<ScaledPixels>` that represents the scaled bounds.
1365    ///
1366    /// # Examples
1367    ///
1368    /// ```
1369    /// # use zed::{Bounds, Point, Size, Pixels};
1370    /// let bounds = Bounds {
1371    ///     origin: Point { x: Pixels(10.0), y: Pixels(20.0) },
1372    ///     size: Size { width: Pixels(30.0), height: Pixels(40.0) },
1373    /// };
1374    /// let display_scale_factor = 2.0;
1375    /// let scaled_bounds = bounds.scale(display_scale_factor);
1376    /// assert_eq!(scaled_bounds, Bounds {
1377    ///     origin: Point { x: ScaledPixels(20.0), y: ScaledPixels(40.0) },
1378    ///     size: Size { width: ScaledPixels(60.0), height: ScaledPixels(80.0) },
1379    /// });
1380    /// ```
1381    pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
1382        Bounds {
1383            origin: self.origin.scale(factor),
1384            size: self.size.scale(factor),
1385        }
1386    }
1387
1388    /// Convert the bounds from logical pixels to physical pixels
1389    pub fn to_device_pixels(&self, factor: f32) -> Bounds<DevicePixels> {
1390        Bounds {
1391            origin: point(
1392                DevicePixels((self.origin.x.0 * factor) as i32),
1393                DevicePixels((self.origin.y.0 * factor) as i32),
1394            ),
1395            size: self.size.to_device_pixels(factor),
1396        }
1397    }
1398}
1399
1400impl Bounds<DevicePixels> {
1401    /// Convert the bounds from physical pixels to logical pixels
1402    pub fn to_pixels(self, scale_factor: f32) -> Bounds<Pixels> {
1403        Bounds {
1404            origin: point(
1405                px(self.origin.x.0 as f32 / scale_factor),
1406                px(self.origin.y.0 as f32 / scale_factor),
1407            ),
1408            size: self.size.to_pixels(scale_factor),
1409        }
1410    }
1411}
1412
1413impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
1414
1415/// Represents the edges of a box in a 2D space, such as padding or margin.
1416///
1417/// Each field represents the size of the edge on one side of the box: `top`, `right`, `bottom`, and `left`.
1418///
1419/// # Examples
1420///
1421/// ```
1422/// # use zed::Edges;
1423/// let edges = Edges {
1424///     top: 10.0,
1425///     right: 20.0,
1426///     bottom: 30.0,
1427///     left: 40.0,
1428/// };
1429///
1430/// assert_eq!(edges.top, 10.0);
1431/// assert_eq!(edges.right, 20.0);
1432/// assert_eq!(edges.bottom, 30.0);
1433/// assert_eq!(edges.left, 40.0);
1434/// ```
1435#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1436#[refineable(Debug)]
1437#[repr(C)]
1438pub struct Edges<T: Clone + Default + Debug> {
1439    /// The size of the top edge.
1440    pub top: T,
1441    /// The size of the right edge.
1442    pub right: T,
1443    /// The size of the bottom edge.
1444    pub bottom: T,
1445    /// The size of the left edge.
1446    pub left: T,
1447}
1448
1449impl<T> Mul for Edges<T>
1450where
1451    T: Mul<Output = T> + Clone + Default + Debug,
1452{
1453    type Output = Self;
1454
1455    fn mul(self, rhs: Self) -> Self::Output {
1456        Self {
1457            top: self.top.clone() * rhs.top,
1458            right: self.right.clone() * rhs.right,
1459            bottom: self.bottom.clone() * rhs.bottom,
1460            left: self.left.clone() * rhs.left,
1461        }
1462    }
1463}
1464
1465impl<T, S> MulAssign<S> for Edges<T>
1466where
1467    T: Mul<S, Output = T> + Clone + Default + Debug,
1468    S: Clone,
1469{
1470    fn mul_assign(&mut self, rhs: S) {
1471        self.top = self.top.clone() * rhs.clone();
1472        self.right = self.right.clone() * rhs.clone();
1473        self.bottom = self.bottom.clone() * rhs.clone();
1474        self.left = self.left.clone() * rhs;
1475    }
1476}
1477
1478impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
1479
1480impl<T: Clone + Default + Debug> Edges<T> {
1481    /// Constructs `Edges` where all sides are set to the same specified value.
1482    ///
1483    /// This function creates an `Edges` instance with the `top`, `right`, `bottom`, and `left` fields all initialized
1484    /// to the same value provided as an argument. This is useful when you want to have uniform edges around a box,
1485    /// such as padding or margin with the same size on all sides.
1486    ///
1487    /// # Arguments
1488    ///
1489    /// * `value` - The value to set for all four sides of the edges.
1490    ///
1491    /// # Returns
1492    ///
1493    /// An `Edges` instance with all sides set to the given value.
1494    ///
1495    /// # Examples
1496    ///
1497    /// ```
1498    /// # use zed::Edges;
1499    /// let uniform_edges = Edges::all(10.0);
1500    /// assert_eq!(uniform_edges.top, 10.0);
1501    /// assert_eq!(uniform_edges.right, 10.0);
1502    /// assert_eq!(uniform_edges.bottom, 10.0);
1503    /// assert_eq!(uniform_edges.left, 10.0);
1504    /// ```
1505    pub fn all(value: T) -> Self {
1506        Self {
1507            top: value.clone(),
1508            right: value.clone(),
1509            bottom: value.clone(),
1510            left: value,
1511        }
1512    }
1513
1514    /// Applies a function to each field of the `Edges`, producing a new `Edges<U>`.
1515    ///
1516    /// This method allows for converting an `Edges<T>` to an `Edges<U>` by specifying a closure
1517    /// that defines how to convert between the two types. The closure is applied to each field
1518    /// (`top`, `right`, `bottom`, `left`), resulting in new edges of the desired type.
1519    ///
1520    /// # Arguments
1521    ///
1522    /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1523    ///
1524    /// # Returns
1525    ///
1526    /// Returns a new `Edges<U>` with each field mapped by the provided function.
1527    ///
1528    /// # Examples
1529    ///
1530    /// ```
1531    /// # use zed::Edges;
1532    /// let edges = Edges { top: 10, right: 20, bottom: 30, left: 40 };
1533    /// let edges_float = edges.map(|&value| value as f32 * 1.1);
1534    /// assert_eq!(edges_float, Edges { top: 11.0, right: 22.0, bottom: 33.0, left: 44.0 });
1535    /// ```
1536    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
1537    where
1538        U: Clone + Default + Debug,
1539    {
1540        Edges {
1541            top: f(&self.top),
1542            right: f(&self.right),
1543            bottom: f(&self.bottom),
1544            left: f(&self.left),
1545        }
1546    }
1547
1548    /// Checks if any of the edges satisfy a given predicate.
1549    ///
1550    /// This method applies a predicate function to each field of the `Edges` and returns `true` if any field satisfies the predicate.
1551    ///
1552    /// # Arguments
1553    ///
1554    /// * `predicate` - A closure that takes a reference to a value of type `T` and returns a `bool`.
1555    ///
1556    /// # Returns
1557    ///
1558    /// Returns `true` if the predicate returns `true` for any of the edge values, `false` otherwise.
1559    ///
1560    /// # Examples
1561    ///
1562    /// ```
1563    /// # use zed::Edges;
1564    /// let edges = Edges {
1565    ///     top: 10,
1566    ///     right: 0,
1567    ///     bottom: 5,
1568    ///     left: 0,
1569    /// };
1570    ///
1571    /// assert!(edges.any(|value| *value == 0));
1572    /// assert!(edges.any(|value| *value > 0));
1573    /// assert!(!edges.any(|value| *value > 10));
1574    /// ```
1575    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
1576        predicate(&self.top)
1577            || predicate(&self.right)
1578            || predicate(&self.bottom)
1579            || predicate(&self.left)
1580    }
1581}
1582
1583impl Edges<Length> {
1584    /// 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.
1585    ///
1586    /// 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.
1587    ///
1588    /// # Returns
1589    ///
1590    /// Returns an `Edges<Length>` with all edges set to `Length::Auto`.
1591    ///
1592    /// # Examples
1593    ///
1594    /// ```
1595    /// # use zed::Edges;
1596    /// let auto_edges = Edges::auto();
1597    /// assert_eq!(auto_edges.top, Length::Auto);
1598    /// assert_eq!(auto_edges.right, Length::Auto);
1599    /// assert_eq!(auto_edges.bottom, Length::Auto);
1600    /// assert_eq!(auto_edges.left, Length::Auto);
1601    /// ```
1602    pub fn auto() -> Self {
1603        Self {
1604            top: Length::Auto,
1605            right: Length::Auto,
1606            bottom: Length::Auto,
1607            left: Length::Auto,
1608        }
1609    }
1610
1611    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1612    ///
1613    /// This is typically used when you want to specify that a box (like a padding or margin area)
1614    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1615    ///
1616    /// # Returns
1617    ///
1618    /// Returns an `Edges<Length>` with all edges set to zero length.
1619    ///
1620    /// # Examples
1621    ///
1622    /// ```
1623    /// # use zed::Edges;
1624    /// let no_edges = Edges::zero();
1625    /// assert_eq!(no_edges.top, Length::Definite(DefiniteLength::from(Pixels(0.))));
1626    /// assert_eq!(no_edges.right, Length::Definite(DefiniteLength::from(Pixels(0.))));
1627    /// assert_eq!(no_edges.bottom, Length::Definite(DefiniteLength::from(Pixels(0.))));
1628    /// assert_eq!(no_edges.left, Length::Definite(DefiniteLength::from(Pixels(0.))));
1629    /// ```
1630    pub fn zero() -> Self {
1631        Self {
1632            top: px(0.).into(),
1633            right: px(0.).into(),
1634            bottom: px(0.).into(),
1635            left: px(0.).into(),
1636        }
1637    }
1638}
1639
1640impl Edges<DefiniteLength> {
1641    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1642    ///
1643    /// This is typically used when you want to specify that a box (like a padding or margin area)
1644    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1645    ///
1646    /// # Returns
1647    ///
1648    /// Returns an `Edges<DefiniteLength>` with all edges set to zero length.
1649    ///
1650    /// # Examples
1651    ///
1652    /// ```
1653    /// # use zed::Edges;
1654    /// let no_edges = Edges::zero();
1655    /// assert_eq!(no_edges.top, DefiniteLength::from(zed::px(0.)));
1656    /// assert_eq!(no_edges.right, DefiniteLength::from(zed::px(0.)));
1657    /// assert_eq!(no_edges.bottom, DefiniteLength::from(zed::px(0.)));
1658    /// assert_eq!(no_edges.left, DefiniteLength::from(zed::px(0.)));
1659    /// ```
1660    pub fn zero() -> Self {
1661        Self {
1662            top: px(0.).into(),
1663            right: px(0.).into(),
1664            bottom: px(0.).into(),
1665            left: px(0.).into(),
1666        }
1667    }
1668
1669    /// Converts the `DefiniteLength` to `Pixels` based on the parent size and the REM size.
1670    ///
1671    /// This method allows for a `DefiniteLength` value to be converted into pixels, taking into account
1672    /// the size of the parent element (for percentage-based lengths) and the size of a rem unit (for rem-based lengths).
1673    ///
1674    /// # Arguments
1675    ///
1676    /// * `parent_size` - `Size<AbsoluteLength>` representing the size of the parent element.
1677    /// * `rem_size` - `Pixels` representing the size of one REM unit.
1678    ///
1679    /// # Returns
1680    ///
1681    /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1682    ///
1683    /// # Examples
1684    ///
1685    /// ```
1686    /// # use zed::{Edges, DefiniteLength, px, AbsoluteLength, Size};
1687    /// let edges = Edges {
1688    ///     top: DefiniteLength::Absolute(AbsoluteLength::Pixels(px(10.0))),
1689    ///     right: DefiniteLength::Fraction(0.5),
1690    ///     bottom: DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0))),
1691    ///     left: DefiniteLength::Fraction(0.25),
1692    /// };
1693    /// let parent_size = Size {
1694    ///     width: AbsoluteLength::Pixels(px(200.0)),
1695    ///     height: AbsoluteLength::Pixels(px(100.0)),
1696    /// };
1697    /// let rem_size = px(16.0);
1698    /// let edges_in_pixels = edges.to_pixels(parent_size, rem_size);
1699    ///
1700    /// assert_eq!(edges_in_pixels.top, px(10.0)); // Absolute length in pixels
1701    /// assert_eq!(edges_in_pixels.right, px(100.0)); // 50% of parent width
1702    /// assert_eq!(edges_in_pixels.bottom, px(32.0)); // 2 rems
1703    /// assert_eq!(edges_in_pixels.left, px(50.0)); // 25% of parent width
1704    /// ```
1705    pub fn to_pixels(&self, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
1706        Edges {
1707            top: self.top.to_pixels(parent_size.height, rem_size),
1708            right: self.right.to_pixels(parent_size.width, rem_size),
1709            bottom: self.bottom.to_pixels(parent_size.height, rem_size),
1710            left: self.left.to_pixels(parent_size.width, rem_size),
1711        }
1712    }
1713}
1714
1715impl Edges<AbsoluteLength> {
1716    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1717    ///
1718    /// This is typically used when you want to specify that a box (like a padding or margin area)
1719    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1720    ///
1721    /// # Returns
1722    ///
1723    /// Returns an `Edges<AbsoluteLength>` with all edges set to zero length.
1724    ///
1725    /// # Examples
1726    ///
1727    /// ```
1728    /// # use zed::Edges;
1729    /// let no_edges = Edges::zero();
1730    /// assert_eq!(no_edges.top, AbsoluteLength::Pixels(Pixels(0.0)));
1731    /// assert_eq!(no_edges.right, AbsoluteLength::Pixels(Pixels(0.0)));
1732    /// assert_eq!(no_edges.bottom, AbsoluteLength::Pixels(Pixels(0.0)));
1733    /// assert_eq!(no_edges.left, AbsoluteLength::Pixels(Pixels(0.0)));
1734    /// ```
1735    pub fn zero() -> Self {
1736        Self {
1737            top: px(0.).into(),
1738            right: px(0.).into(),
1739            bottom: px(0.).into(),
1740            left: px(0.).into(),
1741        }
1742    }
1743
1744    /// Converts the `AbsoluteLength` to `Pixels` based on the `rem_size`.
1745    ///
1746    /// If the `AbsoluteLength` is already in pixels, it simply returns the corresponding `Pixels` value.
1747    /// If the `AbsoluteLength` is in rems, it multiplies the number of rems by the `rem_size` to convert it to pixels.
1748    ///
1749    /// # Arguments
1750    ///
1751    /// * `rem_size` - The size of one rem unit in pixels.
1752    ///
1753    /// # Returns
1754    ///
1755    /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1756    ///
1757    /// # Examples
1758    ///
1759    /// ```
1760    /// # use zed::{Edges, AbsoluteLength, Pixels, px};
1761    /// let edges = Edges {
1762    ///     top: AbsoluteLength::Pixels(px(10.0)),
1763    ///     right: AbsoluteLength::Rems(rems(1.0)),
1764    ///     bottom: AbsoluteLength::Pixels(px(20.0)),
1765    ///     left: AbsoluteLength::Rems(rems(2.0)),
1766    /// };
1767    /// let rem_size = px(16.0);
1768    /// let edges_in_pixels = edges.to_pixels(rem_size);
1769    ///
1770    /// assert_eq!(edges_in_pixels.top, px(10.0)); // Already in pixels
1771    /// assert_eq!(edges_in_pixels.right, px(16.0)); // 1 rem converted to pixels
1772    /// assert_eq!(edges_in_pixels.bottom, px(20.0)); // Already in pixels
1773    /// assert_eq!(edges_in_pixels.left, px(32.0)); // 2 rems converted to pixels
1774    /// ```
1775    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
1776        Edges {
1777            top: self.top.to_pixels(rem_size),
1778            right: self.right.to_pixels(rem_size),
1779            bottom: self.bottom.to_pixels(rem_size),
1780            left: self.left.to_pixels(rem_size),
1781        }
1782    }
1783}
1784
1785impl Edges<Pixels> {
1786    /// Scales the `Edges<Pixels>` by a given factor, returning `Edges<ScaledPixels>`.
1787    ///
1788    /// This method is typically used for adjusting the edge sizes for different display densities or scaling factors.
1789    ///
1790    /// # Arguments
1791    ///
1792    /// * `factor` - The scaling factor to apply to each edge.
1793    ///
1794    /// # Returns
1795    ///
1796    /// Returns a new `Edges<ScaledPixels>` where each edge is the result of scaling the original edge by the given factor.
1797    ///
1798    /// # Examples
1799    ///
1800    /// ```
1801    /// # use zed::{Edges, Pixels};
1802    /// let edges = Edges {
1803    ///     top: Pixels(10.0),
1804    ///     right: Pixels(20.0),
1805    ///     bottom: Pixels(30.0),
1806    ///     left: Pixels(40.0),
1807    /// };
1808    /// let scaled_edges = edges.scale(2.0);
1809    /// assert_eq!(scaled_edges.top, ScaledPixels(20.0));
1810    /// assert_eq!(scaled_edges.right, ScaledPixels(40.0));
1811    /// assert_eq!(scaled_edges.bottom, ScaledPixels(60.0));
1812    /// assert_eq!(scaled_edges.left, ScaledPixels(80.0));
1813    /// ```
1814    pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
1815        Edges {
1816            top: self.top.scale(factor),
1817            right: self.right.scale(factor),
1818            bottom: self.bottom.scale(factor),
1819            left: self.left.scale(factor),
1820        }
1821    }
1822
1823    /// Returns the maximum value of any edge.
1824    ///
1825    /// # Returns
1826    ///
1827    /// The maximum `Pixels` value among all four edges.
1828    pub fn max(&self) -> Pixels {
1829        self.top.max(self.right).max(self.bottom).max(self.left)
1830    }
1831}
1832
1833impl From<f32> for Edges<Pixels> {
1834    fn from(val: f32) -> Self {
1835        let val: Pixels = val.into();
1836        val.into()
1837    }
1838}
1839
1840impl From<Pixels> for Edges<Pixels> {
1841    fn from(val: Pixels) -> Self {
1842        Edges {
1843            top: val,
1844            right: val,
1845            bottom: val,
1846            left: val,
1847        }
1848    }
1849}
1850
1851/// Represents the corners of a box in a 2D space, such as border radius.
1852///
1853/// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`.
1854#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1855#[refineable(Debug)]
1856#[repr(C)]
1857pub struct Corners<T: Clone + Default + Debug> {
1858    /// The value associated with the top left corner.
1859    pub top_left: T,
1860    /// The value associated with the top right corner.
1861    pub top_right: T,
1862    /// The value associated with the bottom right corner.
1863    pub bottom_right: T,
1864    /// The value associated with the bottom left corner.
1865    pub bottom_left: T,
1866}
1867
1868impl<T> Corners<T>
1869where
1870    T: Clone + Default + Debug,
1871{
1872    /// Constructs `Corners` where all sides are set to the same specified value.
1873    ///
1874    /// This function creates a `Corners` instance with the `top_left`, `top_right`, `bottom_right`, and `bottom_left` fields all initialized
1875    /// to the same value provided as an argument. This is useful when you want to have uniform corners around a box,
1876    /// such as a uniform border radius on a rectangle.
1877    ///
1878    /// # Arguments
1879    ///
1880    /// * `value` - The value to set for all four corners.
1881    ///
1882    /// # Returns
1883    ///
1884    /// An `Corners` instance with all corners set to the given value.
1885    ///
1886    /// # Examples
1887    ///
1888    /// ```
1889    /// # use zed::Corners;
1890    /// let uniform_corners = Corners::all(5.0);
1891    /// assert_eq!(uniform_corners.top_left, 5.0);
1892    /// assert_eq!(uniform_corners.top_right, 5.0);
1893    /// assert_eq!(uniform_corners.bottom_right, 5.0);
1894    /// assert_eq!(uniform_corners.bottom_left, 5.0);
1895    /// ```
1896    pub fn all(value: T) -> Self {
1897        Self {
1898            top_left: value.clone(),
1899            top_right: value.clone(),
1900            bottom_right: value.clone(),
1901            bottom_left: value,
1902        }
1903    }
1904}
1905
1906impl Corners<AbsoluteLength> {
1907    /// Converts the `AbsoluteLength` to `Pixels` based on the provided size and rem size, ensuring the resulting
1908    /// `Pixels` do not exceed half of the minimum of the provided size's width and height.
1909    ///
1910    /// This method is particularly useful when dealing with corner radii, where the radius in pixels should not
1911    /// exceed half the size of the box it applies to, to avoid the corners overlapping.
1912    ///
1913    /// # Arguments
1914    ///
1915    /// * `size` - The `Size<Pixels>` against which the minimum allowable radius is determined.
1916    /// * `rem_size` - The size of one REM unit in pixels, used for conversion if the `AbsoluteLength` is in REMs.
1917    ///
1918    /// # Returns
1919    ///
1920    /// Returns a `Corners<Pixels>` instance with each corner's length converted to pixels and clamped to the
1921    /// minimum allowable radius based on the provided size.
1922    ///
1923    /// # Examples
1924    ///
1925    /// ```
1926    /// # use zed::{Corners, AbsoluteLength, Pixels, Size};
1927    /// let corners = Corners {
1928    ///     top_left: AbsoluteLength::Pixels(Pixels(15.0)),
1929    ///     top_right: AbsoluteLength::Rems(Rems(1.0)),
1930    ///     bottom_right: AbsoluteLength::Pixels(Pixels(30.0)),
1931    ///     bottom_left: AbsoluteLength::Rems(Rems(2.0)),
1932    /// };
1933    /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
1934    /// let rem_size = Pixels(16.0);
1935    /// let corners_in_pixels = corners.to_pixels(size, rem_size);
1936    ///
1937    /// // The resulting corners should not exceed half the size of the smallest dimension (50.0 / 2.0 = 25.0).
1938    /// assert_eq!(corners_in_pixels.top_left, Pixels(15.0));
1939    /// assert_eq!(corners_in_pixels.top_right, Pixels(16.0)); // 1 rem converted to pixels
1940    /// assert_eq!(corners_in_pixels.bottom_right, Pixels(30.0).min(Pixels(25.0))); // Clamped to 25.0
1941    /// assert_eq!(corners_in_pixels.bottom_left, Pixels(32.0).min(Pixels(25.0))); // 2 rems converted to pixels and clamped to 25.0
1942    /// ```
1943    pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
1944        let max = size.width.min(size.height) / 2.;
1945        Corners {
1946            top_left: self.top_left.to_pixels(rem_size).min(max),
1947            top_right: self.top_right.to_pixels(rem_size).min(max),
1948            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
1949            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
1950        }
1951    }
1952}
1953
1954impl Corners<Pixels> {
1955    /// Scales the `Corners<Pixels>` by a given factor, returning `Corners<ScaledPixels>`.
1956    ///
1957    /// This method is typically used for adjusting the corner sizes for different display densities or scaling factors.
1958    ///
1959    /// # Arguments
1960    ///
1961    /// * `factor` - The scaling factor to apply to each corner.
1962    ///
1963    /// # Returns
1964    ///
1965    /// Returns a new `Corners<ScaledPixels>` where each corner is the result of scaling the original corner by the given factor.
1966    ///
1967    /// # Examples
1968    ///
1969    /// ```
1970    /// # use zed::{Corners, Pixels};
1971    /// let corners = Corners {
1972    ///     top_left: Pixels(10.0),
1973    ///     top_right: Pixels(20.0),
1974    ///     bottom_right: Pixels(30.0),
1975    ///     bottom_left: Pixels(40.0),
1976    /// };
1977    /// let scaled_corners = corners.scale(2.0);
1978    /// assert_eq!(scaled_corners.top_left, ScaledPixels(20.0));
1979    /// assert_eq!(scaled_corners.top_right, ScaledPixels(40.0));
1980    /// assert_eq!(scaled_corners.bottom_right, ScaledPixels(60.0));
1981    /// assert_eq!(scaled_corners.bottom_left, ScaledPixels(80.0));
1982    /// ```
1983    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
1984        Corners {
1985            top_left: self.top_left.scale(factor),
1986            top_right: self.top_right.scale(factor),
1987            bottom_right: self.bottom_right.scale(factor),
1988            bottom_left: self.bottom_left.scale(factor),
1989        }
1990    }
1991
1992    /// Returns the maximum value of any corner.
1993    ///
1994    /// # Returns
1995    ///
1996    /// The maximum `Pixels` value among all four corners.
1997    pub fn max(&self) -> Pixels {
1998        self.top_left
1999            .max(self.top_right)
2000            .max(self.bottom_right)
2001            .max(self.bottom_left)
2002    }
2003}
2004
2005impl<T: Clone + Default + Debug> Corners<T> {
2006    /// Applies a function to each field of the `Corners`, producing a new `Corners<U>`.
2007    ///
2008    /// This method allows for converting a `Corners<T>` to a `Corners<U>` by specifying a closure
2009    /// that defines how to convert between the two types. The closure is applied to each field
2010    /// (`top_left`, `top_right`, `bottom_right`, `bottom_left`), resulting in new corners of the desired type.
2011    ///
2012    /// # Arguments
2013    ///
2014    /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
2015    ///
2016    /// # Returns
2017    ///
2018    /// Returns a new `Corners<U>` with each field mapped by the provided function.
2019    ///
2020    /// # Examples
2021    ///
2022    /// ```
2023    /// # use zed::{Corners, Pixels};
2024    /// let corners = Corners {
2025    ///     top_left: Pixels(10.0),
2026    ///     top_right: Pixels(20.0),
2027    ///     bottom_right: Pixels(30.0),
2028    ///     bottom_left: Pixels(40.0),
2029    /// };
2030    /// let corners_in_rems = corners.map(|&px| Rems(px.0 / 16.0));
2031    /// assert_eq!(corners_in_rems, Corners {
2032    ///     top_left: Rems(0.625),
2033    ///     top_right: Rems(1.25),
2034    ///     bottom_right: Rems(1.875),
2035    ///     bottom_left: Rems(2.5),
2036    /// });
2037    /// ```
2038    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
2039    where
2040        U: Clone + Default + Debug,
2041    {
2042        Corners {
2043            top_left: f(&self.top_left),
2044            top_right: f(&self.top_right),
2045            bottom_right: f(&self.bottom_right),
2046            bottom_left: f(&self.bottom_left),
2047        }
2048    }
2049}
2050
2051impl<T> Mul for Corners<T>
2052where
2053    T: Mul<Output = T> + Clone + Default + Debug,
2054{
2055    type Output = Self;
2056
2057    fn mul(self, rhs: Self) -> Self::Output {
2058        Self {
2059            top_left: self.top_left.clone() * rhs.top_left,
2060            top_right: self.top_right.clone() * rhs.top_right,
2061            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
2062            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
2063        }
2064    }
2065}
2066
2067impl<T, S> MulAssign<S> for Corners<T>
2068where
2069    T: Mul<S, Output = T> + Clone + Default + Debug,
2070    S: Clone,
2071{
2072    fn mul_assign(&mut self, rhs: S) {
2073        self.top_left = self.top_left.clone() * rhs.clone();
2074        self.top_right = self.top_right.clone() * rhs.clone();
2075        self.bottom_right = self.bottom_right.clone() * rhs.clone();
2076        self.bottom_left = self.bottom_left.clone() * rhs;
2077    }
2078}
2079
2080impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
2081
2082impl From<f32> for Corners<Pixels> {
2083    fn from(val: f32) -> Self {
2084        Corners {
2085            top_left: val.into(),
2086            top_right: val.into(),
2087            bottom_right: val.into(),
2088            bottom_left: val.into(),
2089        }
2090    }
2091}
2092
2093impl From<Pixels> for Corners<Pixels> {
2094    fn from(val: Pixels) -> Self {
2095        Corners {
2096            top_left: val,
2097            top_right: val,
2098            bottom_right: val,
2099            bottom_left: val,
2100        }
2101    }
2102}
2103
2104/// Represents an angle in Radians
2105#[derive(
2106    Clone,
2107    Copy,
2108    Default,
2109    Add,
2110    AddAssign,
2111    Sub,
2112    SubAssign,
2113    Neg,
2114    Div,
2115    DivAssign,
2116    PartialEq,
2117    Serialize,
2118    Deserialize,
2119    Debug,
2120)]
2121#[repr(transparent)]
2122pub struct Radians(pub f32);
2123
2124/// Create a `Radian` from a raw value
2125pub fn radians(value: f32) -> Radians {
2126    Radians(value)
2127}
2128
2129/// A type representing a percentage value.
2130#[derive(
2131    Clone,
2132    Copy,
2133    Default,
2134    Add,
2135    AddAssign,
2136    Sub,
2137    SubAssign,
2138    Neg,
2139    Div,
2140    DivAssign,
2141    PartialEq,
2142    Serialize,
2143    Deserialize,
2144    Debug,
2145)]
2146#[repr(transparent)]
2147pub struct Percentage(pub f32);
2148
2149/// Generate a `Radian` from a percentage of a full circle.
2150pub fn percentage(value: f32) -> Percentage {
2151    debug_assert!(
2152        (0.0..=1.0).contains(&value),
2153        "Percentage must be between 0 and 1"
2154    );
2155    Percentage(value)
2156}
2157
2158impl From<Percentage> for Radians {
2159    fn from(value: Percentage) -> Self {
2160        radians(value.0 * std::f32::consts::PI * 2.0)
2161    }
2162}
2163
2164/// Represents a length in pixels, the base unit of measurement in the UI framework.
2165///
2166/// `Pixels` is a value type that represents an absolute length in pixels, which is used
2167/// for specifying sizes, positions, and distances in the UI. It is the fundamental unit
2168/// of measurement for all visual elements and layout calculations.
2169///
2170/// The inner value is an `f32`, allowing for sub-pixel precision which can be useful for
2171/// anti-aliasing and animations. However, when applied to actual pixel grids, the value
2172/// is typically rounded to the nearest integer.
2173///
2174/// # Examples
2175///
2176/// ```
2177/// use zed::Pixels;
2178///
2179/// // Define a length of 10 pixels
2180/// let length = Pixels(10.0);
2181///
2182/// // Define a length and scale it by a factor of 2
2183/// let scaled_length = length.scale(2.0);
2184/// assert_eq!(scaled_length, Pixels(20.0));
2185/// ```
2186#[derive(
2187    Clone,
2188    Copy,
2189    Default,
2190    Add,
2191    AddAssign,
2192    Sub,
2193    SubAssign,
2194    Neg,
2195    Div,
2196    DivAssign,
2197    PartialEq,
2198    Serialize,
2199    Deserialize,
2200)]
2201#[repr(transparent)]
2202pub struct Pixels(pub f32);
2203
2204impl std::fmt::Display for Pixels {
2205    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2206        f.write_fmt(format_args!("{}px", self.0))
2207    }
2208}
2209
2210impl std::ops::Div for Pixels {
2211    type Output = f32;
2212
2213    fn div(self, rhs: Self) -> Self::Output {
2214        self.0 / rhs.0
2215    }
2216}
2217
2218impl std::ops::DivAssign for Pixels {
2219    fn div_assign(&mut self, rhs: Self) {
2220        *self = Self(self.0 / rhs.0);
2221    }
2222}
2223
2224impl std::ops::RemAssign for Pixels {
2225    fn rem_assign(&mut self, rhs: Self) {
2226        self.0 %= rhs.0;
2227    }
2228}
2229
2230impl std::ops::Rem for Pixels {
2231    type Output = Self;
2232
2233    fn rem(self, rhs: Self) -> Self {
2234        Self(self.0 % rhs.0)
2235    }
2236}
2237
2238impl Mul<f32> for Pixels {
2239    type Output = Pixels;
2240
2241    fn mul(self, other: f32) -> Pixels {
2242        Pixels(self.0 * other)
2243    }
2244}
2245
2246impl Mul<usize> for Pixels {
2247    type Output = Pixels;
2248
2249    fn mul(self, other: usize) -> Pixels {
2250        Pixels(self.0 * other as f32)
2251    }
2252}
2253
2254impl Mul<Pixels> for f32 {
2255    type Output = Pixels;
2256
2257    fn mul(self, rhs: Pixels) -> Self::Output {
2258        Pixels(self * rhs.0)
2259    }
2260}
2261
2262impl MulAssign<f32> for Pixels {
2263    fn mul_assign(&mut self, other: f32) {
2264        self.0 *= other;
2265    }
2266}
2267
2268impl Pixels {
2269    /// Represents zero pixels.
2270    pub const ZERO: Pixels = Pixels(0.0);
2271    /// The maximum value that can be represented by `Pixels`.
2272    pub const MAX: Pixels = Pixels(f32::MAX);
2273
2274    /// Floors the `Pixels` value to the nearest whole number.
2275    ///
2276    /// # Returns
2277    ///
2278    /// Returns a new `Pixels` instance with the floored value.
2279    pub fn floor(&self) -> Self {
2280        Self(self.0.floor())
2281    }
2282
2283    /// Rounds the `Pixels` value to the nearest whole number.
2284    ///
2285    /// # Returns
2286    ///
2287    /// Returns a new `Pixels` instance with the rounded value.
2288    pub fn round(&self) -> Self {
2289        Self(self.0.round())
2290    }
2291
2292    /// Returns the ceiling of the `Pixels` value to the nearest whole number.
2293    ///
2294    /// # Returns
2295    ///
2296    /// Returns a new `Pixels` instance with the ceiling value.
2297    pub fn ceil(&self) -> Self {
2298        Self(self.0.ceil())
2299    }
2300
2301    /// Scales the `Pixels` value by a given factor, producing `ScaledPixels`.
2302    ///
2303    /// This method is used when adjusting pixel values for display scaling factors,
2304    /// such as high DPI (dots per inch) or Retina displays, where the pixel density is higher and
2305    /// thus requires scaling to maintain visual consistency and readability.
2306    ///
2307    /// The resulting `ScaledPixels` represent the scaled value which can be used for rendering
2308    /// calculations where display scaling is considered.
2309    pub fn scale(&self, factor: f32) -> ScaledPixels {
2310        ScaledPixels(self.0 * factor)
2311    }
2312
2313    /// Raises the `Pixels` value to a given power.
2314    ///
2315    /// # Arguments
2316    ///
2317    /// * `exponent` - The exponent to raise the `Pixels` value by.
2318    ///
2319    /// # Returns
2320    ///
2321    /// Returns a new `Pixels` instance with the value raised to the given exponent.
2322    pub fn pow(&self, exponent: f32) -> Self {
2323        Self(self.0.powf(exponent))
2324    }
2325
2326    /// Returns the absolute value of the `Pixels`.
2327    ///
2328    /// # Returns
2329    ///
2330    /// A new `Pixels` instance with the absolute value of the original `Pixels`.
2331    pub fn abs(&self) -> Self {
2332        Self(self.0.abs())
2333    }
2334
2335    /// Returns the sign of the `Pixels` value.
2336    ///
2337    /// # Returns
2338    ///
2339    /// Returns:
2340    /// * `1.0` if the value is positive
2341    /// * `-1.0` if the value is negative
2342    /// * `0.0` if the value is zero
2343    pub fn signum(&self) -> f32 {
2344        self.0.signum()
2345    }
2346
2347    /// Returns the f64 value of `Pixels`.
2348    ///
2349    /// # Returns
2350    ///
2351    /// A f64 value of the `Pixels`.
2352    pub fn to_f64(self) -> f64 {
2353        self.0 as f64
2354    }
2355}
2356
2357impl Mul<Pixels> for Pixels {
2358    type Output = Pixels;
2359
2360    fn mul(self, rhs: Pixels) -> Self::Output {
2361        Pixels(self.0 * rhs.0)
2362    }
2363}
2364
2365impl Eq for Pixels {}
2366
2367impl PartialOrd for Pixels {
2368    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
2369        Some(self.cmp(other))
2370    }
2371}
2372
2373impl Ord for Pixels {
2374    fn cmp(&self, other: &Self) -> cmp::Ordering {
2375        self.0.total_cmp(&other.0)
2376    }
2377}
2378
2379impl std::hash::Hash for Pixels {
2380    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2381        self.0.to_bits().hash(state);
2382    }
2383}
2384
2385impl From<f64> for Pixels {
2386    fn from(pixels: f64) -> Self {
2387        Pixels(pixels as f32)
2388    }
2389}
2390
2391impl From<f32> for Pixels {
2392    fn from(pixels: f32) -> Self {
2393        Pixels(pixels)
2394    }
2395}
2396
2397impl Debug for Pixels {
2398    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2399        write!(f, "{} px", self.0)
2400    }
2401}
2402
2403impl From<Pixels> for f32 {
2404    fn from(pixels: Pixels) -> Self {
2405        pixels.0
2406    }
2407}
2408
2409impl From<&Pixels> for f32 {
2410    fn from(pixels: &Pixels) -> Self {
2411        pixels.0
2412    }
2413}
2414
2415impl From<Pixels> for f64 {
2416    fn from(pixels: Pixels) -> Self {
2417        pixels.0 as f64
2418    }
2419}
2420
2421impl From<Pixels> for u32 {
2422    fn from(pixels: Pixels) -> Self {
2423        pixels.0 as u32
2424    }
2425}
2426
2427impl From<u32> for Pixels {
2428    fn from(pixels: u32) -> Self {
2429        Pixels(pixels as f32)
2430    }
2431}
2432
2433impl From<Pixels> for usize {
2434    fn from(pixels: Pixels) -> Self {
2435        pixels.0 as usize
2436    }
2437}
2438
2439impl From<usize> for Pixels {
2440    fn from(pixels: usize) -> Self {
2441        Pixels(pixels as f32)
2442    }
2443}
2444
2445/// Represents physical pixels on the display.
2446///
2447/// `DevicePixels` is a unit of measurement that refers to the actual pixels on a device's screen.
2448/// This type is used when precise pixel manipulation is required, such as rendering graphics or
2449/// interfacing with hardware that operates on the pixel level. Unlike logical pixels that may be
2450/// affected by the device's scale factor, `DevicePixels` always correspond to real pixels on the
2451/// display.
2452#[derive(
2453    Add,
2454    AddAssign,
2455    Clone,
2456    Copy,
2457    Default,
2458    Div,
2459    Eq,
2460    Hash,
2461    Ord,
2462    PartialEq,
2463    PartialOrd,
2464    Sub,
2465    SubAssign,
2466    Serialize,
2467    Deserialize,
2468)]
2469#[repr(transparent)]
2470pub struct DevicePixels(pub i32);
2471
2472impl DevicePixels {
2473    /// Converts the `DevicePixels` value to the number of bytes needed to represent it in memory.
2474    ///
2475    /// This function is useful when working with graphical data that needs to be stored in a buffer,
2476    /// such as images or framebuffers, where each pixel may be represented by a specific number of bytes.
2477    ///
2478    /// # Arguments
2479    ///
2480    /// * `bytes_per_pixel` - The number of bytes used to represent a single pixel.
2481    ///
2482    /// # Returns
2483    ///
2484    /// The number of bytes required to represent the `DevicePixels` value in memory.
2485    ///
2486    /// # Examples
2487    ///
2488    /// ```
2489    /// # use zed::DevicePixels;
2490    /// let pixels = DevicePixels(10); // 10 device pixels
2491    /// let bytes_per_pixel = 4; // Assume each pixel is represented by 4 bytes (e.g., RGBA)
2492    /// let total_bytes = pixels.to_bytes(bytes_per_pixel);
2493    /// assert_eq!(total_bytes, 40); // 10 pixels * 4 bytes/pixel = 40 bytes
2494    /// ```
2495    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
2496        self.0 as u32 * bytes_per_pixel as u32
2497    }
2498}
2499
2500impl fmt::Debug for DevicePixels {
2501    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2502        write!(f, "{} px (device)", self.0)
2503    }
2504}
2505
2506impl From<DevicePixels> for i32 {
2507    fn from(device_pixels: DevicePixels) -> Self {
2508        device_pixels.0
2509    }
2510}
2511
2512impl From<i32> for DevicePixels {
2513    fn from(device_pixels: i32) -> Self {
2514        DevicePixels(device_pixels)
2515    }
2516}
2517
2518impl From<u32> for DevicePixels {
2519    fn from(device_pixels: u32) -> Self {
2520        DevicePixels(device_pixels as i32)
2521    }
2522}
2523
2524impl From<DevicePixels> for u32 {
2525    fn from(device_pixels: DevicePixels) -> Self {
2526        device_pixels.0 as u32
2527    }
2528}
2529
2530impl From<DevicePixels> for u64 {
2531    fn from(device_pixels: DevicePixels) -> Self {
2532        device_pixels.0 as u64
2533    }
2534}
2535
2536impl From<u64> for DevicePixels {
2537    fn from(device_pixels: u64) -> Self {
2538        DevicePixels(device_pixels as i32)
2539    }
2540}
2541
2542impl From<DevicePixels> for usize {
2543    fn from(device_pixels: DevicePixels) -> Self {
2544        device_pixels.0 as usize
2545    }
2546}
2547
2548impl From<usize> for DevicePixels {
2549    fn from(device_pixels: usize) -> Self {
2550        DevicePixels(device_pixels as i32)
2551    }
2552}
2553
2554/// Represents scaled pixels that take into account the device's scale factor.
2555///
2556/// `ScaledPixels` are used to ensure that UI elements appear at the correct size on devices
2557/// with different pixel densities. When a device has a higher scale factor (such as Retina displays),
2558/// a single logical pixel may correspond to multiple physical pixels. By using `ScaledPixels`,
2559/// dimensions and positions can be specified in a way that scales appropriately across different
2560/// display resolutions.
2561#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2562#[repr(transparent)]
2563pub struct ScaledPixels(pub(crate) f32);
2564
2565impl ScaledPixels {
2566    /// Floors the `ScaledPixels` value to the nearest whole number.
2567    ///
2568    /// # Returns
2569    ///
2570    /// Returns a new `ScaledPixels` instance with the floored value.
2571    pub fn floor(&self) -> Self {
2572        Self(self.0.floor())
2573    }
2574
2575    /// Rounds the `ScaledPixels` value to the nearest whole number.
2576    ///
2577    /// # Returns
2578    ///
2579    /// Returns a new `ScaledPixels` instance with the rounded value.
2580    pub fn ceil(&self) -> Self {
2581        Self(self.0.ceil())
2582    }
2583}
2584
2585impl Eq for ScaledPixels {}
2586
2587impl Debug for ScaledPixels {
2588    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2589        write!(f, "{} px (scaled)", self.0)
2590    }
2591}
2592
2593impl From<ScaledPixels> for DevicePixels {
2594    fn from(scaled: ScaledPixels) -> Self {
2595        DevicePixels(scaled.0.ceil() as i32)
2596    }
2597}
2598
2599impl From<DevicePixels> for ScaledPixels {
2600    fn from(device: DevicePixels) -> Self {
2601        ScaledPixels(device.0 as f32)
2602    }
2603}
2604
2605impl From<ScaledPixels> for f64 {
2606    fn from(scaled_pixels: ScaledPixels) -> Self {
2607        scaled_pixels.0 as f64
2608    }
2609}
2610
2611impl From<ScaledPixels> for u32 {
2612    fn from(pixels: ScaledPixels) -> Self {
2613        pixels.0 as u32
2614    }
2615}
2616
2617/// 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].
2618///
2619/// Rems are used for defining lengths that are scalable and consistent across different UI elements.
2620/// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers),
2621/// making it a flexible unit that adapts to the user's text size preferences. In this framework, `rems` serve a similar
2622/// purpose, allowing for scalable and accessible design that can adjust to different display settings or user preferences.
2623///
2624/// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`.
2625///
2626/// [set_rem_size]: crate::WindowContext::set_rem_size
2627#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
2628pub struct Rems(pub f32);
2629
2630impl Rems {
2631    /// Convert this Rem value to pixels.
2632    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2633        *self * rem_size
2634    }
2635}
2636
2637impl Mul<Pixels> for Rems {
2638    type Output = Pixels;
2639
2640    fn mul(self, other: Pixels) -> Pixels {
2641        Pixels(self.0 * other.0)
2642    }
2643}
2644
2645impl Debug for Rems {
2646    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2647        write!(f, "{} rem", self.0)
2648    }
2649}
2650
2651/// Represents an absolute length in pixels or rems.
2652///
2653/// `AbsoluteLength` can be either a fixed number of pixels, which is an absolute measurement not
2654/// affected by the current font size, or a number of rems, which is relative to the font size of
2655/// the root element. It is used for specifying dimensions that are either independent of or
2656/// related to the typographic scale.
2657#[derive(Clone, Copy, Debug, Neg, PartialEq)]
2658pub enum AbsoluteLength {
2659    /// A length in pixels.
2660    Pixels(Pixels),
2661    /// A length in rems.
2662    Rems(Rems),
2663}
2664
2665impl AbsoluteLength {
2666    /// Checks if the absolute length is zero.
2667    pub fn is_zero(&self) -> bool {
2668        match self {
2669            AbsoluteLength::Pixels(px) => px.0 == 0.0,
2670            AbsoluteLength::Rems(rems) => rems.0 == 0.0,
2671        }
2672    }
2673}
2674
2675impl From<Pixels> for AbsoluteLength {
2676    fn from(pixels: Pixels) -> Self {
2677        AbsoluteLength::Pixels(pixels)
2678    }
2679}
2680
2681impl From<Rems> for AbsoluteLength {
2682    fn from(rems: Rems) -> Self {
2683        AbsoluteLength::Rems(rems)
2684    }
2685}
2686
2687impl AbsoluteLength {
2688    /// Converts an `AbsoluteLength` to `Pixels` based on a given `rem_size`.
2689    ///
2690    /// # Arguments
2691    ///
2692    /// * `rem_size` - The size of one rem in pixels.
2693    ///
2694    /// # Returns
2695    ///
2696    /// Returns the `AbsoluteLength` as `Pixels`.
2697    ///
2698    /// # Examples
2699    ///
2700    /// ```
2701    /// # use zed::{AbsoluteLength, Pixels};
2702    /// let length_in_pixels = AbsoluteLength::Pixels(Pixels(42.0));
2703    /// let length_in_rems = AbsoluteLength::Rems(Rems(2.0));
2704    /// let rem_size = Pixels(16.0);
2705    ///
2706    /// assert_eq!(length_in_pixels.to_pixels(rem_size), Pixels(42.0));
2707    /// assert_eq!(length_in_rems.to_pixels(rem_size), Pixels(32.0));
2708    /// ```
2709    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2710        match self {
2711            AbsoluteLength::Pixels(pixels) => *pixels,
2712            AbsoluteLength::Rems(rems) => rems.to_pixels(rem_size),
2713        }
2714    }
2715}
2716
2717impl Default for AbsoluteLength {
2718    fn default() -> Self {
2719        px(0.).into()
2720    }
2721}
2722
2723/// A non-auto length that can be defined in pixels, rems, or percent of parent.
2724///
2725/// This enum represents lengths that have a specific value, as opposed to lengths that are automatically
2726/// determined by the context. It includes absolute lengths in pixels or rems, and relative lengths as a
2727/// fraction of the parent's size.
2728#[derive(Clone, Copy, Neg, PartialEq)]
2729pub enum DefiniteLength {
2730    /// An absolute length specified in pixels or rems.
2731    Absolute(AbsoluteLength),
2732    /// A relative length specified as a fraction of the parent's size, between 0 and 1.
2733    Fraction(f32),
2734}
2735
2736impl DefiniteLength {
2737    /// Converts the `DefiniteLength` to `Pixels` based on a given `base_size` and `rem_size`.
2738    ///
2739    /// If the `DefiniteLength` is an absolute length, it will be directly converted to `Pixels`.
2740    /// If it is a fraction, the fraction will be multiplied by the `base_size` to get the length in pixels.
2741    ///
2742    /// # Arguments
2743    ///
2744    /// * `base_size` - The base size in `AbsoluteLength` to which the fraction will be applied.
2745    /// * `rem_size` - The size of one rem in pixels, used to convert rems to pixels.
2746    ///
2747    /// # Returns
2748    ///
2749    /// Returns the `DefiniteLength` as `Pixels`.
2750    ///
2751    /// # Examples
2752    ///
2753    /// ```
2754    /// # use zed::{DefiniteLength, AbsoluteLength, Pixels, px, rems};
2755    /// let length_in_pixels = DefiniteLength::Absolute(AbsoluteLength::Pixels(px(42.0)));
2756    /// let length_in_rems = DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0)));
2757    /// let length_as_fraction = DefiniteLength::Fraction(0.5);
2758    /// let base_size = AbsoluteLength::Pixels(px(100.0));
2759    /// let rem_size = px(16.0);
2760    ///
2761    /// assert_eq!(length_in_pixels.to_pixels(base_size, rem_size), Pixels(42.0));
2762    /// assert_eq!(length_in_rems.to_pixels(base_size, rem_size), Pixels(32.0));
2763    /// assert_eq!(length_as_fraction.to_pixels(base_size, rem_size), Pixels(50.0));
2764    /// ```
2765    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
2766        match self {
2767            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
2768            DefiniteLength::Fraction(fraction) => match base_size {
2769                AbsoluteLength::Pixels(px) => px * *fraction,
2770                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
2771            },
2772        }
2773    }
2774}
2775
2776impl Debug for DefiniteLength {
2777    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2778        match self {
2779            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
2780            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
2781        }
2782    }
2783}
2784
2785impl From<Pixels> for DefiniteLength {
2786    fn from(pixels: Pixels) -> Self {
2787        Self::Absolute(pixels.into())
2788    }
2789}
2790
2791impl From<Rems> for DefiniteLength {
2792    fn from(rems: Rems) -> Self {
2793        Self::Absolute(rems.into())
2794    }
2795}
2796
2797impl From<AbsoluteLength> for DefiniteLength {
2798    fn from(length: AbsoluteLength) -> Self {
2799        Self::Absolute(length)
2800    }
2801}
2802
2803impl Default for DefiniteLength {
2804    fn default() -> Self {
2805        Self::Absolute(AbsoluteLength::default())
2806    }
2807}
2808
2809/// A length that can be defined in pixels, rems, percent of parent, or auto.
2810#[derive(Clone, Copy)]
2811pub enum Length {
2812    /// A definite length specified either in pixels, rems, or as a fraction of the parent's size.
2813    Definite(DefiniteLength),
2814    /// An automatic length that is determined by the context in which it is used.
2815    Auto,
2816}
2817
2818impl Debug for Length {
2819    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2820        match self {
2821            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
2822            Length::Auto => write!(f, "auto"),
2823        }
2824    }
2825}
2826
2827/// Constructs a `DefiniteLength` representing a relative fraction of a parent size.
2828///
2829/// This function creates a `DefiniteLength` that is a specified fraction of a parent's dimension.
2830/// The fraction should be a floating-point number between 0.0 and 1.0, where 1.0 represents 100% of the parent's size.
2831///
2832/// # Arguments
2833///
2834/// * `fraction` - The fraction of the parent's size, between 0.0 and 1.0.
2835///
2836/// # Returns
2837///
2838/// A `DefiniteLength` representing the relative length as a fraction of the parent's size.
2839pub fn relative(fraction: f32) -> DefiniteLength {
2840    DefiniteLength::Fraction(fraction)
2841}
2842
2843/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
2844pub fn phi() -> DefiniteLength {
2845    relative(1.618_034)
2846}
2847
2848/// Constructs a `Rems` value representing a length in rems.
2849///
2850/// # Arguments
2851///
2852/// * `rems` - The number of rems for the length.
2853///
2854/// # Returns
2855///
2856/// A `Rems` representing the specified number of rems.
2857pub fn rems(rems: f32) -> Rems {
2858    Rems(rems)
2859}
2860
2861/// Constructs a `Pixels` value representing a length in pixels.
2862///
2863/// # Arguments
2864///
2865/// * `pixels` - The number of pixels for the length.
2866///
2867/// # Returns
2868///
2869/// A `Pixels` representing the specified number of pixels.
2870pub const fn px(pixels: f32) -> Pixels {
2871    Pixels(pixels)
2872}
2873
2874/// Returns a `Length` representing an automatic length.
2875///
2876/// The `auto` length is often used in layout calculations where the length should be determined
2877/// by the layout context itself rather than being explicitly set. This is commonly used in CSS
2878/// for properties like `width`, `height`, `margin`, `padding`, etc., where `auto` can be used
2879/// to instruct the layout engine to calculate the size based on other factors like the size of the
2880/// container or the intrinsic size of the content.
2881///
2882/// # Returns
2883///
2884/// A `Length` variant set to `Auto`.
2885pub fn auto() -> Length {
2886    Length::Auto
2887}
2888
2889impl From<Pixels> for Length {
2890    fn from(pixels: Pixels) -> Self {
2891        Self::Definite(pixels.into())
2892    }
2893}
2894
2895impl From<Rems> for Length {
2896    fn from(rems: Rems) -> Self {
2897        Self::Definite(rems.into())
2898    }
2899}
2900
2901impl From<DefiniteLength> for Length {
2902    fn from(length: DefiniteLength) -> Self {
2903        Self::Definite(length)
2904    }
2905}
2906
2907impl From<AbsoluteLength> for Length {
2908    fn from(length: AbsoluteLength) -> Self {
2909        Self::Definite(length.into())
2910    }
2911}
2912
2913impl Default for Length {
2914    fn default() -> Self {
2915        Self::Definite(DefiniteLength::default())
2916    }
2917}
2918
2919impl From<()> for Length {
2920    fn from(_: ()) -> Self {
2921        Self::Definite(DefiniteLength::default())
2922    }
2923}
2924
2925/// Provides a trait for types that can calculate half of their value.
2926///
2927/// The `Half` trait is used for types that can be evenly divided, returning a new instance of the same type
2928/// representing half of the original value. This is commonly used for types that represent measurements or sizes,
2929/// such as lengths or pixels, where halving is a frequent operation during layout calculations or animations.
2930pub trait Half {
2931    /// Returns half of the current value.
2932    ///
2933    /// # Returns
2934    ///
2935    /// A new instance of the implementing type, representing half of the original value.
2936    fn half(&self) -> Self;
2937}
2938
2939impl Half for i32 {
2940    fn half(&self) -> Self {
2941        self / 2
2942    }
2943}
2944
2945impl Half for f32 {
2946    fn half(&self) -> Self {
2947        self / 2.
2948    }
2949}
2950
2951impl Half for DevicePixels {
2952    fn half(&self) -> Self {
2953        Self(self.0 / 2)
2954    }
2955}
2956
2957impl Half for ScaledPixels {
2958    fn half(&self) -> Self {
2959        Self(self.0 / 2.)
2960    }
2961}
2962
2963impl Half for Pixels {
2964    fn half(&self) -> Self {
2965        Self(self.0 / 2.)
2966    }
2967}
2968
2969impl Half for Rems {
2970    fn half(&self) -> Self {
2971        Self(self.0 / 2.)
2972    }
2973}
2974
2975/// Provides a trait for types that can negate their values.
2976pub trait Negate {
2977    /// Returns the negation of the given value
2978    fn negate(self) -> Self;
2979}
2980
2981impl Negate for i32 {
2982    fn negate(self) -> Self {
2983        -self
2984    }
2985}
2986
2987impl Negate for f32 {
2988    fn negate(self) -> Self {
2989        -self
2990    }
2991}
2992
2993impl Negate for DevicePixels {
2994    fn negate(self) -> Self {
2995        Self(-self.0)
2996    }
2997}
2998
2999impl Negate for ScaledPixels {
3000    fn negate(self) -> Self {
3001        Self(-self.0)
3002    }
3003}
3004
3005impl Negate for Pixels {
3006    fn negate(self) -> Self {
3007        Self(-self.0)
3008    }
3009}
3010
3011impl Negate for Rems {
3012    fn negate(self) -> Self {
3013        Self(-self.0)
3014    }
3015}
3016
3017/// A trait for checking if a value is zero.
3018///
3019/// This trait provides a method to determine if a value is considered to be zero.
3020/// It is implemented for various numeric and length-related types where the concept
3021/// of zero is applicable. This can be useful for comparisons, optimizations, or
3022/// determining if an operation has a neutral effect.
3023pub trait IsZero {
3024    /// Determines if the value is zero.
3025    ///
3026    /// # Returns
3027    ///
3028    /// Returns `true` if the value is zero, `false` otherwise.
3029    fn is_zero(&self) -> bool;
3030}
3031
3032impl IsZero for DevicePixels {
3033    fn is_zero(&self) -> bool {
3034        self.0 == 0
3035    }
3036}
3037
3038impl IsZero for ScaledPixels {
3039    fn is_zero(&self) -> bool {
3040        self.0 == 0.
3041    }
3042}
3043
3044impl IsZero for Pixels {
3045    fn is_zero(&self) -> bool {
3046        self.0 == 0.
3047    }
3048}
3049
3050impl IsZero for Rems {
3051    fn is_zero(&self) -> bool {
3052        self.0 == 0.
3053    }
3054}
3055
3056impl IsZero for AbsoluteLength {
3057    fn is_zero(&self) -> bool {
3058        match self {
3059            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
3060            AbsoluteLength::Rems(rems) => rems.is_zero(),
3061        }
3062    }
3063}
3064
3065impl IsZero for DefiniteLength {
3066    fn is_zero(&self) -> bool {
3067        match self {
3068            DefiniteLength::Absolute(length) => length.is_zero(),
3069            DefiniteLength::Fraction(fraction) => *fraction == 0.,
3070        }
3071    }
3072}
3073
3074impl IsZero for Length {
3075    fn is_zero(&self) -> bool {
3076        match self {
3077            Length::Definite(length) => length.is_zero(),
3078            Length::Auto => false,
3079        }
3080    }
3081}
3082
3083impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
3084    fn is_zero(&self) -> bool {
3085        self.x.is_zero() && self.y.is_zero()
3086    }
3087}
3088
3089impl<T> IsZero for Size<T>
3090where
3091    T: IsZero + Default + Debug + Clone,
3092{
3093    fn is_zero(&self) -> bool {
3094        self.width.is_zero() || self.height.is_zero()
3095    }
3096}
3097
3098impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
3099    fn is_zero(&self) -> bool {
3100        self.size.is_zero()
3101    }
3102}
3103
3104impl<T> IsZero for Corners<T>
3105where
3106    T: IsZero + Clone + Default + Debug,
3107{
3108    fn is_zero(&self) -> bool {
3109        self.top_left.is_zero()
3110            && self.top_right.is_zero()
3111            && self.bottom_right.is_zero()
3112            && self.bottom_left.is_zero()
3113    }
3114}
3115
3116#[cfg(test)]
3117mod tests {
3118    use super::*;
3119
3120    #[test]
3121    fn test_bounds_intersects() {
3122        let bounds1 = Bounds {
3123            origin: Point { x: 0.0, y: 0.0 },
3124            size: Size {
3125                width: 5.0,
3126                height: 5.0,
3127            },
3128        };
3129        let bounds2 = Bounds {
3130            origin: Point { x: 4.0, y: 4.0 },
3131            size: Size {
3132                width: 5.0,
3133                height: 5.0,
3134            },
3135        };
3136        let bounds3 = Bounds {
3137            origin: Point { x: 10.0, y: 10.0 },
3138            size: Size {
3139                width: 5.0,
3140                height: 5.0,
3141            },
3142        };
3143
3144        // Test Case 1: Intersecting bounds
3145        assert!(bounds1.intersects(&bounds2));
3146
3147        // Test Case 2: Non-Intersecting bounds
3148        assert!(!bounds1.intersects(&bounds3));
3149
3150        // Test Case 3: Bounds intersecting with themselves
3151        assert!(bounds1.intersects(&bounds1));
3152    }
3153}