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+
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user