зеркало из https://github.com/mozilla/gecko-dev.git
Bug 368504: Create and use DistributeWidthToColumns for colspan-width and table-width distribution. r+sr=dbaron a=blocking1.9+
This commit is contained in:
Родитель
10b9b95cf9
Коммит
2ed65950de
|
@ -0,0 +1,16 @@
|
|||
<html>
|
||||
<body>
|
||||
xxx
|
||||
<table style="width: 600px" cellspacing=0 cellpadding=0>
|
||||
<tr>
|
||||
<td style="background: lightgreen" colspan=2>x x x x x x x x x x x x </td>
|
||||
<td style="background: gray">xxx</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background: orange" >xxx</td>
|
||||
<td style="background: lightblue">xxx</td>
|
||||
<td style="background: yellow" >xxx</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<html>
|
||||
<body>
|
||||
<table style="width: 600px" cellspacing=0 cellpadding=0>
|
||||
<tr>
|
||||
<td style="width: 1px" colspan=2>xxx</td>
|
||||
<td class="b"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background: lightgreen" colspan=2>x x x x x x x x x x x x </td>
|
||||
<td style="background: gray">xxx</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background: orange" >xxx</td>
|
||||
<td style="background: lightblue">xxx</td>
|
||||
<td style="background: yellow" >xxx</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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...
|
||||
|
|
Загрузка…
Ссылка в новой задаче