diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
index 34be3091e71..168b3c0606b 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
@@ -89,39 +89,14 @@ PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosit
PRBool result = PR_FALSE; // assume that it is not fixed width
PRInt32 unitType;
if (nsnull == aStylePosition) {
- unitType = eStyleUnit_Auto;
+ result=PR_TRUE;
}
else {
unitType = aStylePosition->mWidth.GetUnit();
+ if (eStyleUnit_Coord==unitType)
+ result=PR_TRUE;
}
- switch (unitType) {
- case eStyleUnit_Coord:
- result = PR_TRUE;
-
- case eStyleUnit_Auto:
- case eStyleUnit_Proportional:
- case eStyleUnit_Percent:
- break;
-
- // TODO
- case eStyleUnit_Inherit:
- break;
-
- default:
- NS_ASSERTION(PR_FALSE, "illegal style type in IsFixedWidth");
- break;
- }
- return result;
-}
-
-PRBool BasicTableLayoutStrategy::IsAutoWidth(const nsStylePosition* aStylePosition)
-{
- PRBool result = PR_TRUE; // assume that it is
- if (nsnull!=aStylePosition)
- {
- result = (PRBool)(eStyleUnit_Auto==aStylePosition->mWidth.GetUnit());
- }
return result;
}
@@ -132,6 +107,10 @@ BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aFrame, PRInt32
mTableFrame = aFrame;
mNumCols = aNumCols;
+ mMinTableWidth=0;
+ mMaxTableWidth=0;
+ mFixedTableWidth=0;
+
//cache the value of the cols attribute
nsIFrame * tableFrame = mTableFrame;
// begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
@@ -146,93 +125,7 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
{
}
-PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresContext,
- nsIStyleContext *aTableStyle,
- const nsReflowState& aReflowState,
- nscoord aMaxWidth,
- nscoord &aTotalFixedWidth,
- nscoord &aMinTableWidth,
- nscoord &aMaxTableWidth,
- nsSize* aMaxElementSize)
-{
- PRBool result = PR_TRUE;
- // initialize out parameters
- aTotalFixedWidth=aMinTableWidth=aMaxTableWidth=0;
-
- // Step 1 - assign the width of all fixed-width columns
- AssignFixedColumnWidths(aPresContext, aMaxWidth, aTotalFixedWidth, aMinTableWidth, aMaxTableWidth);
-
- if (nsnull!=aMaxElementSize)
- { // this is where we initialize maxElementSize if it is non-null
- aMaxElementSize->height = 0;
- aMaxElementSize->width = aMinTableWidth;
- if (gsDebug) printf(" setting aMaxElementSize->width = %d\n", aMaxElementSize->width);
- }
- else
- {
- if (gsDebug) printf(" nsnull aMaxElementSize\n");
- }
-
- // Step 2 - determine how much space is really available
- PRInt32 availWidth = aMaxWidth - aTotalFixedWidth;
- nscoord tableWidth = 0;
- PRBool tableIsAutoWidth = nsTableFrame::TableIsAutoWidth(mTableFrame, aTableStyle, aReflowState, tableWidth);
- if (PR_FALSE==tableIsAutoWidth)
- availWidth = tableWidth - aTotalFixedWidth;
-
- // Step 3 - assign the width of all proportional-width columns in the remaining space
- if (gsDebug==PR_TRUE) printf ("Step 2...\n availWidth = %d\n", availWidth);
- result = BalanceProportionalColumns(aPresContext, aReflowState,
- availWidth, aMaxWidth,
- aMinTableWidth, aMaxTableWidth,
- tableWidth, tableIsAutoWidth);
- return result;
-}
-
-/*
-STEP 1
-for every col
- if the col has a fixed width
- set the width to max(fixed width, maxElementSize)
- if the cell spans columns, divide the cell width between the columns
- else skip it for now
-
-take borders and padding into account
-
-STEP 2
-determine the min and max size for the table width
-if col is proportionately specified
- if (col width specified to 0)
- col width = minColWidth
- else if (minTableWidth >= aMaxSize.width)
- set col widths to min, install a hor. scroll bar
- else if (maxTableWidth <= aMaxSize.width)
- set each col to its max size
- else
- W = aMaxSize.width - minTableWidth
- D = maxTableWidth - minTableWidth
- for each col
- d = maxColWidth - minColWidth
- col width = minColWidth + ((d*W)/D)
-
-STEP 3
-if there is space left over
- for every col
- if col is proportionately specified
- add space to col width until it is that proportion of the table width
- do this non-destructively in case there isn't enough space
- if there isn't enough space as determined in the prior step,
- add space in proportion to the proportionate width attribute
- */
-
-
-// Step 1 - assign the width of all fixed-width columns,
-// and calculate min/max table width
-PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresContext,
- nscoord aMaxWidth,
- nscoord &aTotalFixedWidth,
- nscoord &aMinTableWidth,
- nscoord &aMaxTableWidth)
+PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
{
#ifdef DEBUG
nsIFrame *tablePIF=nsnull;
@@ -240,18 +133,87 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!");
#endif
- if (gsDebug==PR_TRUE) printf (" AssignFixedColumnWidths\n");
+ PRBool result = PR_TRUE;
+
+ // Step 1 - assign the width of all fixed-width columns
+ AssignPreliminaryColumnWidths();
+
+ // set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
+ if (nsnull!=aMaxElementSize)
+ {
+ aMaxElementSize->height = 0;
+ aMaxElementSize->width = mMinTableWidth;
+ if (PR_TRUE==gsDebug) printf("BTLS::Init setting aMaxElementSize->width = %d\n", aMaxElementSize->width);
+ }
+
+ return result;
+}
+
+PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyle,
+ const nsReflowState& aReflowState,
+ nscoord aMaxWidth)
+{
+#ifdef DEBUG
+ nsIFrame *tablePIF=nsnull;
+ mTableFrame->GetPrevInFlow(tablePIF);
+ NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!");
+#endif
+
+ PRBool result;
+
+ NS_ASSERTION(nsnull!=aTableStyle, "bad arg");
+ if (nsnull==aTableStyle)
+ return PR_FALSE;
+
+
+ nscoord specifiedTableWidth = 0; // not cached as a data member because it can vary depending on aMaxWidth
+ PRBool tableIsAutoWidth = nsTableFrame::TableIsAutoWidth(mTableFrame, aTableStyle, aReflowState, specifiedTableWidth);
+
+ // Step 2 - determine how much space is really available
+ PRInt32 availWidth = aMaxWidth - mFixedTableWidth;
+ if (PR_FALSE==tableIsAutoWidth)
+ availWidth = specifiedTableWidth - mFixedTableWidth;
+
+ // Step 3 - assign the width of all proportional-width columns in the remaining space
+ if (PR_TRUE==gsDebug)
+ {
+ printf ("BalanceColumnWidths with aMaxWidth = %d, availWidth = %d\n", aMaxWidth, availWidth);
+ printf ("\t\t specifiedTW = %d, min/maxTW = %d %d\n", specifiedTableWidth, mMinTableWidth, mMaxTableWidth);
+ }
+ if (PR_TRUE==gsDebug)
+ {
+ printf("\n%p: BEGIN BALANCE COLUMN WIDTHS\n", mTableFrame);
+ for (PRInt32 i=0; iGetColumnWidth(i));
+ printf("\n");
+ }
+ result = BalanceProportionalColumns(aReflowState, availWidth, aMaxWidth,
+ specifiedTableWidth, tableIsAutoWidth);
+
+ if (PR_TRUE==gsDebug)
+ {
+ printf("\n%p: END BALANCE COLUMN WIDTHS\n", mTableFrame);
+ for (PRInt32 i=0; iGetColumnWidth(i));
+ printf("\n");
+ }
+ return result;
+}
+
+// Step 1 - assign the width of all fixed-width columns, all other columns get there max,
+// and calculate min/max table width
+PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
+{
+ if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
nsVoidArray *spanList=nsnull;
nsVoidArray *colSpanList=nsnull;
- nscoord * effectiveColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveColumnWidths, 0, mNumCols*sizeof(PRInt32));
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
- PRInt32 *minColWidthArray = nsnull;
- PRInt32 *maxColWidthArray = nsnull;
+ PRInt32 *minColWidthArray = nsnull; // used for computing the effect of COLS attribute
+ PRInt32 *maxColWidthArray = nsnull; // used for computing the effect of COLS attribute
if (PR_TRUE==hasColsAttribute)
- {
+ {
minColWidthArray = new PRInt32[mNumCols];
maxColWidthArray = new PRInt32[mNumCols];
}
@@ -261,11 +223,10 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
// for every column, determine it's min and max width, and keep track of the table width
for (PRInt32 colIndex = 0; colIndexGetColFrame(colIndex);
@@ -275,22 +236,16 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
- // Get column width if it has one
+ // Get fixed column width if it has one
PRBool haveColWidth = PR_FALSE;
nscoord specifiedFixedColWidth=0;
- switch (colPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- haveColWidth = PR_TRUE;
- specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
- mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth);
- break;
-
- default:
- break;
+ if (eStyleUnit_Coord==colPosition->mWidth.GetUnit())
+ {
+ haveColWidth = PR_TRUE;
+ specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
}
- // TODO - use specifiedFixedColWidth to influence the width when both col span and fixed col width are given
- /* Scan the column, simulatneously assigning fixed column widths
+ /* 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
@@ -301,14 +256,16 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
- if (minColWidth < spanInfo->cellMinWidth)
- minColWidth = spanInfo->cellMinWidth;
- if (maxColWidth < spanInfo->cellDesiredWidth)
- maxColWidth = spanInfo->cellDesiredWidth;
+ 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, spanInfo->cellMinWidth, spanInfo->cellDesiredWidth);
+ spanIndex, spanInfo->span, cellMinWidth, cellDesiredWidth);
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
@@ -318,6 +275,7 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
}
PRInt32 firstRowIndex = -1;
+ PRInt32 maxColSpan = 1;
for (PRInt32 rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
@@ -332,55 +290,52 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
+ PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame);
+ if (colSpan>maxColSpan)
+ maxColSpan = colSpan;
if (colIndex!=cellFrame->GetColIndex()) {
- // For cells that span rows, we only figure it in once
+ // For cells that span cols, we figure in the row using previously-built SpanInfo
NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
continue;
}
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- PRInt32 colSpan = cellFrame->GetColSpan();
+ nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
if (gsDebug==PR_TRUE)
- printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
+ 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);
- switch (colPosition->mWidth.GetUnit())
+ if (PR_TRUE==haveColWidth)
{
- case eStyleUnit_Coord:
- {
- // This col has a fixed width, so set the cell's width to the
- // larger of (specified width, largest max_element_size of the
- // cells in the column)
- nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
- widthForThisCell = widthForThisCell/colSpan;
- nscoord widthFromCol = mTableFrame->GetColumnWidth(colIndex);
- if (widthFromCol < widthForThisCell)
- {
- if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell);
- mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
- maxColWidth = widthForThisCell;
- }
- }
- break;
-
- default:
- break;
-
+ // This col has a specified fixed width so set the minand max width to the larger of
+ // (specified width, largest max_element_size of the cells in the column)
+ nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
+ widthForThisCell = widthForThisCell/colSpan;
+ mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
+ maxColWidth = widthForThisCell;
+ minColWidth = widthForThisCell;
+ if ((1==colSpan) && (effectiveMaxColumnWidth < widthForThisCell))
+ effectiveMaxColumnWidth = widthForThisCell;
+ if (gsDebug)
+ printf (" setting min and max col width to specified fixed width %d\n", widthForThisCell);
+ }
+ else
+ {
+ if (maxColWidth < cellDesiredWidth)
+ maxColWidth = cellDesiredWidth;
+ if ((1==colSpan) && (effectiveMaxColumnWidth < maxColWidth))
+ effectiveMaxColumnWidth = cellDesiredWidth;
}
- // regardless of the width specification, keep track of the
- // min/max column widths
+ // cellMinWidth can override fixed width, so factor it in here
nscoord cellMinWidth = cellMinSize.width/colSpan;
- nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
- if (maxColWidth < cellDesiredWidth)
- maxColWidth = cellDesiredWidth;
- // effectiveColumnWidth is the width as if no cells with colspans existed
- if ((1==colSpan) && (effectiveColumnWidths[colIndex] < maxColWidth))
- effectiveColumnWidths[colIndex] = cellDesiredWidth;
+ // effectiveMinColumnWidth is the min width as if no cells with colspans existed
+ if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth))
+ effectiveMinColumnWidth = cellMinWidth;
if (1GetCellAt(firstRowIndex, colIndex);
- nsMargin colMargin;
- firstCellInColumn->GetMargin(colMargin);
- nscoord colInset = colMargin.left + colMargin.right;
+ nscoord colInset = mTableFrame->GetCellSpacing();
// keep a running total of the amount of space taken up by all fixed-width columns
if (PR_TRUE==haveColWidth)
- aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
-
+ mFixedTableWidth += specifiedFixedColWidth + (colInset*maxColSpan);
if (gsDebug) {
- printf (" after col %d, aTotalFixedWidth = %d\n",
- colIndex, aTotalFixedWidth);
+ printf (" after col %d, mFixedTableWidth = %d\n", colIndex, mFixedTableWidth);
}
+
+ // cache the computed column info
+ colFrame->SetMinColWidth(minColWidth);
+ colFrame->SetMaxColWidth(maxColWidth);
+ colFrame->SetEffectiveMinColWidth(effectiveMinColumnWidth);
+ colFrame->SetEffectiveMaxColWidth(effectiveMaxColumnWidth);
+ mTableFrame->SetColumnWidth(colIndex, maxColWidth);
+
// add col[i] metrics to the running totals for the table min/max width
- if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth)
- aMinTableWidth += minColWidth + colInset;
- if (aMinTableWidth<=0)
- aMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
- if (NS_UNCONSTRAINEDSIZE!=aMaxTableWidth)
- aMaxTableWidth += maxColWidth + colInset;
- if (aMaxTableWidth<=0)
- aMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
+ if (NS_UNCONSTRAINEDSIZE!=mMinTableWidth)
+ mMinTableWidth += minColWidth + colInset;
+ if (mMinTableWidth<=0)
+ mMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
+ if (NS_UNCONSTRAINEDSIZE!=mMaxTableWidth)
+ mMaxTableWidth += maxColWidth + colInset;
+ if (mMaxTableWidth<=0)
+ mMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (PR_TRUE==hasColsAttribute)
{
minColWidthArray[colIndex] = minColWidth;
@@ -430,12 +388,11 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
}
if (gsDebug==PR_TRUE)
printf (" after col %d, minTableWidth = %d and maxTableWidth = %d\n",
- colIndex, aMinTableWidth, aMaxTableWidth);
-
- } // end Step 1 for fixed-width columns
+ colIndex, mMinTableWidth, mMaxTableWidth);
+ }
// now, post-process the computed values based on the table attributes
- // if there is a COLS attribute, fix up aMinTableWidth and aMaxTableWidth
+ // if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth
if (PR_TRUE==hasColsAttribute)
{
// for every effected column, subtract out its prior contribution and add back in the new value
@@ -456,29 +413,31 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
{
// subtract out the prior contributions of this column
// and add back in the adjusted value
- if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth)
+ if (NS_UNCONSTRAINEDSIZE!=mMinTableWidth)
{
- aMinTableWidth -= minColWidthArray[effectedColIndex];
- aMinTableWidth += maxOfMinColWidths;
+ mMinTableWidth -= minColWidthArray[effectedColIndex];
+ mMinTableWidth += maxOfMinColWidths;
}
- if (NS_UNCONSTRAINEDSIZE!=aMaxTableWidth)
+ if (NS_UNCONSTRAINEDSIZE!=mMaxTableWidth)
{
- aMaxTableWidth -= maxColWidthArray[effectedColIndex];
- aMaxTableWidth += maxOfMaxColWidths;
+ mMaxTableWidth -= maxColWidthArray[effectedColIndex];
+ mMaxTableWidth += maxOfMaxColWidths;
}
+ nsTableColFrame *colFrame;
+ mTableFrame->GetColumnFrame(effectedColIndex, colFrame);
+ colFrame->SetMaxColWidth(maxOfMaxColWidths); // cache the new column max width (min width is uneffected)
+ colFrame->SetEffectiveMaxColWidth(maxOfMaxColWidths);
}
delete [] minColWidthArray;
delete [] maxColWidthArray;
}
if (nsnull!=colSpanList)
- DistributeFixedSpace(colSpanList, effectiveColumnWidths);
- // today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
- if (nsnull!=effectiveColumnWidths)
- delete [] effectiveColumnWidths;
+ DistributeFixedSpace(colSpanList);
if (PR_TRUE==gsDebug)
- printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, aMinTableWidth, aMaxTableWidth);
-
+ printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, mMinTableWidth, mMaxTableWidth);
+
+ // clean up
if (nsnull!=spanList)
delete spanList;
if (nsnull!=colSpanList)
@@ -497,10 +456,10 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
// take the fixed space spanned by the columns in aColSpanList
// and distribute it proportionately (based on desired width)
-void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths)
+void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList)
{
nscoord excess = 0;
- if (PR_TRUE==gsDebug) printf ("DistributeFixedSpace:\n");
+ if (PR_TRUE==gsDebug) printf ("** DistributeFixedSpace:\n");
// for all fixed-width columns, determine the amount of the specified width each column spanned recieves
PRInt32 numSpanningCells = aColSpanList->Count();
for (PRInt32 nextSpanningCell=0; nextSpanningCellGetColumnFrame(colIndex+i, colFrame);
+ totalEffectiveWidth += colFrame->GetEffectiveMaxColWidth();
}
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iGetColumnFrame(colIndex+i, colFrame);
float percent;
- percent = ((float)(aColWidths[colIndex+i]))/((float)totalEffectiveWidth);
+ percent = ((float)(colFrame->GetEffectiveMaxColWidth()))/((float)totalEffectiveWidth);
nscoord colWidth = (nscoord)(totalColWidth*percent);
if (gsDebug==PR_TRUE)
printf(" assigning fixed col width for spanning cells: column %d set to %d\n",
colIndex+i, colWidth);
mTableFrame->SetColumnWidth(colIndex+i, colWidth);
+ colFrame->SetMaxColWidth(colWidth);
}
}
}
-PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+/* assign column widths to all non-fixed-width columns (adjusting fixed-width columns if absolutely necessary)
+ aAvailWidth is the amount of space left in the table to distribute after fixed-width columns are accounted for
+ aMaxWidth is the space the parent gave us (minus border & padding) to fit ourselves into
+ aTableIsAutoWidth is true if the table is auto-width, false if it is anything else (percent, fixed, etc)
+ */
+PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
- nscoord aMinTableWidth,
- nscoord aMaxTableWidth,
- nscoord aTableFixedWidth,
+ nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth)
{
PRBool result = PR_TRUE;
- if (0==aTableFixedWidth)
- {
- if (NS_UNCONSTRAINEDSIZE==aMaxWidth || NS_UNCONSTRAINEDSIZE==aMinTableWidth)
- { // the max width of the table fits comfortably in the available space
- if (gsDebug) printf (" * table laying out in NS_UNCONSTRAINEDSIZE, calling BalanceColumnsTableFits\n");
- result = BalanceColumnsTableFits(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aTableFixedWidth, aTableIsAutoWidth);
- }
- else if (aMinTableWidth > aMaxWidth)
- { // the table doesn't fit in the available space
- if (gsDebug) printf (" * min table does not fit, calling SetColumnsToMinWidth\n");
- result = SetColumnsToMinWidth(aPresContext);
- }
- else if (aMaxTableWidth <= aMaxWidth)
- { // the max width of the table fits comfortably in the available space
- if (gsDebug) printf (" * table desired size fits, calling BalanceColumnsTableFits\n");
- result = BalanceColumnsTableFits(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aTableFixedWidth, aTableIsAutoWidth);
- }
- else
- { // the table fits somewhere between its min and desired size
- if (gsDebug) printf (" * table desired size does not fit, calling BalanceColumnsConstrained\n");
- result = BalanceColumnsConstrained(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aMinTableWidth, aMaxTableWidth);
- }
+ nscoord actualMaxWidth; // the real target width, depends on if we're auto or specified width
+ if (PR_TRUE==aTableIsAutoWidth)
+ actualMaxWidth = aMaxWidth;
+ else
+ actualMaxWidth = aTableSpecifiedWidth;
+
+ if (NS_UNCONSTRAINEDSIZE==aMaxWidth || NS_UNCONSTRAINEDSIZE==mMinTableWidth)
+ { // the max width of the table fits comfortably in the available space
+ if (gsDebug) printf (" * auto table laying out in NS_UNCONSTRAINEDSIZE, calling BalanceColumnsTableFits\n");
+ result = BalanceColumnsTableFits(aReflowState, aAvailWidth,
+ aMaxWidth, aTableSpecifiedWidth, aTableIsAutoWidth);
+ }
+ else if (mMinTableWidth > actualMaxWidth)
+ { // the table doesn't fit in the available space
+ if (gsDebug) printf (" * auto table minTW does not fit, calling SetColumnsToMinWidth\n");
+ result = SetColumnsToMinWidth();
+ }
+ else if (mMaxTableWidth <= actualMaxWidth)
+ { // the max width of the table fits comfortably in the available space
+ if (gsDebug) printf (" * auto table desired size fits, calling BalanceColumnsTableFits\n");
+ result = BalanceColumnsTableFits(aReflowState, aAvailWidth,
+ aMaxWidth, aTableSpecifiedWidth, aTableIsAutoWidth);
}
else
- { // tables with fixed-width have their own rules
- if (NS_UNCONSTRAINEDSIZE==aMinTableWidth)
- { // the table has empty content, and needs to be streched to the specified width
- if (gsDebug) printf (" * specified width table > maxTableWidth, calling BalanceColumnsTableFits\n");
- result = BalanceColumnsTableFits(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aTableFixedWidth, aTableIsAutoWidth);
- }
- else if ((aTableFixedWidth= its max width, so give each column its max requested size
- if (gsDebug) printf (" * specified width table > maxTableWidth, calling BalanceColumnsTableFits\n");
- result = BalanceColumnsTableFits(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aTableFixedWidth, aTableIsAutoWidth);
- }
+ { // the table fits somewhere between its min and desired size
+ if (gsDebug) printf (" * auto table desired size does not fit, calling BalanceColumnsConstrained\n");
+ result = BalanceColumnsConstrained(aReflowState, aAvailWidth,
+ actualMaxWidth);
}
+
return result;
}
-PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresContext)
+// the table doesn't fit, so squeeze every column down to its minimum
+PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth()
{
PRBool result = PR_TRUE;
@@ -626,48 +569,21 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
{
- for (PRInt32 rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
- if (nsnull==cellFrame)
- { // there is no cell in this row that corresponds to this column
- continue;
- }
- if (rowIndex!=cellFrame->GetRowIndex()) {
- // For cells that span rows, we only figure it in once
- NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
- continue;
- }
-
- nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
- PRInt32 colSpan = cellFrame->GetColSpan();
- nscoord cellMinWidth = cellMinSize.width/colSpan;
- if (minColWidth < cellMinWidth)
- minColWidth = cellMinWidth;
- }
+ minColWidth = colFrame->GetMinColWidth();
+ mTableFrame->SetColumnWidth(colIndex, minColWidth);
if (PR_TRUE==hasColsAttribute)
{
minColWidthArray[colIndex] = minColWidth;
}
-
- if (gsDebug==PR_TRUE)
- {
- printf (" for determining width of col %d %s:\n",
- colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)");
- printf (" minColWidth = %d\n", minColWidth);
- }
-
- mTableFrame->SetColumnWidth(colIndex, minColWidth);
- if (gsDebug==PR_TRUE)
- printf (" 2: col %d, set to width = %d\n", colIndex, mTableFrame->GetColumnWidth(colIndex));
}
+ if (gsDebug==PR_TRUE)
+ printf (" 2: col %d, set to width = %d\n", colIndex, mTableFrame->GetColumnWidth(colIndex));
}
// now, post-process the computed values based on the table attributes
- // if there is a COLS attribute, fix up aMinTableWidth and aMaxTableWidth
+ // if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth
if (PR_TRUE==hasColsAttribute)
- {
- // for every effected column, subtract out its prior contribution and add back in the new value
+ { // for every effected column, subtract out its prior contribution and add back in the new value
PRInt32 numColsEffected = mNumCols;
if (NS_STYLE_TABLE_COLS_ALL!=mCols)
numColsEffected = mCols;
@@ -686,40 +602,34 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
if (PR_TRUE==gsDebug)
printf(" 2 (cols): setting %d to %d\n", effectedColIndex, maxOfEffectedColWidths);
}
+ // we're guaranteed here that minColWidthArray has been allocated, and that
+ // if we don't get here, it was never allocated
delete [] minColWidthArray;
}
-
-
return result;
}
-PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+/* the table fits in the given space. Set all columns to their desired width,
+ * and if we are not an auto-width table add extra space to fluff out the total width
+ */
+PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
- nscoord aTableFixedWidth,
+ nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth)
{
-#ifdef DEBUG
- nsIFrame *tablePIF=nsnull;
- mTableFrame->GetPrevInFlow(tablePIF);
- NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!");
-#endif
-
PRBool result = PR_TRUE;
nscoord tableWidth=0; // the width of the table as a result of setting column widths
- nscoord widthOfFixedTableColumns=0; // the sum of the width of all fixed-width columns
+ nscoord widthOfFixedTableColumns=0; // the sum of the width of all fixed-width columns plus margins
// tableWidth - widthOfFixedTableColumns is the width of columns computed in this method
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
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
- nscoord * effectiveColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveColumnWidths, 0, mNumCols*sizeof(PRInt32));
PRInt32 numRows = mTableFrame->GetRowCount();
for (PRInt32 colIndex = 0; colIndexGetCellAt(rowIndex, colIndex);
- if (nsnull!=firstCellInColumn)
- break;
- }
- nsMargin colMargin;
- nscoord colInset = 0;
- if (nsnull!=firstCellInColumn)
- {
- firstCellInColumn->GetMargin(colMargin);
- colInset = colMargin.left + colMargin.right;
- }
+ nscoord colInset = mTableFrame->GetCellSpacing();
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
@@ -784,43 +681,30 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
+ if (colIndex!=cellFrame->GetColIndex()) {
+ // For cells that span cols, we figure in the row using previously-built SpanInfo
+ NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
+ continue;
+ }
- PRInt32 colSpan = cellFrame->GetColSpan();
+ 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();
- PRInt32 cellMinWidth = cellMinSize.width/colSpan;
+ nscoord cellMinWidth = cellMinSize.width/colSpan;
// first get the desired size info from reflow pass 1
- PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
+ nscoord 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, (const nsStyleStruct*&)cellPosition);
- switch (cellPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
- if (gsDebug) printf("cell has specified coord width = %d\n", specifiedCellWidth);
- break;
-
- case eStyleUnit_Percent:
- {
- nscoord tableWidth=0;
- nsIStyleContextPtr tableSC;
- mTableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
- PRBool tableIsAutoWidth = nsTableFrame::TableIsAutoWidth(mTableFrame, tableSC, aReflowState, tableWidth);
- float percent = cellPosition->mWidth.GetPercentValue();
- specifiedCellWidth = (PRInt32)(tableWidth*percent);
- if (gsDebug) printf("specified percent width %f of %d = %d\n",
- percent, tableWidth, specifiedCellWidth);
- break;
- }
-
- case eStyleUnit_Inherit:
- // XXX for now, do nothing
- default:
- case eStyleUnit_Auto:
- break;
+ 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)
{
@@ -828,7 +712,8 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
{
if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
cellDesiredWidth, specifiedCellWidth/colSpan);
- cellDesiredWidth = specifiedCellWidth/colSpan; // TODO: some math needed here for colspans
+ cellDesiredWidth = specifiedCellWidth/colSpan;
+ //QQQ should be proportionately distributed as a post-process
}
}
@@ -839,13 +724,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
minColWidth = cellMinWidth;
if (maxColWidth < cellDesiredWidth)
maxColWidth = cellDesiredWidth;
- // effectiveColumnWidth is the width as if no cells with colspans existed
- if ((1==colSpan) && (effectiveColumnWidths[colIndex] < maxColWidth))
- effectiveColumnWidths[colIndex] = cellDesiredWidth;
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
rowIndex, minColWidth, maxColWidth,
- colIndex, effectiveColumnWidths[colIndex]);
+ 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);
@@ -853,7 +735,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
spanList = new nsVoidArray();
spanList->AppendElement(spanInfo);
}
- }
+ } // end looping through cells in the column
if (gsDebug==PR_TRUE)
{
@@ -869,10 +751,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
nscoord specifiedFixedColumnWidth = -1;
PRBool isAutoWidth = PR_FALSE;
switch (colPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedFixedColumnWidth = colPosition->mWidth.GetCoordValue();
- if (gsDebug) printf("column %d has specified coord width = %d\n", colIndex, specifiedFixedColumnWidth);
- break;
case eStyleUnit_Percent:
specifiedPercentageColWidth = colPosition->mWidth.GetPercentValue();
if (gsDebug) printf("column %d has specified percent width = %f\n", colIndex, specifiedPercentageColWidth);
@@ -927,16 +805,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional: col %d with availWidth %d, gets %d slices with %d slices so far.\n",
colIndex, aAvailWidth, specifiedProportionColumnWidth, totalSlices);
}
- else if (-1!=specifiedFixedColumnWidth)
- { // the column has a specified pixel width
- // if the column was computed to be too small, enlarge the column
- nscoord resolvedWidth = specifiedFixedColumnWidth;
- if (specifiedFixedColumnWidth <= minColWidth)
- resolvedWidth = minColWidth;
- mTableFrame->SetColumnWidth(colIndex, resolvedWidth);
- if (gsDebug==PR_TRUE)
- printf (" 3 fixed: col %d given %d\n", colIndex, resolvedWidth);
- }
else
{ // give the column a percentage of the remaining space
PRInt32 percentage = -1;
@@ -950,10 +818,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
{
percentage = (PRInt32)(specifiedPercentageColWidth*100.0f); // TODO: rounding errors?
// base the % on the total specified fixed width of the table
- mTableFrame->SetColumnWidth(colIndex, (percentage*aTableFixedWidth)/100);
+ mTableFrame->SetColumnWidth(colIndex, (percentage*aTableSpecifiedWidth)/100);
if (gsDebug==PR_TRUE)
- printf (" 3 percent specified: col %d given %d percent of aTableFixedWidth %d, set to width = %d\n",
- colIndex, percentage, aTableFixedWidth, mTableFrame->GetColumnWidth(colIndex));
+ printf (" 3 percent specified: col %d given %d percent of aTableSpecifiedWidth %d, set to width = %d\n",
+ colIndex, percentage, aTableSpecifiedWidth, mTableFrame->GetColumnWidth(colIndex));
}
if (-1==percentage)
{
@@ -975,7 +843,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
else
{ // need to maintain this so we know how much we have left over at the end
- widthOfFixedTableColumns += mTableFrame->GetColumnWidth(colIndex) + colInset;
+ widthOfFixedTableColumns += colFrame->GetMaxColWidth() + colInset;
}
tableWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
}
@@ -985,7 +853,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
if (nsnull!=proportionalColumnsList)
{
// first, figure out the amount of space per slice
- nscoord maxWidthForTable = (0!=aTableFixedWidth) ? aTableFixedWidth : aMaxWidth;
+ nscoord maxWidthForTable = (0!=aTableSpecifiedWidth) ? aTableSpecifiedWidth : aMaxWidth;
if (NS_UNCONSTRAINEDSIZE!=maxWidthForTable)
{
nscoord widthRemaining = maxWidthForTable - tableWidth;
@@ -1001,7 +869,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional step 2: col %d given %d proportion of remaining space %d, set to width = %d\n",
info->mColIndex, info->mProportion, widthRemaining, computedColWidth);
tableWidth += computedColWidth;
- effectiveColumnWidths[info->mColIndex] = computedColWidth;
+// effectiveColumnWidth = computedColWidth;
delete info;
}
}
@@ -1026,7 +894,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional step 2 (unconstrained!): col %d set to width = %d\n",
info->mColIndex, maxOfMaxColWidths);
tableWidth += maxOfMaxColWidths;
- effectiveColumnWidths[info->mColIndex] = maxOfMaxColWidths;
+ nsTableColFrame *colFrame;
+ mTableFrame->GetColumnFrame(info->mColIndex, colFrame);
+ colFrame->SetEffectiveMaxColWidth(maxOfMaxColWidths);
delete info;
}
}
@@ -1038,11 +908,8 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
// columns if possible.
if ((PR_FALSE==aTableIsAutoWidth) && (aAvailWidth > (tableWidth-widthOfFixedTableColumns)))
{
- DistributeExcessSpace(aAvailWidth, tableWidth, widthOfFixedTableColumns, effectiveColumnWidths);
+ DistributeExcessSpace(aAvailWidth, tableWidth, widthOfFixedTableColumns);
}
- // today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
- if (nsnull!=effectiveColumnWidths)
- delete [] effectiveColumnWidths;
if (nsnull!=spanList)
delete spanList;
return result;
@@ -1052,12 +919,12 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
// give extra space to auto-width cells first, or if there are none to all cells
void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
nscoord aTableWidth,
- nscoord aWidthOfFixedTableColumns,
- nscoord *aColWidths)
+ nscoord aWidthOfFixedTableColumns)
{
nscoord excess = 0;
if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d, woftc=%d\n",
aAvailWidth, aTableWidth, aWidthOfFixedTableColumns);
+ nscoord widthMinusFixedColumns = aTableWidth - aWidthOfFixedTableColumns;
// if there are auto-sized columns, give them the extra space
// the trick here is to do the math excluding non-auto width columns
PRInt32 numAutoColumns=0;
@@ -1065,7 +932,6 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0!=numAutoColumns)
{
- nscoord computedTableWidth = aTableWidth - aWidthOfFixedTableColumns;
// 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;
@@ -1075,27 +941,35 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
PRInt32 i;
for (i = 0; iGetColumnFrame(autoColumns[i], colFrame);
+ nscoord effectiveColWidth = colFrame->GetEffectiveMaxColWidth();
+ if (0!=effectiveColWidth)
+ totalEffectiveWidthOfAutoColumns += effectiveColWidth;
else
totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
}
- excess = aAvailWidth - computedTableWidth;
+ // excess is the amount of space that was available minus the computed available width
+ // QQQ shouldn't it just be aMaxWidth - aTableWidth???
+ excess = aAvailWidth - widthMinusFixedColumns;
+
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iGetColumnWidth(colIndex);//aColWidths[colIndex];
+ nsTableColFrame *colFrame;
+ mTableFrame->GetColumnFrame(colIndex, colFrame);
+ nscoord oldColWidth = mTableFrame->GetColumnWidth(colIndex);
float percent;
if (0!=totalEffectiveWidthOfAutoColumns)
- percent = ((float)(aColWidths[colIndex]))/((float)totalEffectiveWidthOfAutoColumns);
+ percent = ((float)(colFrame->GetEffectiveMaxColWidth()))/((float)totalEffectiveWidthOfAutoColumns);
else
percent = ((float)1)/((float)numAutoColumns);
nscoord excessForThisColumn = (nscoord)(excess*percent);
nscoord colWidth = excessForThisColumn+oldColWidth;
if (gsDebug==PR_TRUE)
printf(" distribute excess to auto columns: column %d was %d, now set to %d\n",
- colIndex, aColWidths[colIndex], colWidth);
+ colIndex, oldColWidth, colWidth);
mTableFrame->SetColumnWidth(colIndex, colWidth);
}
}
@@ -1103,13 +977,13 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
// (they must be all fixed and percentage-width columns, or we would have gone into the block above)
else
{
- excess = aAvailWidth - (aTableWidth-aWidthOfFixedTableColumns);
+ excess = aAvailWidth - widthMinusFixedColumns;
if (gsDebug==PR_TRUE)
printf(" aAvailWidth specified as %d, expanding columns by excess = %d\n",
aAvailWidth, excess);
for (PRInt32 colIndex = 0; colIndexGetColumnWidth(colIndex);
float percent;
@@ -1127,15 +1001,11 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
}
}
-/* this method is very similar to BalanaceColumnsTableFits, but there are enough
- * subtle differences that code reuse is impractical. it's a shame.
+/* assign columns widths for a table whose max size doesn't fit in the available space
*/
-PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState& aReflowState,
nscoord aAvailWidth,
- nscoord aMaxWidth,
- nscoord aMinTableWidth,
- nscoord aMaxTableWidth)
+ nscoord aMaxWidth)
{
#ifdef DEBUG
nsIFrame *tablePIF=nsnull;
@@ -1145,17 +1015,14 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
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=0; // the width of the table as a result of setting column widths
+ 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
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
// proportional-width columns are equal (if any are anything other than 1)
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
- nscoord * effectiveMaxColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveMaxColumnWidths, 0, mNumCols*sizeof(PRInt32));
- nscoord * effectiveMinColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveMinColumnWidths, 0, mNumCols*sizeof(PRInt32));
PRInt32 numRows = mTableFrame->GetRowCount();
for (PRInt32 colIndex = 0; colIndexGetCellAt(rowIndex, colIndex);
- if (nsnull!=firstCellInColumn)
- break;
- }
- nsMargin colMargin;
- nscoord colInset = 0;
- if (nsnull!=firstCellInColumn)
- {
- firstCellInColumn->GetMargin(colMargin);
- colInset = colMargin.left + colMargin.right;
- }
+ nscoord colInset = mTableFrame->GetCellSpacing();
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
@@ -1224,8 +1078,13 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
+ if (colIndex!=cellFrame->GetColIndex()) {
+ // For cells that span cols, we figure in the row using previously-built SpanInfo
+ NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
+ continue;
+ }
- PRInt32 colSpan = cellFrame->GetColSpan();
+ PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame);
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
@@ -1237,29 +1096,15 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
const nsStylePosition* cellPosition;
cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition);
switch (cellPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
- if (gsDebug) printf("cell has specified coord width = %d\n", specifiedCellWidth);
- break;
-
case eStyleUnit_Percent:
{
nscoord knownTableWidth=0;
- nsIStyleContextPtr tableSC;
- mTableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
- PRBool tableIsAutoWidth = nsTableFrame::TableIsAutoWidth(mTableFrame, tableSC, aReflowState, knownTableWidth);
float percent = cellPosition->mWidth.GetPercentValue();
- specifiedCellWidth = (PRInt32)(knownTableWidth*percent);
+ specifiedCellWidth = (PRInt32)(aMaxWidth*percent);
if (gsDebug) printf("specified percent width %f of %d = %d\n",
- percent, knownTableWidth, specifiedCellWidth);
+ percent, aMaxWidth, specifiedCellWidth);
break;
}
-
- case eStyleUnit_Inherit:
- // XXX for now, do nothing
- default:
- case eStyleUnit_Auto:
- break;
}
if (-1!=specifiedCellWidth)
{
@@ -1277,19 +1122,16 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
// remember the widest min cell width
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
- // effectiveMinColumnWidth is the width as if no cells with colspans existed
- if ((1==colSpan) && (effectiveMinColumnWidths[colIndex] < minColWidth))
- effectiveMinColumnWidths[colIndex] = cellMinWidth;
// remember the max desired cell width
if (maxColWidth < cellDesiredWidth)
maxColWidth = cellDesiredWidth;
// effectiveMaxColumnWidth is the width as if no cells with colspans existed
- if ((1==colSpan) && (effectiveMaxColumnWidths[colIndex] < maxColWidth))
- effectiveMaxColumnWidths[colIndex] = cellDesiredWidth;
+ if ((1==colSpan) && (colFrame->GetEffectiveMaxColWidth() < maxColWidth))
+ colFrame->SetEffectiveMaxColWidth(cellDesiredWidth);
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
rowIndex, minColWidth, maxColWidth,
- colIndex, effectiveMaxColumnWidths[colIndex], effectiveMaxColumnWidths[colIndex]);
+ 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
@@ -1305,10 +1147,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
printf (" for determining width of col %d %s:\n",
colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)");
printf (" minTableWidth = %d and maxTableWidth = %d\n",
- aMinTableWidth, aMaxTableWidth);
+ mMinTableWidth, mMaxTableWidth);
printf (" minColWidth = %d, maxColWidth = %d, eff=%d,%d\n",
- minColWidth, maxColWidth, effectiveMinColumnWidths[colIndex],
- effectiveMaxColumnWidths[colIndex]);
+ minColWidth, maxColWidth, colFrame->GetEffectiveMinColWidth(),
+ colFrame->GetEffectiveMaxColWidth());
printf (" aAvailWidth = %d\n", aAvailWidth);
}
@@ -1318,10 +1160,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
nscoord specifiedFixedColumnWidth = -1;
PRBool isAutoWidth = PR_FALSE;
switch (colPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedFixedColumnWidth = colPosition->mWidth.GetCoordValue();
- if (gsDebug) printf("column %d has specified coord width = %d\n", colIndex, specifiedFixedColumnWidth);
- break;
case eStyleUnit_Percent:
specifiedPercentageColWidth = colPosition->mWidth.GetPercentValue();
if (gsDebug) printf("column %d has specified percent width = %f\n", colIndex, specifiedPercentageColWidth);
@@ -1379,16 +1217,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
if (1!=specifiedProportionColumnWidth)
equalWidthColumns = PR_FALSE;
}
- else if (-1!=specifiedFixedColumnWidth)
- { // the column has a specified pixel width
- // if the column was computed to be too small, enlarge the column
- nscoord resolvedWidth = specifiedFixedColumnWidth;
- if (specifiedFixedColumnWidth <= minColWidth)
- resolvedWidth = minColWidth;
- mTableFrame->SetColumnWidth(colIndex, resolvedWidth);
- if (gsDebug==PR_TRUE)
- printf (" 4 fixed: col %d given %d\n", colIndex, resolvedWidth);
- }
else
{ // give the column a percentage of the remaining space
PRInt32 percentage = -1;
@@ -1430,14 +1258,30 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
}
}
+ tableWidth += mTableFrame->GetColumnWidth(colIndex);
}
}
/* --- 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, effectiveMinColumnWidths, effectiveMaxColumnWidths);
+ DistributeRemainingSpace(aAvailWidth, tableWidth);
}
- // second, assign a width to proportional-width columns
+
+ // 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);
+ }
+ if (computedWidthaMaxWidth) {
+ AdjustTableThatIsTooWide(computedWidth, aMaxWidth);
+ }
+
+
+ // finally, assign a width to proportional-width columns
if (nsnull!=proportionalColumnsList)
{
// first, figure out the amount of space per slice
@@ -1469,11 +1313,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
// clean up
- // today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
- if (nsnull!=effectiveMinColumnWidths)
- delete [] effectiveMinColumnWidths;
- if (nsnull!=effectiveMaxColumnWidths)
- delete [] effectiveMaxColumnWidths;
if (nsnull!=spanList)
{
NS_ASSERTION(0==spanList->Count(), "space leak, span list not empty");
@@ -1486,20 +1325,18 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
//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 aTableFixedWidth,
- nscoord aComputedTableWidth,
- nscoord *aMinColWidths,
- nscoord *aMaxColWidths)
+void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecifiedWidth,
+ nscoord aComputedTableWidth)
{
if (PR_TRUE==gsDebug)
printf ("DistributeRemainingSpace: fixed width %d > computed table width %d\n",
- aTableFixedWidth, aComputedTableWidth);
+ aTableSpecifiedWidth, aComputedTableWidth);
// if there are auto-sized columns, give them the extra space
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
// availWidth is the difference between the total available width and the
// amount of space already assigned, assuming auto col widths were assigned 0.
- nscoord availWidth = aTableFixedWidth - aComputedTableWidth;
+ nscoord availWidth = aTableSpecifiedWidth - aComputedTableWidth;
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0!=numAutoColumns)
{
@@ -1510,37 +1347,67 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableFixedWidt
PRInt32 i;
for (i = 0; iGetColFrame(autoColumns[i]);
+ nscoord maxEffectiveColWidth = colFrame->GetEffectiveMaxColWidth();
+ if (0!=maxEffectiveColWidth)
+ totalEffectiveWidthOfAutoColumns += maxEffectiveColWidth;
else
totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
}
if (gsDebug==PR_TRUE)
- printf(" aTableFixedWidth specified as %d, availWidth is = %d\n",
- aTableFixedWidth, availWidth);
+ printf(" aTableSpecifiedWidth specified as %d, availWidth is = %d\n",
+ aTableSpecifiedWidth, availWidth);
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iSetColumnWidth(colIndex, colWidth);
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ // 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
+ if (0GetEffectiveMaxColWidth()))/((float)totalEffectiveWidthOfAutoColumns);
+ else
+ percent = ((float)1)/((float)numAutoColumns);
+ nscoord colWidth = (nscoord)(availWidth*percent);
+ 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);
+ }
}
- EnsureCellMinWidths(aMinColWidths);
+
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf ("before EnsureCellMinWidth, computed table width is %d\n",tableWidth);
+ }
+
+ EnsureCellMinWidths();
+ }
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf ("after EnsureCellMinWidth, computed table width is %d\n",tableWidth);
}
}
-void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
+void BasicTableLayoutStrategy::EnsureCellMinWidths()
{
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);
+ */
while (PR_TRUE==atLeastOne)
{
atLeastOne=PR_FALSE;
@@ -1549,11 +1416,13 @@ void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
// first, bump up cells that are below their min to their min width
for (colIndex=0; colIndexGetColFrame(colIndex);
+ nscoord minEffectiveColWidth = colFrame->GetEffectiveMinColWidth();
nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if (colWidthSetColumnWidth(colIndex, aMinColWidths[colIndex]);
+ addedWidth += (minEffectiveColWidth-colWidth);
+ mTableFrame->SetColumnWidth(colIndex, minEffectiveColWidth);
atLeastOne=PR_TRUE;
}
}
@@ -1561,21 +1430,93 @@ void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
//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 minEffectiveColWidth = colFrame->GetEffectiveMinColWidth();
nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if (colWidth>aMinColWidths[colIndex])
+ if (colWidth>minEffectiveColWidth)
{
mTableFrame->SetColumnWidth(colIndex, colWidth-1);
addedWidth--;
+ if (0==addedWidth)
+ { // we're run out of extra space
+ break; // for (colIndex=0; colIndex0))
+ }
}
if (0GetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
+ nscoord excess = aComputedWidth - aTableWidth;
+ if (0GetColumnWidth(colIndex);
+ colWidth -= excessPerColumn;
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ if (colWidth > colFrame->GetEffectiveMinColWidth())
+ mTableFrame->SetColumnWidth(colIndex, colWidth);
+ else
+ mTableFrame->SetColumnWidth(colIndex, colFrame->GetEffectiveMinColWidth());
+ }
+ }
+ }
+}
+
+void BasicTableLayoutStrategy::AdjustTableThatIsTooNarrow(nscoord aComputedWidth,
+ nscoord aTableWidth)
+{
+ PRInt32 numFixedColumns=0;
+ PRInt32 *fixedColumns=nsnull;
+ //XXX todo: exclude fixed width columns
+ //mTableFrame->GetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
+ nscoord excess = aTableWidth - aComputedWidth;
+ if (0GetColumnWidth(colIndex);
+ colWidth += excessPerColumn;
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ if (colWidth >colFrame->GetEffectiveMinColWidth())
+ mTableFrame->SetColumnWidth(colIndex, colWidth);
+ else
+ mTableFrame->SetColumnWidth(colIndex, colFrame->GetEffectiveMinColWidth());
+ }
+ }
+ }
+}
+
+//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 1bca0687baf..0ea87b4d5ca 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
@@ -31,20 +31,24 @@ struct nsStylePosition;
struct SpanInfo
{
- nscoord span;
+ PRInt32 span;
+ const PRInt32 initialColSpan;
nscoord cellMinWidth;
nscoord cellDesiredWidth;
- SpanInfo(nscoord aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
- {
- span = aSpan;
- cellMinWidth = aMinWidth;
- cellDesiredWidth = aDesiredWidth;
- };
-
+ SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth);
~SpanInfo() {};
};
+inline SpanInfo::SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
+ : initialColSpan(aSpan)
+{
+ span = aSpan;
+ cellMinWidth = aMinWidth;
+ cellDesiredWidth = aDesiredWidth;
+}
+
+
/* ---------- BasicTableLayoutStrategy ---------- */
@@ -60,86 +64,69 @@ public:
~BasicTableLayoutStrategy();
- virtual PRBool BalanceColumnWidths(nsIPresContext* aPresContext,
- nsIStyleContext *aTableStyle,
- const nsReflowState& aReflowState,
- nscoord aMaxWidth,
- nscoord &aTotalFixedWidth,
- nscoord &aMinTableWidth,
- nscoord &aMaxTableWidth,
- nsSize* aMaxElementSize);
+ /** call once every time any table thing changes (content, structure, or style) */
+ virtual PRBool Initialize(nsSize* aMaxElementSize);
- /** assign widths for each column that has fixed width.
+ virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle,
+ const nsReflowState& aReflowState,
+ nscoord aMaxWidth);
+
+ /** assign widths for each column.
+ * if the column has a fixed coord width, use it.
+ * if the column includes col spanning cells,
+ * then distribute the fixed space between cells proportionately.
* Computes the minimum and maximum table widths.
- * Sets mColumnWidths as a side effect.
- *
- * @param aPresContext the presentation context
- * @param aMaxWidth the maximum width of the table
- * @param aTableStyle the resolved style for the table
- * @param aTotalFixedWidth out param, the sum of the fixed width columns
- * @param aMinTableWidth out param, the min possible table width
- * @param aMaxTableWidth out param, the max table width
+ * Set column width information in each column frame and in the table frame.
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
- * TODO: should be renamed to "AssignKnownWidthInformation
*/
- virtual PRBool AssignFixedColumnWidths(nsIPresContext* aPresContext,
- nscoord aMaxWidth,
- nscoord & aTotalFixedWidth,
- nscoord & aMinTableWidth,
- nscoord & aMaxTableWidth);
+ virtual PRBool AssignPreliminaryColumnWidths();
/** assign widths for each column that has proportional width inside a table that
* has auto width (width set by the content and available space.)
* Sets mColumnWidths as a side effect.
*
- * @param aPresContext the presentation context
- * @param aTableStyle the resolved style for the table
- * @param aAvailWidth the remaining amount of horizontal space available
- * @param aMaxWidth the total amount of horizontal space available
- * @param aMinTableWidth the min possible table width
- * @param aMaxTableWidth the max table width
+ * @param aTableStyle the resolved style for the table
+ * @param aAvailWidth the remaining amount of horizontal space available
+ * @param aMaxWidth the total amount of horizontal space available
+ * @param aTableSpecifiedWidth the width of the table based on its attributes and its parent's width
+ * @param aTableIsAutoWidth PR_TRUE if the table is auto-width
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
*/
- virtual PRBool BalanceProportionalColumns(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+ virtual PRBool BalanceProportionalColumns(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
- nscoord aMinTableWidth,
- nscoord aMaxTableWidth,
- nscoord aTableFixedWidth,
+ nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth);
/** assign the minimum allowed width for each column that has proportional width.
* Typically called when the min table width doesn't fit in the available space.
* Sets mColumnWidths as a side effect.
*
- * @param aPresContext the presentation context
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*/
- virtual PRBool SetColumnsToMinWidth(nsIPresContext* aPresContext);
+ virtual PRBool SetColumnsToMinWidth();
/** assign the maximum allowed width for each column that has proportional width.
* Typically called when the desired max table width fits in the available space.
* Sets mColumnWidths as a side effect.
*
- * @param aPresContext the presentation context
- * @param aAvailWidth the remaining amount of horizontal space available
- * @param aMaxWidth the total amount of horizontal space available
- * @param aTableFixedWidth the specified width of the table. If there is none,
- * this param is 0
+ * @param aAvailWidth the remaining amount of horizontal space available
+ * @param aMaxWidth the total amount of horizontal space available
+ * @param aTableSpecifiedWidth the specified width of the table. If there is none,
+ * this param is 0
+ * @param aTableIsAutoWidth PR_TRUE if the table is auto-width
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*/
- virtual PRBool BalanceColumnsTableFits(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+ virtual PRBool BalanceColumnsTableFits(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
- nscoord aTableFixedWidth,
+ nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth);
/** assign widths for each column that has proportional width inside a table that
@@ -147,7 +134,6 @@ public:
* HTML 4 specification.
* Sets mColumnWidths as a side effect.
*
- * @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
@@ -158,23 +144,19 @@ public:
*
* TODO: rename this method to reflect that it is a Nav4 compatibility method
*/
- virtual PRBool BalanceColumnsConstrained(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+ virtual PRBool BalanceColumnsConstrained(const nsReflowState& aReflowState,
nscoord aAvailWidth,
- nscoord aMaxWidth,
- nscoord aMinTableWidth,
- nscoord aMaxTableWidth);
+ nscoord aMaxWidth);
/** post-process to AssignFixedColumnWidths
*
* @param aColSpanList a list of fixed-width columns that have colspans
- * @param aColWidths the effective column widths (ignoring col span cells)
*
* NOTE: does not yet properly handle overlapping col spans
*
* @return void
*/
- virtual void DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths);
+ virtual void DistributeFixedSpace(nsVoidArray *aColSpanList);
/** starting with a partially balanced table, compute the amount
* of space to pad each column by to completely balance the table.
@@ -189,8 +171,7 @@ public:
*/
virtual void DistributeExcessSpace(nscoord aAvailWidth,
nscoord aTableWidth,
- nscoord aWidthOfFixedTableColumns,
- nscoord *aColWidths);
+ nscoord aWidthOfFixedTableColumns);
/** starting with a partially balanced table, compute the amount
* of space to remove from each column to completely balance the table.
@@ -203,14 +184,18 @@ public:
* @return void
*/
virtual void DistributeRemainingSpace(nscoord aTableFixedWidth,
- nscoord aComputedTableWidth,
- nscoord *aMinColWidths,
- nscoord *aMaxColWidths);
+ nscoord aComputedTableWidth);
/** 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(nscoord *aMinColWidths);
+ virtual void EnsureCellMinWidths();
+
+ virtual void AdjustTableThatIsTooWide(nscoord aComputedWidth,
+ nscoord aTableWidth);
+
+ virtual void AdjustTableThatIsTooNarrow(nscoord aComputedWidth,
+ nscoord aTableWidth);
/** return true if the style indicates that the width is a specific width
* for the purposes of column width determination.
@@ -218,12 +203,15 @@ public:
*/
virtual PRBool IsFixedWidth(const nsStylePosition* aStylePosition);
- virtual PRBool IsAutoWidth(const nsStylePosition* aStylePosition);
protected:
nsTableFrame * mTableFrame;
PRInt32 mCols;
PRInt32 mNumCols;
+ // cached data
+ nscoord mMinTableWidth; // the absolute smallest width for the table
+ nscoord mMaxTableWidth; // the "natural" size for the table, if unconstrained
+ nscoord mFixedTableWidth; // the amount of space taken up by fixed-width columns
};
diff --git a/mozilla/layout/html/table/src/nsITableLayoutStrategy.h b/mozilla/layout/html/table/src/nsITableLayoutStrategy.h
index 861aa290f3b..543235dbf91 100644
--- a/mozilla/layout/html/table/src/nsITableLayoutStrategy.h
+++ b/mozilla/layout/html/table/src/nsITableLayoutStrategy.h
@@ -22,7 +22,6 @@
#include "nscore.h"
#include "nsSize.h"
-class nsIPresContext;
class nsIStyleContext;
struct nsReflowState;
@@ -30,25 +29,21 @@ class nsITableLayoutStrategy
{
public:
+ /** call once every time any table thing changes (content, structure, or style)
+ * @param aMaxElementSize [OUT] the min possible size of the table
+ */
+ virtual PRBool Initialize(nsSize* aMaxElementSize)=0;
+
/** assign widths for each column, taking into account the table content, the effective style,
* the layout constraints, and the compatibility mode. Sets mColumnWidths as a side effect.
- * @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aReflowState the reflow state for the calling table frame
* @param aMaxWidth the width constraint
- * @param aTotalFixedWidth [OUT] the computed fixed width of the table
- * @param aMinTableWidth [OUT] the computed min width of the table
- * @param aMinTableWidth [OUT] the computed max width of the table
- * @param aMaxElementSize [OUT] the min size of the largest indivisible object
+
*/
- virtual PRBool BalanceColumnWidths(nsIPresContext* aPresContext,
- nsIStyleContext *aTableStyle,
+ virtual PRBool BalanceColumnWidths(nsIStyleContext *aTableStyle,
const nsReflowState& aReflowState,
- nscoord aMaxWidth,
- nscoord &aTotalFixedWidth,
- nscoord &aMinTableWidth,
- nscoord &aMaxTableWidth,
- nsSize* aMaxElementSize)=0;
+ nscoord aMaxWidth)=0;
};
#endif
diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
index 3615f2b3ccf..3ff92ad013e 100644
--- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
@@ -511,10 +511,10 @@ void nsTableCellFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
return;
// get the table frame style context, and from it get cellpadding, cellspacing, and border info
- nsIStyleContextPtr tableSC;
- tableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
- nsStyleTable* tableStyle = (nsStyleTable*)tableSC->GetStyleData(eStyleStruct_Table);
- nsStyleSpacing* tableSpacingStyle = (nsStyleSpacing*)tableSC->GetStyleData(eStyleStruct_Spacing);
+ nsStyleTable* tableStyle;
+ tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
+ nsStyleSpacing* tableSpacingStyle;
+ tableFrame->GetStyleData(eStyleStruct_Spacing,(nsStyleStruct *&)tableSpacingStyle);
nsStyleSpacing* spacingData = (nsStyleSpacing*)mStyleContext->GetMutableStyleData(eStyleStruct_Spacing);
// check to see if cellpadding or cellspacing is defined
diff --git a/mozilla/layout/html/table/src/nsTableColFrame.cpp b/mozilla/layout/html/table/src/nsTableColFrame.cpp
index 4745bd68b5a..4fe0f13656b 100644
--- a/mozilla/layout/html/table/src/nsTableColFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableColFrame.cpp
@@ -38,6 +38,10 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
{
mColIndex = 0;
mRepeat = 0;
+ mMaxColWidth = 0;
+ mMinColWidth = 0;
+ mMaxEffectiveColWidth = 0;
+ mMinEffectiveColWidth = 0;
}
@@ -55,11 +59,12 @@ NS_METHOD nsTableColFrame::Paint(nsIPresContext& aPresContext,
}
-NS_METHOD nsTableColFrame::Reflow(nsIPresContext& aPresContext,
+NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
+ NS_ASSERTION(nsnull!=aPresContext, "bad arg");
aDesiredSize.width=0;
aDesiredSize.height=0;
if (nsnull!=aDesiredSize.maxElementSize)
diff --git a/mozilla/layout/html/table/src/nsTableColFrame.h b/mozilla/layout/html/table/src/nsTableColFrame.h
index 3c70a7955b8..13b8b66691a 100644
--- a/mozilla/layout/html/table/src/nsTableColFrame.h
+++ b/mozilla/layout/html/table/src/nsTableColFrame.h
@@ -34,7 +34,7 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
- NS_IMETHOD Reflow(nsIPresContext& aPresContext,
+ NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
@@ -51,6 +51,18 @@ public:
/** convenience method, calls into cellmap */
nsVoidArray * GetCells();
+ nscoord GetMaxColWidth();
+ void SetMaxColWidth(nscoord aMaxColWidth);
+
+ nscoord GetMinColWidth();
+ void SetMinColWidth(nscoord aMinColWidth);
+
+ nscoord GetEffectiveMaxColWidth();
+ void SetEffectiveMaxColWidth(nscoord aMaxColWidth);
+
+ nscoord GetEffectiveMinColWidth();
+ void SetEffectiveMinColWidth(nscoord aMinColWidth);
+
/** convenience method, calls into cellmap */
PRInt32 Count() const;
@@ -66,11 +78,11 @@ protected:
/** the number of columns that the attributes of this column extend to */
PRInt32 mRepeat;
- nscoord mMaxWidth;
- nscoord mMinWidth;
+ nscoord mMaxColWidth;
+ nscoord mMinColWidth;
- nscoord mMaxEffectiveWidth;
- nscoord mMinEffectiveWidth;
+ nscoord mMaxEffectiveColWidth;
+ nscoord mMinEffectiveColWidth;
};
@@ -93,5 +105,29 @@ inline nsTableColFrame::GetRepeat()
inline void nsTableColFrame::SetColumnIndex (int aColIndex)
{ mColIndex = aColIndex;}
+inline nscoord nsTableColFrame::GetMaxColWidth()
+{ return mMaxColWidth; }
+
+inline void nsTableColFrame::SetMaxColWidth(nscoord aMaxColWidth)
+{ mMaxColWidth = aMaxColWidth; }
+
+inline nscoord nsTableColFrame::GetMinColWidth()
+{ return mMinColWidth; }
+
+inline void nsTableColFrame::SetMinColWidth(nscoord aMinColWidth)
+{ mMinColWidth = aMinColWidth; }
+
+inline nscoord nsTableColFrame::GetEffectiveMaxColWidth()
+{ return mMaxEffectiveColWidth; }
+
+inline void nsTableColFrame::SetEffectiveMaxColWidth(nscoord aMaxColWidth)
+{ mMaxEffectiveColWidth = aMaxColWidth; }
+
+inline nscoord nsTableColFrame::GetEffectiveMinColWidth()
+{ return mMinEffectiveColWidth; }
+
+inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinColWidth)
+{ mMinEffectiveColWidth = aMinColWidth; }
+
#endif
diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp
index 4be7370650a..6c7d634f564 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableFrame.cpp
@@ -396,7 +396,7 @@ nsTableCellFrame * nsTableFrame::GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex)
}
-// return the rows spanned by aCell starting at aRowIndex
+// return the number of rows spanned by aCell starting at aRowIndex
// note that this is different from just the rowspan of aCell
// (that would be GetEffectiveRowSpan (indexOfRowThatContains_aCell, aCell)
//
@@ -416,6 +416,24 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
return rowSpan;
}
+// return the number of cols spanned by aCell starting at aColIndex
+// note that this is different from just the colspan of aCell
+// (that would be GetEffectiveColSpan (indexOfColThatContains_aCell, aCell)
+//
+// XXX Should be moved to colgroup, as GetEffectiveRowSpan should be moved to rowgroup?
+PRInt32 nsTableFrame::GetEffectiveColSpan (PRInt32 aColIndex, nsTableCellFrame *aCell)
+{
+ NS_PRECONDITION (nsnull!=aCell, "bad cell arg");
+ 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 (colCount < (aColIndex + colSpan))
+ return (colCount - aColIndex);
+ return colSpan;
+}
+
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTableFrame::ResetCellMap ()
{
@@ -1198,6 +1216,11 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
// XXX For the time being just fall through and treat it like a
// pass 2 reflow...
mPass = kPASS_SECOND;
+ // calling intialize here resets all the cached info based on new table content
+ if (nsnull!=mTableLayoutStrategy)
+ {
+ mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
+ }
#else
// XXX Hack...
AdjustSiblingsAfterReflow(&aPresContext, state, kidFrame, desiredSize.height -
@@ -2231,9 +2254,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
{
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
- if (gsDebug)
- printf ("BalanceColumnWidths...\n");
-
if (nsnull==mCellMap)
return; // we don't have any information yet, so we can't do any useful work
@@ -2244,11 +2264,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
nsCRT::memset (mColumnWidths, 0, numCols*sizeof(PRInt32));
}
- // need to track min and max table widths
- PRInt32 minTableWidth = 0;
- PRInt32 maxTableWidth = 0;
- PRInt32 totalFixedWidth = 0;
-
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
@@ -2308,13 +2323,9 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
if (nsnull==mTableLayoutStrategy)
{ // TODO: build a different strategy based on the compatibility mode
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, numCols);
+ mTableLayoutStrategy->Initialize(aMaxElementSize);
}
- mTableLayoutStrategy->BalanceColumnWidths(aPresContext, mStyleContext,
- aReflowState, maxWidth,
- totalFixedWidth,
- minTableWidth, maxTableWidth,
- aMaxElementSize);
-
+ mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
}
/**
@@ -2608,7 +2619,7 @@ nsTableFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
nsIStyleContext* kidStyleContext =
aPresContext.ResolveStyleContextFor(content, cf); // kidStyleContext: REFCNT++
nsIContentDelegate* kidDel = nsnull;
- kidDel = content->GetDelegate(&aPresContext); // kidDel: REFCNT++
+ kidDel = content->GetDelegate(&aPresContext); // kidDel: REFCNT++
nsIFrame* duplicateFrame;
nsresult rv = kidDel->CreateFrame(&aPresContext, content, cf,
kidStyleContext, duplicateFrame);
@@ -2825,6 +2836,19 @@ NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin&
return result;
}
+nscoord nsTableFrame::GetCellSpacing()
+{
+ nsTableFrame* tableFrame = this;
+ //XXX remove when table style is fully resolved!
+ GetGeometricParent((nsIFrame *&)tableFrame); // get the outer frame
+ nsStyleTable* tableStyle;
+ tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
+ nscoord cellSpacing = 0;
+ if (tableStyle->mCellSpacing.GetUnit() == eStyleUnit_Coord)
+ cellSpacing = tableStyle->mCellSpacing.GetCoordValue();
+ return cellSpacing;
+}
+
void nsTableFrame::GetColumnsByType(const nsStyleUnit aType,
PRInt32& aOutNumColumns,
PRInt32 *& aOutColumnIndexes)
@@ -2989,27 +3013,34 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsReflowState& aReflowState)
}
else
{
- nsSize tableSize;
- table->GetSize(tableSize);
- parentWidth = tableSize.width;
- spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the row group
- childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(childFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the row
- grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the cell
- greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
-
+ if (nsnull!=((nsTableFrame*)table)->mColumnWidths)
+ {
+ PRInt32 colIndex = ((nsTableCellFrame*)greatgrandchildFrame)->GetColIndex();
+ parentWidth = ((nsTableFrame*)table)->GetColumnWidth(colIndex);
+ }
+ else
+ {
+ nsSize tableSize;
+ table->GetSize(tableSize);
+ parentWidth = tableSize.width;
+ spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
+ parentWidth -= (borderPadding.right + borderPadding.left);
+ // same for the row group
+ childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(childFrame, borderPadding);
+ parentWidth -= (borderPadding.right + borderPadding.left);
+ // same for the row
+ grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
+ parentWidth -= (borderPadding.right + borderPadding.left);
+ // same for the cell
+ greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
+ parentWidth -= (borderPadding.right + borderPadding.left);
+ }
if (PR_TRUE==gsDebugNT)
- printf("%p: found a table frame %p, returning parentWidth %d from frame width %d\n",
- aReflowState.frame, table, parentWidth, tableSize.width);
+ printf("%p: found a table frame %p, returning parentWidth %d \n",
+ aReflowState.frame, table, parentWidth);
}
break;
}
diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h
index c59004e4ddd..9ffdaf42d7e 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.h
+++ b/mozilla/layout/html/table/src/nsTableFrame.h
@@ -142,6 +142,9 @@ public:
/** set the width of the column at aColIndex to aWidth */
virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
+
+ /** helper to get the cell spacing style value */
+ virtual nscoord GetCellSpacing();
/**
* Calculate Layout Information
@@ -167,13 +170,26 @@ public:
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table.
- * @param aRowIndex the first row that contains the cell
- * @param aCell the content object representing the cell
+ *
+ * @param aRowIndex the row from which to measure effective row span
+ * @param aCell the cell
+ *
* @return the row span, correcting for row spans that extend beyond the bottom
* of the table.
*/
virtual PRInt32 GetEffectiveRowSpan(PRInt32 aRowIndex, nsTableCellFrame *aCell);
+ /** return the col span of a cell, taking into account col span magic at the edge
+ * of a table.
+ *
+ * @param aColIndex the column from which to measure effective col span
+ * @param aCell the cell
+ *
+ * @return the col span, correcting for col spans that extend beyond the edge
+ * of the table.
+ */
+ virtual PRInt32 GetEffectiveColSpan(PRInt32 aColIndex, nsTableCellFrame *aCell);
+
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
index cd47a83a684..93c77d2ec55 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
@@ -336,19 +336,22 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
nscoord maxCellTopMargin = 0;
nscoord maxCellBottomMargin = 0;
+ if (PR_TRUE==gsDebug1) printf("%p: RR\n", this);
+
// Reflow each of our existing cell frames
- for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
- // Get the frame's margins, and compare the top and bottom margin
- // against our current max values
- nsMargin kidMargin;
+ for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
+ {
+
+ nscoord cellSpacing = aState.tableFrame->GetCellSpacing();
+
+// just cellSpacing? QQQ
+ nsMargin kidMargin;
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
if (kidMargin.top > maxCellTopMargin)
maxCellTopMargin = kidMargin.top;
if (kidMargin.bottom > maxCellBottomMargin)
maxCellBottomMargin = kidMargin.bottom;
- // left and right margins already taken into account by table layout strategy
-
// Compute the x-origin for the child, taking into account straddlers (cells from prior
// rows with rowspans > 1)
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
@@ -357,10 +360,14 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
for (PRInt32 colIndex=prevColIndex+1; colIndexGetColumnWidth(colIndex);
- aState.x += kidMargin.left + kidMargin.right;
+ aState.x += cellSpacing;
+ if (PR_TRUE==gsDebug1)
+ printf(" in loop, aState.x set to %d from cellSpacing %d and col width\n",
+ aState.x, aState.tableFrame->GetColumnWidth(colIndex), cellSpacing);
}
}
- aState.x += kidMargin.left;
+ aState.x += cellSpacing;
+ if (PR_TRUE==gsDebug1) printf(" past loop, aState.x set to %d\n", aState.x);
// at this point, we know the column widths.
// so we get the avail width from the known column widths
@@ -369,13 +376,15 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
for (PRInt32 numColSpan=0; numColSpanGetColumnWidth(cellColIndex+numColSpan);
- if (0GetColumnWidth(cellColIndex+numColSpan), cellSpacing);
}
+ if (PR_TRUE==gsDebug1) printf(" availWidth for this cell is %d\n", availWidth);
prevColIndex = cellColIndex + (cellColSpan-1); // remember the rightmost column this cell spans into
@@ -461,7 +470,8 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
pKidMaxElementSize);
- aState.x += kidMargin.right; // add in right margin only after cell has been placed
+
+ if (PR_TRUE==gsDebug1) printf(" past PlaceChild, aState.x set to %d\n", aState.x);
// Get the next child
kidFrame->GetNextSibling(kidFrame);
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
index 34be3091e71..168b3c0606b 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
@@ -89,39 +89,14 @@ PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosit
PRBool result = PR_FALSE; // assume that it is not fixed width
PRInt32 unitType;
if (nsnull == aStylePosition) {
- unitType = eStyleUnit_Auto;
+ result=PR_TRUE;
}
else {
unitType = aStylePosition->mWidth.GetUnit();
+ if (eStyleUnit_Coord==unitType)
+ result=PR_TRUE;
}
- switch (unitType) {
- case eStyleUnit_Coord:
- result = PR_TRUE;
-
- case eStyleUnit_Auto:
- case eStyleUnit_Proportional:
- case eStyleUnit_Percent:
- break;
-
- // TODO
- case eStyleUnit_Inherit:
- break;
-
- default:
- NS_ASSERTION(PR_FALSE, "illegal style type in IsFixedWidth");
- break;
- }
- return result;
-}
-
-PRBool BasicTableLayoutStrategy::IsAutoWidth(const nsStylePosition* aStylePosition)
-{
- PRBool result = PR_TRUE; // assume that it is
- if (nsnull!=aStylePosition)
- {
- result = (PRBool)(eStyleUnit_Auto==aStylePosition->mWidth.GetUnit());
- }
return result;
}
@@ -132,6 +107,10 @@ BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aFrame, PRInt32
mTableFrame = aFrame;
mNumCols = aNumCols;
+ mMinTableWidth=0;
+ mMaxTableWidth=0;
+ mFixedTableWidth=0;
+
//cache the value of the cols attribute
nsIFrame * tableFrame = mTableFrame;
// begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED! XXX
@@ -146,93 +125,7 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
{
}
-PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresContext,
- nsIStyleContext *aTableStyle,
- const nsReflowState& aReflowState,
- nscoord aMaxWidth,
- nscoord &aTotalFixedWidth,
- nscoord &aMinTableWidth,
- nscoord &aMaxTableWidth,
- nsSize* aMaxElementSize)
-{
- PRBool result = PR_TRUE;
- // initialize out parameters
- aTotalFixedWidth=aMinTableWidth=aMaxTableWidth=0;
-
- // Step 1 - assign the width of all fixed-width columns
- AssignFixedColumnWidths(aPresContext, aMaxWidth, aTotalFixedWidth, aMinTableWidth, aMaxTableWidth);
-
- if (nsnull!=aMaxElementSize)
- { // this is where we initialize maxElementSize if it is non-null
- aMaxElementSize->height = 0;
- aMaxElementSize->width = aMinTableWidth;
- if (gsDebug) printf(" setting aMaxElementSize->width = %d\n", aMaxElementSize->width);
- }
- else
- {
- if (gsDebug) printf(" nsnull aMaxElementSize\n");
- }
-
- // Step 2 - determine how much space is really available
- PRInt32 availWidth = aMaxWidth - aTotalFixedWidth;
- nscoord tableWidth = 0;
- PRBool tableIsAutoWidth = nsTableFrame::TableIsAutoWidth(mTableFrame, aTableStyle, aReflowState, tableWidth);
- if (PR_FALSE==tableIsAutoWidth)
- availWidth = tableWidth - aTotalFixedWidth;
-
- // Step 3 - assign the width of all proportional-width columns in the remaining space
- if (gsDebug==PR_TRUE) printf ("Step 2...\n availWidth = %d\n", availWidth);
- result = BalanceProportionalColumns(aPresContext, aReflowState,
- availWidth, aMaxWidth,
- aMinTableWidth, aMaxTableWidth,
- tableWidth, tableIsAutoWidth);
- return result;
-}
-
-/*
-STEP 1
-for every col
- if the col has a fixed width
- set the width to max(fixed width, maxElementSize)
- if the cell spans columns, divide the cell width between the columns
- else skip it for now
-
-take borders and padding into account
-
-STEP 2
-determine the min and max size for the table width
-if col is proportionately specified
- if (col width specified to 0)
- col width = minColWidth
- else if (minTableWidth >= aMaxSize.width)
- set col widths to min, install a hor. scroll bar
- else if (maxTableWidth <= aMaxSize.width)
- set each col to its max size
- else
- W = aMaxSize.width - minTableWidth
- D = maxTableWidth - minTableWidth
- for each col
- d = maxColWidth - minColWidth
- col width = minColWidth + ((d*W)/D)
-
-STEP 3
-if there is space left over
- for every col
- if col is proportionately specified
- add space to col width until it is that proportion of the table width
- do this non-destructively in case there isn't enough space
- if there isn't enough space as determined in the prior step,
- add space in proportion to the proportionate width attribute
- */
-
-
-// Step 1 - assign the width of all fixed-width columns,
-// and calculate min/max table width
-PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresContext,
- nscoord aMaxWidth,
- nscoord &aTotalFixedWidth,
- nscoord &aMinTableWidth,
- nscoord &aMaxTableWidth)
+PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
{
#ifdef DEBUG
nsIFrame *tablePIF=nsnull;
@@ -240,18 +133,87 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!");
#endif
- if (gsDebug==PR_TRUE) printf (" AssignFixedColumnWidths\n");
+ PRBool result = PR_TRUE;
+
+ // Step 1 - assign the width of all fixed-width columns
+ AssignPreliminaryColumnWidths();
+
+ // set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
+ if (nsnull!=aMaxElementSize)
+ {
+ aMaxElementSize->height = 0;
+ aMaxElementSize->width = mMinTableWidth;
+ if (PR_TRUE==gsDebug) printf("BTLS::Init setting aMaxElementSize->width = %d\n", aMaxElementSize->width);
+ }
+
+ return result;
+}
+
+PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyle,
+ const nsReflowState& aReflowState,
+ nscoord aMaxWidth)
+{
+#ifdef DEBUG
+ nsIFrame *tablePIF=nsnull;
+ mTableFrame->GetPrevInFlow(tablePIF);
+ NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!");
+#endif
+
+ PRBool result;
+
+ NS_ASSERTION(nsnull!=aTableStyle, "bad arg");
+ if (nsnull==aTableStyle)
+ return PR_FALSE;
+
+
+ nscoord specifiedTableWidth = 0; // not cached as a data member because it can vary depending on aMaxWidth
+ PRBool tableIsAutoWidth = nsTableFrame::TableIsAutoWidth(mTableFrame, aTableStyle, aReflowState, specifiedTableWidth);
+
+ // Step 2 - determine how much space is really available
+ PRInt32 availWidth = aMaxWidth - mFixedTableWidth;
+ if (PR_FALSE==tableIsAutoWidth)
+ availWidth = specifiedTableWidth - mFixedTableWidth;
+
+ // Step 3 - assign the width of all proportional-width columns in the remaining space
+ if (PR_TRUE==gsDebug)
+ {
+ printf ("BalanceColumnWidths with aMaxWidth = %d, availWidth = %d\n", aMaxWidth, availWidth);
+ printf ("\t\t specifiedTW = %d, min/maxTW = %d %d\n", specifiedTableWidth, mMinTableWidth, mMaxTableWidth);
+ }
+ if (PR_TRUE==gsDebug)
+ {
+ printf("\n%p: BEGIN BALANCE COLUMN WIDTHS\n", mTableFrame);
+ for (PRInt32 i=0; iGetColumnWidth(i));
+ printf("\n");
+ }
+ result = BalanceProportionalColumns(aReflowState, availWidth, aMaxWidth,
+ specifiedTableWidth, tableIsAutoWidth);
+
+ if (PR_TRUE==gsDebug)
+ {
+ printf("\n%p: END BALANCE COLUMN WIDTHS\n", mTableFrame);
+ for (PRInt32 i=0; iGetColumnWidth(i));
+ printf("\n");
+ }
+ return result;
+}
+
+// Step 1 - assign the width of all fixed-width columns, all other columns get there max,
+// and calculate min/max table width
+PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
+{
+ if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
nsVoidArray *spanList=nsnull;
nsVoidArray *colSpanList=nsnull;
- nscoord * effectiveColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveColumnWidths, 0, mNumCols*sizeof(PRInt32));
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
- PRInt32 *minColWidthArray = nsnull;
- PRInt32 *maxColWidthArray = nsnull;
+ PRInt32 *minColWidthArray = nsnull; // used for computing the effect of COLS attribute
+ PRInt32 *maxColWidthArray = nsnull; // used for computing the effect of COLS attribute
if (PR_TRUE==hasColsAttribute)
- {
+ {
minColWidthArray = new PRInt32[mNumCols];
maxColWidthArray = new PRInt32[mNumCols];
}
@@ -261,11 +223,10 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
// for every column, determine it's min and max width, and keep track of the table width
for (PRInt32 colIndex = 0; colIndexGetColFrame(colIndex);
@@ -275,22 +236,16 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
- // Get column width if it has one
+ // Get fixed column width if it has one
PRBool haveColWidth = PR_FALSE;
nscoord specifiedFixedColWidth=0;
- switch (colPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- haveColWidth = PR_TRUE;
- specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
- mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth);
- break;
-
- default:
- break;
+ if (eStyleUnit_Coord==colPosition->mWidth.GetUnit())
+ {
+ haveColWidth = PR_TRUE;
+ specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
}
- // TODO - use specifiedFixedColWidth to influence the width when both col span and fixed col width are given
- /* Scan the column, simulatneously assigning fixed column widths
+ /* 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
@@ -301,14 +256,16 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
- if (minColWidth < spanInfo->cellMinWidth)
- minColWidth = spanInfo->cellMinWidth;
- if (maxColWidth < spanInfo->cellDesiredWidth)
- maxColWidth = spanInfo->cellDesiredWidth;
+ 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, spanInfo->cellMinWidth, spanInfo->cellDesiredWidth);
+ spanIndex, spanInfo->span, cellMinWidth, cellDesiredWidth);
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
@@ -318,6 +275,7 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
}
PRInt32 firstRowIndex = -1;
+ PRInt32 maxColSpan = 1;
for (PRInt32 rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
@@ -332,55 +290,52 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
+ PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame);
+ if (colSpan>maxColSpan)
+ maxColSpan = colSpan;
if (colIndex!=cellFrame->GetColIndex()) {
- // For cells that span rows, we only figure it in once
+ // For cells that span cols, we figure in the row using previously-built SpanInfo
NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
continue;
}
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- PRInt32 colSpan = cellFrame->GetColSpan();
+ nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
if (gsDebug==PR_TRUE)
- printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
+ 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);
- switch (colPosition->mWidth.GetUnit())
+ if (PR_TRUE==haveColWidth)
{
- case eStyleUnit_Coord:
- {
- // This col has a fixed width, so set the cell's width to the
- // larger of (specified width, largest max_element_size of the
- // cells in the column)
- nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
- widthForThisCell = widthForThisCell/colSpan;
- nscoord widthFromCol = mTableFrame->GetColumnWidth(colIndex);
- if (widthFromCol < widthForThisCell)
- {
- if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell);
- mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
- maxColWidth = widthForThisCell;
- }
- }
- break;
-
- default:
- break;
-
+ // This col has a specified fixed width so set the minand max width to the larger of
+ // (specified width, largest max_element_size of the cells in the column)
+ nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
+ widthForThisCell = widthForThisCell/colSpan;
+ mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
+ maxColWidth = widthForThisCell;
+ minColWidth = widthForThisCell;
+ if ((1==colSpan) && (effectiveMaxColumnWidth < widthForThisCell))
+ effectiveMaxColumnWidth = widthForThisCell;
+ if (gsDebug)
+ printf (" setting min and max col width to specified fixed width %d\n", widthForThisCell);
+ }
+ else
+ {
+ if (maxColWidth < cellDesiredWidth)
+ maxColWidth = cellDesiredWidth;
+ if ((1==colSpan) && (effectiveMaxColumnWidth < maxColWidth))
+ effectiveMaxColumnWidth = cellDesiredWidth;
}
- // regardless of the width specification, keep track of the
- // min/max column widths
+ // cellMinWidth can override fixed width, so factor it in here
nscoord cellMinWidth = cellMinSize.width/colSpan;
- nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
- if (maxColWidth < cellDesiredWidth)
- maxColWidth = cellDesiredWidth;
- // effectiveColumnWidth is the width as if no cells with colspans existed
- if ((1==colSpan) && (effectiveColumnWidths[colIndex] < maxColWidth))
- effectiveColumnWidths[colIndex] = cellDesiredWidth;
+ // effectiveMinColumnWidth is the min width as if no cells with colspans existed
+ if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth))
+ effectiveMinColumnWidth = cellMinWidth;
if (1GetCellAt(firstRowIndex, colIndex);
- nsMargin colMargin;
- firstCellInColumn->GetMargin(colMargin);
- nscoord colInset = colMargin.left + colMargin.right;
+ nscoord colInset = mTableFrame->GetCellSpacing();
// keep a running total of the amount of space taken up by all fixed-width columns
if (PR_TRUE==haveColWidth)
- aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
-
+ mFixedTableWidth += specifiedFixedColWidth + (colInset*maxColSpan);
if (gsDebug) {
- printf (" after col %d, aTotalFixedWidth = %d\n",
- colIndex, aTotalFixedWidth);
+ printf (" after col %d, mFixedTableWidth = %d\n", colIndex, mFixedTableWidth);
}
+
+ // cache the computed column info
+ colFrame->SetMinColWidth(minColWidth);
+ colFrame->SetMaxColWidth(maxColWidth);
+ colFrame->SetEffectiveMinColWidth(effectiveMinColumnWidth);
+ colFrame->SetEffectiveMaxColWidth(effectiveMaxColumnWidth);
+ mTableFrame->SetColumnWidth(colIndex, maxColWidth);
+
// add col[i] metrics to the running totals for the table min/max width
- if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth)
- aMinTableWidth += minColWidth + colInset;
- if (aMinTableWidth<=0)
- aMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
- if (NS_UNCONSTRAINEDSIZE!=aMaxTableWidth)
- aMaxTableWidth += maxColWidth + colInset;
- if (aMaxTableWidth<=0)
- aMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
+ if (NS_UNCONSTRAINEDSIZE!=mMinTableWidth)
+ mMinTableWidth += minColWidth + colInset;
+ if (mMinTableWidth<=0)
+ mMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
+ if (NS_UNCONSTRAINEDSIZE!=mMaxTableWidth)
+ mMaxTableWidth += maxColWidth + colInset;
+ if (mMaxTableWidth<=0)
+ mMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (PR_TRUE==hasColsAttribute)
{
minColWidthArray[colIndex] = minColWidth;
@@ -430,12 +388,11 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
}
if (gsDebug==PR_TRUE)
printf (" after col %d, minTableWidth = %d and maxTableWidth = %d\n",
- colIndex, aMinTableWidth, aMaxTableWidth);
-
- } // end Step 1 for fixed-width columns
+ colIndex, mMinTableWidth, mMaxTableWidth);
+ }
// now, post-process the computed values based on the table attributes
- // if there is a COLS attribute, fix up aMinTableWidth and aMaxTableWidth
+ // if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth
if (PR_TRUE==hasColsAttribute)
{
// for every effected column, subtract out its prior contribution and add back in the new value
@@ -456,29 +413,31 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
{
// subtract out the prior contributions of this column
// and add back in the adjusted value
- if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth)
+ if (NS_UNCONSTRAINEDSIZE!=mMinTableWidth)
{
- aMinTableWidth -= minColWidthArray[effectedColIndex];
- aMinTableWidth += maxOfMinColWidths;
+ mMinTableWidth -= minColWidthArray[effectedColIndex];
+ mMinTableWidth += maxOfMinColWidths;
}
- if (NS_UNCONSTRAINEDSIZE!=aMaxTableWidth)
+ if (NS_UNCONSTRAINEDSIZE!=mMaxTableWidth)
{
- aMaxTableWidth -= maxColWidthArray[effectedColIndex];
- aMaxTableWidth += maxOfMaxColWidths;
+ mMaxTableWidth -= maxColWidthArray[effectedColIndex];
+ mMaxTableWidth += maxOfMaxColWidths;
}
+ nsTableColFrame *colFrame;
+ mTableFrame->GetColumnFrame(effectedColIndex, colFrame);
+ colFrame->SetMaxColWidth(maxOfMaxColWidths); // cache the new column max width (min width is uneffected)
+ colFrame->SetEffectiveMaxColWidth(maxOfMaxColWidths);
}
delete [] minColWidthArray;
delete [] maxColWidthArray;
}
if (nsnull!=colSpanList)
- DistributeFixedSpace(colSpanList, effectiveColumnWidths);
- // today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
- if (nsnull!=effectiveColumnWidths)
- delete [] effectiveColumnWidths;
+ DistributeFixedSpace(colSpanList);
if (PR_TRUE==gsDebug)
- printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, aMinTableWidth, aMaxTableWidth);
-
+ printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, mMinTableWidth, mMaxTableWidth);
+
+ // clean up
if (nsnull!=spanList)
delete spanList;
if (nsnull!=colSpanList)
@@ -497,10 +456,10 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
// take the fixed space spanned by the columns in aColSpanList
// and distribute it proportionately (based on desired width)
-void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths)
+void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList)
{
nscoord excess = 0;
- if (PR_TRUE==gsDebug) printf ("DistributeFixedSpace:\n");
+ if (PR_TRUE==gsDebug) printf ("** DistributeFixedSpace:\n");
// for all fixed-width columns, determine the amount of the specified width each column spanned recieves
PRInt32 numSpanningCells = aColSpanList->Count();
for (PRInt32 nextSpanningCell=0; nextSpanningCellGetColumnFrame(colIndex+i, colFrame);
+ totalEffectiveWidth += colFrame->GetEffectiveMaxColWidth();
}
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iGetColumnFrame(colIndex+i, colFrame);
float percent;
- percent = ((float)(aColWidths[colIndex+i]))/((float)totalEffectiveWidth);
+ percent = ((float)(colFrame->GetEffectiveMaxColWidth()))/((float)totalEffectiveWidth);
nscoord colWidth = (nscoord)(totalColWidth*percent);
if (gsDebug==PR_TRUE)
printf(" assigning fixed col width for spanning cells: column %d set to %d\n",
colIndex+i, colWidth);
mTableFrame->SetColumnWidth(colIndex+i, colWidth);
+ colFrame->SetMaxColWidth(colWidth);
}
}
}
-PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+/* assign column widths to all non-fixed-width columns (adjusting fixed-width columns if absolutely necessary)
+ aAvailWidth is the amount of space left in the table to distribute after fixed-width columns are accounted for
+ aMaxWidth is the space the parent gave us (minus border & padding) to fit ourselves into
+ aTableIsAutoWidth is true if the table is auto-width, false if it is anything else (percent, fixed, etc)
+ */
+PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
- nscoord aMinTableWidth,
- nscoord aMaxTableWidth,
- nscoord aTableFixedWidth,
+ nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth)
{
PRBool result = PR_TRUE;
- if (0==aTableFixedWidth)
- {
- if (NS_UNCONSTRAINEDSIZE==aMaxWidth || NS_UNCONSTRAINEDSIZE==aMinTableWidth)
- { // the max width of the table fits comfortably in the available space
- if (gsDebug) printf (" * table laying out in NS_UNCONSTRAINEDSIZE, calling BalanceColumnsTableFits\n");
- result = BalanceColumnsTableFits(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aTableFixedWidth, aTableIsAutoWidth);
- }
- else if (aMinTableWidth > aMaxWidth)
- { // the table doesn't fit in the available space
- if (gsDebug) printf (" * min table does not fit, calling SetColumnsToMinWidth\n");
- result = SetColumnsToMinWidth(aPresContext);
- }
- else if (aMaxTableWidth <= aMaxWidth)
- { // the max width of the table fits comfortably in the available space
- if (gsDebug) printf (" * table desired size fits, calling BalanceColumnsTableFits\n");
- result = BalanceColumnsTableFits(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aTableFixedWidth, aTableIsAutoWidth);
- }
- else
- { // the table fits somewhere between its min and desired size
- if (gsDebug) printf (" * table desired size does not fit, calling BalanceColumnsConstrained\n");
- result = BalanceColumnsConstrained(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aMinTableWidth, aMaxTableWidth);
- }
+ nscoord actualMaxWidth; // the real target width, depends on if we're auto or specified width
+ if (PR_TRUE==aTableIsAutoWidth)
+ actualMaxWidth = aMaxWidth;
+ else
+ actualMaxWidth = aTableSpecifiedWidth;
+
+ if (NS_UNCONSTRAINEDSIZE==aMaxWidth || NS_UNCONSTRAINEDSIZE==mMinTableWidth)
+ { // the max width of the table fits comfortably in the available space
+ if (gsDebug) printf (" * auto table laying out in NS_UNCONSTRAINEDSIZE, calling BalanceColumnsTableFits\n");
+ result = BalanceColumnsTableFits(aReflowState, aAvailWidth,
+ aMaxWidth, aTableSpecifiedWidth, aTableIsAutoWidth);
+ }
+ else if (mMinTableWidth > actualMaxWidth)
+ { // the table doesn't fit in the available space
+ if (gsDebug) printf (" * auto table minTW does not fit, calling SetColumnsToMinWidth\n");
+ result = SetColumnsToMinWidth();
+ }
+ else if (mMaxTableWidth <= actualMaxWidth)
+ { // the max width of the table fits comfortably in the available space
+ if (gsDebug) printf (" * auto table desired size fits, calling BalanceColumnsTableFits\n");
+ result = BalanceColumnsTableFits(aReflowState, aAvailWidth,
+ aMaxWidth, aTableSpecifiedWidth, aTableIsAutoWidth);
}
else
- { // tables with fixed-width have their own rules
- if (NS_UNCONSTRAINEDSIZE==aMinTableWidth)
- { // the table has empty content, and needs to be streched to the specified width
- if (gsDebug) printf (" * specified width table > maxTableWidth, calling BalanceColumnsTableFits\n");
- result = BalanceColumnsTableFits(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aTableFixedWidth, aTableIsAutoWidth);
- }
- else if ((aTableFixedWidth= its max width, so give each column its max requested size
- if (gsDebug) printf (" * specified width table > maxTableWidth, calling BalanceColumnsTableFits\n");
- result = BalanceColumnsTableFits(aPresContext, aReflowState, aAvailWidth,
- aMaxWidth, aTableFixedWidth, aTableIsAutoWidth);
- }
+ { // the table fits somewhere between its min and desired size
+ if (gsDebug) printf (" * auto table desired size does not fit, calling BalanceColumnsConstrained\n");
+ result = BalanceColumnsConstrained(aReflowState, aAvailWidth,
+ actualMaxWidth);
}
+
return result;
}
-PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresContext)
+// the table doesn't fit, so squeeze every column down to its minimum
+PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth()
{
PRBool result = PR_TRUE;
@@ -626,48 +569,21 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
{
- for (PRInt32 rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
- if (nsnull==cellFrame)
- { // there is no cell in this row that corresponds to this column
- continue;
- }
- if (rowIndex!=cellFrame->GetRowIndex()) {
- // For cells that span rows, we only figure it in once
- NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
- continue;
- }
-
- nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
- PRInt32 colSpan = cellFrame->GetColSpan();
- nscoord cellMinWidth = cellMinSize.width/colSpan;
- if (minColWidth < cellMinWidth)
- minColWidth = cellMinWidth;
- }
+ minColWidth = colFrame->GetMinColWidth();
+ mTableFrame->SetColumnWidth(colIndex, minColWidth);
if (PR_TRUE==hasColsAttribute)
{
minColWidthArray[colIndex] = minColWidth;
}
-
- if (gsDebug==PR_TRUE)
- {
- printf (" for determining width of col %d %s:\n",
- colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)");
- printf (" minColWidth = %d\n", minColWidth);
- }
-
- mTableFrame->SetColumnWidth(colIndex, minColWidth);
- if (gsDebug==PR_TRUE)
- printf (" 2: col %d, set to width = %d\n", colIndex, mTableFrame->GetColumnWidth(colIndex));
}
+ if (gsDebug==PR_TRUE)
+ printf (" 2: col %d, set to width = %d\n", colIndex, mTableFrame->GetColumnWidth(colIndex));
}
// now, post-process the computed values based on the table attributes
- // if there is a COLS attribute, fix up aMinTableWidth and aMaxTableWidth
+ // if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth
if (PR_TRUE==hasColsAttribute)
- {
- // for every effected column, subtract out its prior contribution and add back in the new value
+ { // for every effected column, subtract out its prior contribution and add back in the new value
PRInt32 numColsEffected = mNumCols;
if (NS_STYLE_TABLE_COLS_ALL!=mCols)
numColsEffected = mCols;
@@ -686,40 +602,34 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
if (PR_TRUE==gsDebug)
printf(" 2 (cols): setting %d to %d\n", effectedColIndex, maxOfEffectedColWidths);
}
+ // we're guaranteed here that minColWidthArray has been allocated, and that
+ // if we don't get here, it was never allocated
delete [] minColWidthArray;
}
-
-
return result;
}
-PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+/* the table fits in the given space. Set all columns to their desired width,
+ * and if we are not an auto-width table add extra space to fluff out the total width
+ */
+PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
- nscoord aTableFixedWidth,
+ nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth)
{
-#ifdef DEBUG
- nsIFrame *tablePIF=nsnull;
- mTableFrame->GetPrevInFlow(tablePIF);
- NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!");
-#endif
-
PRBool result = PR_TRUE;
nscoord tableWidth=0; // the width of the table as a result of setting column widths
- nscoord widthOfFixedTableColumns=0; // the sum of the width of all fixed-width columns
+ nscoord widthOfFixedTableColumns=0; // the sum of the width of all fixed-width columns plus margins
// tableWidth - widthOfFixedTableColumns is the width of columns computed in this method
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
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
- nscoord * effectiveColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveColumnWidths, 0, mNumCols*sizeof(PRInt32));
PRInt32 numRows = mTableFrame->GetRowCount();
for (PRInt32 colIndex = 0; colIndexGetCellAt(rowIndex, colIndex);
- if (nsnull!=firstCellInColumn)
- break;
- }
- nsMargin colMargin;
- nscoord colInset = 0;
- if (nsnull!=firstCellInColumn)
- {
- firstCellInColumn->GetMargin(colMargin);
- colInset = colMargin.left + colMargin.right;
- }
+ nscoord colInset = mTableFrame->GetCellSpacing();
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
@@ -784,43 +681,30 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
+ if (colIndex!=cellFrame->GetColIndex()) {
+ // For cells that span cols, we figure in the row using previously-built SpanInfo
+ NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
+ continue;
+ }
- PRInt32 colSpan = cellFrame->GetColSpan();
+ 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();
- PRInt32 cellMinWidth = cellMinSize.width/colSpan;
+ nscoord cellMinWidth = cellMinSize.width/colSpan;
// first get the desired size info from reflow pass 1
- PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
+ nscoord 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, (const nsStyleStruct*&)cellPosition);
- switch (cellPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
- if (gsDebug) printf("cell has specified coord width = %d\n", specifiedCellWidth);
- break;
-
- case eStyleUnit_Percent:
- {
- nscoord tableWidth=0;
- nsIStyleContextPtr tableSC;
- mTableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
- PRBool tableIsAutoWidth = nsTableFrame::TableIsAutoWidth(mTableFrame, tableSC, aReflowState, tableWidth);
- float percent = cellPosition->mWidth.GetPercentValue();
- specifiedCellWidth = (PRInt32)(tableWidth*percent);
- if (gsDebug) printf("specified percent width %f of %d = %d\n",
- percent, tableWidth, specifiedCellWidth);
- break;
- }
-
- case eStyleUnit_Inherit:
- // XXX for now, do nothing
- default:
- case eStyleUnit_Auto:
- break;
+ 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)
{
@@ -828,7 +712,8 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
{
if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
cellDesiredWidth, specifiedCellWidth/colSpan);
- cellDesiredWidth = specifiedCellWidth/colSpan; // TODO: some math needed here for colspans
+ cellDesiredWidth = specifiedCellWidth/colSpan;
+ //QQQ should be proportionately distributed as a post-process
}
}
@@ -839,13 +724,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
minColWidth = cellMinWidth;
if (maxColWidth < cellDesiredWidth)
maxColWidth = cellDesiredWidth;
- // effectiveColumnWidth is the width as if no cells with colspans existed
- if ((1==colSpan) && (effectiveColumnWidths[colIndex] < maxColWidth))
- effectiveColumnWidths[colIndex] = cellDesiredWidth;
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
rowIndex, minColWidth, maxColWidth,
- colIndex, effectiveColumnWidths[colIndex]);
+ 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);
@@ -853,7 +735,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
spanList = new nsVoidArray();
spanList->AppendElement(spanInfo);
}
- }
+ } // end looping through cells in the column
if (gsDebug==PR_TRUE)
{
@@ -869,10 +751,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
nscoord specifiedFixedColumnWidth = -1;
PRBool isAutoWidth = PR_FALSE;
switch (colPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedFixedColumnWidth = colPosition->mWidth.GetCoordValue();
- if (gsDebug) printf("column %d has specified coord width = %d\n", colIndex, specifiedFixedColumnWidth);
- break;
case eStyleUnit_Percent:
specifiedPercentageColWidth = colPosition->mWidth.GetPercentValue();
if (gsDebug) printf("column %d has specified percent width = %f\n", colIndex, specifiedPercentageColWidth);
@@ -927,16 +805,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional: col %d with availWidth %d, gets %d slices with %d slices so far.\n",
colIndex, aAvailWidth, specifiedProportionColumnWidth, totalSlices);
}
- else if (-1!=specifiedFixedColumnWidth)
- { // the column has a specified pixel width
- // if the column was computed to be too small, enlarge the column
- nscoord resolvedWidth = specifiedFixedColumnWidth;
- if (specifiedFixedColumnWidth <= minColWidth)
- resolvedWidth = minColWidth;
- mTableFrame->SetColumnWidth(colIndex, resolvedWidth);
- if (gsDebug==PR_TRUE)
- printf (" 3 fixed: col %d given %d\n", colIndex, resolvedWidth);
- }
else
{ // give the column a percentage of the remaining space
PRInt32 percentage = -1;
@@ -950,10 +818,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
{
percentage = (PRInt32)(specifiedPercentageColWidth*100.0f); // TODO: rounding errors?
// base the % on the total specified fixed width of the table
- mTableFrame->SetColumnWidth(colIndex, (percentage*aTableFixedWidth)/100);
+ mTableFrame->SetColumnWidth(colIndex, (percentage*aTableSpecifiedWidth)/100);
if (gsDebug==PR_TRUE)
- printf (" 3 percent specified: col %d given %d percent of aTableFixedWidth %d, set to width = %d\n",
- colIndex, percentage, aTableFixedWidth, mTableFrame->GetColumnWidth(colIndex));
+ printf (" 3 percent specified: col %d given %d percent of aTableSpecifiedWidth %d, set to width = %d\n",
+ colIndex, percentage, aTableSpecifiedWidth, mTableFrame->GetColumnWidth(colIndex));
}
if (-1==percentage)
{
@@ -975,7 +843,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
else
{ // need to maintain this so we know how much we have left over at the end
- widthOfFixedTableColumns += mTableFrame->GetColumnWidth(colIndex) + colInset;
+ widthOfFixedTableColumns += colFrame->GetMaxColWidth() + colInset;
}
tableWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
}
@@ -985,7 +853,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
if (nsnull!=proportionalColumnsList)
{
// first, figure out the amount of space per slice
- nscoord maxWidthForTable = (0!=aTableFixedWidth) ? aTableFixedWidth : aMaxWidth;
+ nscoord maxWidthForTable = (0!=aTableSpecifiedWidth) ? aTableSpecifiedWidth : aMaxWidth;
if (NS_UNCONSTRAINEDSIZE!=maxWidthForTable)
{
nscoord widthRemaining = maxWidthForTable - tableWidth;
@@ -1001,7 +869,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional step 2: col %d given %d proportion of remaining space %d, set to width = %d\n",
info->mColIndex, info->mProportion, widthRemaining, computedColWidth);
tableWidth += computedColWidth;
- effectiveColumnWidths[info->mColIndex] = computedColWidth;
+// effectiveColumnWidth = computedColWidth;
delete info;
}
}
@@ -1026,7 +894,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional step 2 (unconstrained!): col %d set to width = %d\n",
info->mColIndex, maxOfMaxColWidths);
tableWidth += maxOfMaxColWidths;
- effectiveColumnWidths[info->mColIndex] = maxOfMaxColWidths;
+ nsTableColFrame *colFrame;
+ mTableFrame->GetColumnFrame(info->mColIndex, colFrame);
+ colFrame->SetEffectiveMaxColWidth(maxOfMaxColWidths);
delete info;
}
}
@@ -1038,11 +908,8 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
// columns if possible.
if ((PR_FALSE==aTableIsAutoWidth) && (aAvailWidth > (tableWidth-widthOfFixedTableColumns)))
{
- DistributeExcessSpace(aAvailWidth, tableWidth, widthOfFixedTableColumns, effectiveColumnWidths);
+ DistributeExcessSpace(aAvailWidth, tableWidth, widthOfFixedTableColumns);
}
- // today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
- if (nsnull!=effectiveColumnWidths)
- delete [] effectiveColumnWidths;
if (nsnull!=spanList)
delete spanList;
return result;
@@ -1052,12 +919,12 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
// give extra space to auto-width cells first, or if there are none to all cells
void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
nscoord aTableWidth,
- nscoord aWidthOfFixedTableColumns,
- nscoord *aColWidths)
+ nscoord aWidthOfFixedTableColumns)
{
nscoord excess = 0;
if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d, woftc=%d\n",
aAvailWidth, aTableWidth, aWidthOfFixedTableColumns);
+ nscoord widthMinusFixedColumns = aTableWidth - aWidthOfFixedTableColumns;
// if there are auto-sized columns, give them the extra space
// the trick here is to do the math excluding non-auto width columns
PRInt32 numAutoColumns=0;
@@ -1065,7 +932,6 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0!=numAutoColumns)
{
- nscoord computedTableWidth = aTableWidth - aWidthOfFixedTableColumns;
// 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;
@@ -1075,27 +941,35 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
PRInt32 i;
for (i = 0; iGetColumnFrame(autoColumns[i], colFrame);
+ nscoord effectiveColWidth = colFrame->GetEffectiveMaxColWidth();
+ if (0!=effectiveColWidth)
+ totalEffectiveWidthOfAutoColumns += effectiveColWidth;
else
totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
}
- excess = aAvailWidth - computedTableWidth;
+ // excess is the amount of space that was available minus the computed available width
+ // QQQ shouldn't it just be aMaxWidth - aTableWidth???
+ excess = aAvailWidth - widthMinusFixedColumns;
+
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iGetColumnWidth(colIndex);//aColWidths[colIndex];
+ nsTableColFrame *colFrame;
+ mTableFrame->GetColumnFrame(colIndex, colFrame);
+ nscoord oldColWidth = mTableFrame->GetColumnWidth(colIndex);
float percent;
if (0!=totalEffectiveWidthOfAutoColumns)
- percent = ((float)(aColWidths[colIndex]))/((float)totalEffectiveWidthOfAutoColumns);
+ percent = ((float)(colFrame->GetEffectiveMaxColWidth()))/((float)totalEffectiveWidthOfAutoColumns);
else
percent = ((float)1)/((float)numAutoColumns);
nscoord excessForThisColumn = (nscoord)(excess*percent);
nscoord colWidth = excessForThisColumn+oldColWidth;
if (gsDebug==PR_TRUE)
printf(" distribute excess to auto columns: column %d was %d, now set to %d\n",
- colIndex, aColWidths[colIndex], colWidth);
+ colIndex, oldColWidth, colWidth);
mTableFrame->SetColumnWidth(colIndex, colWidth);
}
}
@@ -1103,13 +977,13 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
// (they must be all fixed and percentage-width columns, or we would have gone into the block above)
else
{
- excess = aAvailWidth - (aTableWidth-aWidthOfFixedTableColumns);
+ excess = aAvailWidth - widthMinusFixedColumns;
if (gsDebug==PR_TRUE)
printf(" aAvailWidth specified as %d, expanding columns by excess = %d\n",
aAvailWidth, excess);
for (PRInt32 colIndex = 0; colIndexGetColumnWidth(colIndex);
float percent;
@@ -1127,15 +1001,11 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
}
}
-/* this method is very similar to BalanaceColumnsTableFits, but there are enough
- * subtle differences that code reuse is impractical. it's a shame.
+/* assign columns widths for a table whose max size doesn't fit in the available space
*/
-PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState& aReflowState,
nscoord aAvailWidth,
- nscoord aMaxWidth,
- nscoord aMinTableWidth,
- nscoord aMaxTableWidth)
+ nscoord aMaxWidth)
{
#ifdef DEBUG
nsIFrame *tablePIF=nsnull;
@@ -1145,17 +1015,14 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
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=0; // the width of the table as a result of setting column widths
+ 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
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
// proportional-width columns are equal (if any are anything other than 1)
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
- nscoord * effectiveMaxColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveMaxColumnWidths, 0, mNumCols*sizeof(PRInt32));
- nscoord * effectiveMinColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveMinColumnWidths, 0, mNumCols*sizeof(PRInt32));
PRInt32 numRows = mTableFrame->GetRowCount();
for (PRInt32 colIndex = 0; colIndexGetCellAt(rowIndex, colIndex);
- if (nsnull!=firstCellInColumn)
- break;
- }
- nsMargin colMargin;
- nscoord colInset = 0;
- if (nsnull!=firstCellInColumn)
- {
- firstCellInColumn->GetMargin(colMargin);
- colInset = colMargin.left + colMargin.right;
- }
+ nscoord colInset = mTableFrame->GetCellSpacing();
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
@@ -1224,8 +1078,13 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
+ if (colIndex!=cellFrame->GetColIndex()) {
+ // For cells that span cols, we figure in the row using previously-built SpanInfo
+ NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
+ continue;
+ }
- PRInt32 colSpan = cellFrame->GetColSpan();
+ PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame);
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
@@ -1237,29 +1096,15 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
const nsStylePosition* cellPosition;
cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition);
switch (cellPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
- if (gsDebug) printf("cell has specified coord width = %d\n", specifiedCellWidth);
- break;
-
case eStyleUnit_Percent:
{
nscoord knownTableWidth=0;
- nsIStyleContextPtr tableSC;
- mTableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
- PRBool tableIsAutoWidth = nsTableFrame::TableIsAutoWidth(mTableFrame, tableSC, aReflowState, knownTableWidth);
float percent = cellPosition->mWidth.GetPercentValue();
- specifiedCellWidth = (PRInt32)(knownTableWidth*percent);
+ specifiedCellWidth = (PRInt32)(aMaxWidth*percent);
if (gsDebug) printf("specified percent width %f of %d = %d\n",
- percent, knownTableWidth, specifiedCellWidth);
+ percent, aMaxWidth, specifiedCellWidth);
break;
}
-
- case eStyleUnit_Inherit:
- // XXX for now, do nothing
- default:
- case eStyleUnit_Auto:
- break;
}
if (-1!=specifiedCellWidth)
{
@@ -1277,19 +1122,16 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
// remember the widest min cell width
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
- // effectiveMinColumnWidth is the width as if no cells with colspans existed
- if ((1==colSpan) && (effectiveMinColumnWidths[colIndex] < minColWidth))
- effectiveMinColumnWidths[colIndex] = cellMinWidth;
// remember the max desired cell width
if (maxColWidth < cellDesiredWidth)
maxColWidth = cellDesiredWidth;
// effectiveMaxColumnWidth is the width as if no cells with colspans existed
- if ((1==colSpan) && (effectiveMaxColumnWidths[colIndex] < maxColWidth))
- effectiveMaxColumnWidths[colIndex] = cellDesiredWidth;
+ if ((1==colSpan) && (colFrame->GetEffectiveMaxColWidth() < maxColWidth))
+ colFrame->SetEffectiveMaxColWidth(cellDesiredWidth);
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
rowIndex, minColWidth, maxColWidth,
- colIndex, effectiveMaxColumnWidths[colIndex], effectiveMaxColumnWidths[colIndex]);
+ 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
@@ -1305,10 +1147,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
printf (" for determining width of col %d %s:\n",
colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)");
printf (" minTableWidth = %d and maxTableWidth = %d\n",
- aMinTableWidth, aMaxTableWidth);
+ mMinTableWidth, mMaxTableWidth);
printf (" minColWidth = %d, maxColWidth = %d, eff=%d,%d\n",
- minColWidth, maxColWidth, effectiveMinColumnWidths[colIndex],
- effectiveMaxColumnWidths[colIndex]);
+ minColWidth, maxColWidth, colFrame->GetEffectiveMinColWidth(),
+ colFrame->GetEffectiveMaxColWidth());
printf (" aAvailWidth = %d\n", aAvailWidth);
}
@@ -1318,10 +1160,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
nscoord specifiedFixedColumnWidth = -1;
PRBool isAutoWidth = PR_FALSE;
switch (colPosition->mWidth.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedFixedColumnWidth = colPosition->mWidth.GetCoordValue();
- if (gsDebug) printf("column %d has specified coord width = %d\n", colIndex, specifiedFixedColumnWidth);
- break;
case eStyleUnit_Percent:
specifiedPercentageColWidth = colPosition->mWidth.GetPercentValue();
if (gsDebug) printf("column %d has specified percent width = %f\n", colIndex, specifiedPercentageColWidth);
@@ -1379,16 +1217,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
if (1!=specifiedProportionColumnWidth)
equalWidthColumns = PR_FALSE;
}
- else if (-1!=specifiedFixedColumnWidth)
- { // the column has a specified pixel width
- // if the column was computed to be too small, enlarge the column
- nscoord resolvedWidth = specifiedFixedColumnWidth;
- if (specifiedFixedColumnWidth <= minColWidth)
- resolvedWidth = minColWidth;
- mTableFrame->SetColumnWidth(colIndex, resolvedWidth);
- if (gsDebug==PR_TRUE)
- printf (" 4 fixed: col %d given %d\n", colIndex, resolvedWidth);
- }
else
{ // give the column a percentage of the remaining space
PRInt32 percentage = -1;
@@ -1430,14 +1258,30 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
}
}
+ tableWidth += mTableFrame->GetColumnWidth(colIndex);
}
}
/* --- 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, effectiveMinColumnWidths, effectiveMaxColumnWidths);
+ DistributeRemainingSpace(aAvailWidth, tableWidth);
}
- // second, assign a width to proportional-width columns
+
+ // 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);
+ }
+ if (computedWidthaMaxWidth) {
+ AdjustTableThatIsTooWide(computedWidth, aMaxWidth);
+ }
+
+
+ // finally, assign a width to proportional-width columns
if (nsnull!=proportionalColumnsList)
{
// first, figure out the amount of space per slice
@@ -1469,11 +1313,6 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
// clean up
- // today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
- if (nsnull!=effectiveMinColumnWidths)
- delete [] effectiveMinColumnWidths;
- if (nsnull!=effectiveMaxColumnWidths)
- delete [] effectiveMaxColumnWidths;
if (nsnull!=spanList)
{
NS_ASSERTION(0==spanList->Count(), "space leak, span list not empty");
@@ -1486,20 +1325,18 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
//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 aTableFixedWidth,
- nscoord aComputedTableWidth,
- nscoord *aMinColWidths,
- nscoord *aMaxColWidths)
+void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableSpecifiedWidth,
+ nscoord aComputedTableWidth)
{
if (PR_TRUE==gsDebug)
printf ("DistributeRemainingSpace: fixed width %d > computed table width %d\n",
- aTableFixedWidth, aComputedTableWidth);
+ aTableSpecifiedWidth, aComputedTableWidth);
// if there are auto-sized columns, give them the extra space
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
// availWidth is the difference between the total available width and the
// amount of space already assigned, assuming auto col widths were assigned 0.
- nscoord availWidth = aTableFixedWidth - aComputedTableWidth;
+ nscoord availWidth = aTableSpecifiedWidth - aComputedTableWidth;
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0!=numAutoColumns)
{
@@ -1510,37 +1347,67 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableFixedWidt
PRInt32 i;
for (i = 0; iGetColFrame(autoColumns[i]);
+ nscoord maxEffectiveColWidth = colFrame->GetEffectiveMaxColWidth();
+ if (0!=maxEffectiveColWidth)
+ totalEffectiveWidthOfAutoColumns += maxEffectiveColWidth;
else
totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
}
if (gsDebug==PR_TRUE)
- printf(" aTableFixedWidth specified as %d, availWidth is = %d\n",
- aTableFixedWidth, availWidth);
+ printf(" aTableSpecifiedWidth specified as %d, availWidth is = %d\n",
+ aTableSpecifiedWidth, availWidth);
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iSetColumnWidth(colIndex, colWidth);
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ // 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
+ if (0GetEffectiveMaxColWidth()))/((float)totalEffectiveWidthOfAutoColumns);
+ else
+ percent = ((float)1)/((float)numAutoColumns);
+ nscoord colWidth = (nscoord)(availWidth*percent);
+ 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);
+ }
}
- EnsureCellMinWidths(aMinColWidths);
+
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf ("before EnsureCellMinWidth, computed table width is %d\n",tableWidth);
+ }
+
+ EnsureCellMinWidths();
+ }
+ if (PR_TRUE==gsDebug)
+ {
+ nscoord tableWidth=0;
+ for (PRInt32 i=0; iGetColumnWidth(i);
+ printf ("after EnsureCellMinWidth, computed table width is %d\n",tableWidth);
}
}
-void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
+void BasicTableLayoutStrategy::EnsureCellMinWidths()
{
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);
+ */
while (PR_TRUE==atLeastOne)
{
atLeastOne=PR_FALSE;
@@ -1549,11 +1416,13 @@ void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
// first, bump up cells that are below their min to their min width
for (colIndex=0; colIndexGetColFrame(colIndex);
+ nscoord minEffectiveColWidth = colFrame->GetEffectiveMinColWidth();
nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if (colWidthSetColumnWidth(colIndex, aMinColWidths[colIndex]);
+ addedWidth += (minEffectiveColWidth-colWidth);
+ mTableFrame->SetColumnWidth(colIndex, minEffectiveColWidth);
atLeastOne=PR_TRUE;
}
}
@@ -1561,21 +1430,93 @@ void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
//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 minEffectiveColWidth = colFrame->GetEffectiveMinColWidth();
nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
- if (colWidth>aMinColWidths[colIndex])
+ if (colWidth>minEffectiveColWidth)
{
mTableFrame->SetColumnWidth(colIndex, colWidth-1);
addedWidth--;
+ if (0==addedWidth)
+ { // we're run out of extra space
+ break; // for (colIndex=0; colIndex0))
+ }
}
if (0GetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
+ nscoord excess = aComputedWidth - aTableWidth;
+ if (0GetColumnWidth(colIndex);
+ colWidth -= excessPerColumn;
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ if (colWidth > colFrame->GetEffectiveMinColWidth())
+ mTableFrame->SetColumnWidth(colIndex, colWidth);
+ else
+ mTableFrame->SetColumnWidth(colIndex, colFrame->GetEffectiveMinColWidth());
+ }
+ }
+ }
+}
+
+void BasicTableLayoutStrategy::AdjustTableThatIsTooNarrow(nscoord aComputedWidth,
+ nscoord aTableWidth)
+{
+ PRInt32 numFixedColumns=0;
+ PRInt32 *fixedColumns=nsnull;
+ //XXX todo: exclude fixed width columns
+ //mTableFrame->GetColumnsByType(eStyleUnit_Coord, numFixedColumns, fixedColumns);
+ nscoord excess = aTableWidth - aComputedWidth;
+ if (0GetColumnWidth(colIndex);
+ colWidth += excessPerColumn;
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ if (colWidth >colFrame->GetEffectiveMinColWidth())
+ mTableFrame->SetColumnWidth(colIndex, colWidth);
+ else
+ mTableFrame->SetColumnWidth(colIndex, colFrame->GetEffectiveMinColWidth());
+ }
+ }
+ }
+}
+
+//PRBool BasicTableLayoutStrategy::IsFixedWidthColumn(PRInt32 colIndex, PRInt32 *colIndexes)
+
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.h b/mozilla/layout/tables/BasicTableLayoutStrategy.h
index 1bca0687baf..0ea87b4d5ca 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.h
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.h
@@ -31,20 +31,24 @@ struct nsStylePosition;
struct SpanInfo
{
- nscoord span;
+ PRInt32 span;
+ const PRInt32 initialColSpan;
nscoord cellMinWidth;
nscoord cellDesiredWidth;
- SpanInfo(nscoord aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
- {
- span = aSpan;
- cellMinWidth = aMinWidth;
- cellDesiredWidth = aDesiredWidth;
- };
-
+ SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth);
~SpanInfo() {};
};
+inline SpanInfo::SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
+ : initialColSpan(aSpan)
+{
+ span = aSpan;
+ cellMinWidth = aMinWidth;
+ cellDesiredWidth = aDesiredWidth;
+}
+
+
/* ---------- BasicTableLayoutStrategy ---------- */
@@ -60,86 +64,69 @@ public:
~BasicTableLayoutStrategy();
- virtual PRBool BalanceColumnWidths(nsIPresContext* aPresContext,
- nsIStyleContext *aTableStyle,
- const nsReflowState& aReflowState,
- nscoord aMaxWidth,
- nscoord &aTotalFixedWidth,
- nscoord &aMinTableWidth,
- nscoord &aMaxTableWidth,
- nsSize* aMaxElementSize);
+ /** call once every time any table thing changes (content, structure, or style) */
+ virtual PRBool Initialize(nsSize* aMaxElementSize);
- /** assign widths for each column that has fixed width.
+ virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle,
+ const nsReflowState& aReflowState,
+ nscoord aMaxWidth);
+
+ /** assign widths for each column.
+ * if the column has a fixed coord width, use it.
+ * if the column includes col spanning cells,
+ * then distribute the fixed space between cells proportionately.
* Computes the minimum and maximum table widths.
- * Sets mColumnWidths as a side effect.
- *
- * @param aPresContext the presentation context
- * @param aMaxWidth the maximum width of the table
- * @param aTableStyle the resolved style for the table
- * @param aTotalFixedWidth out param, the sum of the fixed width columns
- * @param aMinTableWidth out param, the min possible table width
- * @param aMaxTableWidth out param, the max table width
+ * Set column width information in each column frame and in the table frame.
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
- * TODO: should be renamed to "AssignKnownWidthInformation
*/
- virtual PRBool AssignFixedColumnWidths(nsIPresContext* aPresContext,
- nscoord aMaxWidth,
- nscoord & aTotalFixedWidth,
- nscoord & aMinTableWidth,
- nscoord & aMaxTableWidth);
+ virtual PRBool AssignPreliminaryColumnWidths();
/** assign widths for each column that has proportional width inside a table that
* has auto width (width set by the content and available space.)
* Sets mColumnWidths as a side effect.
*
- * @param aPresContext the presentation context
- * @param aTableStyle the resolved style for the table
- * @param aAvailWidth the remaining amount of horizontal space available
- * @param aMaxWidth the total amount of horizontal space available
- * @param aMinTableWidth the min possible table width
- * @param aMaxTableWidth the max table width
+ * @param aTableStyle the resolved style for the table
+ * @param aAvailWidth the remaining amount of horizontal space available
+ * @param aMaxWidth the total amount of horizontal space available
+ * @param aTableSpecifiedWidth the width of the table based on its attributes and its parent's width
+ * @param aTableIsAutoWidth PR_TRUE if the table is auto-width
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
*/
- virtual PRBool BalanceProportionalColumns(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+ virtual PRBool BalanceProportionalColumns(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
- nscoord aMinTableWidth,
- nscoord aMaxTableWidth,
- nscoord aTableFixedWidth,
+ nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth);
/** assign the minimum allowed width for each column that has proportional width.
* Typically called when the min table width doesn't fit in the available space.
* Sets mColumnWidths as a side effect.
*
- * @param aPresContext the presentation context
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*/
- virtual PRBool SetColumnsToMinWidth(nsIPresContext* aPresContext);
+ virtual PRBool SetColumnsToMinWidth();
/** assign the maximum allowed width for each column that has proportional width.
* Typically called when the desired max table width fits in the available space.
* Sets mColumnWidths as a side effect.
*
- * @param aPresContext the presentation context
- * @param aAvailWidth the remaining amount of horizontal space available
- * @param aMaxWidth the total amount of horizontal space available
- * @param aTableFixedWidth the specified width of the table. If there is none,
- * this param is 0
+ * @param aAvailWidth the remaining amount of horizontal space available
+ * @param aMaxWidth the total amount of horizontal space available
+ * @param aTableSpecifiedWidth the specified width of the table. If there is none,
+ * this param is 0
+ * @param aTableIsAutoWidth PR_TRUE if the table is auto-width
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*/
- virtual PRBool BalanceColumnsTableFits(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+ virtual PRBool BalanceColumnsTableFits(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
- nscoord aTableFixedWidth,
+ nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth);
/** assign widths for each column that has proportional width inside a table that
@@ -147,7 +134,6 @@ public:
* HTML 4 specification.
* Sets mColumnWidths as a side effect.
*
- * @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
@@ -158,23 +144,19 @@ public:
*
* TODO: rename this method to reflect that it is a Nav4 compatibility method
*/
- virtual PRBool BalanceColumnsConstrained(nsIPresContext* aPresContext,
- const nsReflowState& aReflowState,
+ virtual PRBool BalanceColumnsConstrained(const nsReflowState& aReflowState,
nscoord aAvailWidth,
- nscoord aMaxWidth,
- nscoord aMinTableWidth,
- nscoord aMaxTableWidth);
+ nscoord aMaxWidth);
/** post-process to AssignFixedColumnWidths
*
* @param aColSpanList a list of fixed-width columns that have colspans
- * @param aColWidths the effective column widths (ignoring col span cells)
*
* NOTE: does not yet properly handle overlapping col spans
*
* @return void
*/
- virtual void DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths);
+ virtual void DistributeFixedSpace(nsVoidArray *aColSpanList);
/** starting with a partially balanced table, compute the amount
* of space to pad each column by to completely balance the table.
@@ -189,8 +171,7 @@ public:
*/
virtual void DistributeExcessSpace(nscoord aAvailWidth,
nscoord aTableWidth,
- nscoord aWidthOfFixedTableColumns,
- nscoord *aColWidths);
+ nscoord aWidthOfFixedTableColumns);
/** starting with a partially balanced table, compute the amount
* of space to remove from each column to completely balance the table.
@@ -203,14 +184,18 @@ public:
* @return void
*/
virtual void DistributeRemainingSpace(nscoord aTableFixedWidth,
- nscoord aComputedTableWidth,
- nscoord *aMinColWidths,
- nscoord *aMaxColWidths);
+ nscoord aComputedTableWidth);
/** 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(nscoord *aMinColWidths);
+ virtual void EnsureCellMinWidths();
+
+ virtual void AdjustTableThatIsTooWide(nscoord aComputedWidth,
+ nscoord aTableWidth);
+
+ virtual void AdjustTableThatIsTooNarrow(nscoord aComputedWidth,
+ nscoord aTableWidth);
/** return true if the style indicates that the width is a specific width
* for the purposes of column width determination.
@@ -218,12 +203,15 @@ public:
*/
virtual PRBool IsFixedWidth(const nsStylePosition* aStylePosition);
- virtual PRBool IsAutoWidth(const nsStylePosition* aStylePosition);
protected:
nsTableFrame * mTableFrame;
PRInt32 mCols;
PRInt32 mNumCols;
+ // cached data
+ nscoord mMinTableWidth; // the absolute smallest width for the table
+ nscoord mMaxTableWidth; // the "natural" size for the table, if unconstrained
+ nscoord mFixedTableWidth; // the amount of space taken up by fixed-width columns
};
diff --git a/mozilla/layout/tables/nsITableLayoutStrategy.h b/mozilla/layout/tables/nsITableLayoutStrategy.h
index 861aa290f3b..543235dbf91 100644
--- a/mozilla/layout/tables/nsITableLayoutStrategy.h
+++ b/mozilla/layout/tables/nsITableLayoutStrategy.h
@@ -22,7 +22,6 @@
#include "nscore.h"
#include "nsSize.h"
-class nsIPresContext;
class nsIStyleContext;
struct nsReflowState;
@@ -30,25 +29,21 @@ class nsITableLayoutStrategy
{
public:
+ /** call once every time any table thing changes (content, structure, or style)
+ * @param aMaxElementSize [OUT] the min possible size of the table
+ */
+ virtual PRBool Initialize(nsSize* aMaxElementSize)=0;
+
/** assign widths for each column, taking into account the table content, the effective style,
* the layout constraints, and the compatibility mode. Sets mColumnWidths as a side effect.
- * @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aReflowState the reflow state for the calling table frame
* @param aMaxWidth the width constraint
- * @param aTotalFixedWidth [OUT] the computed fixed width of the table
- * @param aMinTableWidth [OUT] the computed min width of the table
- * @param aMinTableWidth [OUT] the computed max width of the table
- * @param aMaxElementSize [OUT] the min size of the largest indivisible object
+
*/
- virtual PRBool BalanceColumnWidths(nsIPresContext* aPresContext,
- nsIStyleContext *aTableStyle,
+ virtual PRBool BalanceColumnWidths(nsIStyleContext *aTableStyle,
const nsReflowState& aReflowState,
- nscoord aMaxWidth,
- nscoord &aTotalFixedWidth,
- nscoord &aMinTableWidth,
- nscoord &aMaxTableWidth,
- nsSize* aMaxElementSize)=0;
+ nscoord aMaxWidth)=0;
};
#endif
diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp
index 3615f2b3ccf..3ff92ad013e 100644
--- a/mozilla/layout/tables/nsTableCellFrame.cpp
+++ b/mozilla/layout/tables/nsTableCellFrame.cpp
@@ -511,10 +511,10 @@ void nsTableCellFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
return;
// get the table frame style context, and from it get cellpadding, cellspacing, and border info
- nsIStyleContextPtr tableSC;
- tableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
- nsStyleTable* tableStyle = (nsStyleTable*)tableSC->GetStyleData(eStyleStruct_Table);
- nsStyleSpacing* tableSpacingStyle = (nsStyleSpacing*)tableSC->GetStyleData(eStyleStruct_Spacing);
+ nsStyleTable* tableStyle;
+ tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
+ nsStyleSpacing* tableSpacingStyle;
+ tableFrame->GetStyleData(eStyleStruct_Spacing,(nsStyleStruct *&)tableSpacingStyle);
nsStyleSpacing* spacingData = (nsStyleSpacing*)mStyleContext->GetMutableStyleData(eStyleStruct_Spacing);
// check to see if cellpadding or cellspacing is defined
diff --git a/mozilla/layout/tables/nsTableColFrame.cpp b/mozilla/layout/tables/nsTableColFrame.cpp
index 4745bd68b5a..4fe0f13656b 100644
--- a/mozilla/layout/tables/nsTableColFrame.cpp
+++ b/mozilla/layout/tables/nsTableColFrame.cpp
@@ -38,6 +38,10 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
{
mColIndex = 0;
mRepeat = 0;
+ mMaxColWidth = 0;
+ mMinColWidth = 0;
+ mMaxEffectiveColWidth = 0;
+ mMinEffectiveColWidth = 0;
}
@@ -55,11 +59,12 @@ NS_METHOD nsTableColFrame::Paint(nsIPresContext& aPresContext,
}
-NS_METHOD nsTableColFrame::Reflow(nsIPresContext& aPresContext,
+NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
+ NS_ASSERTION(nsnull!=aPresContext, "bad arg");
aDesiredSize.width=0;
aDesiredSize.height=0;
if (nsnull!=aDesiredSize.maxElementSize)
diff --git a/mozilla/layout/tables/nsTableColFrame.h b/mozilla/layout/tables/nsTableColFrame.h
index 3c70a7955b8..13b8b66691a 100644
--- a/mozilla/layout/tables/nsTableColFrame.h
+++ b/mozilla/layout/tables/nsTableColFrame.h
@@ -34,7 +34,7 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
- NS_IMETHOD Reflow(nsIPresContext& aPresContext,
+ NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
@@ -51,6 +51,18 @@ public:
/** convenience method, calls into cellmap */
nsVoidArray * GetCells();
+ nscoord GetMaxColWidth();
+ void SetMaxColWidth(nscoord aMaxColWidth);
+
+ nscoord GetMinColWidth();
+ void SetMinColWidth(nscoord aMinColWidth);
+
+ nscoord GetEffectiveMaxColWidth();
+ void SetEffectiveMaxColWidth(nscoord aMaxColWidth);
+
+ nscoord GetEffectiveMinColWidth();
+ void SetEffectiveMinColWidth(nscoord aMinColWidth);
+
/** convenience method, calls into cellmap */
PRInt32 Count() const;
@@ -66,11 +78,11 @@ protected:
/** the number of columns that the attributes of this column extend to */
PRInt32 mRepeat;
- nscoord mMaxWidth;
- nscoord mMinWidth;
+ nscoord mMaxColWidth;
+ nscoord mMinColWidth;
- nscoord mMaxEffectiveWidth;
- nscoord mMinEffectiveWidth;
+ nscoord mMaxEffectiveColWidth;
+ nscoord mMinEffectiveColWidth;
};
@@ -93,5 +105,29 @@ inline nsTableColFrame::GetRepeat()
inline void nsTableColFrame::SetColumnIndex (int aColIndex)
{ mColIndex = aColIndex;}
+inline nscoord nsTableColFrame::GetMaxColWidth()
+{ return mMaxColWidth; }
+
+inline void nsTableColFrame::SetMaxColWidth(nscoord aMaxColWidth)
+{ mMaxColWidth = aMaxColWidth; }
+
+inline nscoord nsTableColFrame::GetMinColWidth()
+{ return mMinColWidth; }
+
+inline void nsTableColFrame::SetMinColWidth(nscoord aMinColWidth)
+{ mMinColWidth = aMinColWidth; }
+
+inline nscoord nsTableColFrame::GetEffectiveMaxColWidth()
+{ return mMaxEffectiveColWidth; }
+
+inline void nsTableColFrame::SetEffectiveMaxColWidth(nscoord aMaxColWidth)
+{ mMaxEffectiveColWidth = aMaxColWidth; }
+
+inline nscoord nsTableColFrame::GetEffectiveMinColWidth()
+{ return mMinEffectiveColWidth; }
+
+inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinColWidth)
+{ mMinEffectiveColWidth = aMinColWidth; }
+
#endif
diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp
index 4be7370650a..6c7d634f564 100644
--- a/mozilla/layout/tables/nsTableFrame.cpp
+++ b/mozilla/layout/tables/nsTableFrame.cpp
@@ -396,7 +396,7 @@ nsTableCellFrame * nsTableFrame::GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex)
}
-// return the rows spanned by aCell starting at aRowIndex
+// return the number of rows spanned by aCell starting at aRowIndex
// note that this is different from just the rowspan of aCell
// (that would be GetEffectiveRowSpan (indexOfRowThatContains_aCell, aCell)
//
@@ -416,6 +416,24 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
return rowSpan;
}
+// return the number of cols spanned by aCell starting at aColIndex
+// note that this is different from just the colspan of aCell
+// (that would be GetEffectiveColSpan (indexOfColThatContains_aCell, aCell)
+//
+// XXX Should be moved to colgroup, as GetEffectiveRowSpan should be moved to rowgroup?
+PRInt32 nsTableFrame::GetEffectiveColSpan (PRInt32 aColIndex, nsTableCellFrame *aCell)
+{
+ NS_PRECONDITION (nsnull!=aCell, "bad cell arg");
+ 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 (colCount < (aColIndex + colSpan))
+ return (colCount - aColIndex);
+ return colSpan;
+}
+
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTableFrame::ResetCellMap ()
{
@@ -1198,6 +1216,11 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
// XXX For the time being just fall through and treat it like a
// pass 2 reflow...
mPass = kPASS_SECOND;
+ // calling intialize here resets all the cached info based on new table content
+ if (nsnull!=mTableLayoutStrategy)
+ {
+ mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
+ }
#else
// XXX Hack...
AdjustSiblingsAfterReflow(&aPresContext, state, kidFrame, desiredSize.height -
@@ -2231,9 +2254,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
{
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
- if (gsDebug)
- printf ("BalanceColumnWidths...\n");
-
if (nsnull==mCellMap)
return; // we don't have any information yet, so we can't do any useful work
@@ -2244,11 +2264,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
nsCRT::memset (mColumnWidths, 0, numCols*sizeof(PRInt32));
}
- // need to track min and max table widths
- PRInt32 minTableWidth = 0;
- PRInt32 maxTableWidth = 0;
- PRInt32 totalFixedWidth = 0;
-
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
@@ -2308,13 +2323,9 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
if (nsnull==mTableLayoutStrategy)
{ // TODO: build a different strategy based on the compatibility mode
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, numCols);
+ mTableLayoutStrategy->Initialize(aMaxElementSize);
}
- mTableLayoutStrategy->BalanceColumnWidths(aPresContext, mStyleContext,
- aReflowState, maxWidth,
- totalFixedWidth,
- minTableWidth, maxTableWidth,
- aMaxElementSize);
-
+ mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
}
/**
@@ -2608,7 +2619,7 @@ nsTableFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
nsIStyleContext* kidStyleContext =
aPresContext.ResolveStyleContextFor(content, cf); // kidStyleContext: REFCNT++
nsIContentDelegate* kidDel = nsnull;
- kidDel = content->GetDelegate(&aPresContext); // kidDel: REFCNT++
+ kidDel = content->GetDelegate(&aPresContext); // kidDel: REFCNT++
nsIFrame* duplicateFrame;
nsresult rv = kidDel->CreateFrame(&aPresContext, content, cf,
kidStyleContext, duplicateFrame);
@@ -2825,6 +2836,19 @@ NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin&
return result;
}
+nscoord nsTableFrame::GetCellSpacing()
+{
+ nsTableFrame* tableFrame = this;
+ //XXX remove when table style is fully resolved!
+ GetGeometricParent((nsIFrame *&)tableFrame); // get the outer frame
+ nsStyleTable* tableStyle;
+ tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
+ nscoord cellSpacing = 0;
+ if (tableStyle->mCellSpacing.GetUnit() == eStyleUnit_Coord)
+ cellSpacing = tableStyle->mCellSpacing.GetCoordValue();
+ return cellSpacing;
+}
+
void nsTableFrame::GetColumnsByType(const nsStyleUnit aType,
PRInt32& aOutNumColumns,
PRInt32 *& aOutColumnIndexes)
@@ -2989,27 +3013,34 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsReflowState& aReflowState)
}
else
{
- nsSize tableSize;
- table->GetSize(tableSize);
- parentWidth = tableSize.width;
- spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the row group
- childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(childFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the row
- grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
- // same for the cell
- greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
- spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
- parentWidth -= (borderPadding.right + borderPadding.left);
-
+ if (nsnull!=((nsTableFrame*)table)->mColumnWidths)
+ {
+ PRInt32 colIndex = ((nsTableCellFrame*)greatgrandchildFrame)->GetColIndex();
+ parentWidth = ((nsTableFrame*)table)->GetColumnWidth(colIndex);
+ }
+ else
+ {
+ nsSize tableSize;
+ table->GetSize(tableSize);
+ parentWidth = tableSize.width;
+ spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
+ parentWidth -= (borderPadding.right + borderPadding.left);
+ // same for the row group
+ childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(childFrame, borderPadding);
+ parentWidth -= (borderPadding.right + borderPadding.left);
+ // same for the row
+ grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
+ parentWidth -= (borderPadding.right + borderPadding.left);
+ // same for the cell
+ greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
+ spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
+ parentWidth -= (borderPadding.right + borderPadding.left);
+ }
if (PR_TRUE==gsDebugNT)
- printf("%p: found a table frame %p, returning parentWidth %d from frame width %d\n",
- aReflowState.frame, table, parentWidth, tableSize.width);
+ printf("%p: found a table frame %p, returning parentWidth %d \n",
+ aReflowState.frame, table, parentWidth);
}
break;
}
diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h
index c59004e4ddd..9ffdaf42d7e 100644
--- a/mozilla/layout/tables/nsTableFrame.h
+++ b/mozilla/layout/tables/nsTableFrame.h
@@ -142,6 +142,9 @@ public:
/** set the width of the column at aColIndex to aWidth */
virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
+
+ /** helper to get the cell spacing style value */
+ virtual nscoord GetCellSpacing();
/**
* Calculate Layout Information
@@ -167,13 +170,26 @@ public:
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table.
- * @param aRowIndex the first row that contains the cell
- * @param aCell the content object representing the cell
+ *
+ * @param aRowIndex the row from which to measure effective row span
+ * @param aCell the cell
+ *
* @return the row span, correcting for row spans that extend beyond the bottom
* of the table.
*/
virtual PRInt32 GetEffectiveRowSpan(PRInt32 aRowIndex, nsTableCellFrame *aCell);
+ /** return the col span of a cell, taking into account col span magic at the edge
+ * of a table.
+ *
+ * @param aColIndex the column from which to measure effective col span
+ * @param aCell the cell
+ *
+ * @return the col span, correcting for col spans that extend beyond the edge
+ * of the table.
+ */
+ virtual PRInt32 GetEffectiveColSpan(PRInt32 aColIndex, nsTableCellFrame *aCell);
+
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp
index cd47a83a684..93c77d2ec55 100644
--- a/mozilla/layout/tables/nsTableRowFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowFrame.cpp
@@ -336,19 +336,22 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
nscoord maxCellTopMargin = 0;
nscoord maxCellBottomMargin = 0;
+ if (PR_TRUE==gsDebug1) printf("%p: RR\n", this);
+
// Reflow each of our existing cell frames
- for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
- // Get the frame's margins, and compare the top and bottom margin
- // against our current max values
- nsMargin kidMargin;
+ for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
+ {
+
+ nscoord cellSpacing = aState.tableFrame->GetCellSpacing();
+
+// just cellSpacing? QQQ
+ nsMargin kidMargin;
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
if (kidMargin.top > maxCellTopMargin)
maxCellTopMargin = kidMargin.top;
if (kidMargin.bottom > maxCellBottomMargin)
maxCellBottomMargin = kidMargin.bottom;
- // left and right margins already taken into account by table layout strategy
-
// Compute the x-origin for the child, taking into account straddlers (cells from prior
// rows with rowspans > 1)
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
@@ -357,10 +360,14 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
for (PRInt32 colIndex=prevColIndex+1; colIndexGetColumnWidth(colIndex);
- aState.x += kidMargin.left + kidMargin.right;
+ aState.x += cellSpacing;
+ if (PR_TRUE==gsDebug1)
+ printf(" in loop, aState.x set to %d from cellSpacing %d and col width\n",
+ aState.x, aState.tableFrame->GetColumnWidth(colIndex), cellSpacing);
}
}
- aState.x += kidMargin.left;
+ aState.x += cellSpacing;
+ if (PR_TRUE==gsDebug1) printf(" past loop, aState.x set to %d\n", aState.x);
// at this point, we know the column widths.
// so we get the avail width from the known column widths
@@ -369,13 +376,15 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
for (PRInt32 numColSpan=0; numColSpanGetColumnWidth(cellColIndex+numColSpan);
- if (0GetColumnWidth(cellColIndex+numColSpan), cellSpacing);
}
+ if (PR_TRUE==gsDebug1) printf(" availWidth for this cell is %d\n", availWidth);
prevColIndex = cellColIndex + (cellColSpan-1); // remember the rightmost column this cell spans into
@@ -461,7 +470,8 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
pKidMaxElementSize);
- aState.x += kidMargin.right; // add in right margin only after cell has been placed
+
+ if (PR_TRUE==gsDebug1) printf(" past PlaceChild, aState.x set to %d\n", aState.x);
// Get the next child
kidFrame->GetNextSibling(kidFrame);