layout-cat 0.1.0

Box-model layout: cascade + block layout over a dom-cat tree using css-cat stylesheets. Produces a LayoutBox tree with positions and dimensions. No mut, no Rc/Arc, no interior mutability, no panics, exhaustive matches. Fourth sub-crate of a Servo-replacement webview runtime targeting Tauri.
//! Length values and their resolution.

/// A length value as written in CSS.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LengthValue {
    /// `auto`.
    Auto,
    /// A pixel length (`16px`).
    Px(f64),
    /// An em length (`1.5em`).  Multiplier on the element's font-size.
    Em(f64),
    /// A percentage (`50%`).
    Percent(f64),
}

impl Eq for LengthValue {}

impl LengthValue {
    /// Resolve to pixels given the containing-block width (for `%`) and
    /// font-size (for `em`).
    ///
    /// `Auto` resolves to `None`; callers decide what `auto` means in
    /// their context (fill, shrink-to-fit, zero, ...).
    #[must_use]
    pub fn resolve(self, containing_width: f64, font_size: f64) -> Option<f64> {
        match self {
            Self::Auto => None,
            Self::Px(v) => Some(v),
            Self::Em(v) => Some(v * font_size),
            Self::Percent(p) => Some(p * containing_width / 100.0),
        }
    }

    /// Resolve with `auto` falling back to `0`.
    #[must_use]
    pub fn resolve_or_zero(self, containing_width: f64, font_size: f64) -> f64 {
        self.resolve(containing_width, font_size).unwrap_or(0.0)
    }
}

/// A point in layout space.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Point {
    x: f64,
    y: f64,
}

impl Eq for Point {}

impl Point {
    /// Build a point.
    #[must_use]
    pub fn new(x: f64, y: f64) -> Self {
        Self { x, y }
    }

    /// The x coordinate.
    #[must_use]
    pub fn x(&self) -> f64 {
        self.x
    }

    /// The y coordinate.
    #[must_use]
    pub fn y(&self) -> f64 {
        self.y
    }
}

/// A rectangle in layout space.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Rect {
    origin: Point,
    width: f64,
    height: f64,
}

impl Eq for Rect {}

impl Rect {
    /// Build a rectangle from origin and dimensions.
    #[must_use]
    pub fn new(origin: Point, width: f64, height: f64) -> Self {
        Self {
            origin,
            width,
            height,
        }
    }

    /// The top-left corner.
    #[must_use]
    pub fn origin(&self) -> Point {
        self.origin
    }

    /// The width.
    #[must_use]
    pub fn width(&self) -> f64 {
        self.width
    }

    /// The height.
    #[must_use]
    pub fn height(&self) -> f64 {
        self.height
    }
}

/// Four-sided edge values (margin, padding, border).
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Edges {
    top: f64,
    right: f64,
    bottom: f64,
    left: f64,
}

impl Eq for Edges {}

impl Edges {
    /// Build edges from four values.
    #[must_use]
    pub fn new(top: f64, right: f64, bottom: f64, left: f64) -> Self {
        Self {
            top,
            right,
            bottom,
            left,
        }
    }

    /// Zero on all sides.
    #[must_use]
    pub fn zero() -> Self {
        Self::default()
    }

    /// The top edge.
    #[must_use]
    pub fn top(&self) -> f64 {
        self.top
    }

    /// The right edge.
    #[must_use]
    pub fn right(&self) -> f64 {
        self.right
    }

    /// The bottom edge.
    #[must_use]
    pub fn bottom(&self) -> f64 {
        self.bottom
    }

    /// The left edge.
    #[must_use]
    pub fn left(&self) -> f64 {
        self.left
    }

    /// Sum of left + right edges (used in width arithmetic).
    #[must_use]
    pub fn horizontal(&self) -> f64 {
        self.left + self.right
    }

    /// Sum of top + bottom edges (used in height arithmetic).
    #[must_use]
    pub fn vertical(&self) -> f64 {
        self.top + self.bottom
    }
}

/// The default font size used when nothing in the cascade has set one.
pub const DEFAULT_FONT_SIZE_PX: f64 = 16.0;