From ac6af515499c1223806cbad12652ecbbef87de0c Mon Sep 17 00:00:00 2001 From: Andi Gallo Date: Mon, 19 Jun 2023 09:28:04 +0000 Subject: [PATCH] LibWeb: Improve span column width distribution Compute the contributions to a spanning cell width from each cell in the span. This better handles uneven column widths, since each cell contribution is proportional with its own width as opposed to the own width of the first cell in the span. This better matches the behavior of other browsers and further aligns with the specification. --- .../expected/table/border-spacing-colspan.txt | 54 +++++++++---------- .../table/clip-spans-to-table-end.txt | 14 ++--- .../colspan-weighted-width-distribution.txt | 39 ++++++++++++++ .../table/colspan-width-distribution.txt | 18 +++---- .../colspan-weighted-width-distribution.html | 18 +++++++ .../LibWeb/Layout/TableFormattingContext.cpp | 37 +++++++------ 6 files changed, 118 insertions(+), 62 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/table/colspan-weighted-width-distribution.txt create mode 100644 Tests/LibWeb/Layout/input/table/colspan-weighted-width-distribution.html diff --git a/Tests/LibWeb/Layout/expected/table/border-spacing-colspan.txt b/Tests/LibWeb/Layout/expected/table/border-spacing-colspan.txt index 04b678b776..894fd83a76 100644 --- a/Tests/LibWeb/Layout/expected/table/border-spacing-colspan.txt +++ b/Tests/LibWeb/Layout/expected/table/border-spacing-colspan.txt @@ -5,14 +5,14 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (8,8) content-size 784x259.34375 children: not-inline BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline TextNode <#text> - TableWrapper <(anonymous)> at (8,8) content-size 241.625x259.34375 [BFC] children: not-inline - Box at (9,9) content-size 241.625x257.34375 table-box [TFC] children: not-inline + TableWrapper <(anonymous)> at (8,8) content-size 239.90625x259.34375 [BFC] children: not-inline + Box
at (9,9) content-size 239.90625x257.34375 table-box [TFC] children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (9,9) content-size 163.625x197.34375 table-row-group children: not-inline + Box at (9,9) content-size 161.90625x197.34375 table-row-group children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (29,19) content-size 163.625x39.46875 table-row children: not-inline + Box at (29,19) content-size 161.90625x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer at (29,58.46875) content-size 163.625x39.46875 table-row children: not-inline + Box at (29,58.46875) content-size 161.90625x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (29,97.9375) content-size 163.625x39.46875 table-row children: not-inline + Box at (29,97.9375) content-size 161.90625x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer at (29,137.40625) content-size 163.625x39.46875 table-row children: not-inline + Box at (29,137.40625) content-size 161.90625x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer at (29,176.875) content-size 163.625x39.46875 table-row children: not-inline + Box at (29,176.875) content-size 161.90625x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer
at (50,30) content-size 14.265625x17.46875 table-cell [BFC] children: inline @@ -22,42 +22,42 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (126.265625,30) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (126.265625,30) content-size 12.546875x17.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: [128.265625,30 9.34375x17.46875] "B" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (202.53125,30) content-size 9.09375x17.46875 table-cell [BFC] children: inline + BlockContainer at (200.8125,30) content-size 9.09375x17.46875 table-cell [BFC] children: inline line 0 width: 6.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [203.53125,30 6.34375x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [201.8125,30 6.34375x17.46875] "1" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (50,79.46875) content-size 90.53125x17.46875 table-cell [BFC] children: inline + BlockContainer at (50,79.46875) content-size 88.8125x17.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: [90,79.46875 10.3125x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [89,79.46875 10.3125x17.46875] "C" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (202.53125,79.46875) content-size 9.09375x17.46875 table-cell [BFC] children: inline + BlockContainer at (200.8125,79.46875) content-size 9.09375x17.46875 table-cell [BFC] children: inline line 0 width: 8.8125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [202.53125,79.46875 8.8125x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [200.8125,79.46875 8.8125x17.46875] "2" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (50,128.9375) content-size 14.265625x17.46875 table-cell [BFC] children: inline @@ -67,23 +67,23 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (126.265625,128.9375) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (126.265625,128.9375) content-size 12.546875x17.46875 table-cell [BFC] children: inline line 0 width: 12.546875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [127.265625,128.9375 12.546875x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [126.265625,128.9375 12.546875x17.46875] "F" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (202.53125,128.9375) content-size 9.09375x17.46875 table-cell [BFC] children: inline + BlockContainer at (200.8125,128.9375) content-size 9.09375x17.46875 table-cell [BFC] children: inline line 0 width: 9.09375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [202.53125,128.9375 9.09375x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [200.8125,128.9375 9.09375x17.46875] "3" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (50,178.40625) content-size 14.265625x17.46875 table-cell [BFC] children: inline @@ -93,23 +93,23 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (126.265625,178.40625) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (126.265625,178.40625) content-size 12.546875x17.46875 table-cell [BFC] children: inline line 0 width: 12.234375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [127.265625,178.40625 12.234375x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [126.265625,178.40625 12.234375x17.46875] "H" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (202.53125,178.40625) content-size 9.09375x17.46875 table-cell [BFC] children: inline + BlockContainer at (200.8125,178.40625) content-size 9.09375x17.46875 table-cell [BFC] children: inline line 0 width: 7.75, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [203.53125,178.40625 7.75x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [201.8125,178.40625 7.75x17.46875] "4" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (50,227.875) content-size 14.265625x17.46875 table-cell [BFC] children: inline @@ -119,16 +119,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (126.265625,227.875) content-size 14.265625x17.46875 table-cell [BFC] children: inline + BlockContainer at (126.265625,227.875) content-size 12.546875x17.46875 table-cell [BFC] children: inline line 0 width: 8.90625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [129.265625,227.875 8.90625x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [128.265625,227.875 8.90625x17.46875] "J" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (202.53125,227.875) content-size 9.09375x17.46875 table-cell [BFC] children: inline + BlockContainer at (200.8125,227.875) content-size 9.09375x17.46875 table-cell [BFC] children: inline line 0 width: 8.453125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 1, rect: [202.53125,227.875 8.453125x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [200.8125,227.875 8.453125x17.46875] "5" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline diff --git a/Tests/LibWeb/Layout/expected/table/clip-spans-to-table-end.txt b/Tests/LibWeb/Layout/expected/table/clip-spans-to-table-end.txt index 4e895c005b..e782db436e 100644 --- a/Tests/LibWeb/Layout/expected/table/clip-spans-to-table-end.txt +++ b/Tests/LibWeb/Layout/expected/table/clip-spans-to-table-end.txt @@ -1,12 +1,12 @@ 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 784x118.40625 children: not-inline - TableWrapper <(anonymous)> at (8,8) content-size 123.171875x118.40625 [BFC] children: not-inline - Box at (8,8) content-size 123.171875x118.40625 table-box [TFC] children: not-inline + TableWrapper <(anonymous)> at (8,8) content-size 92.359375x118.40625 [BFC] children: not-inline + Box
at (8,8) content-size 92.359375x118.40625 table-box [TFC] children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (8,8) content-size 123.171875x118.40625 table-row-group children: not-inline - Box at (8,8) content-size 123.171875x39.46875 table-row children: not-inline + Box at (8,8) content-size 92.359375x118.40625 table-row-group children: not-inline + Box at (8,8) content-size 92.359375x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer at (8,47.46875) content-size 123.171875x39.46875 table-row children: not-inline + Box at (8,47.46875) content-size 92.359375x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer at (8,86.9375) content-size 123.171875x39.46875 table-row children: not-inline + Box at (8,86.9375) content-size 92.359375x39.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer
at (19,19) content-size 8.453125x17.46875 table-cell [BFC] children: inline @@ -32,7 +32,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (19,58.46875) content-size 8.453125x17.46875 table-cell [BFC] children: inline @@ -42,7 +42,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (49.453125,78.203125) content-size 70.71875x17.46875 table-cell [BFC] children: inline + BlockContainer at (49.453125,78.203125) content-size 39.90625x17.46875 table-cell [BFC] children: inline line 0 width: 24.046875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 frag 0 from TextNode start: 0, length: 3, rect: [49.453125,78.203125 24.046875x17.46875] "6-9" @@ -51,7 +51,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (19,97.9375) content-size 8.453125x17.46875 table-cell [BFC] children: inline diff --git a/Tests/LibWeb/Layout/expected/table/colspan-weighted-width-distribution.txt b/Tests/LibWeb/Layout/expected/table/colspan-weighted-width-distribution.txt new file mode 100644 index 0000000000..4a7c674470 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/table/colspan-weighted-width-distribution.txt @@ -0,0 +1,39 @@ +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 784x44.9375 children: not-inline + TableWrapper <(anonymous)> at (8,8) content-size 206x44.9375 [BFC] children: not-inline + Box at (9,9) content-size 204x42.9375 table-box [TFC] children: not-inline + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + Box at (9,9) content-size 204x42.9375 table-row-group children: not-inline + Box at (9,9) content-size 204x21.46875 table-row children: not-inline + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer at (9,30.46875) content-size 204x21.46875 table-row children: not-inline + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer
at (11,11) content-size 176.241651x17.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: [92,11 14.265625x17.46875] + "A" + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer at (191.241651,11) content-size 19.758348x17.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: [196.241651,11 9.34375x17.46875] + "B" + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + Box
at (11,32.46875) content-size 200x17.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: [106,32.46875 10.3125x17.46875] + "C" + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> + BlockContainer <(anonymous)> (not painted) children: inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/expected/table/colspan-width-distribution.txt b/Tests/LibWeb/Layout/expected/table/colspan-width-distribution.txt index d8a29597ca..5ea82c8a54 100644 --- a/Tests/LibWeb/Layout/expected/table/colspan-width-distribution.txt +++ b/Tests/LibWeb/Layout/expected/table/colspan-width-distribution.txt @@ -5,12 +5,12 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (8,8) content-size 784x44.9375 children: not-inline BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline TextNode <#text> - TableWrapper <(anonymous)> at (8,8) content-size 41.122404x44.9375 [BFC] children: not-inline - Box at (9,9) content-size 41.122404x42.9375 table-box [TFC] children: not-inline + TableWrapper <(anonymous)> at (8,8) content-size 35.3125x44.9375 [BFC] children: not-inline + Box
at (9,9) content-size 35.3125x42.9375 table-box [TFC] children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box at (9,9) content-size 43.122404x42.9375 table-row-group children: not-inline - Box at (9,9) content-size 43.122404x21.46875 table-row children: not-inline + Box at (9,9) content-size 37.3125x42.9375 table-row-group children: not-inline + Box at (9,9) content-size 37.3125x21.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer at (9,30.46875) content-size 43.122404x21.46875 table-row children: not-inline + Box at (9,30.46875) content-size 37.3125x21.46875 table-row children: not-inline BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer
at (11,11) content-size 17.561202x17.46875 table-cell [BFC] children: inline @@ -20,21 +20,21 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - BlockContainer at (32.561202,11) content-size 17.561202x17.46875 table-cell [BFC] children: inline + BlockContainer at (32.561202,11) content-size 11.751297x17.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: [36.561202,11 9.34375x17.46875] + frag 0 from TextNode start: 0, length: 1, rect: [33.561202,11 9.34375x17.46875] "B" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline TextNode <#text> - Box
at (11,32.46875) content-size 39.122404x17.46875 table-cell [BFC] children: inline + BlockContainer at (11,32.46875) content-size 33.3125x17.46875 table-cell [BFC] children: inline line 0 width: 33.3125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 3, rect: [14,32.46875 33.3125x17.46875] + frag 0 from TextNode start: 0, length: 3, rect: [11,32.46875 33.3125x17.46875] "CDE" TextNode <#text> BlockContainer <(anonymous)> (not painted) children: inline diff --git a/Tests/LibWeb/Layout/input/table/colspan-weighted-width-distribution.html b/Tests/LibWeb/Layout/input/table/colspan-weighted-width-distribution.html new file mode 100644 index 0000000000..f678b392a3 --- /dev/null +++ b/Tests/LibWeb/Layout/input/table/colspan-weighted-width-distribution.html @@ -0,0 +1,18 @@ + + + + + + + + + + +
AB
C
\ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp index c1d20cfede..3f9d001c1c 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -261,27 +261,26 @@ void TableFormattingContext::compute_table_measures() // Define the baseline border spacing as the sum of the horizontal border-spacing for any columns spanned by the cell, other than the one in which the cell originates. auto baseline_border_spacing = border_spacing() * (cell_span_value - 1); - // The contribution of the cell is the sum of: - // the min-content size of the column based on cells of span up to N-1 - auto cell_min_contribution = rows_or_columns[cell_start_rc_index].min_size; - // and the product of: - // - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size - // - the outer min-content size of the cell minus the baseline max-content size and baseline border spacing, or 0 if this is negative - cell_min_contribution += (rows_or_columns[cell_start_rc_index].max_size / baseline_max_content_size) - * max(CSSPixels(0), cell_min_size(cell) - baseline_max_content_size - baseline_border_spacing); - - // The contribution of the cell is the sum of: - // the max-content size of the column based on cells of span up to N-1 - auto cell_max_contribution = rows_or_columns[cell_start_rc_index].max_size; - // and the product of: - // - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size - // - the outer max-content size of the cell minus the baseline max-content size and the baseline border spacing, or 0 if this is negative - cell_max_contribution += (rows_or_columns[cell_start_rc_index].max_size / baseline_max_content_size) - * max(CSSPixels(0), cell_max_size(cell) - baseline_max_content_size - baseline_border_spacing); - - // Spread contribution to all rows / columns, since we've weighted the gap to the desired spanned size by the the + // Add contribution from all rows / columns, since we've weighted the gap to the desired spanned size by the the // ratio of the max-content size based on cells of span up to N-1 of the row / column to the baseline max-content width. for (auto rc_index = cell_start_rc_index; rc_index < cell_end_rc_index; rc_index++) { + // The contribution of the cell is the sum of: + // the min-content size of the column based on cells of span up to N-1 + auto cell_min_contribution = rows_or_columns[rc_index].min_size; + // and the product of: + // - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size + // - the outer min-content size of the cell minus the baseline max-content size and baseline border spacing, or 0 if this is negative + cell_min_contribution += (rows_or_columns[rc_index].max_size / baseline_max_content_size) + * max(CSSPixels(0), cell_min_size(cell) - baseline_max_content_size - baseline_border_spacing); + + // The contribution of the cell is the sum of: + // the max-content size of the column based on cells of span up to N-1 + auto cell_max_contribution = rows_or_columns[rc_index].max_size; + // and the product of: + // - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size + // - the outer max-content size of the cell minus the baseline max-content size and the baseline border spacing, or 0 if this is negative + cell_max_contribution += (rows_or_columns[rc_index].max_size / baseline_max_content_size) + * max(CSSPixels(0), cell_max_size(cell) - baseline_max_content_size - baseline_border_spacing); cell_min_contributions_by_rc_index[rc_index].append(cell_min_contribution); cell_max_contributions_by_rc_index[rc_index].append(cell_max_contribution); }