diff --git a/layout/reftests/bugs/368504-6-ref.html b/layout/reftests/bugs/368504-6-ref.html
new file mode 100644
index 000000000000..f63c687c17db
--- /dev/null
+++ b/layout/reftests/bugs/368504-6-ref.html
@@ -0,0 +1,16 @@
+
+
+ xxx
+
+
+ | x x x x x x x x x x x x |
+ xxx |
+
+
+ | xxx |
+ xxx |
+ xxx |
+
+
+
+
diff --git a/layout/reftests/bugs/368504-6.html b/layout/reftests/bugs/368504-6.html
new file mode 100644
index 000000000000..c571302f8e0c
--- /dev/null
+++ b/layout/reftests/bugs/368504-6.html
@@ -0,0 +1,19 @@
+
+
+
+
+ | xxx |
+   |
+
+
+ | x x x x x x x x x x x x |
+ xxx |
+
+
+ | xxx |
+ xxx |
+ xxx |
+
+
+
+
diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list
index 6ef143947c36..4754c7bf822f 100644
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -383,12 +383,13 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 368020-5.html 368020-5-ref.html # bug 3
# is too exact
# == 368247-1.html 368247-1-ref.html
== 368247-2.html 368247-2-ref.html
-fails == 368504-1.html 368504-1-ref.html
-fails == 368504-2.html 368504-2-ref.html
-fails == 368504-3a.html 368504-3-ref.html
-fails == 368504-3b.html 368504-3-ref.html
-fails == 368504-4.html 368504-4-ref.html
-fails == 368504-5.html 368504-5-ref.html
+== 368504-1.html 368504-1-ref.html
+== 368504-2.html 368504-2-ref.html
+== 368504-3a.html 368504-3-ref.html
+== 368504-3b.html 368504-3-ref.html
+== 368504-4.html 368504-4-ref.html
+== 368504-5.html 368504-5-ref.html
+== 368504-6.html 368504-6-ref.html
== 368622-1.html 368622-1-ref.html
== 368622-1.html 368622-1-ref.html
== 368651-1.html 368651-1-ref.html
diff --git a/layout/tables/BasicTableLayoutStrategy.cpp b/layout/tables/BasicTableLayoutStrategy.cpp
index c511f9dd1c05..6e0a265c7859 100644
--- a/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/layout/tables/BasicTableLayoutStrategy.cpp
@@ -254,7 +254,6 @@ BasicTableLayoutStrategy::ComputeColumnIntrinsicWidths(nsIRenderingContext* aRen
nsTableFrame *tableFrame = mTableFrame;
nsTableCellMap *cellMap = tableFrame->GetCellMap();
- nscoord spacing = tableFrame->GetCellSpacingX();
SpanningCellSorter spanningCells(tableFrame->PresContext()->PresShell());
// Loop over the columns to consider the columns and cells *without*
@@ -351,191 +350,14 @@ BasicTableLayoutStrategy::ComputeColumnIntrinsicWidths(nsIRenderingContext* aRen
CellWidthInfo info = GetCellWidthInfo(aRenderingContext, cellFrame);
- // Before looping over the spanned columns to distribute
- // this cell's width over the columns it spans, we first
- // compute totals over the spanned columns so we know how to
- // allocate the space.
-
- // Accumulate information about the spanned columns, and
- // subtract the already-used space from |info|.
- nscoord totalSPref = 0, totalSMin = 0; // total existing widths
- nscoord totalSNonPctPref = 0; // total pref width of columns
- // without percentage widths
- nscoord totalSAutoPref = 0; // total pref width of auto-width cols
- PRInt32 nonPctCount = 0; // # of columns without percentage widths
- PRInt32 scol, scol_end;
- for (scol = col, scol_end = col + colSpan;
- scol < scol_end; ++scol) {
- nsTableColFrame *scolFrame = tableFrame->GetColFrame(scol);
- if (!scolFrame) {
- NS_ERROR("column frames out of sync with cell map");
- continue;
- }
-
- if (mTableFrame->GetNumCellsOriginatingInCol(scol) &&
- scol != col) {
- info.minCoord -= spacing;
- info.prefCoord = NSCoordSaturatingSubtract(info.prefCoord,
- spacing,
- nscoord_MAX);
- }
-
- totalSPref += scolFrame->GetPrefCoord();
- totalSMin += scolFrame->GetMinCoord();
- if (!scolFrame->GetHasSpecifiedCoord()) {
- totalSAutoPref += scolFrame->GetPrefCoord();
- }
- float scolPct = scolFrame->GetPrefPercent();
- if (scolPct == 0.0f) {
- totalSNonPctPref += scolFrame->GetPrefCoord();
- ++nonPctCount;
- } else {
- info.prefPercent -= scolPct;
- }
- info.minCoord -= scolFrame->GetMinCoord();
- info.prefCoord =
- NSCoordSaturatingSubtract(info.prefCoord,
- scolFrame->GetPrefCoord(),
- nscoord_MAX);
+ if (info.prefPercent > 0.0f) {
+ DistributePctWidthToColumns(info.prefPercent,
+ col, colSpan);
}
-
- if (info.minCoord < 0)
- info.minCoord = 0;
- if (info.prefCoord < 0)
- info.prefCoord = 0;
- if (info.prefPercent < 0.0f)
- info.prefPercent = 0.0f;
-
- // The min-width of this cell that fits inside the
- // pref-width of the spanned columns gets distributed
- // according to different ratios.
- nscoord minWithinPref =
- PR_MIN(info.minCoord, totalSPref - totalSMin);
- NS_ASSERTION(minWithinPref >= 0, "neither value can be negative");
- nscoord minOutsidePref = info.minCoord - minWithinPref;
-
- // Loop invariants (that we might get confused about as we
- // subtract amounts for completed columns)
- const PRBool spanHasNonPctPref = totalSNonPctPref > 0;
- const PRBool spanHasPref = totalSPref > 0;
- const PRBool spanHasNonPct = nonPctCount > 0;
-
- // ... and actually do the distribution of the widths of
- // this cell exceeding the totals already in the spanned
- // columns.
- for (scol = col, scol_end = col + colSpan;
- scol < scol_end; ++scol) {
- nsTableColFrame *scolFrame = tableFrame->GetColFrame(scol);
- if (!scolFrame) {
- NS_ERROR("column frames out of sync with cell map");
- continue;
- }
-
- // the percentage width (only to columns that don't
- // already have percentage widths, in proportion to
- // the existing pref widths)
- float allocatedPct = 0.0f;
- if (scolFrame->GetPrefPercent() == 0.0f &&
- info.prefPercent != 0.0f) {
- NS_ASSERTION((!spanHasNonPctPref ||
- totalSNonPctPref != 0) &&
- nonPctCount != 0,
- "should not be zero if we haven't allocated "
- "all pref percent");
- if (spanHasNonPctPref) {
- // Group so we're multiplying by 1.0f when we need
- // to use up info.prefPercent.
- allocatedPct = info.prefPercent *
- (float(scolFrame->GetPrefCoord()) /
- float(totalSNonPctPref));
- } else {
- // distribute equally when all pref widths are 0
- allocatedPct = info.prefPercent / float(nonPctCount);
- }
- scolFrame->AddSpanPrefPercent(allocatedPct);
- }
-
- // the part of the min width that fits within the
- // existing pref width
- float minRatio = 0.0f;
- if (minWithinPref > 0) {
- minRatio = float(scolFrame->GetPrefCoord() -
- scolFrame->GetMinCoord()) /
- float(totalSPref - totalSMin);
- }
-
- // the rest of the min width, and the pref width (in
- // proportion to the existing pref widths)
- float coordRatio; // for both min and pref
- if (spanHasPref) {
- if (scolFrame->GetPrefCoord() == 0) {
- // We might have already subtracted all of
- // totalSPref.
- coordRatio = 0.0f;
- } else if (totalSAutoPref == 0) {
- // No auto-width cols left -- dividing up totalSPref
- coordRatio = float(scolFrame->GetPrefCoord()) /
- float(totalSPref);
- } else if (!scolFrame->GetHasSpecifiedCoord()) {
- // There are auto-width cols left, and this is one
- coordRatio = float(scolFrame->GetPrefCoord()) /
- float(totalSAutoPref);
- } else {
- // There are auto-width cols left, and this isn't one
- coordRatio = 0.0f;
- }
- } else {
- // distribute equally when all pref widths are 0
- coordRatio = 1.0f / float(scol_end - scol);
- }
-
- // combine the two min-width distributions, and record
- // min and pref
- nscoord allocatedMinWithinPref =
- NSToCoordRound(float(minWithinPref) * minRatio);
- nscoord allocatedMinOutsidePref =
- NSToCoordRound(float(minOutsidePref) * coordRatio);
- nscoord allocatedPref =
- (info.prefCoord == nscoord_MAX ?
- nscoord_MAX :
- NSToCoordRound(float(info.prefCoord) * coordRatio));
- nscoord spanMin = scolFrame->GetMinCoord() +
- allocatedMinWithinPref + allocatedMinOutsidePref;
- nscoord spanPref =
- NSCoordSaturatingAdd(scolFrame->GetPrefCoord(),
- allocatedPref);
- scolFrame->AddSpanCoords(spanMin, spanPref,
- info.hasSpecifiedWidth);
-
- // To avoid accumulating rounding error from division,
- // subtract everything to do with the column we've
- // passed from the totals.
- minWithinPref -= allocatedMinWithinPref;
- minOutsidePref -= allocatedMinOutsidePref;
- info.prefCoord = NSCoordSaturatingSubtract(info.prefCoord,
- allocatedPref,
- nscoord_MAX);
- info.prefPercent -= allocatedPct;
- totalSPref -= scolFrame->GetPrefCoord();
- totalSMin -= scolFrame->GetMinCoord();
- if (!scolFrame->GetHasSpecifiedCoord()) {
- totalSAutoPref -= scolFrame->GetPrefCoord();
- }
- if (scolFrame->GetPrefPercent() == 0.0f) {
- totalSNonPctPref -= scolFrame->GetPrefCoord();
- --nonPctCount;
- }
- }
-
- // Note that we only distribute the percentage if
- // spanHasNonPct.
- NS_ASSERTION(totalSPref == 0 && totalSMin == 0 &&
- totalSNonPctPref == 0 && nonPctCount == 0 &&
- minOutsidePref == 0 && minWithinPref == 0 &&
- (info.prefCoord == 0 ||
- info.prefCoord == nscoord_MAX) &&
- (info.prefPercent == 0.0f || !spanHasNonPct),
- "didn't subtract all that we added");
+ DistributeWidthToColumns(info.minCoord, col, colSpan,
+ BTLS_MIN_WIDTH, info.hasSpecifiedWidth);
+ DistributeWidthToColumns(info.prefCoord, col, colSpan,
+ BTLS_PREF_WIDTH, info.hasSpecifiedWidth);
} while ((item = item->next));
// Combine the results of the span analysis into the main results,
@@ -699,25 +521,128 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
if (colCount <= 0)
return; // nothing to do
- nscoord spacing = mTableFrame->GetCellSpacingX();
+ DistributeWidthToColumns(width, 0, colCount, BTLS_FINAL_WIDTH, PR_FALSE);
- nscoord min = mMinWidth;
+#ifdef DEBUG_TABLE_STRATEGY
+ printf("ComputeColumnWidths final\n");
+ mTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);
+#endif
+}
+
+void
+BasicTableLayoutStrategy::DistributePctWidthToColumns(float aSpanPrefPct,
+ PRInt32 aFirstCol,
+ PRInt32 aColCount)
+{
+ // First loop to determine:
+ PRInt32 nonPctColCount = 0; // number of spanned columns without % width
+ nscoord nonPctTotalPrefWidth = 0; // total pref width of those columns
+ // and to reduce aSpanPrefPct by columns that already have % width
+
+ PRInt32 scol, scol_end;
+ for (scol = aFirstCol, scol_end = aFirstCol + aColCount;
+ scol < scol_end; ++scol) {
+ nsTableColFrame *scolFrame = mTableFrame->GetColFrame(scol);
+ if (!scolFrame) {
+ NS_ERROR("column frames out of sync with cell map");
+ continue;
+ }
+ float scolPct = scolFrame->GetPrefPercent();
+ if (scolPct == 0.0f) {
+ nonPctTotalPrefWidth += scolFrame->GetPrefCoord();
+ ++nonPctColCount;
+ } else {
+ aSpanPrefPct -= scolPct;
+ }
+ }
+
+ if (aSpanPrefPct <= 0.0f || nonPctColCount == 0) {
+ // There's no %-width on the colspan left over to distribute,
+ // or there are no columns to which we could distribute %-width
+ return;
+ }
+
+ // Second loop, to distribute what remains of aSpanPrefPct
+ // between the non-percent-width spanned columns
+ const PRBool spanHasNonPctPref = nonPctTotalPrefWidth > 0; // Loop invariant
+ for (scol = aFirstCol, scol_end = aFirstCol + aColCount;
+ scol < scol_end; ++scol) {
+ nsTableColFrame *scolFrame = mTableFrame->GetColFrame(scol);
+ if (!scolFrame) {
+ NS_ERROR("column frames out of sync with cell map");
+ continue;
+ }
+
+ // the percentage width (only to columns that don't
+ // already have percentage widths, in proportion to
+ // the existing pref widths)
+ float allocatedPct = 0.0f;
+ if (scolFrame->GetPrefPercent() == 0.0f) {
+ NS_ASSERTION((!spanHasNonPctPref ||
+ nonPctTotalPrefWidth != 0) &&
+ nonPctColCount != 0,
+ "should not be zero if we haven't allocated "
+ "all pref percent");
+ if (spanHasNonPctPref) {
+ // Group so we're multiplying by 1.0f when we need
+ // to use up aSpanPrefPct.
+ allocatedPct = aSpanPrefPct *
+ (float(scolFrame->GetPrefCoord()) /
+ float(nonPctTotalPrefWidth));
+ } else {
+ // distribute equally when all pref widths are 0
+ allocatedPct = aSpanPrefPct / float(nonPctColCount);
+ }
+ // Allocate the percent
+ scolFrame->AddSpanPrefPercent(allocatedPct);
+
+ // To avoid accumulating rounding error from division,
+ // subtract this column's values from the totals.
+ aSpanPrefPct -= allocatedPct;
+ nonPctTotalPrefWidth -= scolFrame->GetPrefCoord();
+ --nonPctColCount;
+ }
+ }
+}
+
+void
+BasicTableLayoutStrategy::DistributeWidthToColumns(nscoord aWidth,
+ PRInt32 aFirstCol,
+ PRInt32 aColCount,
+ BtlsWidthType aWidthType,
+ PRBool aSpanHasSpecifiedWidth)
+{
+ NS_ASSERTION(aWidthType != BTLS_FINAL_WIDTH ||
+ (aFirstCol == 0 &&
+ aColCount == mTableFrame->GetCellMap()->GetColCount()),
+ "Computing final column widths, but didn't get full column range");
// border-spacing isn't part of the basis for percentages.
- nscoord subtract = spacing;
- for (PRInt32 col = 0; col < colCount; ++col) {
+ nscoord spacing = mTableFrame->GetCellSpacingX();
+ nscoord subtract = 0;
+ // aWidth initially includes border-spacing for the boundaries in between
+ // each of the columns. We start at aFirstCol + 1 because the first
+ // in-between boundary would be at the left edge of column aFirstCol + 1
+ for (PRInt32 col = aFirstCol + 1; col < aFirstCol + aColCount; ++col) {
if (mTableFrame->GetNumCellsOriginatingInCol(col)) {
subtract += spacing;
}
}
- width = NSCoordSaturatingSubtract(width, subtract, nscoord_MAX);
- min -= subtract;
-
- // XXX is |width| the right basis for percentage widths?
+ if (aWidthType == BTLS_FINAL_WIDTH) {
+ // If we're computing final col-width, then aWidth initially includes
+ // border spacing on the table's far left + far right edge, too. Need
+ // to subtract those out, too.
+ subtract += spacing * 2;
+ }
+ aWidth = NSCoordSaturatingSubtract(aWidth, subtract, nscoord_MAX);
/*
- * The goal of this function is to allocate |width| to the columns
- * by making an appropriate SetFinalWidth call to each column.
+ * The goal of this function is to distribute |aWidth| between the
+ * columns by making an appropriate AddSpanCoords or SetFinalWidth
+ * call for each column. (We call AddSpanCoords if we're
+ * distributing a column-spanning cell's minimum or preferred width
+ * to its spanned columns. We call SetFinalWidth if we're
+ * distributing a table's final width to its columns.)
*
* The idea is to either assign one of the following sets of widths
* or a weighted average of two adjacent sets of widths. It is not
@@ -740,7 +665,7 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
* 4. [guess_pref] Assign all columns with percentage widths their
* specified width, and all other columns their pref width.
*
- * If |width| is *larger* than what we would assign in (4), then we
+ * If |aWidth| is *larger* than what we would assign in (4), then we
* expand the columns:
*
* a. if any columns without a specified coordinate width or
@@ -769,7 +694,7 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
PRInt32 numInfiniteWidthCols = 0;
PRInt32 col;
- for (col = 0; col < colCount; ++col) {
+ for (col = aFirstCol; col < aFirstCol + aColCount; ++col) {
nsTableColFrame *colFrame = mTableFrame->GetColFrame(col);
if (!colFrame) {
NS_ERROR("column frames out of sync with cell map");
@@ -780,7 +705,7 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
if (colFrame->GetPrefPercent() != 0.0f) {
float pct = colFrame->GetPrefPercent();
total_pct += pct;
- nscoord val = nscoord(float(width) * pct);
+ nscoord val = nscoord(float(aWidth) * pct);
if (val < min_width)
val = min_width;
guess_min_pct += val;
@@ -813,10 +738,10 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
FLEX_PCT_SMALL, // between (1) and (2) above
FLEX_FIXED_SMALL, // between (2) and (3) above
FLEX_FLEX_SMALL, // between (3) and (4) above
- FLEX_FLEX_LARGE, // above (4) above, case (a)
- FLEX_FIXED_LARGE, // above (4) above, case (b)
- FLEX_PCT_LARGE, // above (4) above, case (c)
- FLEX_ALL_LARGE // above (4) above, case (d)
+ FLEX_FLEX_LARGE, // greater than (4) above, case (a)
+ FLEX_FIXED_LARGE, // greater than (4) above, case (b)
+ FLEX_PCT_LARGE, // greater than (4) above, case (c)
+ FLEX_ALL_LARGE // greater than (4) above, case (d)
};
Loop2Type l2t;
@@ -828,28 +753,32 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
nscoord c;
float f;
} basis; // the sum of the statistic over columns to divide it
- if (width < guess_pref) {
- NS_ASSERTION(width >= guess_min, "bad width");
- if (width < guess_min_pct) {
+ if (aWidth < guess_pref) {
+ if ((aWidthType == BTLS_MIN_WIDTH && aWidth <= guess_min) ||
+ (aWidthType == BTLS_PREF_WIDTH && aWidth <= guess_pref)) {
+ // Return early -- we don't have any extra space to distribute.
+ return;
+ }
+ NS_ASSERTION(!(aWidthType == BTLS_FINAL_WIDTH && aWidth < guess_min),
+ "Table width is less than the "
+ "sum of its columns' min widths");
+ if (aWidth < guess_min_pct) {
l2t = FLEX_PCT_SMALL;
- space = width - guess_min;
+ space = aWidth - guess_min;
basis.c = guess_min_pct - guess_min;
- } else if (width < guess_min_spec) {
+ } else if (aWidth < guess_min_spec) {
l2t = FLEX_FIXED_SMALL;
- space = width - guess_min_pct;
+ space = aWidth - guess_min_pct;
basis.c = NSCoordSaturatingSubtract(guess_min_spec, guess_min_pct,
nscoord_MAX);
} else {
l2t = FLEX_FLEX_SMALL;
- space = width - guess_min_spec;
+ space = aWidth - 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;
+ space = NSCoordSaturatingSubtract(aWidth, guess_pref, nscoord_MAX);
if (total_flex_pref > 0) {
l2t = FLEX_FLEX_LARGE;
basis.c = total_flex_pref;
@@ -861,7 +790,7 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
basis.f = total_pct;
} else {
l2t = FLEX_ALL_LARGE;
- basis.c = colCount;
+ basis.c = aColCount;
}
}
@@ -869,13 +798,13 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
printf("ComputeColumnWidths: %d columns in width %d,\n"
" guesses=[%d,%d,%d,%d], totals=[%d,%d,%f],\n"
" l2t=%d, space=%d, basis.c=%d\n",
- colCount, width,
+ aColCount, aWidth,
guess_min, guess_min_pct, guess_min_spec, guess_pref,
total_flex_pref, total_fixed_pref, total_pct,
l2t, space, basis.c);
#endif
- for (col = 0; col < colCount; ++col) {
+ for (col = aFirstCol; col < aFirstCol + aColCount; ++col) {
nsTableColFrame *colFrame = mTableFrame->GetColFrame(col);
if (!colFrame) {
NS_ERROR("column frames out of sync with cell map");
@@ -885,7 +814,7 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
float pct = colFrame->GetPrefPercent();
if (pct != 0.0f) {
- col_width = nscoord(float(width) * pct);
+ col_width = nscoord(float(aWidth) * pct);
nscoord col_min = colFrame->GetMinCoord();
if (col_width < col_min)
col_width = col_min;
@@ -900,7 +829,7 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
col_width = col_width_before_adjust = colFrame->GetMinCoord();
if (pct != 0.0f) {
nscoord pct_minus_min =
- nscoord(float(width) * pct) - col_width;
+ nscoord(float(aWidth) * pct) - col_width;
if (pct_minus_min > 0) {
float c = float(space) / float(basis.c);
basis.c -= pct_minus_min;
@@ -968,9 +897,14 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
NS_ASSERTION(col_width == colFrame->GetPrefCoord(),
"wrong width assigned");
if (col_width != 0) {
- float c = float(space) / float(basis.c);
- basis.c -= col_width;
- col_width += NSToCoordRound(float(col_width) * c);
+ if (space == nscoord_MAX) {
+ basis.c -= col_width;
+ col_width = nscoord_MAX;
+ } else {
+ float c = float(space) / float(basis.c);
+ basis.c -= col_width;
+ col_width += NSToCoordRound(float(col_width) * c);
+ }
}
}
break;
@@ -1006,24 +940,53 @@ BasicTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
break;
}
- space -= col_width - col_width_before_adjust;
+ // Only subtract from space if it's a real number.
+ if (space != nscoord_MAX) {
+ NS_ASSERTION(col_width != nscoord_MAX,
+ "How is col_width nscoord_MAX if space isn't?");
+ NS_ASSERTION(col_width_before_adjust != nscoord_MAX,
+ "How is col_width_before_adjust nscoord_MAX if space isn't?");
+ space -= col_width - col_width_before_adjust;
+ }
NS_ASSERTION(col_width >= colFrame->GetMinCoord(),
"assigned width smaller than min");
-
- nscoord old_final = colFrame->GetFinalWidth();
- colFrame->SetFinalWidth(col_width);
-
- if (old_final != col_width)
- mTableFrame->DidResizeColumns();
+
+ // Apply the new width
+ switch (aWidthType) {
+ case BTLS_MIN_WIDTH:
+ {
+ // Note: AddSpanCoords requires both a min and pref width.
+ // For the pref width, we'll just pass in our computed
+ // min width, because the real pref width will be at least
+ // as big
+ colFrame->AddSpanCoords(col_width, col_width,
+ aSpanHasSpecifiedWidth);
+ }
+ break;
+ case BTLS_PREF_WIDTH:
+ {
+ // Note: AddSpanCoords requires both a min and pref width.
+ // For the min width, we'll just pass in 0, because
+ // the real min width will be at least 0
+ colFrame->AddSpanCoords(0, col_width,
+ aSpanHasSpecifiedWidth);
+ }
+ break;
+ case BTLS_FINAL_WIDTH:
+ {
+ nscoord old_final = colFrame->GetFinalWidth();
+ colFrame->SetFinalWidth(col_width);
+
+ if (old_final != col_width)
+ mTableFrame->DidResizeColumns();
+ }
+ break;
+ }
}
- NS_ASSERTION(space == 0 &&
+ NS_ASSERTION((space == 0 || space == nscoord_MAX) &&
((l2t == FLEX_PCT_LARGE)
? (-0.001f < basis.f && basis.f < 0.001f)
: (basis.c == 0 || basis.c == nscoord_MAX)),
"didn't subtract all that we added");
-#ifdef DEBUG_TABLE_STRATEGY
- printf("ComputeColumnWidths final\n");
- mTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);
-#endif
}
diff --git a/layout/tables/BasicTableLayoutStrategy.h b/layout/tables/BasicTableLayoutStrategy.h
index 62dcb5882f6f..205b682feff4 100644
--- a/layout/tables/BasicTableLayoutStrategy.h
+++ b/layout/tables/BasicTableLayoutStrategy.h
@@ -62,9 +62,42 @@ public:
virtual void ComputeColumnWidths(const nsHTMLReflowState& aReflowState);
private:
+ // NOTE: Using prefix "BTLS" to avoid overlapping names with
+ // the values of nsLayoutUtils::IntrinsicWidthType
+ enum BtlsWidthType { BTLS_MIN_WIDTH,
+ BTLS_PREF_WIDTH,
+ BTLS_FINAL_WIDTH };
+
// Compute intrinsic width member variables on the columns.
void ComputeColumnIntrinsicWidths(nsIRenderingContext* aRenderingContext);
+ // Distribute a colspanning cell's percent width (if any) to its columns.
+ void DistributePctWidthToColumns(float aSpanPrefPct,
+ PRInt32 aFirstCol,
+ PRInt32 aColCount);
+
+ // Distribute a width of some BltsWidthType type to a set of columns.
+ // aWidth: The amount of width to be distributed
+ // aFirstCol: The index (in the table) of the first column to be
+ // considered for receiving width
+ // aColCount: The number of consecutive columns (starting with aFirstCol)
+ // to be considered for receiving width
+ // aWidthType: The type of width being distributed. (BTLS_MIN_WIDTH and
+ // BTLS_PREF_WIDTH are intended to be used for dividing up
+ // colspan's min & pref width. BTLS_FINAL_WIDTH is intended
+ // to be used for distributing the table's final width across
+ // all its columns)
+ // aSpanHasSpecifiedWidth: Should be PR_TRUE iff:
+ // - We're distributing a colspanning cell's
+ // pref or min width to its columns
+ // - The colspanning cell has a specified width.
+ void DistributeWidthToColumns(nscoord aWidth,
+ PRInt32 aFirstCol,
+ PRInt32 aColCount,
+ BtlsWidthType aWidthType,
+ PRBool aSpanHasSpecifiedWidth);
+
+
// Compute the min and pref widths of the table from the width
// variables on the columns.
void ComputeIntrinsicWidths(nsIRenderingContext* aRenderingContext);
diff --git a/layout/tables/nsTableColFrame.cpp b/layout/tables/nsTableColFrame.cpp
index 1d9aa6d3b9a7..2f6599c8fd1f 100644
--- a/layout/tables/nsTableColFrame.cpp
+++ b/layout/tables/nsTableColFrame.cpp
@@ -155,9 +155,9 @@ void nsTableColFrame::Dump(PRInt32 aIndent)
printf(" anonymous-cell ");
break;
}
- printf("\nm:%d c:%d(%c) p:%f sm:%d sc:%d(%c) sp:%f f:%d",
+ printf("\nm:%d c:%d(%c) p:%f sm:%d sc:%d sp:%f f:%d",
mMinCoord, mPrefCoord, mHasSpecifiedCoord ? 's' : 'u', mPrefPercent,
- mSpanMinCoord, mSpanPrefCoord, mSpanHasSpecifiedCoord ? 's' : 'u',
+ mSpanMinCoord, mSpanPrefCoord,
mSpanPrefPercent,
GetFinalWidth());
printf("\n%s**END COL DUMP** ", indent);
diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h
index 15cd58bd8582..146eec19acc6 100644
--- a/layout/tables/nsTableColFrame.h
+++ b/layout/tables/nsTableColFrame.h
@@ -165,7 +165,6 @@ public:
mSpanMinCoord = 0;
mSpanPrefCoord = 0;
mSpanPrefPercent = 0.0f;
- mSpanHasSpecifiedCoord = PR_FALSE;
}
/**
@@ -249,11 +248,7 @@ public:
NS_ASSERTION(aSpanMinCoord <= aSpanPrefCoord,
"intrinsic widths out of order");
- if (aSpanHasSpecifiedCoord && !mSpanHasSpecifiedCoord) {
- mSpanPrefCoord = mSpanMinCoord;
- mSpanHasSpecifiedCoord = PR_TRUE;
- }
- if (!aSpanHasSpecifiedCoord && mSpanHasSpecifiedCoord) {
+ if (!aSpanHasSpecifiedCoord && mHasSpecifiedCoord) {
aSpanPrefCoord = aSpanMinCoord; // NOTE: modifying argument
}
@@ -279,7 +274,7 @@ public:
* the primary variables.
*/
void AccumulateSpanIntrinsics() {
- AddCoords(mSpanMinCoord, mSpanPrefCoord, mHasSpecifiedCoord && mSpanHasSpecifiedCoord);
+ AddCoords(mSpanMinCoord, mSpanPrefCoord, mHasSpecifiedCoord);
AddPrefPercent(mSpanPrefPercent);
}
@@ -322,7 +317,6 @@ protected:
BCPixelSize mBottomContBorderWidth;
PRPackedBool mHasSpecifiedCoord;
- PRPackedBool mSpanHasSpecifiedCoord; // XXX...
nscoord mMinCoord;
nscoord mPrefCoord;
nscoord mSpanMinCoord; // XXX...