Skip to content

Commit

Permalink
Use enum for replaced element constraint violation
Browse files Browse the repository at this point in the history
Signed-off-by: Nico Burns <[email protected]>
  • Loading branch information
nicoburns committed Feb 2, 2025
1 parent ff7c8c9 commit dac5c61
Showing 1 changed file with 37 additions and 16 deletions.
53 changes: 37 additions & 16 deletions packages/blitz-dom/src/layout/replaced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ pub struct ReplacedContext {
pub attr_size: taffy::Size<Option<f32>>,
}

/// Whether a height/width value is violating it's min- and max- constraints
/// The min- and max- constraints cannot both be violated because the max
/// constraint if floored by the min constraint (min constraint takes priority)
enum Violation {
/// Constraints are not violated
None,
/// Min constraint is violated
Min,
/// Max constraint is violated
Max,
}

pub fn replaced_measure_function(
known_dimensions: taffy::Size<Option<f32>>,
parent_size: taffy::Size<Option<f32>>,
Expand Down Expand Up @@ -88,50 +100,61 @@ pub fn replaced_measure_function(
let size = unclamped_size.map(|s| s.max(0.0));

// Violations
let w_min = size.width < min_size.width.unwrap_or(0.0);
let w_max = size.width > max_size.width.unwrap_or(f32::INFINITY);
let h_min = size.height < min_size.height.unwrap_or(0.0);
let h_max = size.height > max_size.height.unwrap_or(f32::INFINITY);
let width_violation = if size.width < min_size.width.unwrap_or(0.0) {
Violation::Min
} else if size.width > max_size.width.unwrap_or(f32::INFINITY) {
Violation::Max
} else {
Violation::None
};

let height_violation = if size.height < min_size.height.unwrap_or(0.0) {
Violation::Min
} else if size.height > max_size.height.unwrap_or(f32::INFINITY) {
Violation::Max
} else {
Violation::None
};

// Clamp following rules in table at
// https://www.w3.org/TR/CSS22/visudet.html#min-max-widths
let size = match (w_min, w_max, h_min, h_max) {
let size = match (width_violation, height_violation) {
// No constraint violation
(false, false, false, false) => size,
(Violation::None, Violation::None) => size,
// w > max-width
(false, true, false, false) => {
(Violation::Max, Violation::None) => {
let max_width = max_size.width.unwrap();
Size {
width: max_width,
height: (max_width * inv_aspect_ratio).maybe_max(min_size.height),
}
}
// w < min-width
(true, false, false, false) => {
(Violation::Min, Violation::None) => {
let min_width = min_size.width.unwrap();
Size {
width: min_width,
height: (min_width * inv_aspect_ratio).maybe_min(max_size.height),
}
}
// h > max-height
(false, false, false, true) => {
(Violation::None, Violation::Max) => {
let max_height = max_size.height.unwrap();
Size {
width: (max_height * aspect_ratio).maybe_max(min_size.width),
height: max_height,
}
}
// h < min-height
(false, false, true, false) => {
(Violation::None, Violation::Min) => {
let min_height = min_size.height.unwrap();
Size {
width: (min_height * aspect_ratio).maybe_min(max_size.width),
height: min_height,
}
}
// (w > max-width) and (h > max-height)
(false, true, false, true) => {
(Violation::Max, Violation::Max) => {
let max_width = max_size.width.unwrap();
let max_height = max_size.height.unwrap();
if max_width / size.width <= max_height / size.height {
Expand All @@ -147,7 +170,7 @@ pub fn replaced_measure_function(
}
}
// (w < min-width) and (h < min-height)
(true, false, true, false) => {
(Violation::Min, Violation::Min) => {
let min_width = min_size.width.unwrap();
let min_height = min_size.height.unwrap();
if min_width / size.width <= min_height / size.height {
Expand All @@ -163,7 +186,7 @@ pub fn replaced_measure_function(
}
}
// (w < min-width) and (h > max-height)
(true, false, false, true) => {
(Violation::Min, Violation::Max) => {
let min_width = min_size.width.unwrap();
let max_height = max_size.height.unwrap();
Size {
Expand All @@ -172,16 +195,14 @@ pub fn replaced_measure_function(
}
}
// (w < min-width) and (h > max-height)
(false, true, true, false) => {
(Violation::Max, Violation::Min) => {
let max_width = max_size.width.unwrap();
let min_height = min_size.height.unwrap();
Size {
width: max_width,
height: min_height,
}
}

_ => unreachable!("Max was already floored by min, so we cannot have both a min and a max violation in the same axis")
};

size + pb_sum
Expand Down

0 comments on commit dac5c61

Please sign in to comment.