Bug 367673, Handle width-computation arithmetic with nscoord_MAX. r=roc sr=roc a1.9=roc

This commit is contained in:
2007-09-24 10:30:42 -07:00
parent cc458c8b7f
commit 0d28f155e9
4 changed files with 158 additions and 23 deletions

View File

@@ -219,7 +219,7 @@ GetWidthInfo(nsIRenderingContext *aRenderingContext,
// XXX Should we ignore percentage padding?
nscoord add = offsets.hPadding + offsets.hBorder;
minCoord += add;
prefCoord += add;
prefCoord = NSCoordSaturatingAdd(prefCoord, add);
}
return CellWidthInfo(minCoord, prefCoord, prefPercent, hasSpecifiedWidth);
@@ -490,8 +490,10 @@ BasicTableLayoutStrategy::ComputeColumnIntrinsicWidths(nsIRenderingContext* aRen
NSToCoordRound(float(minWithinPref) * minRatio);
nscoord allocatedMinOutsidePref =
NSToCoordRound(float(minOutsidePref) * coordRatio);
nscoord allocatedPref =
NSToCoordRound(float(info.prefCoord) * coordRatio);
nscoord allocatedPref =
(info.prefCoord == nscoord_MAX ?
nscoord_MAX :
NSToCoordRound(float(info.prefCoord) * coordRatio));
nscoord spanMin = scolFrame->GetMinCoord() +
allocatedMinWithinPref + allocatedMinOutsidePref;
nscoord spanPref = scolFrame->GetPrefCoord() + allocatedPref;
@@ -503,7 +505,9 @@ BasicTableLayoutStrategy::ComputeColumnIntrinsicWidths(nsIRenderingContext* aRen
// passed from the totals.
minWithinPref -= allocatedMinWithinPref;
minOutsidePref -= allocatedMinOutsidePref;
info.prefCoord -= allocatedPref;
info.prefCoord = NSCoordSaturatingSubtract(info.prefCoord,
allocatedPref,
nscoord_MAX);
info.prefPercent -= allocatedPct;
totalSPref -= scolFrame->GetPrefCoord();
totalSMin -= scolFrame->GetMinCoord();
@@ -521,7 +525,8 @@ BasicTableLayoutStrategy::ComputeColumnIntrinsicWidths(nsIRenderingContext* aRen
NS_ASSERTION(totalSPref == 0 && totalSMin == 0 &&
totalSNonPctPref == 0 && nonPctCount == 0 &&
minOutsidePref == 0 && minWithinPref == 0 &&
info.prefCoord == 0 &&
(info.prefCoord == 0 ||
info.prefCoord == nscoord_MAX) &&
(info.prefPercent == 0.0f || !spanHasNonPct),
"didn't subtract all that we added");
} while ((item = item->next));
@@ -593,7 +598,7 @@ BasicTableLayoutStrategy::ComputeIntrinsicWidths(nsIRenderingContext* aRendering
add += spacing;
}
min += colFrame->GetMinCoord();
pref += colFrame->GetPrefCoord();
pref = NSCoordSaturatingAdd(pref, colFrame->GetPrefCoord());
// Percentages are of the table, so we have to reverse them for
// intrinsic widths.
@@ -640,8 +645,8 @@ BasicTableLayoutStrategy::ComputeIntrinsicWidths(nsIRenderingContext* aRendering
// border-spacing isn't part of the basis for percentages
if (colCount > 0) {
min += add;
pref += add;
pref_pct_expand += add;
pref = NSCoordSaturatingAdd(pref, add);
pref_pct_expand = NSCoordSaturatingAdd(pref_pct_expand, add);
}
mMinWidth = min;
@@ -749,6 +754,7 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
total_flex_pref = 0,
total_fixed_pref = 0;
float total_pct = 0.0f; // 0.0f to 1.0f
PRInt32 numInfiniteWidthCols = 0;
PRInt32 col;
for (col = 0; col < colCount; ++col) {
@@ -769,19 +775,26 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
guess_pref += val;
} else {
nscoord pref_width = colFrame->GetPrefCoord();
guess_pref += pref_width;
if (pref_width == nscoord_MAX) {
numInfiniteWidthCols++;
}
guess_pref = NSCoordSaturatingAdd(guess_pref, pref_width);
guess_min_pct += min_width;
if (colFrame->GetHasSpecifiedCoord()) {
// we'll add on the rest of guess_min_spec outside the
// loop
guess_min_spec += pref_width - min_width;
total_fixed_pref += pref_width;
nscoord delta = NSCoordSaturatingSubtract(pref_width,
min_width, 0);
guess_min_spec = NSCoordSaturatingAdd(guess_min_spec, delta);
total_fixed_pref = NSCoordSaturatingAdd(total_fixed_pref,
pref_width);
} else {
total_flex_pref += pref_width;
total_flex_pref = NSCoordSaturatingAdd(total_flex_pref,
pref_width);
}
}
}
guess_min_spec += guess_min_pct;
guess_min_spec = NSCoordSaturatingAdd(guess_min_spec, guess_min_pct);
// Determine what we're flexing:
enum Loop2Type {
@@ -812,13 +825,18 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
} else if (width < guess_min_spec) {
l2t = FLEX_FIXED_SMALL;
space = width - guess_min_pct;
basis.c = guess_min_spec - guess_min_pct;
basis.c = NSCoordSaturatingSubtract(guess_min_spec, guess_min_pct,
nscoord_MAX);
} else {
l2t = FLEX_FLEX_SMALL;
space = width - guess_min_spec;
basis.c = guess_pref - guess_min_spec;
basis.c = NSCoordSaturatingSubtract(guess_pref, guess_min_spec,
nscoord_MAX);
}
} else {
// Note: Shouldn't have to check for nscoord_MAX in this case, because
// width should be much less than nscoord_MAX, and being here means
// guess_pref is no larger than width.
space = width - guess_pref;
if (total_flex_pref > 0) {
l2t = FLEX_FLEX_LARGE;
@@ -903,11 +921,30 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
NS_ASSERTION(col_width == colFrame->GetPrefCoord(),
"wrong width assigned");
nscoord col_min = colFrame->GetMinCoord();
nscoord pref_minus_min = col_width - col_min;
nscoord pref_minus_min =
NSCoordSaturatingSubtract(col_width, col_min, 0);
col_width = col_width_before_adjust = col_min;
if (pref_minus_min != 0) {
float c = float(space) / float(basis.c);
basis.c -= pref_minus_min;
// If we have infinite-width cols, then the standard
// adjustment to col_width using 'c' won't work,
// because basis.c and pref_minus_min are both
// nscoord_MAX and will cancel each other out in the
// col_width adjustment (making us assign all the
// space to the first inf-width col). To correct for
// this, we'll also divide by numInfiniteWidthCols to
// spread the space equally among the inf-width cols.
if (numInfiniteWidthCols) {
if (colFrame->GetPrefCoord() == nscoord_MAX) {
c = c / float(numInfiniteWidthCols);
numInfiniteWidthCols--;
} else {
c = 0.0f;
}
}
basis.c = NSCoordSaturatingSubtract(basis.c,
pref_minus_min,
nscoord_MAX);
col_width += NSToCoordRound(
float(pref_minus_min) * c);
}
@@ -971,7 +1008,7 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
NS_ASSERTION(space == 0 &&
((l2t == FLEX_PCT_LARGE)
? (-0.001f < basis.f && basis.f < 0.001f)
: (basis.c == 0)),
: (basis.c == 0 || basis.c == nscoord_MAX)),
"didn't subtract all that we added");
#ifdef DEBUG_TABLE_STRATEGY
printf("ComputeColumnWidths final\n");