irrationally-specified table (one where the width attributes of various rows don't add up to the same value,

and/or to the width attribute on the table itself), the rule is to try to give the column the largest value
assigned to it by any cell intersecting that column.
Separate storage is maintained for a column's natural desired width (width from any source other than a cell
with a colspan) and the maximum contribution to the column's width from any cell with a colspan.


git-svn-id: svn://10.0.0.236/trunk@14732 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
buster%netscape.com 1998-11-16 06:46:00 +00:00
parent b0070d4d60
commit aeee0e2b41
10 changed files with 472 additions and 468 deletions

View File

@ -81,23 +81,15 @@ struct ColSpanStruct
/* ---------- BasicTableLayoutStrategy ---------- */
/* return true if the style indicates that the width is proportional
/* return true if the style indicates that the width is fixed
* for the purposes of column width determination
*/
PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosition)
inline
PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosition,
const nsStyleTable* aStyleTable)
{
PRBool result = PR_FALSE; // assume that it is not fixed width
PRInt32 unitType;
if (nsnull == aStylePosition) {
result=PR_TRUE;
}
else {
unitType = aStylePosition->mWidth.GetUnit();
if (eStyleUnit_Coord==unitType)
result=PR_TRUE;
}
return result;
return PRBool ((eStyleUnit_Coord==aStylePosition->mWidth.GetUnit()) ||
(eStyleUnit_Coord==aStyleTable->mSpanWidth.GetUnit()));
}
@ -255,7 +247,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
nsVoidArray *spanList=nsnull;
nsVoidArray *colSpanList=nsnull;
PRInt32 numProvisionalFixedColumns = 0; // used for assigning width from cell with colspan to columns that are spanned
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
@ -278,8 +269,13 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
nscoord maxColWidth = 0; // max col width factoring in table attributes
nscoord effectiveMinColumnWidth = 0; // min col width ignoring cells with colspans
nscoord effectiveMaxColumnWidth = 0; // max col width ignoring cells with colspans
nscoord specifiedFixedColWidth = 0; // the width of the column if given stylistically (or via cell Width attribute)
nscoord specifiedFixedColWidth = 0; /* the width of the column if given stylistically (or via cell Width attribute)
only applicable if haveColWidth==PR_TRUE
*/
PRBool haveColWidth = PR_FALSE; /* if true, the column has a width either from HTML width attribute,
from a style rule on the column,
or from a width attr/style on a cell that has colspan==1
*/
// Get column information
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
@ -287,15 +283,14 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
// Get the columns's style
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
const nsStyleTable* colTableStyle;
colFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct*&)colTableStyle);
// Get fixed column width if it has one
PRBool haveColWidth = PR_FALSE;
if (eStyleUnit_Coord==colPosition->mWidth.GetUnit())
{
haveColWidth = PR_TRUE;
specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
if (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN==colFrame->GetWidthSource())
numProvisionalFixedColumns++;
}
/* Scan the column, simulatneously assigning column widths
@ -346,12 +341,11 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
cellDesiredSize.width, cellDesiredSize.height);
if ((PR_TRUE==haveColWidth) &&
(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN!=colFrame->GetWidthSource()))
if (PR_TRUE==haveColWidth)
{
// This col has a specified fixed width so set the min and max width to the larger of
// (specified width, largest max_element_size of the cells in the column)
// factoring in the min width of the prior cells (stored in minColWidth)
/* This col has a specified coord fixed width, so set the min and max width to the larger of
(specified width, largest max_element_size of the cells in the column)
factoring in the min width of the prior cells (stored in minColWidth) */
nscoord widthForThisCell = specifiedFixedColWidth;
if (0==specifiedFixedColWidth) // set to min
specifiedFixedColWidth = cellMinWidth;
@ -390,7 +384,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
{
// add the column to our list of post-process columns, if all of the intersected columns are auto
PRBool okToAdd = PR_TRUE;
if (numRows==1 || (PR_FALSE==IsFixedWidth(colPosition)))
if (numRows==1 || (PR_FALSE==IsFixedWidth(colPosition, colTableStyle)))
okToAdd = PR_FALSE;
else
{
@ -410,8 +404,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
}
nscoord width = cellDesiredSize.width; // used below as the cell's "natural" width
if ((PR_TRUE == haveColWidth)) //XXX && (PR_TRUE==cellGrantingWidth) ?
width = colSpan*specifiedFixedColWidth;
if (eStyleUnit_Coord==colTableStyle->mSpanWidth.GetUnit())
width = colSpan*colTableStyle->mSpanWidth.GetCoordValue(); // "colSpan*" because table frame divided per column spanned
if (PR_TRUE==okToAdd)
{
@ -434,6 +428,10 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
//bookkeeping: is this the cell that gave the column it's fixed width attribute?
// must be done after "haveColWidth && cellGrantingWidth" used above
/* since we want the biggest, I don't think this is valid anymore
it made sense when the rule was to grab the first cell that contributed a width
*/
/*
if (PR_TRUE==cellGrantingWidth)
{
const nsStylePosition* cellPosition;
@ -441,6 +439,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
}
*/
// book 'em, Danno
if (gsDebug) {
@ -454,7 +453,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
specifiedFixedColWidth=effectiveMinColumnWidth;
// do all the global bookkeeping, factoring in margins
nscoord colInset = mTableFrame->GetCellSpacing();
if (PR_TRUE==gsDebug) printf("* cellSpacing=%d\n", colInset);
// keep a running total of the amount of space taken up by all fixed-width columns
if ((PR_TRUE==haveColWidth) && (nsTableColFrame::eWIDTH_SOURCE_CELL==colFrame->GetWidthSource()))
{
@ -501,123 +499,105 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0&&(0==numAutoColumns && 0==numProvisionalFixedColumns))
{ //table fully specified, so no need to do any extra work here
// for every column, handle spanning cells that impact that column
for (PRInt32 colIndex=0; colIndex<mNumCols; colIndex++)
{
if (gsDebug) printf("handling span for %d\n", colIndex);
PRInt32 spanCount = spanList->Count();
// go through the list backwards so we can delete easily
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{
{ // get each spanInfo struct and see if it impacts this column
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
spanList->RemoveElementAt(spanIndex);
delete spanInfo;
}
}
else
{ // for every column, handle spanning cells that impact that column
for (PRInt32 colIndex=0; colIndex<mNumCols; colIndex++)
{
if (gsDebug) printf("handling span for %d\n", colIndex);
PRInt32 spanCount = spanList->Count();
// go through the list backwards so we can delete easily
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{ // get each spanInfo struct and see if it impacts this column
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
// if the spanInfo is about a column before the current column, it effects
// the current column (otherwise it would have already been deleted.)
if (spanInfo->initialColIndex <= colIndex)
// if the spanInfo is about a column before the current column, it effects
// the current column (otherwise it would have already been deleted.)
if (spanInfo->initialColIndex <= colIndex)
{
if (-1==spanInfo->effectiveMaxWidthOfSpannedCols)
{ // if we have not yet computed effectiveMaxWidthOfSpannedCols, do it now
// first, initialize the sums
spanInfo->effectiveMaxWidthOfSpannedCols=0;
spanInfo->effectiveMinWidthOfSpannedCols=0;
// then compute the sums
for (PRInt32 span=0; span<spanInfo->initialColSpan; span++)
{
nsTableColFrame *nextColFrame = mTableFrame->GetColFrame(colIndex+span);
if (nsnull==nextColFrame)
break;
spanInfo->effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
spanInfo->effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
}
if (gsDebug) printf("effective min total = %d, max total = %d\n",
spanInfo->effectiveMinWidthOfSpannedCols, spanInfo->effectiveMaxWidthOfSpannedCols);
}
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
nscoord colMinWidth = colFrame->GetMinColWidth();
// compute the spanning cell's contribution to the column min width
// this is the "adjusted" column width, used in SetTableToMinWidth
nscoord spanCellMinWidth;
if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
{
if (-1==spanInfo->effectiveMaxWidthOfSpannedCols)
{ // if we have not yet computed effectiveMaxWidthOfSpannedCols, do it now
// first, initialize the sums
spanInfo->effectiveMaxWidthOfSpannedCols=0;
spanInfo->effectiveMinWidthOfSpannedCols=0;
// then compute the sums
for (PRInt32 span=0; span<spanInfo->initialColSpan; span++)
{
nsTableColFrame *nextColFrame = mTableFrame->GetColFrame(colIndex+span);
if (nsnull==nextColFrame)
break;
spanInfo->effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
spanInfo->effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
}
if (gsDebug) printf("effective min total = %d, max total = %d\n",
spanInfo->effectiveMinWidthOfSpannedCols, spanInfo->effectiveMaxWidthOfSpannedCols);
}
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
nscoord colMinWidth = colFrame->GetMinColWidth();
// compute the spanning cell's contribution to the column min width
// this is the "adjusted" column width, used in SetTableToMinWidth
nscoord spanCellMinWidth;
if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
float percent = ((float)(colFrame->GetEffectiveMinColWidth())) /
((float)(spanInfo->effectiveMinWidthOfSpannedCols));
spanCellMinWidth = NSToCoordRound(((float)(spanInfo->cellMinWidth)) * percent);
if (gsDebug==PR_TRUE)
printf ("spanCellMinWidth portion = %d from percent=%f, cellMW=%d, effMinColW=%d, sum=%d\n",
spanCellMinWidth, percent, spanInfo->cellMinWidth, colFrame->GetEffectiveMinColWidth(),
spanInfo->effectiveMinWidthOfSpannedCols);
if (colMinWidth < spanCellMinWidth)
colFrame->SetAdjustedMinColWidth(spanCellMinWidth); // set the new min width for the col
}
else
{
spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
if (colMinWidth < spanCellMinWidth)
{
float percent = ((float)(colFrame->GetEffectiveMinColWidth())) /
((float)(spanInfo->effectiveMinWidthOfSpannedCols));
spanCellMinWidth = NSToCoordRound(((float)(spanInfo->cellMinWidth)) * percent);
colFrame->SetAdjustedMinColWidth(spanCellMinWidth);
}
}
// compute the spanning cell's contribution to the column max width
nscoord colMaxWidth = colFrame->GetMaxColWidth();
nscoord spanCellMaxWidth;
if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
{
float percent = ((float)(colFrame->GetEffectiveMaxColWidth())) /
((float)(spanInfo->effectiveMaxWidthOfSpannedCols));
spanCellMaxWidth = NSToCoordRound(((float)(spanInfo->cellDesiredWidth)) * percent);
if (gsDebug==PR_TRUE)
printf ("spanCellMaxWidth portion = %d with percent = %f from cellDW = %d, effMaxColW=%d and sum=%d\n",
spanCellMaxWidth, percent, spanInfo->cellDesiredWidth, colFrame->GetEffectiveMaxColWidth(),
spanInfo->effectiveMaxWidthOfSpannedCols);
if (colMaxWidth < spanCellMaxWidth)
{
// make sure we're at least as big as our min
spanCellMaxWidth = PR_MAX(spanCellMaxWidth, colMinWidth);
colFrame->SetMaxColWidth(spanCellMaxWidth); // set the new max width for the col
mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
if (gsDebug==PR_TRUE)
printf ("spanCellMinWidth portion = %d from percent=%f, cellMW=%d, effMinColW=%d, sum=%d\n",
spanCellMinWidth, percent, spanInfo->cellMinWidth, colFrame->GetEffectiveMinColWidth(),
spanInfo->effectiveMinWidthOfSpannedCols);
if (colMinWidth < spanCellMinWidth)
colFrame->SetAdjustedMinColWidth(spanCellMinWidth); // set the new min width for the col
}
else
{
spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
if (colMinWidth < spanCellMinWidth)
{
colFrame->SetAdjustedMinColWidth(spanCellMinWidth);
printf ("for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n",
colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
}
}
}
else
{
spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
nscoord minColWidth = colFrame->GetMinColWidth();
spanCellMaxWidth = PR_MAX(spanCellMaxWidth, minColWidth);
colFrame->SetMaxColWidth(spanCellMaxWidth);
mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
if (gsDebug==PR_TRUE)
printf (" for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n",
colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
}
// only compute the col spanner's contribution to the desired cell width
// if the width is from a col spanning cell
if (nsTableColFrame::eWIDTH_SOURCE_CELL!=colFrame->GetWidthSource())
{
// compute the spanning cell's contribution to the column max width
nscoord colMaxWidth = colFrame->GetMaxColWidth();
nscoord spanCellMaxWidth;
if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
{
float percent = ((float)(colFrame->GetEffectiveMaxColWidth())) /
((float)(spanInfo->effectiveMaxWidthOfSpannedCols));
spanCellMaxWidth = NSToCoordRound(((float)(spanInfo->cellDesiredWidth)) * percent);
if (gsDebug==PR_TRUE)
printf ("spanCellMaxWidth portion = %d with percent = %f from cellDW = %d, effMaxColW=%d and sum=%d\n",
spanCellMaxWidth, percent, spanInfo->cellDesiredWidth, colFrame->GetEffectiveMaxColWidth(),
spanInfo->effectiveMaxWidthOfSpannedCols);
if (colMaxWidth < spanCellMaxWidth)
{
// make sure we're at least as big as our min
spanCellMaxWidth = PR_MAX(spanCellMaxWidth, colMinWidth);
colFrame->SetMaxColWidth(spanCellMaxWidth); // set the new max width for the col
mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
if (gsDebug==PR_TRUE)
{
printf ("for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n",
colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
}
}
}
else
{
spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
nscoord minColWidth = colFrame->GetMinColWidth();
spanCellMaxWidth = PR_MAX(spanCellMaxWidth, minColWidth);
colFrame->SetMaxColWidth(spanCellMaxWidth);
mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
if (gsDebug==PR_TRUE)
printf (" for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n",
colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
}
}
spanInfo->span--;
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
delete spanInfo;
}
spanInfo->span--;
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
delete spanInfo;
}
}
}
@ -784,7 +764,7 @@ void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList)
for (i = 0; i<colSpan; i++)
{
mTableFrame->GetColumnFrame(colIndex+i, colFrame);
totalEffectiveWidth += colFrame->GetEffectiveMaxColWidth();
totalEffectiveWidth += colFrame->GetColWidthForComputation();
}
// 2. next, compute the proportion to be added to each column, and add it
@ -792,7 +772,7 @@ void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList)
{
mTableFrame->GetColumnFrame(colIndex+i, colFrame);
float percent;
percent = ((float)(colFrame->GetEffectiveMaxColWidth()))/((float)totalEffectiveWidth);
percent = ((float)(colFrame->GetColWidthForComputation()))/((float)totalEffectiveWidth);
nscoord newColWidth = NSToCoordRound(((float)totalColWidth)*percent);
nscoord minColWidth = colFrame->GetEffectiveMinColWidth();
nscoord oldColWidth = mTableFrame->GetColumnWidth(colIndex+i);
@ -832,7 +812,7 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(const nsHTMLReflowSt
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");
if (gsDebug) printf (" * table laying out in NS_UNCONSTRAINEDSIZE, calling BalanceColumnsTableFits\n");
nscoord bigSpace = gBigSpace;
bigSpace = PR_MAX(bigSpace, mMaxTableWidth);
result = BalanceColumnsTableFits(aReflowState, bigSpace,
@ -840,18 +820,18 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(const nsHTMLReflowSt
}
else if (mMinTableWidth >= actualMaxWidth)
{ // the table doesn't fit in the available space
if (gsDebug) printf (" * auto table minTW does not fit, calling BalanceColumnsTableDoesNotFit\n");
if (gsDebug) printf (" * table minTW does not fit, calling BalanceColumnsTableDoesNotFit\n");
result = BalanceColumnsTableDoesNotFit();
}
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");
if (gsDebug) printf (" * table desired size fits, calling BalanceColumnsTableFits\n");
result = BalanceColumnsTableFits(aReflowState, aAvailWidth,
aMaxWidth, aTableSpecifiedWidth, aTableIsAutoWidth);
}
else
{ // the table fits somewhere between its min and desired size
if (gsDebug) printf (" * auto table desired size does not fit, calling BalanceColumnsConstrained\n");
if (gsDebug) printf (" * table desired size does not fit, calling BalanceColumnsConstrained\n");
result = BalanceColumnsConstrained(aReflowState, aAvailWidth,
actualMaxWidth, aTableIsAutoWidth);
}
@ -884,7 +864,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableDoesNotFit()
// Get the columns's style
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
const nsStyleTable* colTableStyle;
colFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct*&)colTableStyle);
//if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
minAdjustedColWidth = colFrame->GetAdjustedMinColWidth();
mTableFrame->SetColumnWidth(colIndex, minAdjustedColWidth);
@ -959,6 +941,8 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsHTMLReflowState
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
const nsStyleTable* colTableStyle;
colFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct*&)colTableStyle);
// first, deal with any cells that span into this column from a pervious column
// go through the list backwards so we can delete easily
@ -969,7 +953,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsHTMLReflowState
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
if (PR_FALSE==IsFixedWidth(colPosition))
if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
// compute the spanning cell's contribution to the column min width
nscoord spanCellMinWidth;
@ -1056,7 +1040,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsHTMLReflowState
}
// second, process non-fixed-width columns
if (PR_FALSE==IsFixedWidth(colPosition))
if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
for (rowIndex = 0; rowIndex<numRows; rowIndex++)
{ // this col has proportional width, so determine its width requirements
@ -1176,7 +1160,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsHTMLReflowState
if (gsDebug==PR_TRUE)
{
printf (" for determining width of col %d %s:\n",
colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)");
colIndex, !IsFixedWidth(colPosition, colTableStyle)? "(P)":"(A)");
printf (" minColWidth = %d and maxColWidth = %d\n", minColWidth, maxColWidth);
printf (" aAvailWidth = %d\n", aAvailWidth);
}
@ -1692,6 +1676,8 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsHTMLReflowSt
PRInt32 firstRowIndex = -1;
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
const nsStyleTable* colTableStyle;
colFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct*&)colTableStyle);
// first, deal with any cells that span into this column from a pervious column
// go through the list backwards so we can delete easily
@ -1702,7 +1688,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsHTMLReflowSt
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
if (PR_FALSE==IsFixedWidth(colPosition))
if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
// compute the spanning cell's contribution to the column min width
nscoord spanCellMinWidth;
@ -1786,7 +1772,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsHTMLReflowSt
}
// second, process non-fixed-width columns
if (PR_FALSE==IsFixedWidth(colPosition))
if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
for (rowIndex = 0; rowIndex<numRows; rowIndex++)
{
@ -1906,7 +1892,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsHTMLReflowSt
if (gsDebug==PR_TRUE)
{
printf (" for determining width of col %d %s:\n",
colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)");
colIndex, !IsFixedWidth(colPosition, colTableStyle)? "(P)":"(A)");
printf (" minTableWidth = %d and maxTableWidth = %d\n",
mMinTableWidth, mMaxTableWidth);
printf (" minColWidth = %d, maxColWidth = %d, eff=%d,%d\n",

View File

@ -26,6 +26,7 @@
class nsVoidArray;
class nsTableFrame;
struct nsStylePosition;
struct nsStyleTable;
/* ----------- SpanInfo ---------- */
@ -245,7 +246,8 @@ protected:
* for the purposes of column width determination.
* return false if the width changes based on content, parent size, etc.
*/
virtual PRBool IsFixedWidth(const nsStylePosition* aStylePosition);
static PRBool IsFixedWidth(const nsStylePosition* aStylePosition,
const nsStyleTable* aStyleTable);
/** return true if the colIndex is in the list of colIndexes */
virtual PRBool IsColumnInList(const PRInt32 colIndex,

View File

@ -82,6 +82,15 @@ PRInt32 nsTableColFrame::GetSpan()
return tableStyle->mSpan;
}
nscoord nsTableColFrame::GetColWidthForComputation()
{
const nsStylePosition* position;
GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)position));
if (eStyleUnit_Coord==position->mWidth.GetUnit())
return position->mWidth.GetCoordValue();
else
return GetEffectiveMaxColWidth();
}
/* ----- global methods ----- */

View File

@ -82,6 +82,8 @@ public:
PRInt32 GetWidthSource();
void SetWidthSource(PRInt32 aMinColWidth);
nscoord GetColWidthForComputation();
/** convenience method, calls into cellmap */
PRInt32 Count() const;

View File

@ -574,6 +574,9 @@ PRInt32 nsTableFrame::GetEffectiveColSpan (PRInt32 aColIndex, nsTableCellFrame *
NS_PRECONDITION (0<=aColIndex && aColIndex<colCount, "bad col index arg");
PRInt32 result;
/* XXX: it kind of makes sense to ignore colspans when there's only one row, but it doesn't quite work that way :(
it would be good to find out why
*/
/*
if (cellMap->GetRowCount()==1)
return 1;
@ -1448,19 +1451,14 @@ nsresult nsTableFrame::AdjustSiblingsAfterReflow(nsIPresContext& aPresCo
}
// SEC: TODO need to worry about continuing frames prev/next in flow for splitting across pages.
// SEC: TODO need to keep "first pass done" state, update it when ContentChanged notifications come in
/* overview:
if mFirstPassValid is false, this is our first time through since content was last changed
set pass to 1
do pass 1
get min/max info for all cells in an infinite space
do column balancing
set mFirstPassValid to true
do pass 2
if pass is 1,
set pass to 2
use column widths to ResizeReflow cells
do column balancing
do pass 2
use column widths to size table and ResizeReflow rowgroups (and therefore rows and cells)
*/
/* Layout the entire inner table. */
@ -2799,15 +2797,20 @@ void nsTableFrame::AdjustColumnsForCOLSAttribute()
}
}
/*
The rule is: use whatever width is greatest among those specified widths
that span a column. It doesn't matter what comes first, just what is biggest.
Specified widths (when colspan==1) and span widths need to be stored separately,
because specified widths tell us what proportion of the span width to give to each column
(in their absence, we use the desired width of the cell.)
*/
NS_METHOD
nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext,
nsTableCellFrame* aCellFrame,
nsTableRowFrame * aRowFrame)
{
// if this cell is the first non-col-spanning cell to have a width attribute,
// then the width attribute also acts as the width attribute for the entire column
// if the cell has a colspan, the width is used provisionally, divided equally among
// the spanned columns
// the spanned columns until the table layout strategy computes the real column width.
if (PR_TRUE==gsDebug) printf("TIF SetCSFromCell: cell %p in row %p\n", aCellFrame, aRowFrame);
if ((nsnull!=aCellFrame) && (nsnull!=aRowFrame))
{
@ -2826,51 +2829,71 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext,
nsTableColFrame *colFrame;
GetColumnFrame(i+aCellFrame->GetColIndex(), colFrame);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: for col %d\n",i+aCellFrame->GetColIndex());
if (nsTableColFrame::eWIDTH_SOURCE_CELL != colFrame->GetWidthSource())
printf("TIF SetCSFromCell: for col %d\n",i+aCellFrame->GetColIndex());
// if the colspan is 1 and we already have a cell that set this column's width
// then ignore this width attribute
if ((1==colSpan) && (nsTableColFrame::eWIDTH_SOURCE_CELL == colFrame->GetWidthSource()))
{
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: width not yet set from a cell...\n");
if ((1==colSpan) ||
(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN != colFrame->GetWidthSource()))
{
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: colspan was 1 or width was not set from a span\n");
// get the column style and set the width attribute
nsIStyleContext *colSC;
colFrame->GetStyleContext(colSC);
nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
NS_RELEASE(colSC);
// set the column width attribute
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
nscoord width = cellPosition->mWidth.GetCoordValue();
colPosition->mWidth.SetCoordValue(width/colSpan);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col fixed width set to %d ", (width/colSpan));
}
else
{
float width = cellPosition->mWidth.GetPercentValue();
colPosition->mWidth.SetPercentValue(width/colSpan);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col percent width set to %d ", (width/colSpan));
}
// set the column width-set-type
if (1==colSpan)
{
colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
if (PR_TRUE==gsDebug)
printf(" source = CELL\n");
}
else
{
colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
if (PR_TRUE==gsDebug)
printf(" source = SPAN\n");
}
}
printf("TIF SetCSFromCell: width already set from a cell with colspan=1, no-op this cell's width attr\n");
break;
}
// get the column style
nsIStyleContext *colSC;
colFrame->GetStyleContext(colSC);
nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
// if colSpan==1, then we can just set the column width
if (1==colSpan)
{ // set the column width attribute
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
nscoord width = cellPosition->mWidth.GetCoordValue();
colPosition->mWidth.SetCoordValue(width);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col fixed width set to %d from cell", width);
}
else
{
float width = cellPosition->mWidth.GetPercentValue();
colPosition->mWidth.SetPercentValue(width);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col percent width set to %d from cell", width);
}
colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
}
else // we have a colspan > 1. so we need to set the column table style spanWidth
{ // if the cell is a coord width...
nsStyleTable* colTableStyle = (nsStyleTable*) colSC->GetMutableStyleData(eStyleStruct_Table);
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
// set the column width attribute iff this span's contribution to this column
// is greater than any previous information
nscoord cellWidth = cellPosition->mWidth.GetCoordValue();
nscoord widthPerColumn = cellWidth/colSpan;
nscoord widthForThisColumn = widthPerColumn;
if (eStyleUnit_Coord == colTableStyle->mSpanWidth.GetUnit())
widthForThisColumn = PR_MAX(widthForThisColumn, colTableStyle->mSpanWidth.GetCoordValue());
colTableStyle->mSpanWidth.SetCoordValue(widthForThisColumn);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col span width set to %d from spanning cell", widthForThisColumn);
}
// else if the cell has a percent width...
else if (eStyleUnit_Percent == cellPosition->mWidth.GetUnit())
{
// set the column width attribute iff this span's contribution to this column
// is greater than any previous information
float cellWidth = cellPosition->mWidth.GetPercentValue();
float percentPerColumn = cellWidth/(float)colSpan;
float percentForThisColumn = percentPerColumn;
if (eStyleUnit_Percent == colTableStyle->mSpanWidth.GetUnit())
percentForThisColumn = PR_MAX(percentForThisColumn, colTableStyle->mSpanWidth.GetPercentValue());
colTableStyle->mSpanWidth.SetPercentValue(percentForThisColumn);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col span width set to %d from spanning cell", (nscoord)percentForThisColumn);
}
colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
}
NS_RELEASE(colSC);
}
}
}
@ -3425,44 +3448,29 @@ NS_NewTableFrame(nsIContent* aContent,
NS_METHOD nsTableFrame::GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aTableFrame)
{
nsresult result = NS_OK;
aTableFrame = nsnull; // initialize out-param
nsresult rv = NS_ERROR_UNEXPECTED; // the value returned
aTableFrame = nsnull; // initialize out-param
nsIFrame *parentFrame=nsnull;
if (nsnull!=aSourceFrame)
{
nsresult result = aSourceFrame->GetContentParent((nsIFrame *&)aTableFrame);
while ((NS_OK==result) && (nsnull!=aTableFrame))
// "result" is the result of intermediate calls, not the result we return from this method
nsresult result = aSourceFrame->GetContentParent((nsIFrame *&)parentFrame);
while ((NS_OK==result) && (nsnull!=parentFrame))
{
const nsStyleDisplay *display;
aTableFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
parentFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE == display->mDisplay)
{
// at this point, aTableFrame could be an outer frame,
// to find out, scan it's children for another frame with a table display type
// if found, the childFrame must be the inner frame
nsresult rv;
nsIFrame *childFrame=nsnull;
rv = aTableFrame->FirstChild(nsnull, childFrame);
while ((NS_OK==rv) && (nsnull!=childFrame))
{
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)childDisplay);
if (NS_STYLE_DISPLAY_TABLE == childDisplay->mDisplay)
{
aTableFrame = (nsTableFrame *)childFrame;
break;
}
rv = childFrame->GetNextSibling(childFrame);
}
aTableFrame = (nsTableFrame *)parentFrame;
rv = NS_OK; // only set if we found the table frame
break;
}
result = aTableFrame->GetContentParent((nsIFrame *&)aTableFrame);
result = parentFrame->GetContentParent((nsIFrame *&)parentFrame);
}
}
else
result = NS_ERROR_UNEXPECTED; // bad source param
NS_POSTCONDITION(nsnull!=aTableFrame, "unable to find table parent. aTableFrame null.");
NS_POSTCONDITION(NS_OK==result, "unable to find table parent. result!=NS_OK");
return result;
NS_POSTCONDITION(NS_OK==rv, "unable to find table parent. result!=NS_OK");
return rv;
}
/* helper method for determining if this is a nested table or not */
@ -3641,11 +3649,6 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
PRInt32 colSpan = ((nsTableFrame*)rs->frame)->GetEffectiveColSpan(colIndex, ((nsTableCellFrame *)greatgrandchildFrame));
for (PRInt32 i = 0; i<colSpan; i++)
parentWidth += ((nsTableFrame*)rs->frame)->GetColumnWidth(i+colIndex);
if (eStyleUnit_Percent == tablePosition->mWidth.GetUnit())
{
float percent = tablePosition->mWidth.GetPercentValue();
parentWidth = (nscoord)(percent*((float)parentWidth));
}
}
else
{

View File

@ -81,23 +81,15 @@ struct ColSpanStruct
/* ---------- BasicTableLayoutStrategy ---------- */
/* return true if the style indicates that the width is proportional
/* return true if the style indicates that the width is fixed
* for the purposes of column width determination
*/
PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosition)
inline
PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosition,
const nsStyleTable* aStyleTable)
{
PRBool result = PR_FALSE; // assume that it is not fixed width
PRInt32 unitType;
if (nsnull == aStylePosition) {
result=PR_TRUE;
}
else {
unitType = aStylePosition->mWidth.GetUnit();
if (eStyleUnit_Coord==unitType)
result=PR_TRUE;
}
return result;
return PRBool ((eStyleUnit_Coord==aStylePosition->mWidth.GetUnit()) ||
(eStyleUnit_Coord==aStyleTable->mSpanWidth.GetUnit()));
}
@ -255,7 +247,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
nsVoidArray *spanList=nsnull;
nsVoidArray *colSpanList=nsnull;
PRInt32 numProvisionalFixedColumns = 0; // used for assigning width from cell with colspan to columns that are spanned
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
@ -278,8 +269,13 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
nscoord maxColWidth = 0; // max col width factoring in table attributes
nscoord effectiveMinColumnWidth = 0; // min col width ignoring cells with colspans
nscoord effectiveMaxColumnWidth = 0; // max col width ignoring cells with colspans
nscoord specifiedFixedColWidth = 0; // the width of the column if given stylistically (or via cell Width attribute)
nscoord specifiedFixedColWidth = 0; /* the width of the column if given stylistically (or via cell Width attribute)
only applicable if haveColWidth==PR_TRUE
*/
PRBool haveColWidth = PR_FALSE; /* if true, the column has a width either from HTML width attribute,
from a style rule on the column,
or from a width attr/style on a cell that has colspan==1
*/
// Get column information
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
@ -287,15 +283,14 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
// Get the columns's style
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
const nsStyleTable* colTableStyle;
colFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct*&)colTableStyle);
// Get fixed column width if it has one
PRBool haveColWidth = PR_FALSE;
if (eStyleUnit_Coord==colPosition->mWidth.GetUnit())
{
haveColWidth = PR_TRUE;
specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
if (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN==colFrame->GetWidthSource())
numProvisionalFixedColumns++;
}
/* Scan the column, simulatneously assigning column widths
@ -346,12 +341,11 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
cellDesiredSize.width, cellDesiredSize.height);
if ((PR_TRUE==haveColWidth) &&
(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN!=colFrame->GetWidthSource()))
if (PR_TRUE==haveColWidth)
{
// This col has a specified fixed width so set the min and max width to the larger of
// (specified width, largest max_element_size of the cells in the column)
// factoring in the min width of the prior cells (stored in minColWidth)
/* This col has a specified coord fixed width, so set the min and max width to the larger of
(specified width, largest max_element_size of the cells in the column)
factoring in the min width of the prior cells (stored in minColWidth) */
nscoord widthForThisCell = specifiedFixedColWidth;
if (0==specifiedFixedColWidth) // set to min
specifiedFixedColWidth = cellMinWidth;
@ -390,7 +384,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
{
// add the column to our list of post-process columns, if all of the intersected columns are auto
PRBool okToAdd = PR_TRUE;
if (numRows==1 || (PR_FALSE==IsFixedWidth(colPosition)))
if (numRows==1 || (PR_FALSE==IsFixedWidth(colPosition, colTableStyle)))
okToAdd = PR_FALSE;
else
{
@ -410,8 +404,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
}
nscoord width = cellDesiredSize.width; // used below as the cell's "natural" width
if ((PR_TRUE == haveColWidth)) //XXX && (PR_TRUE==cellGrantingWidth) ?
width = colSpan*specifiedFixedColWidth;
if (eStyleUnit_Coord==colTableStyle->mSpanWidth.GetUnit())
width = colSpan*colTableStyle->mSpanWidth.GetCoordValue(); // "colSpan*" because table frame divided per column spanned
if (PR_TRUE==okToAdd)
{
@ -434,6 +428,10 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
//bookkeeping: is this the cell that gave the column it's fixed width attribute?
// must be done after "haveColWidth && cellGrantingWidth" used above
/* since we want the biggest, I don't think this is valid anymore
it made sense when the rule was to grab the first cell that contributed a width
*/
/*
if (PR_TRUE==cellGrantingWidth)
{
const nsStylePosition* cellPosition;
@ -441,6 +439,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
}
*/
// book 'em, Danno
if (gsDebug) {
@ -454,7 +453,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
specifiedFixedColWidth=effectiveMinColumnWidth;
// do all the global bookkeeping, factoring in margins
nscoord colInset = mTableFrame->GetCellSpacing();
if (PR_TRUE==gsDebug) printf("* cellSpacing=%d\n", colInset);
// keep a running total of the amount of space taken up by all fixed-width columns
if ((PR_TRUE==haveColWidth) && (nsTableColFrame::eWIDTH_SOURCE_CELL==colFrame->GetWidthSource()))
{
@ -501,123 +499,105 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0&&(0==numAutoColumns && 0==numProvisionalFixedColumns))
{ //table fully specified, so no need to do any extra work here
// for every column, handle spanning cells that impact that column
for (PRInt32 colIndex=0; colIndex<mNumCols; colIndex++)
{
if (gsDebug) printf("handling span for %d\n", colIndex);
PRInt32 spanCount = spanList->Count();
// go through the list backwards so we can delete easily
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{
{ // get each spanInfo struct and see if it impacts this column
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
spanList->RemoveElementAt(spanIndex);
delete spanInfo;
}
}
else
{ // for every column, handle spanning cells that impact that column
for (PRInt32 colIndex=0; colIndex<mNumCols; colIndex++)
{
if (gsDebug) printf("handling span for %d\n", colIndex);
PRInt32 spanCount = spanList->Count();
// go through the list backwards so we can delete easily
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{ // get each spanInfo struct and see if it impacts this column
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
// if the spanInfo is about a column before the current column, it effects
// the current column (otherwise it would have already been deleted.)
if (spanInfo->initialColIndex <= colIndex)
// if the spanInfo is about a column before the current column, it effects
// the current column (otherwise it would have already been deleted.)
if (spanInfo->initialColIndex <= colIndex)
{
if (-1==spanInfo->effectiveMaxWidthOfSpannedCols)
{ // if we have not yet computed effectiveMaxWidthOfSpannedCols, do it now
// first, initialize the sums
spanInfo->effectiveMaxWidthOfSpannedCols=0;
spanInfo->effectiveMinWidthOfSpannedCols=0;
// then compute the sums
for (PRInt32 span=0; span<spanInfo->initialColSpan; span++)
{
nsTableColFrame *nextColFrame = mTableFrame->GetColFrame(colIndex+span);
if (nsnull==nextColFrame)
break;
spanInfo->effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
spanInfo->effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
}
if (gsDebug) printf("effective min total = %d, max total = %d\n",
spanInfo->effectiveMinWidthOfSpannedCols, spanInfo->effectiveMaxWidthOfSpannedCols);
}
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
nscoord colMinWidth = colFrame->GetMinColWidth();
// compute the spanning cell's contribution to the column min width
// this is the "adjusted" column width, used in SetTableToMinWidth
nscoord spanCellMinWidth;
if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
{
if (-1==spanInfo->effectiveMaxWidthOfSpannedCols)
{ // if we have not yet computed effectiveMaxWidthOfSpannedCols, do it now
// first, initialize the sums
spanInfo->effectiveMaxWidthOfSpannedCols=0;
spanInfo->effectiveMinWidthOfSpannedCols=0;
// then compute the sums
for (PRInt32 span=0; span<spanInfo->initialColSpan; span++)
{
nsTableColFrame *nextColFrame = mTableFrame->GetColFrame(colIndex+span);
if (nsnull==nextColFrame)
break;
spanInfo->effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth();
spanInfo->effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth();
}
if (gsDebug) printf("effective min total = %d, max total = %d\n",
spanInfo->effectiveMinWidthOfSpannedCols, spanInfo->effectiveMaxWidthOfSpannedCols);
}
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
nscoord colMinWidth = colFrame->GetMinColWidth();
// compute the spanning cell's contribution to the column min width
// this is the "adjusted" column width, used in SetTableToMinWidth
nscoord spanCellMinWidth;
if (0!=spanInfo->effectiveMinWidthOfSpannedCols)
float percent = ((float)(colFrame->GetEffectiveMinColWidth())) /
((float)(spanInfo->effectiveMinWidthOfSpannedCols));
spanCellMinWidth = NSToCoordRound(((float)(spanInfo->cellMinWidth)) * percent);
if (gsDebug==PR_TRUE)
printf ("spanCellMinWidth portion = %d from percent=%f, cellMW=%d, effMinColW=%d, sum=%d\n",
spanCellMinWidth, percent, spanInfo->cellMinWidth, colFrame->GetEffectiveMinColWidth(),
spanInfo->effectiveMinWidthOfSpannedCols);
if (colMinWidth < spanCellMinWidth)
colFrame->SetAdjustedMinColWidth(spanCellMinWidth); // set the new min width for the col
}
else
{
spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
if (colMinWidth < spanCellMinWidth)
{
float percent = ((float)(colFrame->GetEffectiveMinColWidth())) /
((float)(spanInfo->effectiveMinWidthOfSpannedCols));
spanCellMinWidth = NSToCoordRound(((float)(spanInfo->cellMinWidth)) * percent);
colFrame->SetAdjustedMinColWidth(spanCellMinWidth);
}
}
// compute the spanning cell's contribution to the column max width
nscoord colMaxWidth = colFrame->GetMaxColWidth();
nscoord spanCellMaxWidth;
if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
{
float percent = ((float)(colFrame->GetEffectiveMaxColWidth())) /
((float)(spanInfo->effectiveMaxWidthOfSpannedCols));
spanCellMaxWidth = NSToCoordRound(((float)(spanInfo->cellDesiredWidth)) * percent);
if (gsDebug==PR_TRUE)
printf ("spanCellMaxWidth portion = %d with percent = %f from cellDW = %d, effMaxColW=%d and sum=%d\n",
spanCellMaxWidth, percent, spanInfo->cellDesiredWidth, colFrame->GetEffectiveMaxColWidth(),
spanInfo->effectiveMaxWidthOfSpannedCols);
if (colMaxWidth < spanCellMaxWidth)
{
// make sure we're at least as big as our min
spanCellMaxWidth = PR_MAX(spanCellMaxWidth, colMinWidth);
colFrame->SetMaxColWidth(spanCellMaxWidth); // set the new max width for the col
mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
if (gsDebug==PR_TRUE)
printf ("spanCellMinWidth portion = %d from percent=%f, cellMW=%d, effMinColW=%d, sum=%d\n",
spanCellMinWidth, percent, spanInfo->cellMinWidth, colFrame->GetEffectiveMinColWidth(),
spanInfo->effectiveMinWidthOfSpannedCols);
if (colMinWidth < spanCellMinWidth)
colFrame->SetAdjustedMinColWidth(spanCellMinWidth); // set the new min width for the col
}
else
{
spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan;
if (colMinWidth < spanCellMinWidth)
{
colFrame->SetAdjustedMinColWidth(spanCellMinWidth);
printf ("for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n",
colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
}
}
}
else
{
spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
nscoord minColWidth = colFrame->GetMinColWidth();
spanCellMaxWidth = PR_MAX(spanCellMaxWidth, minColWidth);
colFrame->SetMaxColWidth(spanCellMaxWidth);
mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
if (gsDebug==PR_TRUE)
printf (" for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n",
colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
}
// only compute the col spanner's contribution to the desired cell width
// if the width is from a col spanning cell
if (nsTableColFrame::eWIDTH_SOURCE_CELL!=colFrame->GetWidthSource())
{
// compute the spanning cell's contribution to the column max width
nscoord colMaxWidth = colFrame->GetMaxColWidth();
nscoord spanCellMaxWidth;
if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
{
float percent = ((float)(colFrame->GetEffectiveMaxColWidth())) /
((float)(spanInfo->effectiveMaxWidthOfSpannedCols));
spanCellMaxWidth = NSToCoordRound(((float)(spanInfo->cellDesiredWidth)) * percent);
if (gsDebug==PR_TRUE)
printf ("spanCellMaxWidth portion = %d with percent = %f from cellDW = %d, effMaxColW=%d and sum=%d\n",
spanCellMaxWidth, percent, spanInfo->cellDesiredWidth, colFrame->GetEffectiveMaxColWidth(),
spanInfo->effectiveMaxWidthOfSpannedCols);
if (colMaxWidth < spanCellMaxWidth)
{
// make sure we're at least as big as our min
spanCellMaxWidth = PR_MAX(spanCellMaxWidth, colMinWidth);
colFrame->SetMaxColWidth(spanCellMaxWidth); // set the new max width for the col
mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width
if (gsDebug==PR_TRUE)
{
printf ("for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n",
colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
}
}
}
else
{
spanCellMaxWidth = spanInfo->cellDesiredWidth/spanInfo->initialColSpan;
nscoord minColWidth = colFrame->GetMinColWidth();
spanCellMaxWidth = PR_MAX(spanCellMaxWidth, minColWidth);
colFrame->SetMaxColWidth(spanCellMaxWidth);
mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth);
if (gsDebug==PR_TRUE)
printf (" for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n",
colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth);
}
}
spanInfo->span--;
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
delete spanInfo;
}
spanInfo->span--;
if (0==spanInfo->span)
{
spanList->RemoveElementAt(spanIndex);
delete spanInfo;
}
}
}
@ -784,7 +764,7 @@ void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList)
for (i = 0; i<colSpan; i++)
{
mTableFrame->GetColumnFrame(colIndex+i, colFrame);
totalEffectiveWidth += colFrame->GetEffectiveMaxColWidth();
totalEffectiveWidth += colFrame->GetColWidthForComputation();
}
// 2. next, compute the proportion to be added to each column, and add it
@ -792,7 +772,7 @@ void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList)
{
mTableFrame->GetColumnFrame(colIndex+i, colFrame);
float percent;
percent = ((float)(colFrame->GetEffectiveMaxColWidth()))/((float)totalEffectiveWidth);
percent = ((float)(colFrame->GetColWidthForComputation()))/((float)totalEffectiveWidth);
nscoord newColWidth = NSToCoordRound(((float)totalColWidth)*percent);
nscoord minColWidth = colFrame->GetEffectiveMinColWidth();
nscoord oldColWidth = mTableFrame->GetColumnWidth(colIndex+i);
@ -832,7 +812,7 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(const nsHTMLReflowSt
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");
if (gsDebug) printf (" * table laying out in NS_UNCONSTRAINEDSIZE, calling BalanceColumnsTableFits\n");
nscoord bigSpace = gBigSpace;
bigSpace = PR_MAX(bigSpace, mMaxTableWidth);
result = BalanceColumnsTableFits(aReflowState, bigSpace,
@ -840,18 +820,18 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(const nsHTMLReflowSt
}
else if (mMinTableWidth >= actualMaxWidth)
{ // the table doesn't fit in the available space
if (gsDebug) printf (" * auto table minTW does not fit, calling BalanceColumnsTableDoesNotFit\n");
if (gsDebug) printf (" * table minTW does not fit, calling BalanceColumnsTableDoesNotFit\n");
result = BalanceColumnsTableDoesNotFit();
}
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");
if (gsDebug) printf (" * table desired size fits, calling BalanceColumnsTableFits\n");
result = BalanceColumnsTableFits(aReflowState, aAvailWidth,
aMaxWidth, aTableSpecifiedWidth, aTableIsAutoWidth);
}
else
{ // the table fits somewhere between its min and desired size
if (gsDebug) printf (" * auto table desired size does not fit, calling BalanceColumnsConstrained\n");
if (gsDebug) printf (" * table desired size does not fit, calling BalanceColumnsConstrained\n");
result = BalanceColumnsConstrained(aReflowState, aAvailWidth,
actualMaxWidth, aTableIsAutoWidth);
}
@ -884,7 +864,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableDoesNotFit()
// Get the columns's style
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
const nsStyleTable* colTableStyle;
colFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct*&)colTableStyle);
//if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
minAdjustedColWidth = colFrame->GetAdjustedMinColWidth();
mTableFrame->SetColumnWidth(colIndex, minAdjustedColWidth);
@ -959,6 +941,8 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsHTMLReflowState
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
const nsStyleTable* colTableStyle;
colFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct*&)colTableStyle);
// first, deal with any cells that span into this column from a pervious column
// go through the list backwards so we can delete easily
@ -969,7 +953,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsHTMLReflowState
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
if (PR_FALSE==IsFixedWidth(colPosition))
if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
// compute the spanning cell's contribution to the column min width
nscoord spanCellMinWidth;
@ -1056,7 +1040,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsHTMLReflowState
}
// second, process non-fixed-width columns
if (PR_FALSE==IsFixedWidth(colPosition))
if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
for (rowIndex = 0; rowIndex<numRows; rowIndex++)
{ // this col has proportional width, so determine its width requirements
@ -1176,7 +1160,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(const nsHTMLReflowState
if (gsDebug==PR_TRUE)
{
printf (" for determining width of col %d %s:\n",
colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)");
colIndex, !IsFixedWidth(colPosition, colTableStyle)? "(P)":"(A)");
printf (" minColWidth = %d and maxColWidth = %d\n", minColWidth, maxColWidth);
printf (" aAvailWidth = %d\n", aAvailWidth);
}
@ -1692,6 +1676,8 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsHTMLReflowSt
PRInt32 firstRowIndex = -1;
const nsStylePosition* colPosition;
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
const nsStyleTable* colTableStyle;
colFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct*&)colTableStyle);
// first, deal with any cells that span into this column from a pervious column
// go through the list backwards so we can delete easily
@ -1702,7 +1688,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsHTMLReflowSt
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
{
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
if (PR_FALSE==IsFixedWidth(colPosition))
if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
// compute the spanning cell's contribution to the column min width
nscoord spanCellMinWidth;
@ -1786,7 +1772,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsHTMLReflowSt
}
// second, process non-fixed-width columns
if (PR_FALSE==IsFixedWidth(colPosition))
if (PR_FALSE==IsFixedWidth(colPosition, colTableStyle))
{
for (rowIndex = 0; rowIndex<numRows; rowIndex++)
{
@ -1906,7 +1892,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsHTMLReflowSt
if (gsDebug==PR_TRUE)
{
printf (" for determining width of col %d %s:\n",
colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)");
colIndex, !IsFixedWidth(colPosition, colTableStyle)? "(P)":"(A)");
printf (" minTableWidth = %d and maxTableWidth = %d\n",
mMinTableWidth, mMaxTableWidth);
printf (" minColWidth = %d, maxColWidth = %d, eff=%d,%d\n",

View File

@ -26,6 +26,7 @@
class nsVoidArray;
class nsTableFrame;
struct nsStylePosition;
struct nsStyleTable;
/* ----------- SpanInfo ---------- */
@ -245,7 +246,8 @@ protected:
* for the purposes of column width determination.
* return false if the width changes based on content, parent size, etc.
*/
virtual PRBool IsFixedWidth(const nsStylePosition* aStylePosition);
static PRBool IsFixedWidth(const nsStylePosition* aStylePosition,
const nsStyleTable* aStyleTable);
/** return true if the colIndex is in the list of colIndexes */
virtual PRBool IsColumnInList(const PRInt32 colIndex,

View File

@ -82,6 +82,15 @@ PRInt32 nsTableColFrame::GetSpan()
return tableStyle->mSpan;
}
nscoord nsTableColFrame::GetColWidthForComputation()
{
const nsStylePosition* position;
GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)position));
if (eStyleUnit_Coord==position->mWidth.GetUnit())
return position->mWidth.GetCoordValue();
else
return GetEffectiveMaxColWidth();
}
/* ----- global methods ----- */

View File

@ -82,6 +82,8 @@ public:
PRInt32 GetWidthSource();
void SetWidthSource(PRInt32 aMinColWidth);
nscoord GetColWidthForComputation();
/** convenience method, calls into cellmap */
PRInt32 Count() const;

View File

@ -574,6 +574,9 @@ PRInt32 nsTableFrame::GetEffectiveColSpan (PRInt32 aColIndex, nsTableCellFrame *
NS_PRECONDITION (0<=aColIndex && aColIndex<colCount, "bad col index arg");
PRInt32 result;
/* XXX: it kind of makes sense to ignore colspans when there's only one row, but it doesn't quite work that way :(
it would be good to find out why
*/
/*
if (cellMap->GetRowCount()==1)
return 1;
@ -1448,19 +1451,14 @@ nsresult nsTableFrame::AdjustSiblingsAfterReflow(nsIPresContext& aPresCo
}
// SEC: TODO need to worry about continuing frames prev/next in flow for splitting across pages.
// SEC: TODO need to keep "first pass done" state, update it when ContentChanged notifications come in
/* overview:
if mFirstPassValid is false, this is our first time through since content was last changed
set pass to 1
do pass 1
get min/max info for all cells in an infinite space
do column balancing
set mFirstPassValid to true
do pass 2
if pass is 1,
set pass to 2
use column widths to ResizeReflow cells
do column balancing
do pass 2
use column widths to size table and ResizeReflow rowgroups (and therefore rows and cells)
*/
/* Layout the entire inner table. */
@ -2799,15 +2797,20 @@ void nsTableFrame::AdjustColumnsForCOLSAttribute()
}
}
/*
The rule is: use whatever width is greatest among those specified widths
that span a column. It doesn't matter what comes first, just what is biggest.
Specified widths (when colspan==1) and span widths need to be stored separately,
because specified widths tell us what proportion of the span width to give to each column
(in their absence, we use the desired width of the cell.)
*/
NS_METHOD
nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext,
nsTableCellFrame* aCellFrame,
nsTableRowFrame * aRowFrame)
{
// if this cell is the first non-col-spanning cell to have a width attribute,
// then the width attribute also acts as the width attribute for the entire column
// if the cell has a colspan, the width is used provisionally, divided equally among
// the spanned columns
// the spanned columns until the table layout strategy computes the real column width.
if (PR_TRUE==gsDebug) printf("TIF SetCSFromCell: cell %p in row %p\n", aCellFrame, aRowFrame);
if ((nsnull!=aCellFrame) && (nsnull!=aRowFrame))
{
@ -2826,51 +2829,71 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext,
nsTableColFrame *colFrame;
GetColumnFrame(i+aCellFrame->GetColIndex(), colFrame);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: for col %d\n",i+aCellFrame->GetColIndex());
if (nsTableColFrame::eWIDTH_SOURCE_CELL != colFrame->GetWidthSource())
printf("TIF SetCSFromCell: for col %d\n",i+aCellFrame->GetColIndex());
// if the colspan is 1 and we already have a cell that set this column's width
// then ignore this width attribute
if ((1==colSpan) && (nsTableColFrame::eWIDTH_SOURCE_CELL == colFrame->GetWidthSource()))
{
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: width not yet set from a cell...\n");
if ((1==colSpan) ||
(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN != colFrame->GetWidthSource()))
{
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: colspan was 1 or width was not set from a span\n");
// get the column style and set the width attribute
nsIStyleContext *colSC;
colFrame->GetStyleContext(colSC);
nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
NS_RELEASE(colSC);
// set the column width attribute
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
nscoord width = cellPosition->mWidth.GetCoordValue();
colPosition->mWidth.SetCoordValue(width/colSpan);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col fixed width set to %d ", (width/colSpan));
}
else
{
float width = cellPosition->mWidth.GetPercentValue();
colPosition->mWidth.SetPercentValue(width/colSpan);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col percent width set to %d ", (width/colSpan));
}
// set the column width-set-type
if (1==colSpan)
{
colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
if (PR_TRUE==gsDebug)
printf(" source = CELL\n");
}
else
{
colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
if (PR_TRUE==gsDebug)
printf(" source = SPAN\n");
}
}
printf("TIF SetCSFromCell: width already set from a cell with colspan=1, no-op this cell's width attr\n");
break;
}
// get the column style
nsIStyleContext *colSC;
colFrame->GetStyleContext(colSC);
nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
// if colSpan==1, then we can just set the column width
if (1==colSpan)
{ // set the column width attribute
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
nscoord width = cellPosition->mWidth.GetCoordValue();
colPosition->mWidth.SetCoordValue(width);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col fixed width set to %d from cell", width);
}
else
{
float width = cellPosition->mWidth.GetPercentValue();
colPosition->mWidth.SetPercentValue(width);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col percent width set to %d from cell", width);
}
colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
}
else // we have a colspan > 1. so we need to set the column table style spanWidth
{ // if the cell is a coord width...
nsStyleTable* colTableStyle = (nsStyleTable*) colSC->GetMutableStyleData(eStyleStruct_Table);
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
// set the column width attribute iff this span's contribution to this column
// is greater than any previous information
nscoord cellWidth = cellPosition->mWidth.GetCoordValue();
nscoord widthPerColumn = cellWidth/colSpan;
nscoord widthForThisColumn = widthPerColumn;
if (eStyleUnit_Coord == colTableStyle->mSpanWidth.GetUnit())
widthForThisColumn = PR_MAX(widthForThisColumn, colTableStyle->mSpanWidth.GetCoordValue());
colTableStyle->mSpanWidth.SetCoordValue(widthForThisColumn);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col span width set to %d from spanning cell", widthForThisColumn);
}
// else if the cell has a percent width...
else if (eStyleUnit_Percent == cellPosition->mWidth.GetUnit())
{
// set the column width attribute iff this span's contribution to this column
// is greater than any previous information
float cellWidth = cellPosition->mWidth.GetPercentValue();
float percentPerColumn = cellWidth/(float)colSpan;
float percentForThisColumn = percentPerColumn;
if (eStyleUnit_Percent == colTableStyle->mSpanWidth.GetUnit())
percentForThisColumn = PR_MAX(percentForThisColumn, colTableStyle->mSpanWidth.GetPercentValue());
colTableStyle->mSpanWidth.SetPercentValue(percentForThisColumn);
if (PR_TRUE==gsDebug)
printf("TIF SetCSFromCell: col span width set to %d from spanning cell", (nscoord)percentForThisColumn);
}
colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
}
NS_RELEASE(colSC);
}
}
}
@ -3425,44 +3448,29 @@ NS_NewTableFrame(nsIContent* aContent,
NS_METHOD nsTableFrame::GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aTableFrame)
{
nsresult result = NS_OK;
aTableFrame = nsnull; // initialize out-param
nsresult rv = NS_ERROR_UNEXPECTED; // the value returned
aTableFrame = nsnull; // initialize out-param
nsIFrame *parentFrame=nsnull;
if (nsnull!=aSourceFrame)
{
nsresult result = aSourceFrame->GetContentParent((nsIFrame *&)aTableFrame);
while ((NS_OK==result) && (nsnull!=aTableFrame))
// "result" is the result of intermediate calls, not the result we return from this method
nsresult result = aSourceFrame->GetContentParent((nsIFrame *&)parentFrame);
while ((NS_OK==result) && (nsnull!=parentFrame))
{
const nsStyleDisplay *display;
aTableFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
parentFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE == display->mDisplay)
{
// at this point, aTableFrame could be an outer frame,
// to find out, scan it's children for another frame with a table display type
// if found, the childFrame must be the inner frame
nsresult rv;
nsIFrame *childFrame=nsnull;
rv = aTableFrame->FirstChild(nsnull, childFrame);
while ((NS_OK==rv) && (nsnull!=childFrame))
{
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)childDisplay);
if (NS_STYLE_DISPLAY_TABLE == childDisplay->mDisplay)
{
aTableFrame = (nsTableFrame *)childFrame;
break;
}
rv = childFrame->GetNextSibling(childFrame);
}
aTableFrame = (nsTableFrame *)parentFrame;
rv = NS_OK; // only set if we found the table frame
break;
}
result = aTableFrame->GetContentParent((nsIFrame *&)aTableFrame);
result = parentFrame->GetContentParent((nsIFrame *&)parentFrame);
}
}
else
result = NS_ERROR_UNEXPECTED; // bad source param
NS_POSTCONDITION(nsnull!=aTableFrame, "unable to find table parent. aTableFrame null.");
NS_POSTCONDITION(NS_OK==result, "unable to find table parent. result!=NS_OK");
return result;
NS_POSTCONDITION(NS_OK==rv, "unable to find table parent. result!=NS_OK");
return rv;
}
/* helper method for determining if this is a nested table or not */
@ -3641,11 +3649,6 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsHTMLReflowState& aReflowSta
PRInt32 colSpan = ((nsTableFrame*)rs->frame)->GetEffectiveColSpan(colIndex, ((nsTableCellFrame *)greatgrandchildFrame));
for (PRInt32 i = 0; i<colSpan; i++)
parentWidth += ((nsTableFrame*)rs->frame)->GetColumnWidth(i+colIndex);
if (eStyleUnit_Percent == tablePosition->mWidth.GetUnit())
{
float percent = tablePosition->mWidth.GetPercentValue();
parentWidth = (nscoord)(percent*((float)parentWidth));
}
}
else
{