mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:47:34 +00:00
LibWeb: Express intrinsic size layout via size constraints
Previously, we had three layout modes: - Normal: - Everything uses the computed values from CSS. - MinContent: - Containing blocks act as if they have 0 width. - All line breaking opportunities are taken. - MaxContent: - Containing blocks act as if they have infinite width. - Only forced line breaks are accepted. The above was based on a set of misunderstandings of CSS sizing. A major problem with the above was that *all* containing blocks behaved differently during intrinsic size layout, not just the relevant one. With this patch there are only two layout modes: - Normal: - Everything uses the computed values from CSS. - IntrinsicSizeDetermination: - One or more boxes have size constraints applied. There are two size constraints per layout box, set here: - FormattingState::NodeState::width_constraint - FormattingState::NodeState::height_constraint They are of type SizeConstraint and can be one of None, MinContent, or MaxContent. The default is None. When performing an IntrinsicSizeDetermination layout, we now assign a size constraint to the box we're trying to determine the intrinsic size of, which is then honored by using two new helpers to query the dimensions of containing blocks: - FormattingContext::containing_block_width_for(Box) - FormattingContext::containing_block_height_for(Box) If there's a relevant constraint in effect on the Box, the size of its containing block is adjusted accordingly. This is essentially an implementation of the "available space" constraints from CSS-SIZING-3. I'm sure some things will break from this, and we'll have to deal with that separately. Spec: https://drafts.csswg.org/css-sizing-3/#available
This commit is contained in:
parent
66d08d2417
commit
64959a8504
13 changed files with 213 additions and 174 deletions
|
@ -78,7 +78,7 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode layout_mode)
|
|||
determine_flex_base_size_and_hypothetical_main_size(flex_item);
|
||||
}
|
||||
|
||||
if (layout_mode == LayoutMode::MinContent || layout_mode == LayoutMode::MaxContent) {
|
||||
if (m_flex_container_state.width_constraint != SizeConstraint::None || m_flex_container_state.height_constraint != SizeConstraint::None) {
|
||||
// We're computing intrinsic size for the flex container.
|
||||
determine_intrinsic_size_of_flex_container(layout_mode);
|
||||
|
||||
|
@ -740,7 +740,7 @@ float FlexFormattingContext::content_based_minimum_size(FlexItem const& item) co
|
|||
void FlexFormattingContext::determine_main_size_of_flex_container(bool const main_is_constrained, float const main_min_size, float const main_max_size)
|
||||
{
|
||||
// FIXME: This function should make use of our ability to calculate the flex container's
|
||||
// intrinsic max-content sizes via LayoutMode::MaxContent.
|
||||
// intrinsic max-content sizes.
|
||||
|
||||
if (!main_is_constrained || !m_available_space->main.has_value()) {
|
||||
// Uses https://www.w3.org/TR/css-flexbox-1/#intrinsic-main-sizes
|
||||
|
@ -1348,7 +1348,7 @@ float FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container(Lay
|
|||
// The min-content main size of a single-line flex container is calculated identically to the max-content main size,
|
||||
// except that the flex items’ min-content contributions are used instead of their max-content contributions.
|
||||
// However, for a multi-line container, it is simply the largest min-content contribution of all the non-collapsed flex items in the flex container.
|
||||
if (!is_single_line() && layout_mode == LayoutMode::MinContent) {
|
||||
if (!is_single_line() && (m_flex_container_state.width_constraint == SizeConstraint::MinContent || m_flex_container_state.height_constraint == SizeConstraint::MinContent)) {
|
||||
float largest_contribution = 0;
|
||||
for (auto const& flex_item : m_flex_items) {
|
||||
// FIXME: Skip collapsed flex items.
|
||||
|
@ -1368,7 +1368,7 @@ float FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container(Lay
|
|||
// This is the item’s max-content flex fraction.
|
||||
for (auto& flex_item : m_flex_items) {
|
||||
float contribution;
|
||||
if (layout_mode == LayoutMode::MinContent)
|
||||
if (m_flex_container_state.width_constraint == SizeConstraint::MinContent || m_flex_container_state.height_constraint == SizeConstraint::MinContent)
|
||||
contribution = calculate_main_min_content_contribution(flex_item);
|
||||
else
|
||||
contribution = calculate_main_max_content_contribution(flex_item);
|
||||
|
@ -1433,9 +1433,9 @@ float FlexFormattingContext::calculate_intrinsic_cross_size_of_flex_container(La
|
|||
float largest_contribution = 0;
|
||||
for (auto& flex_item : m_flex_items) {
|
||||
float contribution;
|
||||
if (layout_mode == LayoutMode::MinContent)
|
||||
if (m_flex_container_state.width_constraint == SizeConstraint::MinContent || m_flex_container_state.height_constraint == SizeConstraint::MinContent)
|
||||
contribution = calculate_cross_min_content_contribution(flex_item);
|
||||
else if (layout_mode == LayoutMode::MaxContent)
|
||||
else if (m_flex_container_state.width_constraint == SizeConstraint::MaxContent || m_flex_container_state.height_constraint == SizeConstraint::MaxContent)
|
||||
contribution = calculate_cross_max_content_contribution(flex_item);
|
||||
largest_contribution = max(largest_contribution, contribution);
|
||||
}
|
||||
|
@ -1529,6 +1529,16 @@ float FlexFormattingContext::calculate_min_content_main_size(FlexItem const& ite
|
|||
return is_row_layout() ? calculate_min_content_width(item.box) : calculate_min_content_height(item.box);
|
||||
}
|
||||
|
||||
float FlexFormattingContext::calculate_fit_content_main_size(FlexItem const& item) const
|
||||
{
|
||||
return is_row_layout() ? calculate_fit_content_width(item.box, m_available_space->main) : calculate_fit_content_height(item.box, m_available_space->main);
|
||||
}
|
||||
|
||||
float FlexFormattingContext::calculate_fit_content_cross_size(FlexItem const& item) const
|
||||
{
|
||||
return is_row_layout() ? calculate_fit_content_height(item.box, m_available_space->cross) : calculate_fit_content_width(item.box, m_available_space->cross);
|
||||
}
|
||||
|
||||
float FlexFormattingContext::calculate_max_content_main_size(FlexItem const& item) const
|
||||
{
|
||||
return is_row_layout() ? calculate_max_content_width(item.box) : calculate_max_content_height(item.box);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue