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:
parent
b0070d4d60
commit
aeee0e2b41
@ -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",
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 ----- */
|
||||
|
||||
|
||||
@ -82,6 +82,8 @@ public:
|
||||
PRInt32 GetWidthSource();
|
||||
void SetWidthSource(PRInt32 aMinColWidth);
|
||||
|
||||
nscoord GetColWidthForComputation();
|
||||
|
||||
/** convenience method, calls into cellmap */
|
||||
PRInt32 Count() const;
|
||||
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 ----- */
|
||||
|
||||
|
||||
@ -82,6 +82,8 @@ public:
|
||||
PRInt32 GetWidthSource();
|
||||
void SetWidthSource(PRInt32 aMinColWidth);
|
||||
|
||||
nscoord GetColWidthForComputation();
|
||||
|
||||
/** convenience method, calls into cellmap */
|
||||
PRInt32 Count() const;
|
||||
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user