diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
index 928569e665d..5e40107aaa8 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
@@ -1921,7 +1921,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
break;
}
- /* set the column width, knowing that the table fits in the available space */
+ /* set the column width, knowing that the table is constrained */
if (0==specifiedProportionColumnWidth || 0.0==specifiedPercentageColWidth)
{ // col width is specified to be the minimum
mTableFrame->SetColumnWidth(colIndex, minColWidth);
@@ -1940,7 +1940,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
}
else if (PR_TRUE==isAutoWidth)
{ // column's width is determined by its content, done in post-processing
- mTableFrame->SetColumnWidth(colIndex, 0); // set to 0 width for now
+ mTableFrame->SetColumnWidth(colIndex, minColWidth); // reserve the column's min width
atLeastOneAutoWidthColumn = PR_TRUE;
}
else if (-1!=specifiedProportionColumnWidth)
@@ -2016,7 +2016,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
// first, assign autoWidth columns a width
if (PR_TRUE==atLeastOneAutoWidthColumn)
{ // proportionately distribute the remaining space to autowidth columns
- DistributeRemainingSpace(aMaxWidth, tableWidth, aTableIsAutoWidth);
+ // "0" for the last param tells DistributeRemainingSpace that this is the top (non-recursive) call
+ PRInt32 topRecursiveControl=0;
+ DistributeRemainingSpace(aMaxWidth, tableWidth, aTableIsAutoWidth, topRecursiveControl);
}
// second, fix up tables where column width attributes give us a table that is too wide or too narrow
@@ -2090,12 +2092,20 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
return result;
}
+static const PRInt32 kRecursionLimit=10; // backwards compatible with Nav4
+
// take the remaining space in the table and distribute it proportionately
// to the auto-width cells in the table (based on desired width)
void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecifiedWidth,
- nscoord aComputedTableWidth,
- PRBool aTableIsAutoWidth)
+ nscoord &aComputedTableWidth,
+ PRBool aTableIsAutoWidth,
+ PRInt32 &aRecursionControl)
{
+ aRecursionControl++;
+ if (kRecursionLimit<=aRecursionControl) // only allow kRecursionLimit iterations, as per Nav4. See laytable.c
+ return;
+ nscoord sumOfMinWidths = 0; // sum of min widths of each auto column
+ nscoord aStartingComputedTableWidth = aComputedTableWidth; // remember this so we can see if we're making any progress
if (PR_TRUE==gsDebug)
printf ("DistributeRemainingSpace: fixed width %d > computed table width %d\n",
aTableSpecifiedWidth, aComputedTableWidth);
@@ -2105,6 +2115,7 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0!=numAutoColumns)
{
+ PRInt32 numColumnsToBeResized=0;
// there's at least one auto-width column, so give it (them) the extra space
// proportionately distributed extra space, based on the column's desired size
nscoord totalEffectiveWidthOfAutoColumns = 0;
@@ -2112,12 +2123,18 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
PRInt32 i;
for (i = 0; iGetColFrame(autoColumns[i]);
+ nscoord startingColWidth = mTableFrame->GetColumnWidth(colIndex);
nscoord maxEffectiveColWidth = colFrame->GetEffectiveMaxColWidth();
- if (0!=maxEffectiveColWidth)
- totalEffectiveWidthOfAutoColumns += maxEffectiveColWidth;
- else
- totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
+ if ((PR_FALSE==aTableIsAutoWidth)||(startingColWidthGetColumnWidth(autoColumns[i]);
+ }
}
// availWidth is the difference between the total available width and the
// amount of space already assigned, assuming auto col widths were assigned 0.
@@ -2132,46 +2149,52 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
{
PRInt32 colIndex = autoColumns[i];
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ nscoord startingColWidth = mTableFrame->GetColumnWidth(colIndex);
+ nscoord maxEffectiveColWidth = colFrame->GetEffectiveMaxColWidth();
// if we actually have room to distribute, do it here
- // otherwise, the auto columns will remain 0-width until expanded to their minimum in EnsureCellMinWidths
+ // otherwise, the auto columns already are set to their minimum
if (0GetEffectiveMaxColWidth()))/((float)totalEffectiveWidthOfAutoColumns);
- else
- percent = ((float)1)/((float)numAutoColumns);
- nscoord colWidth = (nscoord)(availWidth*percent);
- // in an auto width table, the column cannot be wider than its max width
- if (PR_TRUE==aTableIsAutoWidth)
- { // since the table shrinks to the content width, don't be wider than the content max width
- colWidth = PR_MIN(colWidth, colFrame->GetMaxColWidth()); // XXX can this legally be 0?
+ if ((PR_FALSE==aTableIsAutoWidth)||(startingColWidthGetMaxColWidth());
+ aComputedTableWidth += newColWidth-colWidth;
+ colWidth = newColWidth;
+ }
+ else
+ aComputedTableWidth += colWidth - startingColWidth;
+ if (gsDebug==PR_TRUE)
+ printf(" distribute width to auto columns: column %d was %d, now set to %d\n",
+ colIndex, colFrame->GetEffectiveMaxColWidth(), colWidth);
+ mTableFrame->SetColumnWidth(colIndex, colWidth);
}
- if (gsDebug==PR_TRUE)
- printf(" distribute width to auto columns: column %d was %d, now set to %d\n",
- colIndex, colFrame->GetEffectiveMaxColWidth(), colWidth);
- mTableFrame->SetColumnWidth(colIndex, colWidth);
}
}
- if (PR_TRUE==gsDebug)
- {
- nscoord tableWidth=0;
- printf("before EnsureCellMinWidth: ");
- for (PRInt32 i=0; iGetColumnWidth(i);
- printf(" %d ", mTableFrame->GetColumnWidth(i));
+ DistributeRemainingSpace(aTableSpecifiedWidth, aComputedTableWidth, aTableIsAutoWidth, aRecursionControl);
}
- printf ("\n computed table width is %d\n",tableWidth);
}
-
- EnsureCellMinWidths(PR_FALSE);
}
if (PR_TRUE==gsDebug)
{
nscoord tableWidth=0;
- printf("after EnsureCellMinWidth: ");
+ printf("at end of DistributeRemainingSpace: ");
for (PRInt32 i=0; iGetColumnWidth(i);
@@ -2181,84 +2204,6 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
}
}
-void BasicTableLayoutStrategy::EnsureCellMinWidths(PRBool aShrinkFixedWidthCells)
-{
- PRBool atLeastOne = PR_TRUE;
- PRBool *colsToRemoveFrom = new PRBool[mNumCols];
- for (PRInt32 i=0; iGetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
- for (PRInt32 i=0; iGetColFrame(colIndex);
- nscoord minColWidth = colFrame->GetMinColWidth();
- nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if (colWidthSetColumnWidth(colIndex, minColWidth);
- atLeastOne=PR_TRUE;
- }
- }
- // second, remove the added space from cells that can afford to slim down
- //QQQ boy is this slow! there has to be a faster way that is still guaranteed to be accurate...
-
- while ((addedWidth>0))
- { // while we still have some extra space, and last time we were able to take some off...
- PRInt32 startingAddedWidth = addedWidth;
- for (colIndex=0; colIndexGetColFrame(colIndex);
- nscoord minColWidth = colFrame->GetMinColWidth();
- nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if ((colWidth>minColWidth) && (PR_TRUE==colsToRemoveFrom[colIndex]))
- {
- mTableFrame->SetColumnWidth(colIndex, colWidth-1);
- addedWidth--;
- if (0==addedWidth)
- { // we're run out of extra space
- break; // for (colIndex=0; colIndex0))
- }
- }
- if (0SetColumnWidth(colIndex, minColWidth);
@@ -1940,7 +1940,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
}
else if (PR_TRUE==isAutoWidth)
{ // column's width is determined by its content, done in post-processing
- mTableFrame->SetColumnWidth(colIndex, 0); // set to 0 width for now
+ mTableFrame->SetColumnWidth(colIndex, minColWidth); // reserve the column's min width
atLeastOneAutoWidthColumn = PR_TRUE;
}
else if (-1!=specifiedProportionColumnWidth)
@@ -2016,7 +2016,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
// first, assign autoWidth columns a width
if (PR_TRUE==atLeastOneAutoWidthColumn)
{ // proportionately distribute the remaining space to autowidth columns
- DistributeRemainingSpace(aMaxWidth, tableWidth, aTableIsAutoWidth);
+ // "0" for the last param tells DistributeRemainingSpace that this is the top (non-recursive) call
+ PRInt32 topRecursiveControl=0;
+ DistributeRemainingSpace(aMaxWidth, tableWidth, aTableIsAutoWidth, topRecursiveControl);
}
// second, fix up tables where column width attributes give us a table that is too wide or too narrow
@@ -2090,12 +2092,20 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
return result;
}
+static const PRInt32 kRecursionLimit=10; // backwards compatible with Nav4
+
// take the remaining space in the table and distribute it proportionately
// to the auto-width cells in the table (based on desired width)
void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecifiedWidth,
- nscoord aComputedTableWidth,
- PRBool aTableIsAutoWidth)
+ nscoord &aComputedTableWidth,
+ PRBool aTableIsAutoWidth,
+ PRInt32 &aRecursionControl)
{
+ aRecursionControl++;
+ if (kRecursionLimit<=aRecursionControl) // only allow kRecursionLimit iterations, as per Nav4. See laytable.c
+ return;
+ nscoord sumOfMinWidths = 0; // sum of min widths of each auto column
+ nscoord aStartingComputedTableWidth = aComputedTableWidth; // remember this so we can see if we're making any progress
if (PR_TRUE==gsDebug)
printf ("DistributeRemainingSpace: fixed width %d > computed table width %d\n",
aTableSpecifiedWidth, aComputedTableWidth);
@@ -2105,6 +2115,7 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0!=numAutoColumns)
{
+ PRInt32 numColumnsToBeResized=0;
// there's at least one auto-width column, so give it (them) the extra space
// proportionately distributed extra space, based on the column's desired size
nscoord totalEffectiveWidthOfAutoColumns = 0;
@@ -2112,12 +2123,18 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
PRInt32 i;
for (i = 0; iGetColFrame(autoColumns[i]);
+ nscoord startingColWidth = mTableFrame->GetColumnWidth(colIndex);
nscoord maxEffectiveColWidth = colFrame->GetEffectiveMaxColWidth();
- if (0!=maxEffectiveColWidth)
- totalEffectiveWidthOfAutoColumns += maxEffectiveColWidth;
- else
- totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
+ if ((PR_FALSE==aTableIsAutoWidth)||(startingColWidthGetColumnWidth(autoColumns[i]);
+ }
}
// availWidth is the difference between the total available width and the
// amount of space already assigned, assuming auto col widths were assigned 0.
@@ -2132,46 +2149,52 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
{
PRInt32 colIndex = autoColumns[i];
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ nscoord startingColWidth = mTableFrame->GetColumnWidth(colIndex);
+ nscoord maxEffectiveColWidth = colFrame->GetEffectiveMaxColWidth();
// if we actually have room to distribute, do it here
- // otherwise, the auto columns will remain 0-width until expanded to their minimum in EnsureCellMinWidths
+ // otherwise, the auto columns already are set to their minimum
if (0GetEffectiveMaxColWidth()))/((float)totalEffectiveWidthOfAutoColumns);
- else
- percent = ((float)1)/((float)numAutoColumns);
- nscoord colWidth = (nscoord)(availWidth*percent);
- // in an auto width table, the column cannot be wider than its max width
- if (PR_TRUE==aTableIsAutoWidth)
- { // since the table shrinks to the content width, don't be wider than the content max width
- colWidth = PR_MIN(colWidth, colFrame->GetMaxColWidth()); // XXX can this legally be 0?
+ if ((PR_FALSE==aTableIsAutoWidth)||(startingColWidthGetMaxColWidth());
+ aComputedTableWidth += newColWidth-colWidth;
+ colWidth = newColWidth;
+ }
+ else
+ aComputedTableWidth += colWidth - startingColWidth;
+ if (gsDebug==PR_TRUE)
+ printf(" distribute width to auto columns: column %d was %d, now set to %d\n",
+ colIndex, colFrame->GetEffectiveMaxColWidth(), colWidth);
+ mTableFrame->SetColumnWidth(colIndex, colWidth);
}
- if (gsDebug==PR_TRUE)
- printf(" distribute width to auto columns: column %d was %d, now set to %d\n",
- colIndex, colFrame->GetEffectiveMaxColWidth(), colWidth);
- mTableFrame->SetColumnWidth(colIndex, colWidth);
}
}
- if (PR_TRUE==gsDebug)
- {
- nscoord tableWidth=0;
- printf("before EnsureCellMinWidth: ");
- for (PRInt32 i=0; iGetColumnWidth(i);
- printf(" %d ", mTableFrame->GetColumnWidth(i));
+ DistributeRemainingSpace(aTableSpecifiedWidth, aComputedTableWidth, aTableIsAutoWidth, aRecursionControl);
}
- printf ("\n computed table width is %d\n",tableWidth);
}
-
- EnsureCellMinWidths(PR_FALSE);
}
if (PR_TRUE==gsDebug)
{
nscoord tableWidth=0;
- printf("after EnsureCellMinWidth: ");
+ printf("at end of DistributeRemainingSpace: ");
for (PRInt32 i=0; iGetColumnWidth(i);
@@ -2181,84 +2204,6 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
}
}
-void BasicTableLayoutStrategy::EnsureCellMinWidths(PRBool aShrinkFixedWidthCells)
-{
- PRBool atLeastOne = PR_TRUE;
- PRBool *colsToRemoveFrom = new PRBool[mNumCols];
- for (PRInt32 i=0; iGetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
- for (PRInt32 i=0; iGetColFrame(colIndex);
- nscoord minColWidth = colFrame->GetMinColWidth();
- nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if (colWidthSetColumnWidth(colIndex, minColWidth);
- atLeastOne=PR_TRUE;
- }
- }
- // second, remove the added space from cells that can afford to slim down
- //QQQ boy is this slow! there has to be a faster way that is still guaranteed to be accurate...
-
- while ((addedWidth>0))
- { // while we still have some extra space, and last time we were able to take some off...
- PRInt32 startingAddedWidth = addedWidth;
- for (colIndex=0; colIndexGetColFrame(colIndex);
- nscoord minColWidth = colFrame->GetMinColWidth();
- nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if ((colWidth>minColWidth) && (PR_TRUE==colsToRemoveFrom[colIndex]))
- {
- mTableFrame->SetColumnWidth(colIndex, colWidth-1);
- addedWidth--;
- if (0==addedWidth)
- { // we're run out of extra space
- break; // for (colIndex=0; colIndex0))
- }
- }
- if (0