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