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