diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 3f7e7b6511a..25080fec230 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -472,7 +472,7 @@ void BlockFormattingContext::layout_inline_children(BlockContainer const& block_ auto& block_container_state = m_state.get_mutable(block_container); - InlineFormattingContext context(m_state, block_container, *this); + InlineFormattingContext context(m_state, block_container, block_container_state, *this); context.run( block_container, layout_mode, diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 87a40b5b5a7..d1be17afc43 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, Andreas Kling + * Copyright (c) 2020-2024, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -18,9 +18,13 @@ namespace Web::Layout { -InlineFormattingContext::InlineFormattingContext(LayoutState& state, BlockContainer const& containing_block, BlockFormattingContext& parent) +InlineFormattingContext::InlineFormattingContext( + LayoutState& state, + BlockContainer const& containing_block, + LayoutState::UsedValues& containing_block_used_values, + BlockFormattingContext& parent) : FormattingContext(Type::Inline, state, containing_block, &parent) - , m_containing_block_state(state.get(containing_block)) + , m_containing_block_used_values(containing_block_used_values) { } @@ -39,7 +43,7 @@ BlockFormattingContext const& InlineFormattingContext::parent() const CSSPixels InlineFormattingContext::leftmost_x_offset_at(CSSPixels y) const { // NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC. - auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(m_containing_block_state, parent().root()); + auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(m_containing_block_used_values, parent().root()); CSSPixels y_in_root = box_in_root_rect.y() + y; auto space_and_containing_margin = parent().space_used_and_containing_margin_for_floats(y_in_root); auto left_side_floats_limit_to_right = space_and_containing_margin.left_total_containing_margin + space_and_containing_margin.left_used_space; @@ -55,7 +59,7 @@ CSSPixels InlineFormattingContext::leftmost_x_offset_at(CSSPixels y) const AvailableSize InlineFormattingContext::available_space_for_line(CSSPixels y) const { - auto intrusions = parent().intrusion_by_floats_into_box(m_containing_block_state, y); + auto intrusions = parent().intrusion_by_floats_into_box(m_containing_block_used_values, y); if (m_available_space->width.is_definite()) { return AvailableSize::make_definite(m_available_space->width.to_px_or_zero() - (intrusions.left + intrusions.right)); } else { @@ -81,7 +85,7 @@ void InlineFormattingContext::run(Box const&, LayoutMode layout_mode, AvailableS CSSPixels content_height = 0; - for (auto& line_box : m_containing_block_state.line_boxes) { + for (auto& line_box : m_containing_block_used_values.line_boxes) { content_height += line_box.height(); } @@ -174,7 +178,7 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l // NOTE: Flex containers with `auto` height are treated as `max-content`, so we can compute their height early. if (box_state.has_definite_height() || box.display().is_flex_inside()) - parent().compute_height(box, AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_definite(m_containing_block_state.content_height()))); + parent().compute_height(box, AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_definite(m_containing_block_used_values.content_height()))); auto independent_formatting_context = layout_inside(box, layout_mode, box_state.available_inner_space_or_constraints_from(*m_available_space)); @@ -183,7 +187,7 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l // FIXME: (10.6.6) If 'height' is 'auto', the height depends on the element's descendants per 10.6.7. parent().compute_height(box, AvailableSpace(AvailableSize::make_indefinite(), AvailableSize::make_indefinite())); } else { - auto inner_height = calculate_inner_height(box, AvailableSize::make_definite(m_containing_block_state.content_height()), height_value); + auto inner_height = calculate_inner_height(box, AvailableSize::make_definite(m_containing_block_used_values.content_height()), height_value); box_state.set_content_height(inner_height); } @@ -242,12 +246,11 @@ void InlineFormattingContext::apply_justification_to_fragments(CSS::TextJustify void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) { - auto& containing_block_state = m_state.get_mutable(containing_block()); - auto& line_boxes = containing_block_state.line_boxes; + auto& line_boxes = m_containing_block_used_values.line_boxes; line_boxes.clear_with_capacity(); - InlineLevelIterator iterator(*this, m_state, containing_block(), layout_mode); - LineBuilder line_builder(*this, m_state); + InlineLevelIterator iterator(*this, m_state, containing_block(), m_containing_block_used_values, layout_mode); + LineBuilder line_builder(*this, m_state, m_containing_block_used_values); // NOTE: When we ignore collapsible whitespace chunks at the start of a line, // we have to remember how much start margin that chunk had in the inline @@ -371,7 +374,7 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) bool InlineFormattingContext::any_floats_intrude_at_y(CSSPixels y) const { - auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(m_containing_block_state, parent().root()); + auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(m_containing_block_used_values, parent().root()); CSSPixels y_in_root = box_in_root_rect.y() + y; auto space_and_containing_margin = parent().space_used_and_containing_margin_for_floats(y_in_root); return space_and_containing_margin.left_used_space > 0 || space_and_containing_margin.right_used_space > 0; @@ -379,8 +382,8 @@ bool InlineFormattingContext::any_floats_intrude_at_y(CSSPixels y) const bool InlineFormattingContext::can_fit_new_line_at_y(CSSPixels y) const { - auto top_intrusions = parent().intrusion_by_floats_into_box(m_containing_block_state, y); - auto bottom_intrusions = parent().intrusion_by_floats_into_box(m_containing_block_state, y + containing_block().computed_values().line_height() - 1); + auto top_intrusions = parent().intrusion_by_floats_into_box(m_containing_block_used_values, y); + auto bottom_intrusions = parent().intrusion_by_floats_into_box(m_containing_block_used_values, y + containing_block().computed_values().line_height() - 1); auto left_edge = [](auto& space) -> CSSPixels { return space.left; diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h index 72b4da4d4f9..c1a115307e5 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, Andreas Kling + * Copyright (c) 2020-2024, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -15,7 +15,7 @@ namespace Web::Layout { class InlineFormattingContext final : public FormattingContext { public: - InlineFormattingContext(LayoutState&, BlockContainer const& containing_block, BlockFormattingContext& parent); + InlineFormattingContext(LayoutState&, BlockContainer const& containing_block, LayoutState::UsedValues& containing_block_used_values, BlockFormattingContext& parent); ~InlineFormattingContext(); BlockFormattingContext& parent(); @@ -41,7 +41,7 @@ private: void generate_line_boxes(LayoutMode); void apply_justification_to_fragments(CSS::TextJustify, LineBox&, bool is_last_line); - LayoutState::UsedValues const& m_containing_block_state; + LayoutState::UsedValues& m_containing_block_used_values; Optional m_available_space; diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp index 88be6cb8a4c..5445b28dc9c 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp @@ -13,12 +13,12 @@ namespace Web::Layout { -InlineLevelIterator::InlineLevelIterator(Layout::InlineFormattingContext& inline_formatting_context, Layout::LayoutState& layout_state, Layout::BlockContainer const& container, LayoutMode layout_mode) +InlineLevelIterator::InlineLevelIterator(Layout::InlineFormattingContext& inline_formatting_context, Layout::LayoutState& layout_state, Layout::BlockContainer const& containing_block, LayoutState::UsedValues const& containing_block_used_values, LayoutMode layout_mode) : m_inline_formatting_context(inline_formatting_context) , m_layout_state(layout_state) - , m_container(container) - , m_container_state(layout_state.get(container)) - , m_next_node(container.first_child()) + , m_containing_block(containing_block) + , m_containing_block_used_values(containing_block_used_values) + , m_next_node(containing_block.first_child()) , m_layout_mode(layout_mode) { skip_to_next(); @@ -34,9 +34,9 @@ void InlineLevelIterator::enter_node_with_box_model_metrics(Layout::NodeWithStyl auto& used_values = m_layout_state.get_mutable(node); auto const& computed_values = node.computed_values(); - used_values.margin_left = computed_values.margin().left().to_px(node, m_container_state.content_width()); + used_values.margin_left = computed_values.margin().left().to_px(node, m_containing_block_used_values.content_width()); used_values.border_left = computed_values.border_left().width; - used_values.padding_left = computed_values.padding().left().to_px(node, m_container_state.content_width()); + used_values.padding_left = computed_values.padding().left().to_px(node, m_containing_block_used_values.content_width()); m_extra_leading_metrics->margin += used_values.margin_left; m_extra_leading_metrics->border += used_values.border_left; @@ -57,9 +57,9 @@ void InlineLevelIterator::exit_node_with_box_model_metrics() auto& used_values = m_layout_state.get_mutable(node); auto const& computed_values = node->computed_values(); - used_values.margin_right = computed_values.margin().right().to_px(node, m_container_state.content_width()); + used_values.margin_right = computed_values.margin().right().to_px(node, m_containing_block_used_values.content_width()); used_values.border_right = computed_values.border_right().width; - used_values.padding_right = computed_values.padding().right().to_px(node, m_container_state.content_width()); + used_values.padding_right = computed_values.padding().right().to_px(node, m_containing_block_used_values.content_width()); m_extra_trailing_metrics->margin += used_values.margin_right; m_extra_trailing_metrics->border += used_values.border_right; @@ -107,7 +107,7 @@ void InlineLevelIterator::compute_next() if (m_next_node == nullptr) return; do { - m_next_node = next_inline_node_in_pre_order(*m_next_node, m_container); + m_next_node = next_inline_node_in_pre_order(*m_next_node, m_containing_block); } while (m_next_node && (!m_next_node->is_inline() && !m_next_node->is_out_of_flow(m_inline_formatting_context))); } diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h index ce369e26460..de7f568a616 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h +++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.h @@ -50,7 +50,7 @@ public: } }; - InlineLevelIterator(Layout::InlineFormattingContext&, LayoutState&, Layout::BlockContainer const&, LayoutMode); + InlineLevelIterator(Layout::InlineFormattingContext&, LayoutState&, Layout::BlockContainer const& containing_block, LayoutState::UsedValues const& containing_block_used_values, LayoutMode); Optional next(); CSSPixels next_non_whitespace_sequence_width(); @@ -71,8 +71,8 @@ private: Layout::InlineFormattingContext& m_inline_formatting_context; Layout::LayoutState& m_layout_state; - JS::NonnullGCPtr m_container; - Layout::LayoutState::UsedValues const& m_container_state; + JS::NonnullGCPtr m_containing_block; + LayoutState::UsedValues const& m_containing_block_used_values; JS::GCPtr m_current_node; JS::GCPtr m_next_node; LayoutMode const m_layout_mode; diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp index 31013166210..e16dd3cb8ed 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -10,12 +10,12 @@ namespace Web::Layout { -LineBuilder::LineBuilder(InlineFormattingContext& context, LayoutState& layout_state) +LineBuilder::LineBuilder(InlineFormattingContext& context, LayoutState& layout_state, LayoutState::UsedValues& containing_block_used_values) : m_context(context) , m_layout_state(layout_state) - , m_containing_block_state(layout_state.get_mutable(context.containing_block())) + , m_containing_block_used_values(containing_block_used_values) { - m_text_indent = m_context.containing_block().computed_values().text_indent().to_px(m_context.containing_block(), m_containing_block_state.content_width()); + m_text_indent = m_context.containing_block().computed_values().text_indent().to_px(m_context.containing_block(), m_containing_block_used_values.content_width()); begin_new_line(false); } @@ -35,7 +35,7 @@ void LineBuilder::break_line(ForcedBreak forced_break, Optional next_ size_t break_count = 0; bool floats_intrude_at_current_y = false; do { - m_containing_block_state.line_boxes.append(LineBox()); + m_containing_block_used_values.line_boxes.append(LineBox()); begin_new_line(true, break_count == 0); break_count++; floats_intrude_at_current_y = m_context.any_floats_intrude_at_y(m_current_y); @@ -71,14 +71,14 @@ void LineBuilder::begin_new_line(bool increment_y, bool is_first_break_in_sequen m_last_line_needs_update = true; // FIXME: Support text-indent with "each-line". - if (m_containing_block_state.line_boxes.size() <= 1) { + if (m_containing_block_used_values.line_boxes.size() <= 1) { ensure_last_line_box().m_width += m_text_indent; } } LineBox& LineBuilder::ensure_last_line_box() { - auto& line_boxes = m_containing_block_state.line_boxes; + auto& line_boxes = m_containing_block_used_values.line_boxes; if (line_boxes.is_empty()) line_boxes.append(LineBox {}); return line_boxes.last(); @@ -92,7 +92,7 @@ void LineBuilder::append_box(Box const& box, CSSPixels leading_size, CSSPixels t m_max_height_on_current_line = max(m_max_height_on_current_line, box_state.margin_box_height()); box_state.containing_line_box_fragment = LineBoxFragmentCoordinate { - .line_box_index = m_containing_block_state.line_boxes.size() - 1, + .line_box_index = m_containing_block_used_values.line_boxes.size() - 1, .fragment_index = line_box.fragments().size() - 1, }; } @@ -139,7 +139,7 @@ bool LineBuilder::should_break(CSSPixels next_item_width) if (m_available_width_for_current_line.is_max_content()) return false; - auto const& line_boxes = m_containing_block_state.line_boxes; + auto const& line_boxes = m_containing_block_used_values.line_boxes; if (line_boxes.is_empty() || line_boxes.last().is_empty()) { // If we don't have a single line box yet *and* there are no floats intruding // at this Y coordinate, we don't need to break before inserting anything. @@ -155,7 +155,7 @@ bool LineBuilder::should_break(CSSPixels next_item_width) void LineBuilder::update_last_line() { m_last_line_needs_update = false; - auto& line_boxes = m_containing_block_state.line_boxes; + auto& line_boxes = m_containing_block_used_values.line_boxes; if (line_boxes.is_empty()) return; @@ -330,7 +330,7 @@ void LineBuilder::update_last_line() void LineBuilder::remove_last_line_if_empty() { // If there's an empty line box at the bottom, just remove it instead of giving it height. - auto& line_boxes = m_containing_block_state.line_boxes; + auto& line_boxes = m_containing_block_used_values.line_boxes; if (!line_boxes.is_empty() && line_boxes.last().is_empty()) { line_boxes.take_last(); m_last_line_needs_update = false; @@ -343,8 +343,8 @@ void LineBuilder::recalculate_available_space() auto available_at_top_of_line_box = m_context.available_space_for_line(m_current_y); auto available_at_bottom_of_line_box = m_context.available_space_for_line(m_current_y + current_line_height - 1); m_available_width_for_current_line = min(available_at_bottom_of_line_box, available_at_top_of_line_box); - if (!m_containing_block_state.line_boxes.is_empty()) - m_containing_block_state.line_boxes.last().m_original_available_width = m_available_width_for_current_line; + if (!m_containing_block_used_values.line_boxes.is_empty()) + m_containing_block_used_values.line_boxes.last().m_original_available_width = m_available_width_for_current_line; } } diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.h b/Userland/Libraries/LibWeb/Layout/LineBuilder.h index 279f8eff4a0..80bbe6193d6 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.h +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.h @@ -15,7 +15,7 @@ class LineBuilder { AK_MAKE_NONMOVABLE(LineBuilder); public: - LineBuilder(InlineFormattingContext&, LayoutState&); + LineBuilder(InlineFormattingContext&, LayoutState&, LayoutState::UsedValues& containing_block_used_values); ~LineBuilder(); enum class ForcedBreak { @@ -58,7 +58,7 @@ private: InlineFormattingContext& m_context; LayoutState& m_layout_state; - LayoutState::UsedValues& m_containing_block_state; + LayoutState::UsedValues& m_containing_block_used_values; AvailableSize m_available_width_for_current_line { AvailableSize::make_indefinite() }; CSSPixels m_current_y { 0 }; CSSPixels m_max_height_on_current_line { 0 };