diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
index d9383e38e53..20ae676c6e3 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
@@ -112,13 +112,7 @@ BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aFrame, PRInt32
mFixedTableWidth=0;
//cache the value of the cols attribute
- nsIFrame * tableFrame = mTableFrame;
-// begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
- tableFrame->GetGeometricParent(tableFrame);
-// end REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
- nsStyleTable *tableStyle;
- tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
- mCols = tableStyle->mCols;
+ mCols = mTableFrame->GetEffectiveCOLSAttribute();
}
BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
@@ -254,34 +248,9 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
/* Scan the column, simulatneously assigning column widths
* and computing the min/max column widths
*/
- // first, deal with any cells that span into this column from a pervious column
- if (nsnull!=spanList)
- {
- PRInt32 spanCount = spanList->Count();
- // go through the list backwards so we can delete easily
- for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
- {
- SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
- nscoord cellMinWidth = (spanInfo->cellMinWidth)/(spanInfo->initialColSpan);
- if (minColWidth < cellMinWidth)
- minColWidth = cellMinWidth;
- nscoord cellDesiredWidth = (spanInfo->cellDesiredWidth)/(spanInfo->initialColSpan);
- if (maxColWidth < cellDesiredWidth)
- maxColWidth = cellDesiredWidth;
- spanInfo->span--;
- if (gsDebug==PR_TRUE)
- printf (" for spanning cell %d with remaining span=%d, min = %d and des = %d\n",
- spanIndex, spanInfo->span, cellMinWidth, cellDesiredWidth);
- if (0==spanInfo->span)
- {
- spanList->RemoveElementAt(spanIndex);
- delete spanInfo;
- }
- }
- }
-
PRInt32 firstRowIndex = -1;
PRInt32 maxColSpan = 1;
+ PRBool cellGrantingWidth=PR_TRUE;
for (PRInt32 rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
@@ -307,21 +276,23 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
+ nscoord cellDesiredWidth = cellDesiredSize.width;
if (gsDebug==PR_TRUE)
printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
cellDesiredSize.width, cellDesiredSize.height);
- if (PR_TRUE==haveColWidth)
+ if (PR_TRUE==haveColWidth && PR_TRUE==cellGrantingWidth)
{
- // This col has a specified fixed width so set the minand max width to the larger of
+ // This col has a specified fixed width so set the min and max width to the larger of
// (specified width, largest max_element_size of the cells in the column)
+ // factoring in the min width of the prior cells (stored in minColWidth)
nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
+ widthForThisCell = PR_MAX(widthForThisCell, minColWidth);
widthForThisCell = widthForThisCell/colSpan;
mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
maxColWidth = widthForThisCell;
- minColWidth = widthForThisCell;
+ //minColWidth = (cellMinSize.width)/colSpan;
if ((1==colSpan) && (effectiveMaxColumnWidth < widthForThisCell))
effectiveMaxColumnWidth = widthForThisCell;
if (gsDebug)
@@ -335,8 +306,18 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
effectiveMaxColumnWidth = cellDesiredWidth;
}
+ //bookkeeping: is this the cell that gave the column it's fixed width attribute?
+ // must be done after "haveColWidth && cellGrantingWidth" used above
+ if (PR_TRUE==cellGrantingWidth && 1==colSpan)
+ {
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
+ if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
+ cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
+ }
+
// cellMinWidth can override fixed width, so factor it in here
- nscoord cellMinWidth = cellMinSize.width/colSpan;
+ nscoord cellMinWidth = cellMinSize.width;
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
// effectiveMinColumnWidth is the min width as if no cells with colspans existed
@@ -344,14 +325,36 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
effectiveMinColumnWidth = cellMinWidth;
if (1AppendElement(colSpanInfo);
+ // add the column to our list of post-process columns, if all of the intersected columns are auto
+ PRBool okToAdd = PR_TRUE;
+ if (numRows==1 || (PR_FALSE==IsFixedWidth(colPosition)))
+ okToAdd = PR_FALSE;
+ else
+ {
+ for (PRInt32 i=1; iGetColumnFrame(i+colIndex, cf);
+ const nsStylePosition* colPos;
+ cf->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPos);
+ if (colPos->mWidth.GetUnit() != eStyleUnit_Auto)
+ {
+ okToAdd = PR_FALSE;
+ break;
+ }
+ }
+ }
+
+ if (PR_TRUE==okToAdd)
+ {
+ ColSpanStruct *colSpanInfo = new ColSpanStruct(colSpan, colIndex, cellDesiredSize.width);
+ if (nsnull==colSpanList)
+ colSpanList = new nsVoidArray();
+ colSpanList->AppendElement(colSpanInfo);
+ }
// add the cell to our list of spanning cells
- SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
+ SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan, cellMinWidth, cellDesiredWidth);
if (nsnull==spanList)
spanList = new nsVoidArray();
spanList->AppendElement(spanInfo);
@@ -366,26 +369,30 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
nscoord colInset = mTableFrame->GetCellSpacing();
// keep a running total of the amount of space taken up by all fixed-width columns
if (PR_TRUE==haveColWidth)
- mFixedTableWidth += specifiedFixedColWidth + (colInset*maxColSpan);
+ {
+ mFixedTableWidth += maxColWidth + colInset;
+ if (0==colIndex)
+ mFixedTableWidth += colInset;
+ }
if (gsDebug) {
printf (" after col %d, mFixedTableWidth = %d\n", colIndex, mFixedTableWidth);
}
// cache the computed column info
- colFrame->SetMinColWidth(minColWidth);
- colFrame->SetMaxColWidth(maxColWidth);
+ colFrame->SetMinColWidth(effectiveMinColumnWidth);
+ colFrame->SetMaxColWidth(effectiveMaxColumnWidth);
colFrame->SetEffectiveMinColWidth(effectiveMinColumnWidth);
colFrame->SetEffectiveMaxColWidth(effectiveMaxColumnWidth);
- mTableFrame->SetColumnWidth(colIndex, maxColWidth);
+ mTableFrame->SetColumnWidth(colIndex, effectiveMaxColumnWidth);
// add col[i] metrics to the running totals for the table min/max width
if (NS_UNCONSTRAINEDSIZE!=mMinTableWidth)
- mMinTableWidth += minColWidth + colInset;
- if (mMinTableWidth<=0)
+ mMinTableWidth += effectiveMinColumnWidth + colInset;
+ if (mMinTableWidth<0)
mMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (NS_UNCONSTRAINEDSIZE!=mMaxTableWidth)
- mMaxTableWidth += maxColWidth + colInset;
- if (mMaxTableWidth<=0)
+ mMaxTableWidth += effectiveMaxColumnWidth + colInset;
+ if (mMaxTableWidth<0)
mMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (PR_TRUE==hasColsAttribute)
{
@@ -398,6 +405,110 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
}
// now, post-process the computed values based on the table attributes
+
+ // first, factor in min/max values of spanning cells proportionately.
+ // We can't do this above in the first loop, because we don't have enough information
+ // to determine the proportion each column gets from spanners.
+ if (nsnull!=spanList)
+ {
+ for (PRInt32 colIndex=0; colIndexCount();
+ // go through the list backwards so we can delete easily
+ for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
+ {
+ SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
+ // if the spanInfo is about a column before the current column, it effects
+ // the current column (otherwise it would have already been deleted.)
+ if (spanInfo->initialColIndex <= colIndex)
+ {
+ if (0==spanInfo->effectiveMaxWidthOfSpannedCols)
+ {
+ for (PRInt32 span=0; spaninitialColSpan; span++)
+ {
+ nsTableColFrame *nextColFrame = mTableFrame->GetColFrame(colIndex+span);
+ if (nsnull==nextColFrame)
+ break;
+ spanInfo->effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
+ spanInfo->effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
+ }
+ }
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ // compute the spanning cell's contribution to the column min width
+ nscoord colMinWidth = colFrame->GetMinColWidth();
+ nscoord spanCellMinWidth;
+ if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
+ {
+ spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMinWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (colMinWidth < spanCellMinWidth)
+ {
+ colFrame->SetMinColWidth(spanCellMinWidth); // set the new min width for the col
+ mMinTableWidth += spanCellMinWidth-colMinWidth; // add in the col min width delta
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ old min = %d, new min = %d\n",
+ colIndex, spanInfo->span, colMinWidth, spanCellMinWidth);
+ }
+ }
+ else
+ {
+ spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
+ colFrame->SetMinColWidth(spanCellMinWidth);
+ //QQQ is mMinTableWidth already taken care of at this point?
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ old min = %d, new min = %d\n",
+ colIndex, spanInfo->span, colMinWidth, spanCellMinWidth);
+ }
+
+
+ // compute the spanning cell's contribution to the column max width
+ nscoord colMaxWidth = colFrame->GetMaxColWidth();
+ nscoord spanCellMaxWidth;
+ if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
+ {
+ spanCellMaxWidth = (spanInfo->cellDesiredWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist max: %d of %d\n", spanCellMaxWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (colMaxWidth < spanCellMaxWidth)
+ {
+ colFrame->SetMaxColWidth(spanCellMaxWidth); // set the new max width for the col
+ mMaxTableWidth += spanCellMaxWidth-colMaxWidth; // add in the col max width delta
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ old max = %d, new max = %d\n",
+ colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
+ }
+ }
+ else
+ {
+ spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
+ colFrame->SetMaxColWidth(spanCellMaxWidth);
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ old max = %d, new max = %d\n",
+ colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
+ }
+
+ spanInfo->span--;
+ if (0==spanInfo->span)
+ {
+ spanList->RemoveElementAt(spanIndex);
+ delete spanInfo;
+ }
+ }
+ }
+ }
+ }
+
+
+ // second, handle the COLS attribute (equal column widths)
// if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth
if (PR_TRUE==hasColsAttribute)
{
@@ -639,11 +750,11 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aR
for (PRInt32 colIndex = 0; colIndexGetColFrame(colIndex);
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
+ PRInt32 minColWidth = colFrame->GetMinColWidth();
+ PRInt32 maxColWidth = 0;
PRInt32 rowIndex;
PRInt32 firstRowIndex = -1;
nscoord colInset = mTableFrame->GetCellSpacing();
@@ -652,6 +763,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aR
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
// first, deal with any cells that span into this column from a pervious column
+ // go through the list backwards so we can delete easily
if (nsnull!=spanList)
{
PRInt32 spanCount = spanList->Count();
@@ -661,15 +773,65 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aR
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
if (PR_FALSE==IsFixedWidth(colPosition))
{
- if (minColWidth < spanInfo->cellMinWidth)
- minColWidth = spanInfo->cellMinWidth;
- if (maxColWidth < spanInfo->cellDesiredWidth)
- maxColWidth = spanInfo->cellDesiredWidth;
+ // compute the spanning cell's contribution to the column min width
+ nscoord spanCellMinWidth;
+ if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
+ {
+ spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMinWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (minColWidth < spanCellMinWidth)
+ {
+ minColWidth = spanCellMinWidth; // set the new min width for the col
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new min = %d\n",
+ colIndex, spanInfo->span, minColWidth);
+ }
+ }
+ else
+ {
+ spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
+ minColWidth = spanCellMinWidth;
+ //QQQ is mMinTableWidth already taken care of at this point?
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new min = %d\n",
+ colIndex, spanInfo->span, minColWidth);
+ }
+
+
+ // compute the spanning cell's contribution to the column max width
+ nscoord spanCellMaxWidth;
+ if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
+ {
+ spanCellMaxWidth = (spanInfo->cellDesiredWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist max: %d of %d\n", spanCellMaxWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (maxColWidth < spanCellMaxWidth)
+ {
+ maxColWidth = spanCellMaxWidth; // set the new max width for the col
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new max = %d\n",
+ colIndex, spanInfo->span, maxColWidth);
+ }
+ }
+ else
+ {
+ spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
+ maxColWidth = spanCellMaxWidth;
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new max = %d\n",
+ colIndex, spanInfo->span, maxColWidth);
+ }
}
spanInfo->span--;
- if (gsDebug==PR_TRUE)
- printf (" for spanning cell %d with remaining span=%d, min = %d and des = %d\n",
- spanIndex, spanInfo->span, spanInfo->cellMinWidth, spanInfo->cellDesiredWidth);
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
@@ -702,53 +864,93 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aR
}
PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame);
- // distribute a portion of the spanning cell's min and max width to this column
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
-
- nscoord cellMinWidth = cellMinSize.width/colSpan;
- // first get the desired size info from reflow pass 1
- nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
+ nscoord cellMinWidth=colFrame->GetMinColWidth();
+ nscoord cellDesiredWidth=colFrame->GetMaxColWidth();
// then get the desired size info factoring in the cell style attributes
- nscoord specifiedCellWidth=-1;
- const nsStylePosition* cellPosition;
- cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
- if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
- { //QQQ what if table is auto width?
- float percent = cellPosition->mWidth.GetPercentValue();
- specifiedCellWidth = (PRInt32)(aTableSpecifiedWidth*percent);
- if (gsDebug) printf("specified percent width %f of %d = %d\n",
- percent, aTableSpecifiedWidth, specifiedCellWidth);
- }
- if (-1!=specifiedCellWidth)
+ if (1==colSpan)
{
- if (specifiedCellWidth/colSpan>cellMinWidth)
+ cellMinWidth = cellMinSize.width;
+ cellDesiredWidth = cellDesiredSize.width;
+ nscoord specifiedCellWidth=-1;
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
+ if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
+ { //QQQ what if table is auto width?
+ float percent = cellPosition->mWidth.GetPercentValue();
+ specifiedCellWidth = (PRInt32)(aTableSpecifiedWidth*percent);
+ if (gsDebug) printf("specified percent width %f of %d = %d\n",
+ percent, aTableSpecifiedWidth, specifiedCellWidth);
+ }
+ if (-1!=specifiedCellWidth)
{
- if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
- cellDesiredWidth, specifiedCellWidth/colSpan);
- cellDesiredWidth = specifiedCellWidth/colSpan;
- //QQQ should be proportionately distributed as a post-process
+ if (specifiedCellWidth>cellMinWidth)
+ {
+ if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
+ cellDesiredWidth, specifiedCellWidth);
+ cellDesiredWidth = specifiedCellWidth;
+ }
+ }
+ }
+ else
+ { // colSpan>1, get the proportion for this column
+ // then get the desired size info factoring in the cell style attributes
+ nscoord effectiveMaxWidthOfSpannedCols = colFrame->GetEffectiveMaxColWidth();
+ nscoord effectiveMinWidthOfSpannedCols = colFrame->GetEffectiveMinColWidth();
+ for (PRInt32 span=1; spanGetColFrame(colIndex+span);
+ if (nsnull==nextColFrame)
+ break;
+ effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
+ effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
+ }
+ nscoord specifiedCellWidth=-1;
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
+ if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
+ { //QQQ what if table is auto width?
+ float percent = cellPosition->mWidth.GetPercentValue();
+ specifiedCellWidth = (PRInt32)(aTableSpecifiedWidth*percent);
+ if (gsDebug) printf("specified percent width %f of %d = %d\n",
+ percent, aTableSpecifiedWidth, specifiedCellWidth);
+ }
+ if (-1!=specifiedCellWidth)
+ {
+ float percentForThisCol = (float)(cellDesiredSize.width * colFrame->GetEffectiveMaxColWidth()) /
+ (float)effectiveMaxWidthOfSpannedCols;
+ nscoord cellWidthForThisCol = (nscoord)(specifiedCellWidth * percentForThisCol);
+ if (cellWidthForThisCol>cellMinWidth)
+ {
+ if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
+ cellDesiredWidth, cellWidthForThisCol);
+ cellDesiredWidth = cellWidthForThisCol;
+ }
+ }
+ // otherwise it's already been factored in.
+ // now, if this column holds the cell, create a spanInfo struct for the cell
+ // so subsequent columns can take a proportion of this cell's space into account
+ if (cellFrame->GetColIndex()==colIndex)
+ { // add this cell to span list iff we are currently processing the column the cell starts in
+ SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan-1, cellMinSize.width, cellDesiredSize.width);
+ spanInfo->effectiveMaxWidthOfSpannedCols = effectiveMaxWidthOfSpannedCols;
+ spanInfo->effectiveMinWidthOfSpannedCols = effectiveMinWidthOfSpannedCols;
+ if (nsnull==spanList)
+ spanList = new nsVoidArray();
+ spanList->AppendElement(spanInfo);
}
}
if (PR_TRUE==gsDebug)
printf("factoring in cell %d with colSpan=%d\n factoring in min=%d and desired=%d\n",
rowIndex, colSpan, cellMinWidth, cellDesiredWidth);
- if (minColWidth < cellMinWidth)
- minColWidth = cellMinWidth;
if (maxColWidth < cellDesiredWidth)
maxColWidth = cellDesiredWidth;
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
rowIndex, minColWidth, maxColWidth,
colIndex, colFrame->GetEffectiveMaxColWidth());
- if ((1GetColIndex()==colIndex))
- { // add this cell to span list iff we are currently processing the column the cell starts in
- SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
- if (nsnull==spanList)
- spanList = new nsVoidArray();
- spanList->AppendElement(spanInfo);
- }
} // end looping through cells in the column
if (gsDebug==PR_TRUE)
@@ -1032,8 +1234,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
PRBool result = PR_TRUE;
PRInt32 maxOfAllMinColWidths = 0; // for the case where we have equal column widths, this is the smallest a column can be
- nscoord tableWidth; // the width of the table as a result of setting column widths
- tableWidth = aMaxWidth-aAvailWidth; // the starting table width is the sum of fixed-width columns
+ nscoord tableWidth=0; // the width of the table as a result of setting column widths
PRInt32 totalSlices=0; // the total number of slices the proportional-width columns request
nsVoidArray *proportionalColumnsList=nsnull; // a list of the columns that are proportional-width
PRBool equalWidthColumns = PR_TRUE; // remember if we're in the special case where all
@@ -1041,6 +1242,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
PRBool atLeastOneAutoWidthColumn = PR_FALSE; // true if at least one column is auto-width, requiring us to post-process
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
PRInt32 numRows = mTableFrame->GetRowCount();
+ nscoord colInset = mTableFrame->GetCellSpacing();
for (PRInt32 colIndex = 0; colIndexGetCellSpacing();
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
// first, deal with any cells that span into this column from a pervious column
+ // go through the list backwards so we can delete easily
if (nsnull!=spanList)
{
PRInt32 spanCount = spanList->Count();
@@ -1068,15 +1270,65 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
if (PR_FALSE==IsFixedWidth(colPosition))
{
- if (minColWidth < spanInfo->cellMinWidth)
- minColWidth = spanInfo->cellMinWidth;
- if (maxColWidth < spanInfo->cellDesiredWidth)
- maxColWidth = spanInfo->cellDesiredWidth;
+ // compute the spanning cell's contribution to the column min width
+ nscoord spanCellMinWidth;
+ if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
+ {
+ spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMinWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (minColWidth < spanCellMinWidth)
+ {
+ minColWidth = spanCellMinWidth; // set the new min width for the col
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new min = %d\n",
+ colIndex, spanInfo->span, minColWidth);
+ }
+ }
+ else
+ {
+ spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
+ minColWidth = spanCellMinWidth;
+ //QQQ is mMinTableWidth already taken care of at this point?
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new min = %d\n",
+ colIndex, spanInfo->span, minColWidth);
+ }
+
+
+ // compute the spanning cell's contribution to the column max width
+ nscoord spanCellMaxWidth;
+ if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
+ {
+ spanCellMaxWidth = (spanInfo->cellDesiredWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist max: %d of %d\n", spanCellMaxWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (maxColWidth < spanCellMaxWidth)
+ {
+ maxColWidth = spanCellMaxWidth; // set the new max width for the col
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new max = %d\n",
+ colIndex, spanInfo->span, maxColWidth);
+ }
+ }
+ else
+ {
+ spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
+ maxColWidth = spanCellMaxWidth;
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new max = %d\n",
+ colIndex, spanInfo->span, maxColWidth);
+ }
}
spanInfo->span--;
- if (gsDebug==PR_TRUE)
- printf (" for spanning cell %d with remaining span=%d, min = %d and des = %d\n",
- spanIndex, spanInfo->span, spanInfo->cellMinWidth, spanInfo->cellDesiredWidth);
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
@@ -1085,6 +1337,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
}
}
+ // second, process non-fixed-width columns
if (PR_FALSE==IsFixedWidth(colPosition))
{
for (rowIndex = 0; rowIndexGetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- PRInt32 cellMinWidth = cellMinSize.width/colSpan;
- // first get the desired size info from reflow pass 1
- PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
- // then get the desired size info factoring in the cell style attributes
- nscoord specifiedCellWidth=-1;
- const nsStylePosition* cellPosition;
- cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition);
- switch (cellPosition->mWidth.GetUnit()) {
- case eStyleUnit_Percent:
+ nscoord cellMinWidth=colFrame->GetMinColWidth();
+ nscoord cellDesiredWidth=colFrame->GetMaxColWidth();
+ if (1==colSpan)
+ {
+ cellMinWidth = cellMinSize.width;
+ cellDesiredWidth = cellDesiredSize.width;
+ nscoord specifiedCellWidth=-1;
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
+ if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
{
- nscoord knownTableWidth=0;
float percent = cellPosition->mWidth.GetPercentValue();
specifiedCellWidth = (PRInt32)(aMaxWidth*percent);
if (gsDebug) printf("specified percent width %f of %d = %d\n",
percent, aMaxWidth, specifiedCellWidth);
- break;
+ }
+ if (-1!=specifiedCellWidth)
+ {
+ if (specifiedCellWidth>cellMinWidth)
+ {
+ if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
+ cellDesiredWidth, specifiedCellWidth);
+ cellDesiredWidth = specifiedCellWidth;
+ }
}
}
- if (-1!=specifiedCellWidth)
- {
- if (specifiedCellWidth>cellMinWidth)
+ else
+ { // colSpan>1, get the proportion for this column
+ // then get the desired size info factoring in the cell style attributes
+ nscoord effectiveMaxWidthOfSpannedCols = colFrame->GetEffectiveMaxColWidth();
+ nscoord effectiveMinWidthOfSpannedCols = colFrame->GetEffectiveMinColWidth();
+ for (PRInt32 span=1; spanGetColFrame(colIndex+span);
+ if (nsnull==nextColFrame)
+ break;
+ effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
+ effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
+ }
+ nscoord specifiedCellWidth=-1;
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
+ if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
+ { //QQQ what if table is auto width?
+ float percent = cellPosition->mWidth.GetPercentValue();
+ specifiedCellWidth = (PRInt32)(aMaxWidth*percent);
+ if (gsDebug) printf("specified percent width %f of %d = %d\n",
+ percent, aMaxWidth, specifiedCellWidth);
+ }
+ if (-1!=specifiedCellWidth)
+ {
+ float percentForThisCol = (float)(cellDesiredSize.width * colFrame->GetEffectiveMaxColWidth()) /
+ (float)effectiveMaxWidthOfSpannedCols;
+ nscoord cellWidthForThisCol = (nscoord)(specifiedCellWidth * percentForThisCol);
+ if (cellWidthForThisCol>cellMinWidth)
+ {
+ if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
+ cellDesiredWidth, cellWidthForThisCol);
+ cellDesiredWidth = cellWidthForThisCol;
+ }
+ }
+ // otherwise it's already been factored in.
+ // now, if this column holds the cell, create a spanInfo struct for the cell
+ // so subsequent columns can take a proportion of this cell's space into account
+ if (cellFrame->GetColIndex()==colIndex)
+ { // add this cell to span list iff we are currently processing the column the cell starts in
+ SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan-1, cellMinSize.width, cellDesiredSize.width);
+ spanInfo->effectiveMaxWidthOfSpannedCols = effectiveMaxWidthOfSpannedCols;
+ spanInfo->effectiveMinWidthOfSpannedCols = effectiveMinWidthOfSpannedCols;
+ if (nsnull==spanList)
+ spanList = new nsVoidArray();
+ spanList->AppendElement(spanInfo);
}
}
@@ -1153,14 +1453,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
rowIndex, minColWidth, maxColWidth,
colIndex, colFrame->GetEffectiveMinColWidth(), colFrame->GetEffectiveMaxColWidth());
- if ((1GetColIndex()==colIndex))
- { // if this cell spans columns and we are processing the column that owns the cell
- // add the cell to our list of spanners
- SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
- if (nsnull==spanList)
- spanList = new nsVoidArray();
- spanList->AppendElement(spanInfo);
- }
}
if (gsDebug==PR_TRUE)
@@ -1178,7 +1470,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
// Get column width if it has one
nscoord specifiedProportionColumnWidth = -1;
float specifiedPercentageColWidth = -1.0f;
- nscoord specifiedFixedColumnWidth = -1;
PRBool isAutoWidth = PR_FALSE;
switch (colPosition->mWidth.GetUnit()) {
case eStyleUnit_Percent:
@@ -1279,23 +1570,23 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
}
}
}
- tableWidth += mTableFrame->GetColumnWidth(colIndex);
}
+ tableWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
}
/* --- post-process if necessary --- */
// first, assign autoWidth columns a width
if (PR_TRUE==atLeastOneAutoWidthColumn)
{ // proportionately distribute the remaining space to autowidth columns
- DistributeRemainingSpace(aAvailWidth, tableWidth);
+ DistributeRemainingSpace(aMaxWidth, tableWidth);
}
// second, fix up tables where column width attributes give us a table that is too wide or too narrow
nscoord computedWidth=0;
for (PRInt32 i=0; iGetColumnWidth(i);
+ computedWidth += mTableFrame->GetColumnWidth(i) + colInset;
}
- if (computedWidthaMaxWidth) {
AdjustTableThatIsTooWide(computedWidth, aMaxWidth);
@@ -1343,7 +1634,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
return result;
}
-//XXX: make sure aTFW takes into account fixed width cells already assigned
// 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,
@@ -1404,31 +1694,46 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
if (PR_TRUE==gsDebug)
{
nscoord tableWidth=0;
- for (PRInt32 i=0; iGetColumnWidth(i);
- printf ("before EnsureCellMinWidth, computed table width is %d\n",tableWidth);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
}
- EnsureCellMinWidths();
+ EnsureCellMinWidths(PR_FALSE);
}
if (PR_TRUE==gsDebug)
{
nscoord tableWidth=0;
- for (PRInt32 i=0; iGetColumnWidth(i);
- printf ("after EnsureCellMinWidth, computed table width is %d\n",tableWidth);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
}
}
-void BasicTableLayoutStrategy::EnsureCellMinWidths()
+void BasicTableLayoutStrategy::EnsureCellMinWidths(PRBool aShrinkFixedWidthCells)
{
PRBool atLeastOne = PR_TRUE;
- /* XXX we'll use this if it turns out that fixed-width cells
- XXX should NOT be shrunk to accomodate table width
- PRInt32 numFixedColumns;
- PRInt32 *fixedColumns=nsnull;
- mTableFrame->GetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
- */
+ PRBool *colsToRemoveFrom = new PRBool[mNumCols];
+ for (PRInt32 i=0; iGetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
+ for (PRInt32 i=0; i0))
{ // while we still have some extra space, and last time we were able to take some off...
PRInt32 startingAddedWidth = addedWidth;
@@ -1457,7 +1763,7 @@ void BasicTableLayoutStrategy::EnsureCellMinWidths()
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
nscoord minEffectiveColWidth = colFrame->GetEffectiveMinColWidth();
nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if (colWidth>minEffectiveColWidth)
+ if ((colWidth>minEffectiveColWidth) && (PR_TRUE==colsToRemoveFrom[colIndex]))
{
mTableFrame->SetColumnWidth(colIndex, colWidth-1);
addedWidth--;
@@ -1469,7 +1775,17 @@ void BasicTableLayoutStrategy::EnsureCellMinWidths()
}
if (startingAddedWidth==addedWidth)
{ // we we unable to find any columns to remove space from
- break; // while ((addedWidth>0))
+ PRBool okToContinue=PR_FALSE;
+ for (PRInt32 i=0; i0))
}
}
if (0GetColumnWidth(i);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
+ }
+
PRInt32 numFixedColumns=0;
PRInt32 *fixedColumns=nsnull;
//XXX todo: exclude fixed width columns
@@ -1508,11 +1837,34 @@ void BasicTableLayoutStrategy::AdjustTableThatIsTooWide(nscoord aComputedWidth,
}
}
}
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ printf("after AdjustTableThatIsTooWide: ");
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
+ }
}
void BasicTableLayoutStrategy::AdjustTableThatIsTooNarrow(nscoord aComputedWidth,
nscoord aTableWidth)
{
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ printf("before AdjustTableThatIsTooNarrow: ");
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
+ }
+
PRInt32 numFixedColumns=0;
PRInt32 *fixedColumns=nsnull;
//XXX todo: exclude fixed width columns
@@ -1536,6 +1888,17 @@ void BasicTableLayoutStrategy::AdjustTableThatIsTooNarrow(nscoord aComputedWidth
}
}
}
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ printf("after AdjustTableThatIsTooNarrow: ");
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
+ }
}
//PRBool BasicTableLayoutStrategy::IsFixedWidthColumn(PRInt32 colIndex, PRInt32 *colIndexes)
diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
index 0ea87b4d5ca..d3ab22e9c76 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
@@ -33,19 +33,26 @@ struct SpanInfo
{
PRInt32 span;
const PRInt32 initialColSpan;
+ const PRInt32 initialColIndex;
nscoord cellMinWidth;
nscoord cellDesiredWidth;
+ nscoord effectiveMinWidthOfSpannedCols;
+ nscoord effectiveMaxWidthOfSpannedCols;
- SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth);
+ SpanInfo(PRInt32 aColIndex, PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth);
~SpanInfo() {};
};
-inline SpanInfo::SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
- : initialColSpan(aSpan)
+inline SpanInfo::SpanInfo(PRInt32 aColIndex, PRInt32 aSpan,
+ nscoord aMinWidth, nscoord aDesiredWidth)
+ : initialColIndex(aColIndex),
+ initialColSpan(aSpan)
{
span = aSpan;
cellMinWidth = aMinWidth;
cellDesiredWidth = aDesiredWidth;
+ effectiveMinWidthOfSpannedCols=0;
+ effectiveMaxWidthOfSpannedCols=0;
}
@@ -189,7 +196,7 @@ public:
/** force all cells to be at least their minimum width, removing any excess space
* created in the process from fat cells that can afford to lose a little tonnage.
*/
- virtual void EnsureCellMinWidths();
+ virtual void EnsureCellMinWidths(PRBool aShrinkFixedWidthCells);
virtual void AdjustTableThatIsTooWide(nscoord aComputedWidth,
nscoord aTableWidth);
diff --git a/mozilla/layout/html/table/src/nsTableColFrame.cpp b/mozilla/layout/html/table/src/nsTableColFrame.cpp
index 4fe0f13656b..e90fd2c36a6 100644
--- a/mozilla/layout/html/table/src/nsTableColFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableColFrame.cpp
@@ -42,6 +42,7 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
mMinColWidth = 0;
mMaxEffectiveColWidth = 0;
mMinEffectiveColWidth = 0;
+ mWidthSource = eWIDTH_SOURCE_NONE;
}
diff --git a/mozilla/layout/html/table/src/nsTableColFrame.h b/mozilla/layout/html/table/src/nsTableColFrame.h
index 13b8b66691a..ffe92282e4b 100644
--- a/mozilla/layout/html/table/src/nsTableColFrame.h
+++ b/mozilla/layout/html/table/src/nsTableColFrame.h
@@ -24,6 +24,11 @@
class nsTableColFrame : public nsFrame {
public:
+ enum {eWIDTH_SOURCE_NONE =0, // no cell has contributed to the width style
+ eWIDTH_SOURCE_CELL =1, // a cell specified a width
+ eWIDTH_SOURCE_CELL_WITH_SPAN=2 // a cell implicitly specified a width via colspan
+ };
+
void Init(PRInt32 aColIndex, PRInt32 aRepeat);
static nsresult NewFrame(nsIFrame** aInstancePtrResult,
@@ -63,6 +68,9 @@ public:
nscoord GetEffectiveMinColWidth();
void SetEffectiveMinColWidth(nscoord aMinColWidth);
+ PRInt32 GetWidthSource();
+ void SetWidthSource(PRInt32 aMinColWidth);
+
/** convenience method, calls into cellmap */
PRInt32 Count() const;
@@ -84,6 +92,8 @@ protected:
nscoord mMaxEffectiveColWidth;
nscoord mMinEffectiveColWidth;
+ PRInt32 mWidthSource;
+
};
@@ -129,5 +139,10 @@ inline nscoord nsTableColFrame::GetEffectiveMinColWidth()
inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinColWidth)
{ mMinEffectiveColWidth = aMinColWidth; }
+inline PRInt32 nsTableColFrame::GetWidthSource()
+{ return mWidthSource; }
+
+inline void nsTableColFrame::SetWidthSource(PRInt32 aWidthSource)
+{ mWidthSource = aWidthSource; }
#endif
diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp
index f78657ea24b..f98989c9ff1 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableFrame.cpp
@@ -364,6 +364,26 @@ PRInt32 nsTableFrame::GetRowCount ()
return rowCount;
}
+PRInt32 nsTableFrame::GetColCount ()
+{
+ PRInt32 colCount = 0;
+
+ if (nsnull != mCellMap)
+ return mCellMap->GetColCount();
+
+ nsIFrame *child=mFirstChild;
+ while (nsnull!=child)
+ {
+ const nsStyleDisplay *childDisplay;
+ child->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ colCount += ((nsTableColGroupFrame *)child)->GetColumnCount ();
+ child->GetNextSibling(child);
+ }
+ return colCount;
+}
+
+
nsTableColFrame * nsTableFrame::GetColFrame(PRInt32 aColIndex)
{
nsTableColFrame *result = nsnull;
@@ -405,8 +425,8 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
NS_PRECONDITION (nsnull!=aCell, "bad cell arg");
NS_PRECONDITION (0<=aRowIndex && aRowIndexGetRowSpan();
- int rowCount = GetRowCount();
+ PRInt32 rowSpan = aCell->GetRowSpan();
+ PRInt32 rowCount = GetRowCount();
if (rowCount < (aRowIndex + rowSpan))
return (rowCount - aRowIndex);
return rowSpan;
@@ -423,13 +443,33 @@ PRInt32 nsTableFrame::GetEffectiveColSpan (PRInt32 aColIndex, nsTableCellFrame *
NS_PRECONDITION (nsnull!=mCellMap, "bad call, mCellMap not yet allocated.");
NS_PRECONDITION (0<=aColIndex && aColIndexGetColCount(), "bad col index arg");
- int colSpan = aCell->GetColSpan();
- int colCount = mCellMap->GetColCount();
+ if (mCellMap->GetRowCount()==1)
+ return 1;
+ PRInt32 colSpan = aCell->GetColSpan();
+ PRInt32 colCount = mCellMap->GetColCount();
if (colCount < (aColIndex + colSpan))
return (colCount - aColIndex);
return colSpan;
}
+PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
+{
+ NS_PRECONDITION (nsnull!=mCellMap, "bad call, mCellMap not yet allocated.");
+ PRInt32 result;
+ nsIFrame *tableFrame = this;
+// begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
+ tableFrame->GetGeometricParent(tableFrame);
+// end REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
+ nsStyleTable *tableStyle;
+ tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
+ result = tableStyle->mCols;
+ PRInt32 numCols = GetColCount();
+ if (result>numCols)
+ result = numCols;
+ return result;
+}
+
+
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTableFrame::ResetCellMap ()
{
@@ -2385,20 +2425,20 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext,
// also acts as the width attribute for the entire column
if ((nsnull!=aPresContext) && (nsnull!=aCellFrame) && (nsnull!=aRowFrame))
{
- if (0==aRowFrame->GetRowIndex())
- {
- // get the cell style info
- const nsStylePosition* cellPosition;
- aCellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
- if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) ||
- (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())) {
- // compute the width per column spanned
- PRInt32 colSpan = aCellFrame->GetColSpan();
- for (PRInt32 i=0; iGetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
+ if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) ||
+ (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())) {
+ // compute the width per column spanned
+ PRInt32 colSpan = aCellFrame->GetColSpan();
+ for (PRInt32 i=0; iGetColIndex(), colFrame);
+ if (nsTableColFrame::eWIDTH_SOURCE_CELL != colFrame->GetWidthSource())
{
- // get the appropriate column frame
- nsTableColFrame *colFrame;
- GetColumnFrame(i+aCellFrame->GetColIndex(), colFrame);
// get the column style and set the width attribute
nsIStyleContext* colSC;
colFrame->GetStyleContext(aPresContext, colSC);
@@ -2414,6 +2454,11 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext,
float width = cellPosition->mWidth.GetPercentValue();
colPosition->mWidth.SetPercentValue(width/colSpan);
}
+ // set the column width-set-type
+ if (1==colSpan)
+ colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
+ else
+ colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
}
}
}
@@ -2505,7 +2550,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
{ // if it's a row group, get the cells and set the column style if appropriate
nsIFrame *rowFrame;
childFrame->FirstChild(rowFrame);
- if (nsnull!=rowFrame)
+ while (nsnull!=rowFrame)
{
nsIFrame *cellFrame;
rowFrame->FirstChild(cellFrame);
@@ -2518,6 +2563,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
cellFrame->GetNextSibling(cellFrame);
}
+ rowFrame->GetNextSibling(rowFrame);
}
}
childFrame->GetNextSibling(childFrame);
diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h
index 9ffdaf42d7e..9aa086486b8 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.h
+++ b/mozilla/layout/html/table/src/nsTableFrame.h
@@ -190,6 +190,12 @@ public:
*/
virtual PRInt32 GetEffectiveColSpan(PRInt32 aColIndex, nsTableCellFrame *aCell);
+ /** return the value of the COLS attribute, adjusted for the
+ * actual number of columns in the table
+ */
+ PRInt32 GetEffectiveCOLSAttribute();
+
+
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
@@ -406,6 +412,8 @@ public: /* ----- Cell Map public methods ----- */
*/
virtual PRInt32 GetRowCount();
+ virtual PRInt32 GetColCount();
+
nsTableColFrame * GetColFrame(PRInt32 aColIndex);
nsTableCellFrame * GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex);
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
index 66b78ca9f0a..4f8a2492eba 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
@@ -464,7 +464,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
// begin special Nav4 compatibility code
if (0==cellWidth)
{
- cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
+ cellWidth = availWidth;
}
// end special Nav4 compatibility code
@@ -537,6 +537,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
nsSize kidAvailSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
// See if there's a width constraint for the cell
+ /*
const nsStylePosition* cellPosition = (const nsStylePosition*)
kidSC->GetStyleData(eStyleStruct_Position);
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
@@ -544,7 +545,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
kidAvailSize.width = cellPosition->mWidth.GetCoordValue();
}
NS_RELEASE(kidSC);
-
+ */
// Get the child's margins
nsMargin margin;
nscoord topMargin = 0;
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
index d9383e38e53..20ae676c6e3 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
@@ -112,13 +112,7 @@ BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aFrame, PRInt32
mFixedTableWidth=0;
//cache the value of the cols attribute
- nsIFrame * tableFrame = mTableFrame;
-// begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
- tableFrame->GetGeometricParent(tableFrame);
-// end REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
- nsStyleTable *tableStyle;
- tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
- mCols = tableStyle->mCols;
+ mCols = mTableFrame->GetEffectiveCOLSAttribute();
}
BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
@@ -254,34 +248,9 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
/* Scan the column, simulatneously assigning column widths
* and computing the min/max column widths
*/
- // first, deal with any cells that span into this column from a pervious column
- if (nsnull!=spanList)
- {
- PRInt32 spanCount = spanList->Count();
- // go through the list backwards so we can delete easily
- for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
- {
- SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
- nscoord cellMinWidth = (spanInfo->cellMinWidth)/(spanInfo->initialColSpan);
- if (minColWidth < cellMinWidth)
- minColWidth = cellMinWidth;
- nscoord cellDesiredWidth = (spanInfo->cellDesiredWidth)/(spanInfo->initialColSpan);
- if (maxColWidth < cellDesiredWidth)
- maxColWidth = cellDesiredWidth;
- spanInfo->span--;
- if (gsDebug==PR_TRUE)
- printf (" for spanning cell %d with remaining span=%d, min = %d and des = %d\n",
- spanIndex, spanInfo->span, cellMinWidth, cellDesiredWidth);
- if (0==spanInfo->span)
- {
- spanList->RemoveElementAt(spanIndex);
- delete spanInfo;
- }
- }
- }
-
PRInt32 firstRowIndex = -1;
PRInt32 maxColSpan = 1;
+ PRBool cellGrantingWidth=PR_TRUE;
for (PRInt32 rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
@@ -307,21 +276,23 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
+ nscoord cellDesiredWidth = cellDesiredSize.width;
if (gsDebug==PR_TRUE)
printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
cellDesiredSize.width, cellDesiredSize.height);
- if (PR_TRUE==haveColWidth)
+ if (PR_TRUE==haveColWidth && PR_TRUE==cellGrantingWidth)
{
- // This col has a specified fixed width so set the minand max width to the larger of
+ // This col has a specified fixed width so set the min and max width to the larger of
// (specified width, largest max_element_size of the cells in the column)
+ // factoring in the min width of the prior cells (stored in minColWidth)
nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
+ widthForThisCell = PR_MAX(widthForThisCell, minColWidth);
widthForThisCell = widthForThisCell/colSpan;
mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
maxColWidth = widthForThisCell;
- minColWidth = widthForThisCell;
+ //minColWidth = (cellMinSize.width)/colSpan;
if ((1==colSpan) && (effectiveMaxColumnWidth < widthForThisCell))
effectiveMaxColumnWidth = widthForThisCell;
if (gsDebug)
@@ -335,8 +306,18 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
effectiveMaxColumnWidth = cellDesiredWidth;
}
+ //bookkeeping: is this the cell that gave the column it's fixed width attribute?
+ // must be done after "haveColWidth && cellGrantingWidth" used above
+ if (PR_TRUE==cellGrantingWidth && 1==colSpan)
+ {
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
+ if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
+ cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
+ }
+
// cellMinWidth can override fixed width, so factor it in here
- nscoord cellMinWidth = cellMinSize.width/colSpan;
+ nscoord cellMinWidth = cellMinSize.width;
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
// effectiveMinColumnWidth is the min width as if no cells with colspans existed
@@ -344,14 +325,36 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
effectiveMinColumnWidth = cellMinWidth;
if (1AppendElement(colSpanInfo);
+ // add the column to our list of post-process columns, if all of the intersected columns are auto
+ PRBool okToAdd = PR_TRUE;
+ if (numRows==1 || (PR_FALSE==IsFixedWidth(colPosition)))
+ okToAdd = PR_FALSE;
+ else
+ {
+ for (PRInt32 i=1; iGetColumnFrame(i+colIndex, cf);
+ const nsStylePosition* colPos;
+ cf->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPos);
+ if (colPos->mWidth.GetUnit() != eStyleUnit_Auto)
+ {
+ okToAdd = PR_FALSE;
+ break;
+ }
+ }
+ }
+
+ if (PR_TRUE==okToAdd)
+ {
+ ColSpanStruct *colSpanInfo = new ColSpanStruct(colSpan, colIndex, cellDesiredSize.width);
+ if (nsnull==colSpanList)
+ colSpanList = new nsVoidArray();
+ colSpanList->AppendElement(colSpanInfo);
+ }
// add the cell to our list of spanning cells
- SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
+ SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan, cellMinWidth, cellDesiredWidth);
if (nsnull==spanList)
spanList = new nsVoidArray();
spanList->AppendElement(spanInfo);
@@ -366,26 +369,30 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
nscoord colInset = mTableFrame->GetCellSpacing();
// keep a running total of the amount of space taken up by all fixed-width columns
if (PR_TRUE==haveColWidth)
- mFixedTableWidth += specifiedFixedColWidth + (colInset*maxColSpan);
+ {
+ mFixedTableWidth += maxColWidth + colInset;
+ if (0==colIndex)
+ mFixedTableWidth += colInset;
+ }
if (gsDebug) {
printf (" after col %d, mFixedTableWidth = %d\n", colIndex, mFixedTableWidth);
}
// cache the computed column info
- colFrame->SetMinColWidth(minColWidth);
- colFrame->SetMaxColWidth(maxColWidth);
+ colFrame->SetMinColWidth(effectiveMinColumnWidth);
+ colFrame->SetMaxColWidth(effectiveMaxColumnWidth);
colFrame->SetEffectiveMinColWidth(effectiveMinColumnWidth);
colFrame->SetEffectiveMaxColWidth(effectiveMaxColumnWidth);
- mTableFrame->SetColumnWidth(colIndex, maxColWidth);
+ mTableFrame->SetColumnWidth(colIndex, effectiveMaxColumnWidth);
// add col[i] metrics to the running totals for the table min/max width
if (NS_UNCONSTRAINEDSIZE!=mMinTableWidth)
- mMinTableWidth += minColWidth + colInset;
- if (mMinTableWidth<=0)
+ mMinTableWidth += effectiveMinColumnWidth + colInset;
+ if (mMinTableWidth<0)
mMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (NS_UNCONSTRAINEDSIZE!=mMaxTableWidth)
- mMaxTableWidth += maxColWidth + colInset;
- if (mMaxTableWidth<=0)
+ mMaxTableWidth += effectiveMaxColumnWidth + colInset;
+ if (mMaxTableWidth<0)
mMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (PR_TRUE==hasColsAttribute)
{
@@ -398,6 +405,110 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
}
// now, post-process the computed values based on the table attributes
+
+ // first, factor in min/max values of spanning cells proportionately.
+ // We can't do this above in the first loop, because we don't have enough information
+ // to determine the proportion each column gets from spanners.
+ if (nsnull!=spanList)
+ {
+ for (PRInt32 colIndex=0; colIndexCount();
+ // go through the list backwards so we can delete easily
+ for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
+ {
+ SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
+ // if the spanInfo is about a column before the current column, it effects
+ // the current column (otherwise it would have already been deleted.)
+ if (spanInfo->initialColIndex <= colIndex)
+ {
+ if (0==spanInfo->effectiveMaxWidthOfSpannedCols)
+ {
+ for (PRInt32 span=0; spaninitialColSpan; span++)
+ {
+ nsTableColFrame *nextColFrame = mTableFrame->GetColFrame(colIndex+span);
+ if (nsnull==nextColFrame)
+ break;
+ spanInfo->effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
+ spanInfo->effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
+ }
+ }
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ // compute the spanning cell's contribution to the column min width
+ nscoord colMinWidth = colFrame->GetMinColWidth();
+ nscoord spanCellMinWidth;
+ if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
+ {
+ spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMinWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (colMinWidth < spanCellMinWidth)
+ {
+ colFrame->SetMinColWidth(spanCellMinWidth); // set the new min width for the col
+ mMinTableWidth += spanCellMinWidth-colMinWidth; // add in the col min width delta
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ old min = %d, new min = %d\n",
+ colIndex, spanInfo->span, colMinWidth, spanCellMinWidth);
+ }
+ }
+ else
+ {
+ spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
+ colFrame->SetMinColWidth(spanCellMinWidth);
+ //QQQ is mMinTableWidth already taken care of at this point?
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ old min = %d, new min = %d\n",
+ colIndex, spanInfo->span, colMinWidth, spanCellMinWidth);
+ }
+
+
+ // compute the spanning cell's contribution to the column max width
+ nscoord colMaxWidth = colFrame->GetMaxColWidth();
+ nscoord spanCellMaxWidth;
+ if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
+ {
+ spanCellMaxWidth = (spanInfo->cellDesiredWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist max: %d of %d\n", spanCellMaxWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (colMaxWidth < spanCellMaxWidth)
+ {
+ colFrame->SetMaxColWidth(spanCellMaxWidth); // set the new max width for the col
+ mMaxTableWidth += spanCellMaxWidth-colMaxWidth; // add in the col max width delta
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ old max = %d, new max = %d\n",
+ colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
+ }
+ }
+ else
+ {
+ spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
+ colFrame->SetMaxColWidth(spanCellMaxWidth);
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ old max = %d, new max = %d\n",
+ colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
+ }
+
+ spanInfo->span--;
+ if (0==spanInfo->span)
+ {
+ spanList->RemoveElementAt(spanIndex);
+ delete spanInfo;
+ }
+ }
+ }
+ }
+ }
+
+
+ // second, handle the COLS attribute (equal column widths)
// if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth
if (PR_TRUE==hasColsAttribute)
{
@@ -639,11 +750,11 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aR
for (PRInt32 colIndex = 0; colIndexGetColFrame(colIndex);
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
+ PRInt32 minColWidth = colFrame->GetMinColWidth();
+ PRInt32 maxColWidth = 0;
PRInt32 rowIndex;
PRInt32 firstRowIndex = -1;
nscoord colInset = mTableFrame->GetCellSpacing();
@@ -652,6 +763,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aR
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
// first, deal with any cells that span into this column from a pervious column
+ // go through the list backwards so we can delete easily
if (nsnull!=spanList)
{
PRInt32 spanCount = spanList->Count();
@@ -661,15 +773,65 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aR
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
if (PR_FALSE==IsFixedWidth(colPosition))
{
- if (minColWidth < spanInfo->cellMinWidth)
- minColWidth = spanInfo->cellMinWidth;
- if (maxColWidth < spanInfo->cellDesiredWidth)
- maxColWidth = spanInfo->cellDesiredWidth;
+ // compute the spanning cell's contribution to the column min width
+ nscoord spanCellMinWidth;
+ if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
+ {
+ spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMinWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (minColWidth < spanCellMinWidth)
+ {
+ minColWidth = spanCellMinWidth; // set the new min width for the col
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new min = %d\n",
+ colIndex, spanInfo->span, minColWidth);
+ }
+ }
+ else
+ {
+ spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
+ minColWidth = spanCellMinWidth;
+ //QQQ is mMinTableWidth already taken care of at this point?
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new min = %d\n",
+ colIndex, spanInfo->span, minColWidth);
+ }
+
+
+ // compute the spanning cell's contribution to the column max width
+ nscoord spanCellMaxWidth;
+ if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
+ {
+ spanCellMaxWidth = (spanInfo->cellDesiredWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist max: %d of %d\n", spanCellMaxWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (maxColWidth < spanCellMaxWidth)
+ {
+ maxColWidth = spanCellMaxWidth; // set the new max width for the col
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new max = %d\n",
+ colIndex, spanInfo->span, maxColWidth);
+ }
+ }
+ else
+ {
+ spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
+ maxColWidth = spanCellMaxWidth;
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new max = %d\n",
+ colIndex, spanInfo->span, maxColWidth);
+ }
}
spanInfo->span--;
- if (gsDebug==PR_TRUE)
- printf (" for spanning cell %d with remaining span=%d, min = %d and des = %d\n",
- spanIndex, spanInfo->span, spanInfo->cellMinWidth, spanInfo->cellDesiredWidth);
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
@@ -702,53 +864,93 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aR
}
PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame);
- // distribute a portion of the spanning cell's min and max width to this column
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
-
- nscoord cellMinWidth = cellMinSize.width/colSpan;
- // first get the desired size info from reflow pass 1
- nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
+ nscoord cellMinWidth=colFrame->GetMinColWidth();
+ nscoord cellDesiredWidth=colFrame->GetMaxColWidth();
// then get the desired size info factoring in the cell style attributes
- nscoord specifiedCellWidth=-1;
- const nsStylePosition* cellPosition;
- cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
- if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
- { //QQQ what if table is auto width?
- float percent = cellPosition->mWidth.GetPercentValue();
- specifiedCellWidth = (PRInt32)(aTableSpecifiedWidth*percent);
- if (gsDebug) printf("specified percent width %f of %d = %d\n",
- percent, aTableSpecifiedWidth, specifiedCellWidth);
- }
- if (-1!=specifiedCellWidth)
+ if (1==colSpan)
{
- if (specifiedCellWidth/colSpan>cellMinWidth)
+ cellMinWidth = cellMinSize.width;
+ cellDesiredWidth = cellDesiredSize.width;
+ nscoord specifiedCellWidth=-1;
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
+ if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
+ { //QQQ what if table is auto width?
+ float percent = cellPosition->mWidth.GetPercentValue();
+ specifiedCellWidth = (PRInt32)(aTableSpecifiedWidth*percent);
+ if (gsDebug) printf("specified percent width %f of %d = %d\n",
+ percent, aTableSpecifiedWidth, specifiedCellWidth);
+ }
+ if (-1!=specifiedCellWidth)
{
- if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
- cellDesiredWidth, specifiedCellWidth/colSpan);
- cellDesiredWidth = specifiedCellWidth/colSpan;
- //QQQ should be proportionately distributed as a post-process
+ if (specifiedCellWidth>cellMinWidth)
+ {
+ if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
+ cellDesiredWidth, specifiedCellWidth);
+ cellDesiredWidth = specifiedCellWidth;
+ }
+ }
+ }
+ else
+ { // colSpan>1, get the proportion for this column
+ // then get the desired size info factoring in the cell style attributes
+ nscoord effectiveMaxWidthOfSpannedCols = colFrame->GetEffectiveMaxColWidth();
+ nscoord effectiveMinWidthOfSpannedCols = colFrame->GetEffectiveMinColWidth();
+ for (PRInt32 span=1; spanGetColFrame(colIndex+span);
+ if (nsnull==nextColFrame)
+ break;
+ effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
+ effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
+ }
+ nscoord specifiedCellWidth=-1;
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
+ if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
+ { //QQQ what if table is auto width?
+ float percent = cellPosition->mWidth.GetPercentValue();
+ specifiedCellWidth = (PRInt32)(aTableSpecifiedWidth*percent);
+ if (gsDebug) printf("specified percent width %f of %d = %d\n",
+ percent, aTableSpecifiedWidth, specifiedCellWidth);
+ }
+ if (-1!=specifiedCellWidth)
+ {
+ float percentForThisCol = (float)(cellDesiredSize.width * colFrame->GetEffectiveMaxColWidth()) /
+ (float)effectiveMaxWidthOfSpannedCols;
+ nscoord cellWidthForThisCol = (nscoord)(specifiedCellWidth * percentForThisCol);
+ if (cellWidthForThisCol>cellMinWidth)
+ {
+ if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
+ cellDesiredWidth, cellWidthForThisCol);
+ cellDesiredWidth = cellWidthForThisCol;
+ }
+ }
+ // otherwise it's already been factored in.
+ // now, if this column holds the cell, create a spanInfo struct for the cell
+ // so subsequent columns can take a proportion of this cell's space into account
+ if (cellFrame->GetColIndex()==colIndex)
+ { // add this cell to span list iff we are currently processing the column the cell starts in
+ SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan-1, cellMinSize.width, cellDesiredSize.width);
+ spanInfo->effectiveMaxWidthOfSpannedCols = effectiveMaxWidthOfSpannedCols;
+ spanInfo->effectiveMinWidthOfSpannedCols = effectiveMinWidthOfSpannedCols;
+ if (nsnull==spanList)
+ spanList = new nsVoidArray();
+ spanList->AppendElement(spanInfo);
}
}
if (PR_TRUE==gsDebug)
printf("factoring in cell %d with colSpan=%d\n factoring in min=%d and desired=%d\n",
rowIndex, colSpan, cellMinWidth, cellDesiredWidth);
- if (minColWidth < cellMinWidth)
- minColWidth = cellMinWidth;
if (maxColWidth < cellDesiredWidth)
maxColWidth = cellDesiredWidth;
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
rowIndex, minColWidth, maxColWidth,
colIndex, colFrame->GetEffectiveMaxColWidth());
- if ((1GetColIndex()==colIndex))
- { // add this cell to span list iff we are currently processing the column the cell starts in
- SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
- if (nsnull==spanList)
- spanList = new nsVoidArray();
- spanList->AppendElement(spanInfo);
- }
} // end looping through cells in the column
if (gsDebug==PR_TRUE)
@@ -1032,8 +1234,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
PRBool result = PR_TRUE;
PRInt32 maxOfAllMinColWidths = 0; // for the case where we have equal column widths, this is the smallest a column can be
- nscoord tableWidth; // the width of the table as a result of setting column widths
- tableWidth = aMaxWidth-aAvailWidth; // the starting table width is the sum of fixed-width columns
+ nscoord tableWidth=0; // the width of the table as a result of setting column widths
PRInt32 totalSlices=0; // the total number of slices the proportional-width columns request
nsVoidArray *proportionalColumnsList=nsnull; // a list of the columns that are proportional-width
PRBool equalWidthColumns = PR_TRUE; // remember if we're in the special case where all
@@ -1041,6 +1242,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
PRBool atLeastOneAutoWidthColumn = PR_FALSE; // true if at least one column is auto-width, requiring us to post-process
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
PRInt32 numRows = mTableFrame->GetRowCount();
+ nscoord colInset = mTableFrame->GetCellSpacing();
for (PRInt32 colIndex = 0; colIndexGetCellSpacing();
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
// first, deal with any cells that span into this column from a pervious column
+ // go through the list backwards so we can delete easily
if (nsnull!=spanList)
{
PRInt32 spanCount = spanList->Count();
@@ -1068,15 +1270,65 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
if (PR_FALSE==IsFixedWidth(colPosition))
{
- if (minColWidth < spanInfo->cellMinWidth)
- minColWidth = spanInfo->cellMinWidth;
- if (maxColWidth < spanInfo->cellDesiredWidth)
- maxColWidth = spanInfo->cellDesiredWidth;
+ // compute the spanning cell's contribution to the column min width
+ nscoord spanCellMinWidth;
+ if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
+ {
+ spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMinWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (minColWidth < spanCellMinWidth)
+ {
+ minColWidth = spanCellMinWidth; // set the new min width for the col
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new min = %d\n",
+ colIndex, spanInfo->span, minColWidth);
+ }
+ }
+ else
+ {
+ spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
+ minColWidth = spanCellMinWidth;
+ //QQQ is mMinTableWidth already taken care of at this point?
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new min = %d\n",
+ colIndex, spanInfo->span, minColWidth);
+ }
+
+
+ // compute the spanning cell's contribution to the column max width
+ nscoord spanCellMaxWidth;
+ if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
+ {
+ spanCellMaxWidth = (spanInfo->cellDesiredWidth * colFrame->GetEffectiveMinColWidth()) /
+ (spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (gsDebug==PR_TRUE)
+ printf (" spanlist max: %d of %d\n", spanCellMaxWidth, spanInfo->effectiveMaxWidthOfSpannedCols);
+ if (maxColWidth < spanCellMaxWidth)
+ {
+ maxColWidth = spanCellMaxWidth; // set the new max width for the col
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new max = %d\n",
+ colIndex, spanInfo->span, maxColWidth);
+ }
+ }
+ else
+ {
+ spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
+ maxColWidth = spanCellMaxWidth;
+ mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
+ if (gsDebug==PR_TRUE)
+ printf (" for spanning cell into col %d with remaining span=%d, \
+ new max = %d\n",
+ colIndex, spanInfo->span, maxColWidth);
+ }
}
spanInfo->span--;
- if (gsDebug==PR_TRUE)
- printf (" for spanning cell %d with remaining span=%d, min = %d and des = %d\n",
- spanIndex, spanInfo->span, spanInfo->cellMinWidth, spanInfo->cellDesiredWidth);
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
@@ -1085,6 +1337,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
}
}
+ // second, process non-fixed-width columns
if (PR_FALSE==IsFixedWidth(colPosition))
{
for (rowIndex = 0; rowIndexGetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- PRInt32 cellMinWidth = cellMinSize.width/colSpan;
- // first get the desired size info from reflow pass 1
- PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
- // then get the desired size info factoring in the cell style attributes
- nscoord specifiedCellWidth=-1;
- const nsStylePosition* cellPosition;
- cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition);
- switch (cellPosition->mWidth.GetUnit()) {
- case eStyleUnit_Percent:
+ nscoord cellMinWidth=colFrame->GetMinColWidth();
+ nscoord cellDesiredWidth=colFrame->GetMaxColWidth();
+ if (1==colSpan)
+ {
+ cellMinWidth = cellMinSize.width;
+ cellDesiredWidth = cellDesiredSize.width;
+ nscoord specifiedCellWidth=-1;
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
+ if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
{
- nscoord knownTableWidth=0;
float percent = cellPosition->mWidth.GetPercentValue();
specifiedCellWidth = (PRInt32)(aMaxWidth*percent);
if (gsDebug) printf("specified percent width %f of %d = %d\n",
percent, aMaxWidth, specifiedCellWidth);
- break;
+ }
+ if (-1!=specifiedCellWidth)
+ {
+ if (specifiedCellWidth>cellMinWidth)
+ {
+ if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
+ cellDesiredWidth, specifiedCellWidth);
+ cellDesiredWidth = specifiedCellWidth;
+ }
}
}
- if (-1!=specifiedCellWidth)
- {
- if (specifiedCellWidth>cellMinWidth)
+ else
+ { // colSpan>1, get the proportion for this column
+ // then get the desired size info factoring in the cell style attributes
+ nscoord effectiveMaxWidthOfSpannedCols = colFrame->GetEffectiveMaxColWidth();
+ nscoord effectiveMinWidthOfSpannedCols = colFrame->GetEffectiveMinColWidth();
+ for (PRInt32 span=1; spanGetColFrame(colIndex+span);
+ if (nsnull==nextColFrame)
+ break;
+ effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
+ effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
+ }
+ nscoord specifiedCellWidth=-1;
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
+ if (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())
+ { //QQQ what if table is auto width?
+ float percent = cellPosition->mWidth.GetPercentValue();
+ specifiedCellWidth = (PRInt32)(aMaxWidth*percent);
+ if (gsDebug) printf("specified percent width %f of %d = %d\n",
+ percent, aMaxWidth, specifiedCellWidth);
+ }
+ if (-1!=specifiedCellWidth)
+ {
+ float percentForThisCol = (float)(cellDesiredSize.width * colFrame->GetEffectiveMaxColWidth()) /
+ (float)effectiveMaxWidthOfSpannedCols;
+ nscoord cellWidthForThisCol = (nscoord)(specifiedCellWidth * percentForThisCol);
+ if (cellWidthForThisCol>cellMinWidth)
+ {
+ if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
+ cellDesiredWidth, cellWidthForThisCol);
+ cellDesiredWidth = cellWidthForThisCol;
+ }
+ }
+ // otherwise it's already been factored in.
+ // now, if this column holds the cell, create a spanInfo struct for the cell
+ // so subsequent columns can take a proportion of this cell's space into account
+ if (cellFrame->GetColIndex()==colIndex)
+ { // add this cell to span list iff we are currently processing the column the cell starts in
+ SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan-1, cellMinSize.width, cellDesiredSize.width);
+ spanInfo->effectiveMaxWidthOfSpannedCols = effectiveMaxWidthOfSpannedCols;
+ spanInfo->effectiveMinWidthOfSpannedCols = effectiveMinWidthOfSpannedCols;
+ if (nsnull==spanList)
+ spanList = new nsVoidArray();
+ spanList->AppendElement(spanInfo);
}
}
@@ -1153,14 +1453,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
rowIndex, minColWidth, maxColWidth,
colIndex, colFrame->GetEffectiveMinColWidth(), colFrame->GetEffectiveMaxColWidth());
- if ((1GetColIndex()==colIndex))
- { // if this cell spans columns and we are processing the column that owns the cell
- // add the cell to our list of spanners
- SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
- if (nsnull==spanList)
- spanList = new nsVoidArray();
- spanList->AppendElement(spanInfo);
- }
}
if (gsDebug==PR_TRUE)
@@ -1178,7 +1470,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
// Get column width if it has one
nscoord specifiedProportionColumnWidth = -1;
float specifiedPercentageColWidth = -1.0f;
- nscoord specifiedFixedColumnWidth = -1;
PRBool isAutoWidth = PR_FALSE;
switch (colPosition->mWidth.GetUnit()) {
case eStyleUnit_Percent:
@@ -1279,23 +1570,23 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
}
}
}
- tableWidth += mTableFrame->GetColumnWidth(colIndex);
}
+ tableWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
}
/* --- post-process if necessary --- */
// first, assign autoWidth columns a width
if (PR_TRUE==atLeastOneAutoWidthColumn)
{ // proportionately distribute the remaining space to autowidth columns
- DistributeRemainingSpace(aAvailWidth, tableWidth);
+ DistributeRemainingSpace(aMaxWidth, tableWidth);
}
// second, fix up tables where column width attributes give us a table that is too wide or too narrow
nscoord computedWidth=0;
for (PRInt32 i=0; iGetColumnWidth(i);
+ computedWidth += mTableFrame->GetColumnWidth(i) + colInset;
}
- if (computedWidthaMaxWidth) {
AdjustTableThatIsTooWide(computedWidth, aMaxWidth);
@@ -1343,7 +1634,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState&
return result;
}
-//XXX: make sure aTFW takes into account fixed width cells already assigned
// 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,
@@ -1404,31 +1694,46 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecified
if (PR_TRUE==gsDebug)
{
nscoord tableWidth=0;
- for (PRInt32 i=0; iGetColumnWidth(i);
- printf ("before EnsureCellMinWidth, computed table width is %d\n",tableWidth);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
}
- EnsureCellMinWidths();
+ EnsureCellMinWidths(PR_FALSE);
}
if (PR_TRUE==gsDebug)
{
nscoord tableWidth=0;
- for (PRInt32 i=0; iGetColumnWidth(i);
- printf ("after EnsureCellMinWidth, computed table width is %d\n",tableWidth);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
}
}
-void BasicTableLayoutStrategy::EnsureCellMinWidths()
+void BasicTableLayoutStrategy::EnsureCellMinWidths(PRBool aShrinkFixedWidthCells)
{
PRBool atLeastOne = PR_TRUE;
- /* XXX we'll use this if it turns out that fixed-width cells
- XXX should NOT be shrunk to accomodate table width
- PRInt32 numFixedColumns;
- PRInt32 *fixedColumns=nsnull;
- mTableFrame->GetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
- */
+ PRBool *colsToRemoveFrom = new PRBool[mNumCols];
+ for (PRInt32 i=0; iGetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
+ for (PRInt32 i=0; i0))
{ // while we still have some extra space, and last time we were able to take some off...
PRInt32 startingAddedWidth = addedWidth;
@@ -1457,7 +1763,7 @@ void BasicTableLayoutStrategy::EnsureCellMinWidths()
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
nscoord minEffectiveColWidth = colFrame->GetEffectiveMinColWidth();
nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if (colWidth>minEffectiveColWidth)
+ if ((colWidth>minEffectiveColWidth) && (PR_TRUE==colsToRemoveFrom[colIndex]))
{
mTableFrame->SetColumnWidth(colIndex, colWidth-1);
addedWidth--;
@@ -1469,7 +1775,17 @@ void BasicTableLayoutStrategy::EnsureCellMinWidths()
}
if (startingAddedWidth==addedWidth)
{ // we we unable to find any columns to remove space from
- break; // while ((addedWidth>0))
+ PRBool okToContinue=PR_FALSE;
+ for (PRInt32 i=0; i0))
}
}
if (0GetColumnWidth(i);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
+ }
+
PRInt32 numFixedColumns=0;
PRInt32 *fixedColumns=nsnull;
//XXX todo: exclude fixed width columns
@@ -1508,11 +1837,34 @@ void BasicTableLayoutStrategy::AdjustTableThatIsTooWide(nscoord aComputedWidth,
}
}
}
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ printf("after AdjustTableThatIsTooWide: ");
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
+ }
}
void BasicTableLayoutStrategy::AdjustTableThatIsTooNarrow(nscoord aComputedWidth,
nscoord aTableWidth)
{
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ printf("before AdjustTableThatIsTooNarrow: ");
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
+ }
+
PRInt32 numFixedColumns=0;
PRInt32 *fixedColumns=nsnull;
//XXX todo: exclude fixed width columns
@@ -1536,6 +1888,17 @@ void BasicTableLayoutStrategy::AdjustTableThatIsTooNarrow(nscoord aComputedWidth
}
}
}
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ printf("after AdjustTableThatIsTooNarrow: ");
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf(" %d ", mTableFrame->GetColumnWidth(i));
+ }
+ printf ("\n computed table width is %d\n",tableWidth);
+ }
}
//PRBool BasicTableLayoutStrategy::IsFixedWidthColumn(PRInt32 colIndex, PRInt32 *colIndexes)
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.h b/mozilla/layout/tables/BasicTableLayoutStrategy.h
index 0ea87b4d5ca..d3ab22e9c76 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.h
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.h
@@ -33,19 +33,26 @@ struct SpanInfo
{
PRInt32 span;
const PRInt32 initialColSpan;
+ const PRInt32 initialColIndex;
nscoord cellMinWidth;
nscoord cellDesiredWidth;
+ nscoord effectiveMinWidthOfSpannedCols;
+ nscoord effectiveMaxWidthOfSpannedCols;
- SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth);
+ SpanInfo(PRInt32 aColIndex, PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth);
~SpanInfo() {};
};
-inline SpanInfo::SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
- : initialColSpan(aSpan)
+inline SpanInfo::SpanInfo(PRInt32 aColIndex, PRInt32 aSpan,
+ nscoord aMinWidth, nscoord aDesiredWidth)
+ : initialColIndex(aColIndex),
+ initialColSpan(aSpan)
{
span = aSpan;
cellMinWidth = aMinWidth;
cellDesiredWidth = aDesiredWidth;
+ effectiveMinWidthOfSpannedCols=0;
+ effectiveMaxWidthOfSpannedCols=0;
}
@@ -189,7 +196,7 @@ public:
/** force all cells to be at least their minimum width, removing any excess space
* created in the process from fat cells that can afford to lose a little tonnage.
*/
- virtual void EnsureCellMinWidths();
+ virtual void EnsureCellMinWidths(PRBool aShrinkFixedWidthCells);
virtual void AdjustTableThatIsTooWide(nscoord aComputedWidth,
nscoord aTableWidth);
diff --git a/mozilla/layout/tables/nsTableColFrame.cpp b/mozilla/layout/tables/nsTableColFrame.cpp
index 4fe0f13656b..e90fd2c36a6 100644
--- a/mozilla/layout/tables/nsTableColFrame.cpp
+++ b/mozilla/layout/tables/nsTableColFrame.cpp
@@ -42,6 +42,7 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
mMinColWidth = 0;
mMaxEffectiveColWidth = 0;
mMinEffectiveColWidth = 0;
+ mWidthSource = eWIDTH_SOURCE_NONE;
}
diff --git a/mozilla/layout/tables/nsTableColFrame.h b/mozilla/layout/tables/nsTableColFrame.h
index 13b8b66691a..ffe92282e4b 100644
--- a/mozilla/layout/tables/nsTableColFrame.h
+++ b/mozilla/layout/tables/nsTableColFrame.h
@@ -24,6 +24,11 @@
class nsTableColFrame : public nsFrame {
public:
+ enum {eWIDTH_SOURCE_NONE =0, // no cell has contributed to the width style
+ eWIDTH_SOURCE_CELL =1, // a cell specified a width
+ eWIDTH_SOURCE_CELL_WITH_SPAN=2 // a cell implicitly specified a width via colspan
+ };
+
void Init(PRInt32 aColIndex, PRInt32 aRepeat);
static nsresult NewFrame(nsIFrame** aInstancePtrResult,
@@ -63,6 +68,9 @@ public:
nscoord GetEffectiveMinColWidth();
void SetEffectiveMinColWidth(nscoord aMinColWidth);
+ PRInt32 GetWidthSource();
+ void SetWidthSource(PRInt32 aMinColWidth);
+
/** convenience method, calls into cellmap */
PRInt32 Count() const;
@@ -84,6 +92,8 @@ protected:
nscoord mMaxEffectiveColWidth;
nscoord mMinEffectiveColWidth;
+ PRInt32 mWidthSource;
+
};
@@ -129,5 +139,10 @@ inline nscoord nsTableColFrame::GetEffectiveMinColWidth()
inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinColWidth)
{ mMinEffectiveColWidth = aMinColWidth; }
+inline PRInt32 nsTableColFrame::GetWidthSource()
+{ return mWidthSource; }
+
+inline void nsTableColFrame::SetWidthSource(PRInt32 aWidthSource)
+{ mWidthSource = aWidthSource; }
#endif
diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp
index f78657ea24b..f98989c9ff1 100644
--- a/mozilla/layout/tables/nsTableFrame.cpp
+++ b/mozilla/layout/tables/nsTableFrame.cpp
@@ -364,6 +364,26 @@ PRInt32 nsTableFrame::GetRowCount ()
return rowCount;
}
+PRInt32 nsTableFrame::GetColCount ()
+{
+ PRInt32 colCount = 0;
+
+ if (nsnull != mCellMap)
+ return mCellMap->GetColCount();
+
+ nsIFrame *child=mFirstChild;
+ while (nsnull!=child)
+ {
+ const nsStyleDisplay *childDisplay;
+ child->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ colCount += ((nsTableColGroupFrame *)child)->GetColumnCount ();
+ child->GetNextSibling(child);
+ }
+ return colCount;
+}
+
+
nsTableColFrame * nsTableFrame::GetColFrame(PRInt32 aColIndex)
{
nsTableColFrame *result = nsnull;
@@ -405,8 +425,8 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
NS_PRECONDITION (nsnull!=aCell, "bad cell arg");
NS_PRECONDITION (0<=aRowIndex && aRowIndexGetRowSpan();
- int rowCount = GetRowCount();
+ PRInt32 rowSpan = aCell->GetRowSpan();
+ PRInt32 rowCount = GetRowCount();
if (rowCount < (aRowIndex + rowSpan))
return (rowCount - aRowIndex);
return rowSpan;
@@ -423,13 +443,33 @@ PRInt32 nsTableFrame::GetEffectiveColSpan (PRInt32 aColIndex, nsTableCellFrame *
NS_PRECONDITION (nsnull!=mCellMap, "bad call, mCellMap not yet allocated.");
NS_PRECONDITION (0<=aColIndex && aColIndexGetColCount(), "bad col index arg");
- int colSpan = aCell->GetColSpan();
- int colCount = mCellMap->GetColCount();
+ if (mCellMap->GetRowCount()==1)
+ return 1;
+ PRInt32 colSpan = aCell->GetColSpan();
+ PRInt32 colCount = mCellMap->GetColCount();
if (colCount < (aColIndex + colSpan))
return (colCount - aColIndex);
return colSpan;
}
+PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
+{
+ NS_PRECONDITION (nsnull!=mCellMap, "bad call, mCellMap not yet allocated.");
+ PRInt32 result;
+ nsIFrame *tableFrame = this;
+// begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
+ tableFrame->GetGeometricParent(tableFrame);
+// end REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
+ nsStyleTable *tableStyle;
+ tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
+ result = tableStyle->mCols;
+ PRInt32 numCols = GetColCount();
+ if (result>numCols)
+ result = numCols;
+ return result;
+}
+
+
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTableFrame::ResetCellMap ()
{
@@ -2385,20 +2425,20 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext,
// also acts as the width attribute for the entire column
if ((nsnull!=aPresContext) && (nsnull!=aCellFrame) && (nsnull!=aRowFrame))
{
- if (0==aRowFrame->GetRowIndex())
- {
- // get the cell style info
- const nsStylePosition* cellPosition;
- aCellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
- if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) ||
- (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())) {
- // compute the width per column spanned
- PRInt32 colSpan = aCellFrame->GetColSpan();
- for (PRInt32 i=0; iGetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
+ if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) ||
+ (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())) {
+ // compute the width per column spanned
+ PRInt32 colSpan = aCellFrame->GetColSpan();
+ for (PRInt32 i=0; iGetColIndex(), colFrame);
+ if (nsTableColFrame::eWIDTH_SOURCE_CELL != colFrame->GetWidthSource())
{
- // get the appropriate column frame
- nsTableColFrame *colFrame;
- GetColumnFrame(i+aCellFrame->GetColIndex(), colFrame);
// get the column style and set the width attribute
nsIStyleContext* colSC;
colFrame->GetStyleContext(aPresContext, colSC);
@@ -2414,6 +2454,11 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext,
float width = cellPosition->mWidth.GetPercentValue();
colPosition->mWidth.SetPercentValue(width/colSpan);
}
+ // set the column width-set-type
+ if (1==colSpan)
+ colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
+ else
+ colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
}
}
}
@@ -2505,7 +2550,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
{ // if it's a row group, get the cells and set the column style if appropriate
nsIFrame *rowFrame;
childFrame->FirstChild(rowFrame);
- if (nsnull!=rowFrame)
+ while (nsnull!=rowFrame)
{
nsIFrame *cellFrame;
rowFrame->FirstChild(cellFrame);
@@ -2518,6 +2563,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
cellFrame->GetNextSibling(cellFrame);
}
+ rowFrame->GetNextSibling(rowFrame);
}
}
childFrame->GetNextSibling(childFrame);
diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h
index 9ffdaf42d7e..9aa086486b8 100644
--- a/mozilla/layout/tables/nsTableFrame.h
+++ b/mozilla/layout/tables/nsTableFrame.h
@@ -190,6 +190,12 @@ public:
*/
virtual PRInt32 GetEffectiveColSpan(PRInt32 aColIndex, nsTableCellFrame *aCell);
+ /** return the value of the COLS attribute, adjusted for the
+ * actual number of columns in the table
+ */
+ PRInt32 GetEffectiveCOLSAttribute();
+
+
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
@@ -406,6 +412,8 @@ public: /* ----- Cell Map public methods ----- */
*/
virtual PRInt32 GetRowCount();
+ virtual PRInt32 GetColCount();
+
nsTableColFrame * GetColFrame(PRInt32 aColIndex);
nsTableCellFrame * GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex);
diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp
index 66b78ca9f0a..4f8a2492eba 100644
--- a/mozilla/layout/tables/nsTableRowFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowFrame.cpp
@@ -464,7 +464,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
// begin special Nav4 compatibility code
if (0==cellWidth)
{
- cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
+ cellWidth = availWidth;
}
// end special Nav4 compatibility code
@@ -537,6 +537,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
nsSize kidAvailSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
// See if there's a width constraint for the cell
+ /*
const nsStylePosition* cellPosition = (const nsStylePosition*)
kidSC->GetStyleData(eStyleStruct_Position);
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
@@ -544,7 +545,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
kidAvailSize.width = cellPosition->mWidth.GetCoordValue();
}
NS_RELEASE(kidSC);
-
+ */
// Get the child's margins
nsMargin margin;
nscoord topMargin = 0;