mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:17:44 +00:00
LibWeb: Treat replaced size constraint resolutions as mutually exclusive
Previously, we would run through all the constraints in the spec one by one, but if we check and resolve each constraint in the order they are defined in the spec, only the first four will ever match. This leads me to believe that these constraints are meant to be mutually exclusive instead, meaning that we must check the most specific constraints first and return upon the first resolution that matches.
This commit is contained in:
parent
34c5043cbe
commit
051f357110
1 changed files with 34 additions and 35 deletions
|
@ -259,50 +259,49 @@ FormattingContext::ShrinkToFitResult FormattingContext::calculate_shrink_to_fit_
|
|||
CSSPixelSize FormattingContext::solve_replaced_size_constraint(CSSPixels input_width, CSSPixels input_height, Box const& box, AvailableSpace const& available_space) const
|
||||
{
|
||||
// 10.4 Minimum and maximum widths: 'min-width' and 'max-width'
|
||||
// https://www.w3.org/TR/CSS22/visudet.html#min-max-widths
|
||||
|
||||
auto const& containing_block = *box.non_anonymous_containing_block();
|
||||
auto const& containing_block_state = m_state.get(containing_block);
|
||||
auto width_of_containing_block = containing_block_state.content_width();
|
||||
auto height_of_containing_block = containing_block_state.content_height();
|
||||
|
||||
CSSPixels specified_min_width = box.computed_values().min_width().is_auto() ? 0 : box.computed_values().min_width().to_px(box, width_of_containing_block);
|
||||
CSSPixels specified_max_width = should_treat_max_width_as_none(box, available_space.width) ? input_width : box.computed_values().max_width().to_px(box, width_of_containing_block);
|
||||
CSSPixels specified_min_height = box.computed_values().min_height().is_auto() ? 0 : box.computed_values().min_height().to_px(box, height_of_containing_block);
|
||||
CSSPixels specified_max_height = should_treat_max_height_as_none(box, available_space.height) ? input_height : box.computed_values().max_height().to_px(box, height_of_containing_block);
|
||||
auto min_width = box.computed_values().min_width().is_auto() ? 0 : box.computed_values().min_width().to_px(box, width_of_containing_block);
|
||||
auto specified_max_width = should_treat_max_width_as_none(box, available_space.width) ? input_width : box.computed_values().max_width().to_px(box, width_of_containing_block);
|
||||
auto max_width = max(min_width, specified_max_width);
|
||||
|
||||
auto min_width = min(specified_min_width, specified_max_width);
|
||||
auto max_width = max(specified_min_width, specified_max_width);
|
||||
auto min_height = min(specified_min_height, specified_max_height);
|
||||
auto max_height = max(specified_min_height, specified_max_height);
|
||||
auto min_height = box.computed_values().min_height().is_auto() ? 0 : box.computed_values().min_height().to_px(box, height_of_containing_block);
|
||||
auto specified_max_height = should_treat_max_height_as_none(box, available_space.height) ? input_height : box.computed_values().max_height().to_px(box, height_of_containing_block);
|
||||
auto max_height = max(min_height, specified_max_height);
|
||||
|
||||
struct Size {
|
||||
CSSPixels width;
|
||||
CSSPixels height;
|
||||
} size = { input_width, input_height };
|
||||
auto& w = size.width;
|
||||
auto& h = size.height;
|
||||
auto aspect_ratio = input_width / input_height;
|
||||
|
||||
if (w > max_width)
|
||||
size = { max_width, max(max_width * (h / w), min_height) };
|
||||
if (w < min_width)
|
||||
size = { min_width, min(min_width * (h / w), max_height) };
|
||||
if (h > max_height)
|
||||
size = { max(max_height * (w / h), min_width), max_height };
|
||||
if (h < min_height)
|
||||
size = { min(min_height * (w / h), max_width), min_height };
|
||||
if ((w > max_width && h > max_height) && (max_width / w <= max_height / h))
|
||||
size = { max_width, max(min_height, max_width * (h / w)) };
|
||||
if ((w > max_width && h > max_height) && (max_width / w > max_height / h))
|
||||
size = { max(min_width, max_height * (w / h)), max_height };
|
||||
if ((w < min_width && h < min_height) && (min_width / w <= min_height / h))
|
||||
size = { min(max_width, min_height * (w / h)), min_height };
|
||||
if ((w < min_width && h < min_height) && (min_width / w > min_height / h))
|
||||
size = { min_width, min(max_height, min_width * (h / w)) };
|
||||
if (w < min_width && h > max_height)
|
||||
size = { min_width, max_height };
|
||||
if (w > max_width && h < min_height)
|
||||
size = { max_width, min_height };
|
||||
return { w, h };
|
||||
// These are from the "Constraint Violation" table in spec, but reordered so that each condition is
|
||||
// interpreted as mutually exclusive to any other.
|
||||
if (input_width < min_width && input_height > max_height)
|
||||
return { min_width, max_height };
|
||||
if (input_width > max_width && input_height < min_height)
|
||||
return { max_width, min_height };
|
||||
|
||||
if (input_width > max_width && input_height > max_height && max_width / input_width <= max_height / input_height)
|
||||
return { max_width, max(min_height, max_width / aspect_ratio) };
|
||||
if (input_width > max_width && input_height > max_height && max_width / input_width > max_height / input_height)
|
||||
return { max(min_width, max_height * aspect_ratio), max_height };
|
||||
if (input_width < min_width && input_height < min_height && min_width / input_width <= min_height / input_height)
|
||||
return { min(max_width, min_height * aspect_ratio), min_height };
|
||||
if (input_width < min_width && input_height < min_height && min_width / input_width > min_height / input_height)
|
||||
return { min_width, min(max_height, min_width / aspect_ratio) };
|
||||
|
||||
if (input_width > max_width)
|
||||
return { max_width, max(max_width / aspect_ratio, min_height) };
|
||||
if (input_width < min_width)
|
||||
return { min_width, min(min_width / aspect_ratio, max_height) };
|
||||
if (input_height > max_height)
|
||||
return { max(max_height * aspect_ratio, min_width), max_height };
|
||||
if (input_height < min_height)
|
||||
return { min(min_height * aspect_ratio, max_width), min_height };
|
||||
|
||||
return { input_width, input_height };
|
||||
}
|
||||
|
||||
Optional<CSSPixels> FormattingContext::compute_auto_height_for_absolutely_positioned_element(Box const& box, AvailableSpace const& available_space, BeforeOrAfterInsideLayout before_or_after_inside_layout) const
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue