From 61c27815e4b8e7e17ed9fed9bb703a98d794887c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 10 Jul 2022 22:06:20 +0200 Subject: [PATCH] LibWeb: More specialization of intrinsic sizing layout This patch adds a separate entry point for this kind of layout. We override it in BFC to set up initial width/height values for the BFC root block. Resulting dimensions are assigned as content_width and content_height at the end of intrinsic sizing, for each axis, if it's either "auto" or there's a min-content or max-content constraint in effect. --- .../LibWeb/Layout/BlockFormattingContext.cpp | 34 +++++++++++++++---- .../LibWeb/Layout/BlockFormattingContext.h | 1 + .../LibWeb/Layout/FormattingContext.cpp | 13 ++++--- .../LibWeb/Layout/FormattingContext.h | 2 ++ 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index ae56b33bcc..3a789ff3e6 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -369,8 +369,10 @@ void BlockFormattingContext::layout_inline_children(BlockContainer const& block_ auto& block_container_state = m_state.get_mutable(block_container); if (layout_mode == LayoutMode::IntrinsicSizeDetermination) { - block_container_state.content_width = containing_block_width_for(block_container); - block_container_state.content_height = containing_block_height_for(block_container); + if (block_container.computed_values().width().is_auto() || block_container_state.width_constraint != SizeConstraint::None) + block_container_state.content_width = containing_block_width_for(block_container); + if (block_container.computed_values().height().is_auto() || block_container_state.height_constraint != SizeConstraint::None) + block_container_state.content_height = containing_block_height_for(block_container); } InlineFormattingContext context(m_state, block_container, *this); @@ -385,7 +387,8 @@ void BlockFormattingContext::layout_inline_children(BlockContainer const& block_ } if (layout_mode == LayoutMode::IntrinsicSizeDetermination) { - block_container_state.content_width = max_line_width; + if (block_container.computed_values().width().is_auto() || block_container_state.width_constraint != SizeConstraint::None) + block_container_state.content_width = max_line_width; } // FIXME: This is weird. Figure out a way to make callers responsible for setting the content height. @@ -449,6 +452,19 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain independent_formatting_context->parent_context_did_dimension_child_root_box(); } +void BlockFormattingContext::run_intrinsic_size_determination(Box const& box) +{ + auto& box_state = m_state.get_mutable(box); + + if (box.has_definite_width()) + box_state.content_width = box.computed_values().width().resolved(box, CSS::Length::make_px(containing_block_width_for(box))).to_px(box); + + if (box.has_definite_height()) + box_state.content_height = box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box); + + run(box, LayoutMode::IntrinsicSizeDetermination); +} + void BlockFormattingContext::layout_block_level_children(BlockContainer const& block_container, LayoutMode layout_mode) { VERIFY(!block_container.children_are_inline()); @@ -457,8 +473,10 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer const& b if (layout_mode == LayoutMode::IntrinsicSizeDetermination) { auto& block_container_state = m_state.get_mutable(block_container); - block_container_state.content_width = containing_block_width_for(block_container); - block_container_state.content_height = containing_block_height_for(block_container); + if (block_container.computed_values().width().is_auto() || block_container_state.width_constraint != SizeConstraint::None) + block_container_state.content_width = containing_block_width_for(block_container); + if (block_container.computed_values().height().is_auto() || block_container_state.height_constraint != SizeConstraint::None) + block_container_state.content_height = containing_block_height_for(block_container); } block_container.for_each_child_of_type([&](Box& box) { @@ -468,8 +486,10 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer const& b if (layout_mode == LayoutMode::IntrinsicSizeDetermination) { auto& block_container_state = m_state.get_mutable(block_container); - block_container_state.content_width = greatest_child_width(block_container); - block_container_state.content_height = content_height; + if (block_container.computed_values().width().is_auto() || block_container_state.width_constraint != SizeConstraint::None) + block_container_state.content_width = greatest_child_width(block_container); + if (block_container.computed_values().height().is_auto() || block_container_state.height_constraint != SizeConstraint::None) + block_container_state.content_height = content_height; } } diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h index 39753ebbf3..d91dc51211 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h @@ -22,6 +22,7 @@ public: ~BlockFormattingContext(); virtual void run(Box const&, LayoutMode) override; + virtual void run_intrinsic_size_determination(Box const&) override; bool is_initial() const; diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index aa9fac9c43..4594ce8f2c 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -28,6 +28,11 @@ FormattingContext::FormattingContext(Type type, FormattingState& state, Box cons FormattingContext::~FormattingContext() = default; +void FormattingContext::run_intrinsic_size_determination(Box const& box) +{ + run(box, LayoutMode::IntrinsicSizeDetermination); +} + bool FormattingContext::creates_block_formatting_context(Box const& box) { if (box.is_root_element()) @@ -863,7 +868,7 @@ float FormattingContext::calculate_min_content_width(Layout::Box const& box) con auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); VERIFY(context); - context->run(box, LayoutMode::IntrinsicSizeDetermination); + context->run_intrinsic_size_determination(box); if (context->type() == FormattingContext::Type::Flex) { cache.min_content_width = box_state.content_width; } else { @@ -893,7 +898,7 @@ float FormattingContext::calculate_max_content_width(Layout::Box const& box) con auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); VERIFY(context); - context->run(box, LayoutMode::IntrinsicSizeDetermination); + context->run_intrinsic_size_determination(box); if (context->type() == FormattingContext::Type::Flex) { cache.max_content_width = box_state.content_width; } else { @@ -924,7 +929,7 @@ float FormattingContext::calculate_min_content_height(Layout::Box const& box) co auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); VERIFY(context); - context->run(box, LayoutMode::IntrinsicSizeDetermination); + context->run_intrinsic_size_determination(box); if (context->type() == FormattingContext::Type::Flex) { cache.min_content_height = box_state.content_height; } else { @@ -955,7 +960,7 @@ float FormattingContext::calculate_max_content_height(Layout::Box const& box) co auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); VERIFY(context); - context->run(box, LayoutMode::IntrinsicSizeDetermination); + context->run_intrinsic_size_determination(box); if (context->type() == FormattingContext::Type::Flex) { cache.max_content_height = box_state.content_height; } else { diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.h b/Userland/Libraries/LibWeb/Layout/FormattingContext.h index 74fb58ff80..28f2b6fbd1 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.h @@ -61,6 +61,8 @@ public: static float containing_block_width_for(Box const&, FormattingState const&); static float containing_block_height_for(Box const&, FormattingState const&); + virtual void run_intrinsic_size_determination(Box const&); + protected: FormattingContext(Type, FormattingState&, Box const&, FormattingContext* parent = nullptr);