Fix slight errors when widths can't be round-tripped through floats. (
Bug 467141) r+sr=roc
--- a/layout/tables/FixedTableLayoutStrategy.cpp
+++ b/layout/tables/FixedTableLayoutStrategy.cpp
@@ -163,16 +163,28 @@ FixedTableLayoutStrategy::GetPrefWidth(n
/* virtual */ void
FixedTableLayoutStrategy::MarkIntrinsicWidthsDirty()
{
mMinWidth = NS_INTRINSIC_WIDTH_UNKNOWN;
mLastCalcWidth = nscoord_MIN;
}
+static inline nscoord
+AllocateUnassigned(nscoord aUnassignedSpace, float aShare)
+{
+ if (aShare == 1.0f) {
+ // This happens when the numbers we're dividing to get aShare
+ // are equal. We want to return unassignedSpace exactly, even
+ // if it can't be precisely round-tripped through float.
+ return aUnassignedSpace;
+ }
+ return NSToCoordRound(float(aUnassignedSpace) * aShare);
+}
+
/* virtual */ void
FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowState)
{
nscoord tableWidth = aReflowState.ComputedWidth();
if (mLastCalcWidth == tableWidth)
return;
mLastCalcWidth = tableWidth;
@@ -352,18 +364,18 @@ FixedTableLayoutStrategy::ComputeColumnW
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)));
+ nscoord toAdd = AllocateUnassigned(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;
}
@@ -381,18 +393,18 @@ FixedTableLayoutStrategy::ComputeColumnW
}
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));
+ nscoord toAdd = AllocateUnassigned(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");
@@ -401,22 +413,23 @@ FixedTableLayoutStrategy::ComputeColumnW
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));
+ nscoord toAdd = AllocateUnassigned(unassignedSpace,
+ 1.0f / float(colsLeft));
colFrame->SetFinalWidth(toAdd);
unassignedSpace -= toAdd;
--colsLeft;
}
+ NS_ASSERTION(unassignedSpace == 0, "failed to redistribute");
}
}
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;
}
new file mode 100644
--- /dev/null
+++ b/layout/tables/crashtests/467141-1.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<table width="16211982" cellspacing="0" style="table-layout: fixed;"><tbody><tr><td width="26"></td></tr></tbody></table>
+</body>
+</html>
--- a/layout/tables/crashtests/crashtests.list
+++ b/layout/tables/crashtests/crashtests.list
@@ -51,8 +51,9 @@ load 408753-1.xhtml
load 411582.xhtml
load 413180-1.html
load 416845-1.xhtml
load 416845-2.xhtml
load 416845-3.html
load 423514-1.xhtml
load 456041.html
load 457115.html
+load 467141-1.html