From b96920a9d6e04f1f19c598d94cb78d67bd8635b9 Mon Sep 17 00:00:00 2001 From: Mathis Wiehl Date: Tue, 14 Mar 2023 10:28:01 +0100 Subject: [PATCH] LibWeb: Consider margins of atomic inlines in layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to CSS Inline Layout Module Level 3 ยง 2.2 Step 1. atomic inlines should be layed out in a line box based on their margin box. However, up until this patch we were unconditionally considering only the border box during line box height calculation. This made us essentially drop all vertical margins for atomic inlines. --- ...with-vertical-margins-vertical-align-top.txt | 12 ++++++++++++ .../inline-box-with-vertical-margins.txt | 12 ++++++++++++ .../replaced-box-with-vertical-margins.txt | 12 ++++++++++++ Tests/LibWeb/Layout/input/buggie.png | Bin 0 -> 9015 bytes ...ith-vertical-margins-vertical-align-top.html | 16 ++++++++++++++++ .../input/inline-box-with-vertical-margins.html | 15 +++++++++++++++ .../replaced-box-with-vertical-margins.html | 10 ++++++++++ .../Libraries/LibWeb/Layout/LayoutState.cpp | 6 +++--- .../Libraries/LibWeb/Layout/LineBoxFragment.cpp | 5 +++++ .../Libraries/LibWeb/Layout/LineBoxFragment.h | 2 ++ .../Libraries/LibWeb/Layout/LineBuilder.cpp | 16 +++++++++++----- 11 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/inline-box-with-vertical-margins-vertical-align-top.txt create mode 100644 Tests/LibWeb/Layout/expected/inline-box-with-vertical-margins.txt create mode 100644 Tests/LibWeb/Layout/expected/replaced-box-with-vertical-margins.txt create mode 100644 Tests/LibWeb/Layout/input/buggie.png create mode 100644 Tests/LibWeb/Layout/input/inline-box-with-vertical-margins-vertical-align-top.html create mode 100644 Tests/LibWeb/Layout/input/inline-box-with-vertical-margins.html create mode 100644 Tests/LibWeb/Layout/input/replaced-box-with-vertical-margins.html diff --git a/Tests/LibWeb/Layout/expected/inline-box-with-vertical-margins-vertical-align-top.txt b/Tests/LibWeb/Layout/expected/inline-box-with-vertical-margins-vertical-align-top.txt new file mode 100644 index 0000000000..c15b1aeece --- /dev/null +++ b/Tests/LibWeb/Layout/expected/inline-box-with-vertical-margins-vertical-align-top.txt @@ -0,0 +1,12 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x191 children: not-inline + BlockContainer at (8,8) content-size 784x175 children: inline + line 0 width: 210.828125, height: 175, bottom: 175, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 6, rect: [8,8 43.125x17.46875] + "Well, " + frag 1 from BlockContainer start: 0, length: 0, rect: [51,58 100x100] + frag 2 from TextNode start: 0, length: 9, rect: [151,8 67.703125x17.46875] + " friends." + TextNode <#text> + BlockContainer at (51,58) content-size 100x100 inline-block children: not-inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/expected/inline-box-with-vertical-margins.txt b/Tests/LibWeb/Layout/expected/inline-box-with-vertical-margins.txt new file mode 100644 index 0000000000..cb06afebbd --- /dev/null +++ b/Tests/LibWeb/Layout/expected/inline-box-with-vertical-margins.txt @@ -0,0 +1,12 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x194.46875 children: not-inline + BlockContainer at (8,8) content-size 784x178.46875 children: inline + line 0 width: 210.828125, height: 178.46875, bottom: 178.46875, baseline: 175 + frag 0 from TextNode start: 0, length: 6, rect: [8,169 43.125x17.46875] + "Well, " + frag 1 from BlockContainer start: 0, length: 0, rect: [51,58 100x100] + frag 2 from TextNode start: 0, length: 9, rect: [151,169 67.703125x17.46875] + " friends." + TextNode <#text> + BlockContainer at (51,58) content-size 100x100 inline-block children: not-inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/expected/replaced-box-with-vertical-margins.txt b/Tests/LibWeb/Layout/expected/replaced-box-with-vertical-margins.txt new file mode 100644 index 0000000000..40d4e4c77e --- /dev/null +++ b/Tests/LibWeb/Layout/expected/replaced-box-with-vertical-margins.txt @@ -0,0 +1,12 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x232.46875 children: not-inline + BlockContainer at (8,8) content-size 784x216.46875 children: inline + line 0 width: 174.828125, height: 216.46875, bottom: 216.46875, baseline: 213 + frag 0 from TextNode start: 0, length: 6, rect: [8,207 43.125x17.46875] + "Well, " + frag 1 from ImageBox start: 0, length: 0, rect: [51,33 64x138] + frag 2 from TextNode start: 0, length: 9, rect: [115,207 67.703125x17.46875] + " friends." + TextNode <#text> + ImageBox at (51,33) content-size 64x138 children: not-inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/input/buggie.png b/Tests/LibWeb/Layout/input/buggie.png new file mode 100644 index 0000000000000000000000000000000000000000..94558bd2d37da81d777e8b78cbf46fa0c9870dca GIT binary patch literal 9015 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 + body { + font-family: 'SerenitySans'; + } + + #inline-box { + background-color: red; + margin-top: 50px; + margin-bottom: 25px; + width: 100px; + height: 100px; + + display: inline-block; + vertical-align: top; + } +Well,
friends. \ No newline at end of file diff --git a/Tests/LibWeb/Layout/input/inline-box-with-vertical-margins.html b/Tests/LibWeb/Layout/input/inline-box-with-vertical-margins.html new file mode 100644 index 0000000000..5d97907368 --- /dev/null +++ b/Tests/LibWeb/Layout/input/inline-box-with-vertical-margins.html @@ -0,0 +1,15 @@ +Well,
friends. \ No newline at end of file diff --git a/Tests/LibWeb/Layout/input/replaced-box-with-vertical-margins.html b/Tests/LibWeb/Layout/input/replaced-box-with-vertical-margins.html new file mode 100644 index 0000000000..eddf1d5c29 --- /dev/null +++ b/Tests/LibWeb/Layout/input/replaced-box-with-vertical-margins.html @@ -0,0 +1,10 @@ +Well, friends. \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp index a430dfe5ba..0daee83ab7 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp @@ -110,7 +110,7 @@ CSSPixels box_baseline(LayoutState const& state, Box const& box) return box_state.border_box_top(); case CSS::VerticalAlign::Bottom: // Bottom: Align the bottom of the aligned subtree with the bottom of the line box. - return box_state.content_height() + box_state.border_box_bottom(); + return box_state.content_height() + box_state.margin_box_top(); case CSS::VerticalAlign::TextTop: // TextTop: Align the top of the box with the top of the parent's content area (see 10.6.1). return box.computed_values().font_size(); @@ -123,13 +123,13 @@ CSSPixels box_baseline(LayoutState const& state, Box const& box) } if (!box_state.line_boxes.is_empty()) - return box_state.border_box_top() + box_state.offset.y() + box_state.line_boxes.last().baseline(); + return box_state.margin_box_top() + box_state.offset.y() + box_state.line_boxes.last().baseline(); if (box.has_children() && !box.children_are_inline()) { auto const* child_box = box.last_child_of_type(); VERIFY(child_box); return box_baseline(state, *child_box); } - return box_state.border_box_height(); + return box_state.margin_box_height(); } CSSPixelRect margin_box_rect(Box const& box, LayoutState const& state) diff --git a/Userland/Libraries/LibWeb/Layout/LineBoxFragment.cpp b/Userland/Libraries/LibWeb/Layout/LineBoxFragment.cpp index d040ce45d1..b617c00610 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBoxFragment.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBoxFragment.cpp @@ -149,4 +149,9 @@ CSSPixelRect LineBoxFragment::selection_rect(Gfx::Font const& font) const return {}; } +bool LineBoxFragment::is_atomic_inline() const +{ + return layout_node().is_replaced_box() || (layout_node().display().is_inline_outside() && !layout_node().display().is_flow_inside()); +} + } diff --git a/Userland/Libraries/LibWeb/Layout/LineBoxFragment.h b/Userland/Libraries/LibWeb/Layout/LineBoxFragment.h index b8566b57f5..26d96a5bbc 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBoxFragment.h +++ b/Userland/Libraries/LibWeb/Layout/LineBoxFragment.h @@ -76,6 +76,8 @@ public: CSSPixelRect selection_rect(Gfx::Font const&) const; + bool is_atomic_inline() const; + private: Node const& m_layout_node; int m_start { 0 }; diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp index 89b735d208..b09adc0fe7 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -78,7 +78,7 @@ void LineBuilder::append_box(Box const& box, CSSPixels leading_size, CSSPixels t auto& box_state = m_layout_state.get_mutable(box); auto& line_box = ensure_last_line_box(); line_box.add_fragment(box, 0, 0, leading_size, trailing_size, leading_margin, trailing_margin, box_state.content_width(), box_state.content_height(), box_state.border_box_top(), box_state.border_box_bottom()); - m_max_height_on_current_line = max(m_max_height_on_current_line, box_state.border_box_height()); + 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, @@ -235,11 +235,17 @@ void LineBuilder::update_last_line() CSSPixels new_fragment_y = 0; auto y_value_for_alignment = [&](CSS::VerticalAlign vertical_align) { + CSSPixels effective_box_top = fragment.border_box_top(); + if (fragment.is_atomic_inline()) { + auto const& fragment_box_state = m_layout_state.get(static_cast(fragment.layout_node())); + effective_box_top = fragment_box_state.margin_box_top(); + } + switch (vertical_align) { case CSS::VerticalAlign::Baseline: - return m_current_y + line_box_baseline - fragment.baseline() + fragment.border_box_top(); + return m_current_y + line_box_baseline - fragment.baseline() + effective_box_top; case CSS::VerticalAlign::Top: - return m_current_y + fragment.border_box_top(); + return m_current_y + effective_box_top; case CSS::VerticalAlign::Middle: case CSS::VerticalAlign::Bottom: case CSS::VerticalAlign::Sub: @@ -247,7 +253,7 @@ void LineBuilder::update_last_line() case CSS::VerticalAlign::TextBottom: case CSS::VerticalAlign::TextTop: // FIXME: These are all 'baseline' - return m_current_y + line_box_baseline - fragment.baseline() + fragment.border_box_top(); + return m_current_y + line_box_baseline - fragment.baseline() + effective_box_top; } VERIFY_NOT_REACHED(); }; @@ -268,7 +274,7 @@ void LineBuilder::update_last_line() CSSPixels bottom_of_inline_box = 0; { // FIXME: Support inline-table elements. - if (fragment.layout_node().is_replaced_box() || (fragment.layout_node().display().is_inline_outside() && !fragment.layout_node().display().is_flow_inside())) { + if (fragment.is_atomic_inline()) { auto const& fragment_box_state = m_layout_state.get(static_cast(fragment.layout_node())); top_of_inline_box = (fragment.offset().y() - fragment_box_state.margin_box_top()); bottom_of_inline_box = (fragment.offset().y() + fragment_box_state.content_height() + fragment_box_state.margin_box_bottom());