1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-08 19:27:35 +00:00

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.
This commit is contained in:
Andi Gallo 2023-06-19 09:28:04 +00:00 committed by Andreas Kling
parent b37fbcb159
commit ac6af51549
6 changed files with 118 additions and 62 deletions

View file

@ -5,14 +5,14 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <body> 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 <table> 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 <table> at (9,9) content-size 239.90625x257.34375 table-box [TFC] children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
Box <tbody> at (9,9) content-size 163.625x197.34375 table-row-group children: not-inline
Box <tbody> at (9,9) content-size 161.90625x197.34375 table-row-group children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
Box <tr> at (29,19) content-size 163.625x39.46875 table-row children: not-inline
Box <tr> at (29,19) content-size 161.90625x39.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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 <td> at (126.265625,30) content-size 14.265625x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <td> at (202.53125,30) content-size 9.09375x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <tr> at (29,58.46875) content-size 163.625x39.46875 table-row children: not-inline
Box <tr> at (29,58.46875) content-size 161.90625x39.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> at (50,79.46875) content-size 90.53125x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <td> at (202.53125,79.46875) content-size 9.09375x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <tr> at (29,97.9375) content-size 163.625x39.46875 table-row children: not-inline
Box <tr> at (29,97.9375) content-size 161.90625x39.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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 <td> at (126.265625,128.9375) content-size 14.265625x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <td> at (202.53125,128.9375) content-size 9.09375x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <tr> at (29,137.40625) content-size 163.625x39.46875 table-row children: not-inline
Box <tr> at (29,137.40625) content-size 161.90625x39.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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 <td> at (126.265625,178.40625) content-size 14.265625x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <td> at (202.53125,178.40625) content-size 9.09375x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <tr> at (29,176.875) content-size 163.625x39.46875 table-row children: not-inline
Box <tr> at (29,176.875) content-size 161.90625x39.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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 <td> at (126.265625,227.875) content-size 14.265625x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <td> at (202.53125,227.875) content-size 9.09375x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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

View file

@ -1,12 +1,12 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> 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 <table> 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 <table> at (8,8) content-size 92.359375x118.40625 table-box [TFC] children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
Box <tbody> at (8,8) content-size 123.171875x118.40625 table-row-group children: not-inline
Box <tr> at (8,8) content-size 123.171875x39.46875 table-row children: not-inline
Box <tbody> at (8,8) content-size 92.359375x118.40625 table-row-group children: not-inline
Box <tr> at (8,8) content-size 92.359375x39.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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 <tr> at (8,47.46875) content-size 123.171875x39.46875 table-row children: not-inline
Box <tr> at (8,47.46875) content-size 92.359375x39.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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 <td> at (49.453125,78.203125) content-size 70.71875x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <tr> at (8,86.9375) content-size 123.171875x39.46875 table-row children: not-inline
Box <tr> at (8,86.9375) content-size 92.359375x39.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> at (19,97.9375) content-size 8.453125x17.46875 table-cell [BFC] children: inline

View file

@ -0,0 +1,39 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x44.9375 children: not-inline
TableWrapper <(anonymous)> at (8,8) content-size 206x44.9375 [BFC] children: not-inline
Box <table> at (9,9) content-size 204x42.9375 table-box [TFC] children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
Box <tbody> at (9,9) content-size 204x42.9375 table-row-group children: not-inline
Box <tr> at (9,9) content-size 204x21.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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 <td> 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 <tr> at (9,30.46875) content-size 204x21.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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>

View file

@ -5,12 +5,12 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <body> 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 <table> 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 <table> at (9,9) content-size 35.3125x42.9375 table-box [TFC] children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
Box <tbody> at (9,9) content-size 43.122404x42.9375 table-row-group children: not-inline
Box <tr> at (9,9) content-size 43.122404x21.46875 table-row children: not-inline
Box <tbody> at (9,9) content-size 37.3125x42.9375 table-row-group children: not-inline
Box <tr> at (9,9) content-size 37.3125x21.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> 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 <td> at (32.561202,11) content-size 17.561202x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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 <tr> at (9,30.46875) content-size 43.122404x21.46875 table-row children: not-inline
Box <tr> at (9,30.46875) content-size 37.3125x21.46875 table-row children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> at (11,32.46875) content-size 39.122404x17.46875 table-cell [BFC] children: inline
BlockContainer <td> 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

View file

@ -0,0 +1,18 @@
<style>
table,
td {
border: 1px solid black;
border-spacing: 0px;
text-align: center;
}
</style>
<table>
<tr>
<td style="width: 180px;">A</td>
<td style="width: 20px;">B</td>
</tr>
<tr>
<td colspan="2">C</td>
</tr>
</table>

View file

@ -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<RowOrColumn>() * (cell_span_value - 1);
// 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[cell_start_rc_index].min_size;
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[cell_start_rc_index].max_size / baseline_max_content_size)
cell_min_contribution += (rows_or_columns[rc_index].max_size / baseline_max_content_size)
* max(CSSPixels(0), cell_min_size<RowOrColumn>(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;
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[cell_start_rc_index].max_size / baseline_max_content_size)
cell_max_contribution += (rows_or_columns[rc_index].max_size / baseline_max_content_size)
* max(CSSPixels(0), cell_max_size<RowOrColumn>(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
// 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++) {
cell_min_contributions_by_rc_index[rc_index].append(cell_min_contribution);
cell_max_contributions_by_rc_index[rc_index].append(cell_max_contribution);
}