geometry.rs

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