From 4c81d3948359e6155cea6ff9dfbceed33124be3e Mon Sep 17 00:00:00 2001 From: Andi Gallo Date: Fri, 7 Jul 2023 05:31:54 +0000 Subject: [PATCH] LibWeb: Adjust border widths for tables using collapsing borders When using the collapsing border model, cells on either side of the edge get half the specified width of the border for their box model. --- .../border-conflict-resolution-with-col.txt | 36 +++++++++---------- .../LibWeb/Layout/expected/table/borders.txt | 34 +++++++++--------- .../Libraries/LibWeb/Layout/LayoutState.h | 23 +++++++----- .../LibWeb/Layout/TableFormattingContext.cpp | 11 +++--- .../Libraries/LibWeb/Painting/PaintableBox.h | 16 ++++++--- 5 files changed, 67 insertions(+), 53 deletions(-) diff --git a/Tests/LibWeb/Layout/expected/table/border-conflict-resolution-with-col.txt b/Tests/LibWeb/Layout/expected/table/border-conflict-resolution-with-col.txt index 45cf47b56e..64553d27ce 100644 --- a/Tests/LibWeb/Layout/expected/table/border-conflict-resolution-with-col.txt +++ b/Tests/LibWeb/Layout/expected/table/border-conflict-resolution-with-col.txt @@ -1,63 +1,63 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline - BlockContainer at (0,0) content-size 800x181.875 [BFC] children: not-inline + BlockContainer at (0,0) content-size 800x177.875 [BFC] children: not-inline BlockContainer <(anonymous)> at (0,0) content-size 800x0 children: inline TextNode <#text> - BlockContainer at (8,8) content-size 784x165.875 children: not-inline + BlockContainer at (8,8) content-size 784x161.875 children: not-inline BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline TextNode <#text> - TableWrapper <(anonymous)> at (8,8) content-size 64.265625x165.875 [BFC] children: not-inline - Box at (8,8) content-size 64.265625x165.875 table-box [TFC] children: not-inline + TableWrapper <(anonymous)> at (8,8) content-size 60.265625x161.875 [BFC] children: not-inline + Box
at (8,8) content-size 60.265625x161.875 table-box [TFC] children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer (not painted) table-column-group children: not-inline BlockContainer (not painted) children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (8,8) content-size 64.265625x165.875 table-row-group children: not-inline + Box at (8,8) content-size 60.265625x161.875 table-row-group children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (8,8) content-size 64.265625x43.46875 table-row children: not-inline + Box at (8,8) content-size 60.265625x41.468749 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (8,51.46875) content-size 64.265625x39.46875 table-row children: not-inline + Box at (8,49.468749) content-size 60.265625x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (8,90.9375) content-size 64.265625x39.46875 table-row children: not-inline + Box at (8,88.9375) content-size 60.265625x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (8,130.40625) content-size 64.265625x43.46875 table-row children: not-inline + Box at (8,128.40625) content-size 60.265625x41.468749 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer
at (33,23) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (31,20.999999) content-size 14.265625x17.46875 table-cell [BFC] children: inline line 0 width: 14.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [33,23 14.265625x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [31,20.999999 14.265625x17.46875] "A" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (33,62.46875) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (31,60.468749) content-size 14.265625x17.46875 table-cell [BFC] children: inline line 0 width: 9.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [33,62.46875 9.34375x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [31,60.468749 9.34375x17.46875] "B" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (33,101.9375) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (31,99.9375) content-size 14.265625x17.46875 table-cell [BFC] children: inline line 0 width: 10.3125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [33,101.9375 10.3125x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [31,99.9375 10.3125x17.46875] "C" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (33,141.40625) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (31,139.40625) content-size 14.265625x17.46875 table-cell [BFC] children: inline line 0 width: 11.140625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [33,141.40625 11.140625x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [31,139.40625 11.140625x17.46875] "D" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline @@ -66,5 +66,5 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer <(anonymous)> at (8,173.875) content-size 784x0 children: inline + BlockContainer <(anonymous)> at (8,169.875) content-size 784x0 children: inline TextNode <#text> diff --git a/Tests/LibWeb/Layout/expected/table/borders.txt b/Tests/LibWeb/Layout/expected/table/borders.txt index c0f60a0a13..24a481fe82 100644 --- a/Tests/LibWeb/Layout/expected/table/borders.txt +++ b/Tests/LibWeb/Layout/expected/table/borders.txt @@ -1,6 +1,6 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline - BlockContainer at (8,8) content-size 784x285.625 children: not-inline + BlockContainer at (8,8) content-size 784x265.625 children: not-inline TableWrapper <(anonymous)> at (8,8) content-size 174.296875x74.40625 [BFC] children: not-inline Box at (9,9) content-size 172.296875x72.40625 table-box [TFC] children: not-inline BlockContainer <(anonymous)> (not painted) children: inline @@ -195,11 +195,11 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer <(anonymous)> at (8,201.21875) content-size 784x0 children: inline TextNode <#text> TextNode <#text> - TableWrapper <(anonymous)> at (8,201.21875) content-size 178.296875x92.40625 [BFC] children: not-inline - Box at (8,201.21875) content-size 178.296875x92.40625 table-box [TFC] children: not-inline + TableWrapper <(anonymous)> at (8,201.21875) content-size 168.296875x72.40625 [BFC] children: not-inline + Box at (8,201.21875) content-size 168.296875x72.40625 table-box [TFC] children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (8,201.21875) content-size 178.296875x27.46875 table-row children: not-inline + Box at (8,201.21875) content-size 168.296875x22.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer at (8,201.21875) content-size 82.015625x17.46875 table-cell [BFC] children: inline @@ -209,52 +209,52 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (110.015625,201.21875) content-size 76.28125x17.46875 table-cell [BFC] children: inline + BlockContainer at (100.015625,201.21875) content-size 76.28125x17.46875 table-cell [BFC] children: inline line 0 width: 76.28125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 8, rect: [110.015625,201.21875 76.28125x17.46875] + frag 0 from TextNode start: 0, length: 8, rect: [100.015625,201.21875 76.28125x17.46875] "Lastname" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (8,228.6875) content-size 178.296875x37.46875 table-row children: not-inline + Box at (8,223.6875) content-size 168.296875x27.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (8,238.6875) content-size 82.015625x17.46875 table-cell [BFC] children: inline + BlockContainer at (8,228.6875) content-size 82.015625x17.46875 table-cell [BFC] children: inline line 0 width: 44.65625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 5, rect: [8,238.6875 44.65625x17.46875] + frag 0 from TextNode start: 0, length: 5, rect: [8,228.6875 44.65625x17.46875] "Peter" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (110.015625,238.6875) content-size 76.28125x17.46875 table-cell [BFC] children: inline + BlockContainer at (100.015625,228.6875) content-size 76.28125x17.46875 table-cell [BFC] children: inline line 0 width: 53.671875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 7, rect: [110.015625,238.6875 53.671875x17.46875] + frag 0 from TextNode start: 0, length: 7, rect: [100.015625,228.6875 53.671875x17.46875] "Griffin" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (8,266.15625) content-size 178.296875x27.46875 table-row children: not-inline + Box at (8,251.15625) content-size 168.296875x22.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (8,276.15625) content-size 82.015625x17.46875 table-cell [BFC] children: inline + BlockContainer at (8,256.15625) content-size 82.015625x17.46875 table-cell [BFC] children: inline line 0 width: 35.125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 4, rect: [8,276.15625 35.125x17.46875] + frag 0 from TextNode start: 0, length: 4, rect: [8,256.15625 35.125x17.46875] "Lois" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (110.015625,276.15625) content-size 76.28125x17.46875 table-cell [BFC] children: inline + BlockContainer at (100.015625,256.15625) content-size 76.28125x17.46875 table-cell [BFC] children: inline line 0 width: 53.671875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 7, rect: [110.015625,276.15625 53.671875x17.46875] + frag 0 from TextNode start: 0, length: 7, rect: [100.015625,256.15625 53.671875x17.46875] "Griffin" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer <(anonymous)> at (8,293.625) content-size 784x0 children: inline + BlockContainer <(anonymous)> at (8,273.625) content-size 784x0 children: inline TextNode <#text> diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.h b/Userland/Libraries/LibWeb/Layout/LayoutState.h index 6cc887cd5b..8d15abbe28 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.h +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.h @@ -98,18 +98,18 @@ struct LayoutState { Vector line_boxes; - CSSPixels margin_box_left() const { return margin_left + border_left + padding_left; } - CSSPixels margin_box_right() const { return margin_right + border_right + padding_right; } - CSSPixels margin_box_top() const { return margin_top + border_top + padding_top; } - CSSPixels margin_box_bottom() const { return margin_bottom + border_bottom + padding_bottom; } + CSSPixels margin_box_left() const { return margin_left + border_left_collapsed() + padding_left; } + CSSPixels margin_box_right() const { return margin_right + border_right_collapsed() + padding_right; } + CSSPixels margin_box_top() const { return margin_top + border_top_collapsed() + padding_top; } + CSSPixels margin_box_bottom() const { return margin_bottom + border_bottom_collapsed() + padding_bottom; } CSSPixels margin_box_width() const { return margin_box_left() + content_width() + margin_box_right(); } CSSPixels margin_box_height() const { return margin_box_top() + content_height() + margin_box_bottom(); } - CSSPixels border_box_left() const { return border_left + padding_left; } - CSSPixels border_box_right() const { return border_right + padding_right; } - CSSPixels border_box_top() const { return border_top + padding_top; } - CSSPixels border_box_bottom() const { return border_bottom + padding_bottom; } + CSSPixels border_box_left() const { return border_left_collapsed() + padding_left; } + CSSPixels border_box_right() const { return border_right_collapsed() + padding_right; } + CSSPixels border_box_top() const { return border_top_collapsed() + padding_top; } + CSSPixels border_box_bottom() const { return border_bottom_collapsed() + padding_bottom; } CSSPixels border_box_width() const { return border_box_left() + content_width() + border_box_right(); } CSSPixels border_box_height() const { return border_box_top() + content_height() + border_box_bottom(); } @@ -129,6 +129,13 @@ struct LayoutState { AvailableSize available_width_inside() const; AvailableSize available_height_inside() const; + bool use_collapsing_borders_model() const { return m_override_borders_data.has_value(); } + // Implement the collapsing border model https://www.w3.org/TR/CSS22/tables.html#collapsing-borders. + CSSPixels border_left_collapsed() const { return use_collapsing_borders_model() ? round(border_left / 2) : border_left; } + CSSPixels border_right_collapsed() const { return use_collapsing_borders_model() ? round(border_right / 2) : border_right; } + CSSPixels border_top_collapsed() const { return use_collapsing_borders_model() ? round(border_top / 2) : border_top; } + CSSPixels border_bottom_collapsed() const { return use_collapsing_borders_model() ? round(border_bottom / 2) : border_bottom; } + JS::GCPtr m_node { nullptr }; CSSPixels m_content_width { 0 }; diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp index bd621a4ab6..02be400e2e 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -174,11 +174,12 @@ void TableFormattingContext::compute_cell_measures(AvailableSpace const& availab CSSPixels padding_right = computed_values.padding().right().to_px(cell.box, containing_block.content_width()); auto const& cell_state = m_state.get(cell.box); - auto is_collapse = cell.box->computed_values().border_collapse() == CSS::BorderCollapse::Collapse; - CSSPixels border_top = is_collapse ? cell_state.border_top : computed_values.border_top().width; - CSSPixels border_bottom = is_collapse ? cell_state.border_bottom : computed_values.border_bottom().width; - CSSPixels border_left = is_collapse ? cell_state.border_left : computed_values.border_left().width; - CSSPixels border_right = is_collapse ? cell_state.border_right : computed_values.border_right().width; + auto use_collapsing_borders_model = cell_state.override_borders_data().has_value(); + // Implement the collapsing border model https://www.w3.org/TR/CSS22/tables.html#collapsing-borders. + CSSPixels border_top = use_collapsing_borders_model ? round(cell_state.border_top / 2) : computed_values.border_top().width; + CSSPixels border_bottom = use_collapsing_borders_model ? round(cell_state.border_bottom / 2) : computed_values.border_bottom().width; + CSSPixels border_left = use_collapsing_borders_model ? round(cell_state.border_left / 2) : computed_values.border_left().width; + CSSPixels border_right = use_collapsing_borders_model ? round(cell_state.border_right / 2) : computed_values.border_right().width; auto height = computed_values.height().to_px(cell.box, containing_block.content_height()); auto width = (computed_values.width().is_length() || !table_width_is_auto) ? computed_values.width().to_px(cell.box, containing_block.content_width()) : 0; diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.h b/Userland/Libraries/LibWeb/Painting/PaintableBox.h index 9813000f5e..7ec51ac61e 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.h @@ -64,10 +64,16 @@ public: { auto padded_rect = this->absolute_padding_box_rect(); CSSPixelRect rect; - rect.set_x(padded_rect.x() - box_model().border.left); - rect.set_width(padded_rect.width() + box_model().border.left + box_model().border.right); - rect.set_y(padded_rect.y() - box_model().border.top); - rect.set_height(padded_rect.height() + box_model().border.top + box_model().border.bottom); + auto use_collapsing_borders_model = override_borders_data().has_value(); + // Implement the collapsing border model https://www.w3.org/TR/CSS22/tables.html#collapsing-borders. + auto border_top = use_collapsing_borders_model ? round(box_model().border.top / 2) : box_model().border.top; + auto border_bottom = use_collapsing_borders_model ? round(box_model().border.bottom / 2) : box_model().border.bottom; + auto border_left = use_collapsing_borders_model ? round(box_model().border.left / 2) : box_model().border.left; + auto border_right = use_collapsing_borders_model ? round(box_model().border.right / 2) : box_model().border.right; + rect.set_x(padded_rect.x() - border_left); + rect.set_width(padded_rect.width() + border_left + border_right); + rect.set_y(padded_rect.y() - border_top); + rect.set_height(padded_rect.height() + border_top + border_bottom); return rect; } @@ -124,7 +130,7 @@ public: bool is_out_of_view(PaintContext&) const; void set_override_borders_data(BordersData const& override_borders_data) { m_override_borders_data = override_borders_data; } - auto const& override_borders_data() const { return m_override_borders_data; } + Optional const& override_borders_data() const { return m_override_borders_data; } struct TableCellCoordinates { size_t row_index;