From 3cd243672f4c9ba1973380965d32b463b19a8b7d Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Tue, 25 Nov 2008 13:27:54 -0800 Subject: [PATCH] Distribute extra space in fixed-layout tables where all columns have widths proportionally rather than equally, for compatibility. (Bug 445142) r=bernd sr=roc a=blocking1.9.1+ --- layout/reftests/bugs/445142-1-ref.html | 147 ++++++++++++++++ layout/reftests/bugs/445142-1a.html | 149 ++++++++++++++++ layout/reftests/bugs/445142-1b.html | 187 ++++++++++++++++++++ layout/reftests/bugs/445142-1c.html | 155 +++++++++++++++++ layout/reftests/bugs/445142-2-ref.html | 148 ++++++++++++++++ layout/reftests/bugs/445142-2a.html | 150 ++++++++++++++++ layout/reftests/bugs/445142-2b.html | 188 +++++++++++++++++++++ layout/reftests/bugs/reftest.list | 5 + layout/tables/FixedTableLayoutStrategy.cpp | 91 ++++++++-- 9 files changed, 1208 insertions(+), 12 deletions(-) create mode 100644 layout/reftests/bugs/445142-1-ref.html create mode 100644 layout/reftests/bugs/445142-1a.html create mode 100644 layout/reftests/bugs/445142-1b.html create mode 100644 layout/reftests/bugs/445142-1c.html create mode 100644 layout/reftests/bugs/445142-2-ref.html create mode 100644 layout/reftests/bugs/445142-2a.html create mode 100644 layout/reftests/bugs/445142-2b.html diff --git a/layout/reftests/bugs/445142-1-ref.html b/layout/reftests/bugs/445142-1-ref.html new file mode 100644 index 00000000000..265497df60d --- /dev/null +++ b/layout/reftests/bugs/445142-1-ref.html @@ -0,0 +1,147 @@ + + + + table-layout: fixed width distribution with unassigned space + + + + + + + + + + +
100px
+ + + + + +
700px
+ + + + + +
600px
+ + + + + + +
100px200px
+ + + + + + +
150px300px
+ + + + + +
20%
+ + + + + +
100%
+ + + + + +
120%
+ + + + + + +
20%40%
+ + + + + + +
30%60%
+ + + + + + +
20%100px
+ + + + + + + +
20%100pxdiv
+ + + + + + +
20%
0
+ + + + + + +
20%
0%
+ + + + + + +
100px
0
+ + + + + + +
100px
0%
+ + + + + + +
00
+ + + + + + +
0%0
+ + + diff --git a/layout/reftests/bugs/445142-1a.html b/layout/reftests/bugs/445142-1a.html new file mode 100644 index 00000000000..8ab69ad821b --- /dev/null +++ b/layout/reftests/bugs/445142-1a.html @@ -0,0 +1,149 @@ + + + + table-layout: fixed width distribution with unassigned space + + + + + + + + + + +
100px
+ + + + + +
700px
+ + + + + +
600px
+ + + + + + +
100px200px
+ + + + + + +
150px300px
+ + + + + +
20%
+ + + + + +
100%
+ + + + + +
120%
+ + + + + + +
20%40%
+ + + + + + +
30%60%
+ + + + + + +
20%100px
+ + + + + + + +
20%100px
div
+ + + + + + +
20%0
+ + + + + + +
20%0%
+ + + + + + +
100px0
+ + + + + + +
100px0%
+ + + + + + +
00
+ + + + + + +
0%0
+ + + diff --git a/layout/reftests/bugs/445142-1b.html b/layout/reftests/bugs/445142-1b.html new file mode 100644 index 00000000000..57102394dc2 --- /dev/null +++ b/layout/reftests/bugs/445142-1b.html @@ -0,0 +1,187 @@ + + + + table-layout: fixed width distribution with unassigned space + + + + + + + + + + + + + +
100px
+ + + + + + +
700px
+ + + + + + +
600px
+ + + + + + + + +
100px200px
+ + + + + + + + +
150px300px
+ + + + + + +
20%
+ + + + + + +
100%
+ + + + + + +
120%
+ + + + + + + + +
20%40%
+ + + + + + + + +
30%60%
+ + + + + + + + +
20%100px
+ + + + + + + + + + +
20%100px
div
+ + + + + + + + +
20%0
+ + + + + + + + +
20%0%
+ + + + + + + + +
100px0
+ + + + + + + + +
100px0%
+ + + + + + + + +
00
+ + + + + + + + +
0%0
+ + + diff --git a/layout/reftests/bugs/445142-1c.html b/layout/reftests/bugs/445142-1c.html new file mode 100644 index 00000000000..cef8cfc6ee3 --- /dev/null +++ b/layout/reftests/bugs/445142-1c.html @@ -0,0 +1,155 @@ + + + + table-layout: fixed width distribution with unassigned space + + + + + + + + + + + + +
100px
+ + + + + +
700px
+ + + + + +
600px
+ + + + + + +
100px200px
+ + + + + + +
150px300px
+ + + + + +
20%
+ + + + + +
100%
+ + + + + +
120%
+ + + + + + +
20%40%
+ + + + + + +
30%60%
+ + + + + + +
20%100px
+ + + + + + + +
20%100px
div
+ + + + + + +
20%0
+ + + + + + +
20%0%
+ + + + + + +
100px0
+ + + + + + +
100px0%
+ + + + + + +
00
+ + + + + + +
0%0
+ + + diff --git a/layout/reftests/bugs/445142-2-ref.html b/layout/reftests/bugs/445142-2-ref.html new file mode 100644 index 00000000000..31be5f7d66b --- /dev/null +++ b/layout/reftests/bugs/445142-2-ref.html @@ -0,0 +1,148 @@ + + + + table-layout: fixed width distribution with unassigned space + + + + + + + + + + +
100px
+ + + + + +
500px
+ + + + + +
600px
+ + + + + + +
100px200px
+ + + + + + +
150px300px
+ + + + + +
20%
+ + + + + +
100%
+ + + + + +
120%
+ + + + + + +
20%40%
+ + + + + + +
30%60%
+ + + + + + +
20%100px
+ + + + + + + +
20%100pxdiv
+ + + + + + +
20%
0
+ + + + + + +
20%
0%
+ + + + + + +
100px
0
+ + + + + + +
100px
0%
+ + + + + + +
00
+ + + + + + +
0%0
+ + + diff --git a/layout/reftests/bugs/445142-2a.html b/layout/reftests/bugs/445142-2a.html new file mode 100644 index 00000000000..e89c2fabd1b --- /dev/null +++ b/layout/reftests/bugs/445142-2a.html @@ -0,0 +1,150 @@ + + + + table-layout: fixed width distribution with unassigned space + + + + + + + + + + +
100px
+ + + + + +
500px
+ + + + + +
600px
+ + + + + + +
100px200px
+ + + + + + +
150px300px
+ + + + + +
20%
+ + + + + +
100%
+ + + + + +
120%
+ + + + + + +
20%40%
+ + + + + + +
30%60%
+ + + + + + +
20%100px
+ + + + + + + +
20%100px
div
+ + + + + + +
20%0
+ + + + + + +
20%0%
+ + + + + + +
100px0
+ + + + + + +
100px0%
+ + + + + + +
00
+ + + + + + +
0%0
+ + + diff --git a/layout/reftests/bugs/445142-2b.html b/layout/reftests/bugs/445142-2b.html new file mode 100644 index 00000000000..f633e498ff4 --- /dev/null +++ b/layout/reftests/bugs/445142-2b.html @@ -0,0 +1,188 @@ + + + + table-layout: fixed width distribution with unassigned space + + + + + + + + + + + + + +
100px
+ + + + + + +
500px
+ + + + + + +
600px
+ + + + + + + + +
100px200px
+ + + + + + + + +
150px300px
+ + + + + + +
20%
+ + + + + + +
100%
+ + + + + + +
120%
+ + + + + + + + +
20%40%
+ + + + + + + + +
30%60%
+ + + + + + + + +
20%100px
+ + + + + + + + + + +
20%100px
div
+ + + + + + + + +
20%0
+ + + + + + + + +
20%0%
+ + + + + + + + +
100px0
+ + + + + + + + +
100px0%
+ + + + + + + + +
00
+ + + + + + + + +
0%0
+ + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 9f1a3de6269..24333849270 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -919,6 +919,11 @@ fails == 441259-2.html 441259-2-ref.html # bug 441400 == 444928-2.html 444928-2-ref.html != 444928-3.html 444928-3-notref.html == 445004-1.html 445004-1-ref.html +== 445142-1a.html 445142-1-ref.html +== 445142-1b.html 445142-1-ref.html +== 445142-1c.html 445142-1-ref.html +== 445142-2a.html 445142-2-ref.html +== 445142-2b.html 445142-2-ref.html == 446100-1a.html about:blank == 446100-1b.html about:blank == 446100-1c.html about:blank diff --git a/layout/tables/FixedTableLayoutStrategy.cpp b/layout/tables/FixedTableLayoutStrategy.cpp index cfd35dc9cef..257d4c1a546 100644 --- a/layout/tables/FixedTableLayoutStrategy.cpp +++ b/layout/tables/FixedTableLayoutStrategy.cpp @@ -199,10 +199,14 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt const nscoord unassignedMarker = nscoord_MIN; // We use the PrefPercent on the columns to store the percentages - // used to compute column widths in case we need to reduce their - // basis. + // used to compute column widths in case we need to shrink or expand + // the columns. float pctTotal = 0.0f; + // Accumulate the total specified (non-percent) on the columns for + // distributing excess width to the columns. + nscoord specTotal = 0; + for (PRInt32 col = 0; col < colCount; ++col) { nsTableColFrame *colFrame = mTableFrame->GetColFrame(col); if (!colFrame) { @@ -217,6 +221,7 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt colWidth = nsLayoutUtils::ComputeWidthValue( aReflowState.rendContext, colFrame, 0, 0, 0, *styleWidth); + specTotal += colWidth; } else if (styleWidth->GetUnit() == eStyleUnit_Percent) { float pct = styleWidth->GetPercentValue(); colWidth = NSToCoordFloor(pct * float(tableWidth)); @@ -272,6 +277,9 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt if (colWidth < 0) colWidth = 0; } + if (styleWidth->GetUnit() != eStyleUnit_Percent) { + specTotal += colWidth; + } } } else { colWidth = unassignedMarker; @@ -313,6 +321,8 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt } if (unassignedCount > 0) { + // The spec says to distribute the remaining space evenly among + // the columns. nscoord toAssign = unassignedSpace / unassignedCount; for (PRInt32 col = 0; col < colCount; ++col) { nsTableColFrame *colFrame = mTableFrame->GetColFrame(col); @@ -324,17 +334,74 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt colFrame->SetFinalWidth(toAssign); } } else if (unassignedSpace > 0) { - // The spec says to distribute extra space evenly. (That's not - // what WinIE6 does, though. It treats percentages and - // nonpercentages differently.) - nscoord toAdd = unassignedSpace / colCount; - for (PRInt32 col = 0; col < colCount; ++col) { - nsTableColFrame *colFrame = mTableFrame->GetColFrame(col); - if (!colFrame) { - NS_ERROR("column frames out of sync with cell map"); - continue; + // The spec doesn't say how to distribute the unassigned space. + if (specTotal > 0) { + // Distribute proportionally to non-percentage columns. + nscoord specUndist = specTotal; + for (PRInt32 col = 0; col < colCount; ++col) { + nsTableColFrame *colFrame = mTableFrame->GetColFrame(col); + if (!colFrame) { + NS_ERROR("column frames out of sync with cell map"); + continue; + } + if (colFrame->GetPrefPercent() == 0.0f) { + NS_ASSERTION(colFrame->GetFinalWidth() <= specUndist, + "widths don't add up"); + nscoord toAdd = NSToCoordRound(float(unassignedSpace) * + (float(colFrame->GetFinalWidth()) / float(specUndist))); + specUndist -= colFrame->GetFinalWidth(); + colFrame->SetFinalWidth(colFrame->GetFinalWidth() + toAdd); + unassignedSpace -= toAdd; + if (specUndist <= 0) { + NS_ASSERTION(specUndist == 0, + "math should be exact"); + break; + } + } + } + NS_ASSERTION(unassignedSpace == 0, "failed to redistribute"); + } else if (pctTotal > 0) { + // Distribute proportionally to percentage columns. + float pctUndist = pctTotal; + for (PRInt32 col = 0; col < colCount; ++col) { + nsTableColFrame *colFrame = mTableFrame->GetColFrame(col); + if (!colFrame) { + NS_ERROR("column frames out of sync with cell map"); + continue; + } + if (pctUndist < colFrame->GetPrefPercent()) { + // This can happen with floating-point math. + NS_ASSERTION(colFrame->GetPrefPercent() - pctUndist + < 0.0001, + "widths don't add up"); + pctUndist = colFrame->GetPrefPercent(); + } + nscoord toAdd = NSToCoordRound(float(unassignedSpace) * + (colFrame->GetPrefPercent() / pctUndist)); + colFrame->SetFinalWidth(colFrame->GetFinalWidth() + toAdd); + unassignedSpace -= toAdd; + pctUndist -= colFrame->GetPrefPercent(); + if (pctUndist <= 0.0f) { + break; + } + } + NS_ASSERTION(unassignedSpace == 0, "failed to redistribute"); + } else { + // Distribute equally to the zero-width columns. + PRInt32 colsLeft = colCount; + for (PRInt32 col = 0; col < colCount; ++col) { + nsTableColFrame *colFrame = mTableFrame->GetColFrame(col); + if (!colFrame) { + NS_ERROR("column frames out of sync with cell map"); + continue; + } + NS_ASSERTION(colFrame->GetFinalWidth() == 0, "yikes"); + nscoord toAdd = NSToCoordRound(float(unassignedSpace) / + float(colsLeft)); + colFrame->SetFinalWidth(toAdd); + unassignedSpace -= toAdd; + --colsLeft; } - colFrame->SetFinalWidth(colFrame->GetFinalWidth() + toAdd); } } }