mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
LibWeb: Implement CSS fit-content algorithm precisely as spec says
We were using the available space in place of the stretch-fit size. This was an oversight, and this patch fixes that. It's very possible that this will uncover broken behavior elsewhere.
This commit is contained in:
parent
d7d8e3c78b
commit
27a7c5ef40
Notes:
sideshowbarker
2024-07-17 05:47:39 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/27a7c5ef40
2 changed files with 40 additions and 28 deletions
|
@ -1056,49 +1056,44 @@ void FormattingContext::compute_inset(Box const& box)
|
|||
resolve_two_opposing_insets(computed_values.inset().top(), computed_values.inset().bottom(), box_state.inset_top, box_state.inset_bottom, containing_block_height_for(box));
|
||||
}
|
||||
|
||||
float FormattingContext::calculate_fit_content_size(float min_content_size, float max_content_size, AvailableSize const& available_size) const
|
||||
// https://drafts.csswg.org/css-sizing-3/#fit-content-size
|
||||
float FormattingContext::calculate_fit_content_width(Layout::Box const& box, AvailableSpace const& available_space) const
|
||||
{
|
||||
// If the available space in a given axis is definite, equal to clamp(min-content size, stretch-fit size, max-content size)
|
||||
// If the available space in a given axis is definite,
|
||||
// equal to clamp(min-content size, stretch-fit size, max-content size)
|
||||
// (i.e. max(min-content size, min(max-content size, stretch-fit size))).
|
||||
if (available_size.is_definite()) {
|
||||
// FIXME: Compute the real stretch-fit size.
|
||||
auto stretch_fit_size = available_size.to_px();
|
||||
auto s = max(min_content_size, min(max_content_size, stretch_fit_size));
|
||||
return s;
|
||||
if (available_space.width.is_definite()) {
|
||||
return max(calculate_min_content_width(box),
|
||||
min(calculate_stretch_fit_width(box, available_space.width),
|
||||
calculate_max_content_width(box)));
|
||||
}
|
||||
|
||||
// When sizing under a min-content constraint, equal to the min-content size.
|
||||
if (available_size.is_min_content())
|
||||
return min_content_size;
|
||||
|
||||
// Otherwise, equal to the max-content size in that axis.
|
||||
return max_content_size;
|
||||
}
|
||||
|
||||
float FormattingContext::calculate_fit_content_width(Layout::Box const& box, AvailableSpace const& available_space) const
|
||||
{
|
||||
// When sizing under a min-content constraint, equal to the min-content size.
|
||||
// NOTE: We check this first, to avoid needlessly calculating the max-content size.
|
||||
if (available_space.width.is_min_content())
|
||||
return calculate_min_content_width(box);
|
||||
|
||||
if (available_space.width.is_max_content())
|
||||
return calculate_max_content_width(box);
|
||||
|
||||
return calculate_fit_content_size(calculate_min_content_width(box), calculate_max_content_width(box), available_space.width);
|
||||
// Otherwise, equal to the max-content size in that axis.
|
||||
return calculate_max_content_width(box);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-sizing-3/#fit-content-size
|
||||
float FormattingContext::calculate_fit_content_height(Layout::Box const& box, AvailableSpace const& available_space) const
|
||||
{
|
||||
// If the available space in a given axis is definite,
|
||||
// equal to clamp(min-content size, stretch-fit size, max-content size)
|
||||
// (i.e. max(min-content size, min(max-content size, stretch-fit size))).
|
||||
if (available_space.height.is_definite()) {
|
||||
return max(calculate_min_content_height(box, available_space.width),
|
||||
min(calculate_stretch_fit_height(box, available_space.height),
|
||||
calculate_max_content_height(box, available_space.width)));
|
||||
}
|
||||
|
||||
// When sizing under a min-content constraint, equal to the min-content size.
|
||||
// NOTE: We check this first, to avoid needlessly calculating the max-content size.
|
||||
if (available_space.height.is_min_content())
|
||||
return calculate_min_content_height(box, available_space.width);
|
||||
|
||||
if (available_space.height.is_max_content())
|
||||
return calculate_max_content_height(box, available_space.width);
|
||||
|
||||
return calculate_fit_content_size(calculate_min_content_height(box, available_space.width), calculate_max_content_height(box, available_space.width), available_space.height);
|
||||
// Otherwise, equal to the max-content size in that axis.
|
||||
return calculate_max_content_height(box, available_space.width);
|
||||
}
|
||||
|
||||
float FormattingContext::calculate_min_content_width(Layout::Box const& box) const
|
||||
|
@ -1382,4 +1377,20 @@ float FormattingContext::calculate_stretch_fit_width(Box const& box, AvailableSi
|
|||
- box_state.border_right;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-sizing-3/#stretch-fit-size
|
||||
float FormattingContext::calculate_stretch_fit_height(Box const& box, AvailableSize const& available_height) const
|
||||
{
|
||||
// The size a box would take if its outer size filled the available space in the given axis;
|
||||
// in other words, the stretch fit into the available space, if that is definite.
|
||||
// Undefined if the available space is indefinite.
|
||||
auto const& box_state = m_state.get(box);
|
||||
return available_height.to_px()
|
||||
- box_state.margin_top
|
||||
- box_state.margin_bottom
|
||||
- box_state.padding_top
|
||||
- box_state.padding_bottom
|
||||
- box_state.border_top
|
||||
- box_state.border_bottom;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,7 +70,8 @@ public:
|
|||
|
||||
float compute_box_y_position_with_respect_to_siblings(Box const&) const;
|
||||
|
||||
float calculate_stretch_fit_width(Box const&, AvailableSize const&) const;
|
||||
[[nodiscard]] float calculate_stretch_fit_width(Box const&, AvailableSize const&) const;
|
||||
[[nodiscard]] float calculate_stretch_fit_height(Box const&, AvailableSize const&) const;
|
||||
|
||||
virtual bool can_determine_size_of_child() const { return false; }
|
||||
virtual void determine_width_of_child(Box const&, AvailableSpace const&) { }
|
||||
|
|
Loading…
Reference in a new issue