diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
index baadba77204..1101961df05 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
@@ -19,16 +19,13 @@
#include "BasicTableLayoutStrategy.h"
#include "nsTableFrame.h"
#include "nsTableColFrame.h"
-#include "nsColLayoutData.h"
-#include "nsCellLayoutData.h"
-#include "nsTableCol.h"
#include "nsTableCellFrame.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
+#include "nsVoidArray.h"
#include "nsIPtr.h"
#include "nsHTMLIIDs.h"
-NS_DEF_PTR(nsTableCol);
NS_DEF_PTR(nsIStyleContext);
@@ -64,6 +61,23 @@ struct ProportionalColumnLayoutStruct
};
+/* ---------- ColSpanStruct ---------- */
+struct ColSpanStruct
+{
+ PRInt32 colIndex;
+ PRInt32 colSpan;
+ nscoord width;
+
+ ColSpanStruct(PRInt32 aSpan, PRInt32 aIndex, nscoord aWidth)
+ {
+ colSpan = aSpan;
+ colIndex = aIndex;
+ width = aWidth;
+ }
+};
+
+
+
/* ---------- BasicTableLayoutStrategy ---------- */
@@ -228,7 +242,9 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
if (gsDebug==PR_TRUE) printf (" AssignFixedColumnWidths\n");
nsVoidArray *spanList=nsnull;
-
+ nsVoidArray *colSpanList=nsnull;
+ nscoord * effectiveColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
+ nsCRT::memset (effectiveColumnWidths, 0, mNumCols*sizeof(PRInt32));
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
@@ -240,26 +256,24 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
maxColWidthArray = new PRInt32[mNumCols];
}
+ PRInt32 numRows = mTableFrame->GetRowCount();
+
// for every column, determine it's min and max width, and keep track of the table width
for (PRInt32 colIndex = 0; colIndexGetColumnLayoutData();
- nsColLayoutData * colData = (nsColLayoutData *)(columnLayoutData->ElementAt(colIndex));
- NS_ASSERTION(nsnull != colData, "bad column data");
- nsTableColFrame *colFrame = colData->GetColFrame();
- NS_ASSERTION(nsnull!=colFrame, "bad col frame");
-
// need to track min/max column width for setting min/max table widths
+ // QQQ: Eventually, this will be cached in col frame
+ // We'll just ask the column frame to compute this, and it'll use cached info if available
PRInt32 minColWidth = 0;
PRInt32 maxColWidth = 0;
- nsVoidArray *cells = colData->GetCells();
- PRInt32 numCells = cells->Count();
- if (gsDebug==PR_TRUE) printf (" for column %d numCells = %d\n", colIndex, numCells);
+
+ // Get column information
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ NS_ASSERTION(nsnull!=colFrame, "bad col frame");
// Get the columns's style
- nsIStyleContextPtr colSC;
- colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
- const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
// Get column width if it has one
PRBool haveColWidth = PR_FALSE;
@@ -268,7 +282,7 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
case eStyleUnit_Coord:
haveColWidth = PR_TRUE;
specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
- mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth); //QQQ add in margins?
+ mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth);
break;
default:
@@ -303,38 +317,49 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
}
}
- for (PRInt32 cellIndex = 0; cellIndexElementAt(cellIndex));
- if (nsnull == data) {
- // For cells that span rows there's only cell layout data for the first row
+ nsTableCellFrame * cellFrame = mTableFrame->GetCellAt(rowIndex, colIndex);
+ if (nsnull==cellFrame)
+ { // there is no cell in this row that corresponds to this column
+ continue;
+ }
+ if (-1==firstRowIndex)
+ firstRowIndex = rowIndex;
+ if (rowIndex!=cellFrame->GetRowIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
+ continue;
+ }
+ if (colIndex!=cellFrame->GetColIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
continue;
}
-
- nsMargin margin;
- nsresult result = data->GetMargin(margin);
- nsSize * cellMinSize = data->GetMaxElementSize();
- nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
- NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
- PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
+ nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
+ nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
+ PRInt32 colSpan = cellFrame->GetColSpan();
if (gsDebug==PR_TRUE)
- printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d, margins %d %d\n",
- cellIndex, colSpan, cellMinSize->width, cellMinSize->height,
- cellDesiredSize->width, cellDesiredSize->height,
- margin.left, margin.right);
+ printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
+ rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
+ cellDesiredSize.width, cellDesiredSize.height);
- switch (colPosition->mWidth.GetUnit()) {
+ switch (colPosition->mWidth.GetUnit())
+ {
case eStyleUnit_Coord:
{
// This col has a fixed width, so set the cell's width to the
// larger of (specified width, largest max_element_size of the
// cells in the column)
- PRInt32 widthForThisCell = PR_MAX(cellMinSize->width, colPosition->mWidth.GetCoordValue());
- if (mTableFrame->GetColumnWidth(colIndex) < widthForThisCell)
+ nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
+ widthForThisCell = widthForThisCell/colSpan;
+ nscoord widthFromCol = mTableFrame->GetColumnWidth(colIndex);
+ if (widthFromCol < widthForThisCell)
{
if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell);
- mTableFrame->SetColumnWidth(colIndex, widthForThisCell); //QQQ add in margins?
+ mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
maxColWidth = widthForThisCell;
}
}
@@ -347,24 +372,24 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
// regardless of the width specification, keep track of the
// min/max column widths
- nscoord cellMinWidth = cellMinSize->width/colSpan;
- nscoord cellDesiredWidth = cellDesiredSize->width/colSpan;
-
- if (aMaxWidth!=cellDesiredSize->width)
- {
- if (NS_UNCONSTRAINEDSIZE!=cellMinWidth)
- cellMinWidth += margin.left + margin.right;
- if (NS_UNCONSTRAINEDSIZE!=cellDesiredWidth)
- cellDesiredWidth += margin.left + margin.right;
- }
-
+ nscoord cellMinWidth = cellMinSize.width/colSpan;
+ nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
if (maxColWidth < cellDesiredWidth)
maxColWidth = cellDesiredWidth;
+ // effectiveColumnWidth is the width as if no cells with colspans existed
+ if ((1==colSpan) && (effectiveColumnWidths[colIndex] < maxColWidth))
+ effectiveColumnWidths[colIndex] = cellDesiredWidth;
if (1AppendElement(colSpanInfo);
+
+ // add the cell to our list of spanning cells
SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
if (nsnull==spanList)
spanList = new nsVoidArray();
@@ -372,26 +397,30 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
}
if (gsDebug) {
printf (" after cell %d, minColWidth = %d and maxColWidth = %d\n",
- cellIndex, minColWidth, maxColWidth);
+ rowIndex, minColWidth, maxColWidth);
}
}
+ // do all the global bookkeeping, factoring in margins
+ nsTableCellFrame * firstCellInColumn = mTableFrame->GetCellAt(firstRowIndex, colIndex);
+ nsMargin colMargin;
+ firstCellInColumn->GetMargin(colMargin);
+ nscoord colInset = colMargin.left + colMargin.right;
// keep a running total of the amount of space taken up by all fixed-width columns
if (PR_TRUE==haveColWidth)
- aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex);
+ aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
if (gsDebug) {
printf (" after col %d, aTotalFixedWidth = %d\n",
colIndex, aTotalFixedWidth);
}
-
// add col[i] metrics to the running totals for the table min/max width
if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth)
- aMinTableWidth += minColWidth; // SEC: insets!
+ aMinTableWidth += minColWidth + colInset;
if (aMinTableWidth<=0)
aMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (NS_UNCONSTRAINEDSIZE!=aMaxTableWidth)
- aMaxTableWidth += maxColWidth; // SEC: insets!
+ aMaxTableWidth += maxColWidth + colInset;
if (aMaxTableWidth<=0)
aMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (PR_TRUE==hasColsAttribute)
@@ -441,15 +470,59 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
delete [] minColWidthArray;
delete [] maxColWidthArray;
}
+ if (nsnull!=colSpanList)
+ DistributeFixedSpace(colSpanList, effectiveColumnWidths);
+ // today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
+ if (nsnull!=effectiveColumnWidths)
+ delete [] effectiveColumnWidths;
if (PR_TRUE==gsDebug)
printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, aMinTableWidth, aMaxTableWidth);
if (nsnull!=spanList)
delete spanList;
+ if (nsnull!=colSpanList)
+ delete colSpanList;
return PR_TRUE;
}
+// take the fixed space spanned by the columns in aColSpanList
+// and distribute it proportionately (based on desired width)
+void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths)
+{
+ nscoord excess = 0;
+ if (PR_TRUE==gsDebug) printf ("DistributeFixedSpace:\n");
+ // for all fixed-width columns, determine the amount of the specified width each column spanned recieves
+ PRInt32 numSpanningCells = aColSpanList->Count();
+ for (PRInt32 nextSpanningCell=0; nextSpanningCellElementAt(nextSpanningCell);
+ PRInt32 colIndex = colInfo->colIndex;
+ PRInt32 colSpan = colInfo->colSpan;
+ nscoord totalColWidth = colInfo->width;
+
+ // 1. get the sum of the effective widths of the columns in the span
+ nscoord totalEffectiveWidth=0;
+ PRInt32 i;
+ for (i = 0; iSetColumnWidth(colIndex+i, colWidth);
+ }
+ }
+}
+
PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nscoord aAvailWidth,
@@ -529,35 +602,37 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
minColWidthArray = new PRInt32[mNumCols];
}
- nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData();
- PRInt32 numCols = columnLayoutData->Count();
- for (PRInt32 colIndex = 0; colIndexGetRowCount();
+ for (PRInt32 colIndex = 0; colIndexElementAt(colIndex));
- nsVoidArray *cells = colData->GetCells();
PRInt32 minColWidth = 0;
PRInt32 maxColWidth = 0;
- PRInt32 numCells = cells->Count();
if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex);
- // XXX need column frame to ask this question
- const nsStylePosition* colPosition = nsnull;
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ NS_ASSERTION(nsnull!=colFrame, "bad col frame");
+ // Get the columns's style
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
{
- for (PRInt32 cellIndex = 0; cellIndexElementAt(cellIndex));
- if (nsnull==data)
- { // For cells that span rows there's only cell layout data for the first row
+ for (PRInt32 rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
+ if (nsnull==cellFrame)
+ { // there is no cell in this row that corresponds to this column
continue;
}
- nsMargin margin;
- data->GetMargin(margin);
- nsSize * cellMinSize = data->GetMaxElementSize();
- NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
- nscoord cellMinWidth = cellMinSize->width; // do we need to take into account colSpan here?
- cellMinWidth += margin.left + margin.right;
+ if (rowIndex!=cellFrame->GetRowIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
+ continue;
+ }
+
+ nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
+ PRInt32 colSpan = cellFrame->GetColSpan();
+ nscoord cellMinWidth = cellMinSize.width/colSpan;
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
}
@@ -624,32 +699,42 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
PRBool result = PR_TRUE;
nscoord tableWidth=0; // the width of the table as a result of setting column widths
+ nscoord widthOfFixedTableColumns=0; // the sum of the width of all fixed-width columns
+ // tableWidth - widthOfFixedTableColumns is the width of columns computed in this method
PRInt32 totalSlices=0; // the total number of slices the proportional-width columns request
nsVoidArray *proportionalColumnsList=nsnull; // a list of the columns that are proportional-width
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
- nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData();
- PRInt32 numCols = columnLayoutData->Count();
- nscoord * effectiveColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveColumnWidths, 0, numCols*sizeof(PRInt32));
- for (PRInt32 colIndex = 0; colIndexGetRowCount();
+
+ for (PRInt32 colIndex = 0; colIndexElementAt(colIndex));
- nsVoidArray *cells = colData->GetCells();
- PRInt32 numCells = cells->Count();
-
- // Get the columns's style
- nsTableColFrame *colFrame = colData->GetColFrame();
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
- nsIStyleContextPtr colSC;
- colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
- const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
- if (gsDebug) printf("col %d has frame %p with style %p and pos %p\n",
- colIndex, colFrame, (nsIStyleContext *)colSC, colPosition);
+ PRInt32 rowIndex;
+ PRInt32 firstRowIndex = -1;
+ nsTableCellFrame * firstCellInColumn;
+ for (rowIndex=0; rowIndexGetCellAt(rowIndex, colIndex);
+ if (nsnull!=firstCellInColumn)
+ break;
+ }
+ nsMargin colMargin;
+ nscoord colInset = 0;
+ if (nsnull!=firstCellInColumn)
+ {
+ firstCellInColumn->GetMargin(colMargin);
+ colInset = colMargin.left + colMargin.right;
+ }
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
{
// first, deal with any cells that span into this column from a pervious column
@@ -676,33 +761,33 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
}
- for (PRInt32 cellIndex = 0; cellIndexElementAt(cellIndex));
- if (nsnull == data) {
- // For cells that span columns there's only cell layout data for the first column
+ nsTableCellFrame * cellFrame = mTableFrame->GetCellAt(rowIndex, colIndex);
+ if (nsnull==cellFrame)
+ { // there is no cell in this row that corresponds to this column
+ continue;
+ }
+ if (-1==firstRowIndex)
+ firstRowIndex = rowIndex;
+ if (rowIndex!=cellFrame->GetRowIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
- PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
+ PRInt32 colSpan = cellFrame->GetColSpan();
// distribute a portion of the spanning cell's min and max width to this column
- nsSize * cellMinSize = data->GetMaxElementSize();
- NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
- nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
- NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
+ nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
+ nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- nsMargin margin;
- nsresult result = data->GetMargin(margin);
- nscoord marginWidth = margin.left + margin.right;
- PRInt32 cellMinWidth = cellMinSize->width/colSpan + marginWidth;
+ PRInt32 cellMinWidth = cellMinSize.width/colSpan;
// first get the desired size info from reflow pass 1
- PRInt32 cellDesiredWidth = cellDesiredSize->width/colSpan + marginWidth;
+ PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
// then get the desired size info factoring in the cell style attributes
nscoord specifiedCellWidth=-1;
- nsIStyleContextPtr cellSC;
- data->GetCellFrame()->GetStyleContext(aPresContext, cellSC.AssignRef());
- const nsStylePosition* cellPosition = (const nsStylePosition*)
- cellSC->GetStyleData(eStyleStruct_Position);
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
switch (cellPosition->mWidth.GetUnit()) {
case eStyleUnit_Coord:
specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
@@ -730,17 +815,17 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
if (-1!=specifiedCellWidth)
{
- if (specifiedCellWidth>cellMinWidth)
+ if (specifiedCellWidth/colSpan>cellMinWidth)
{
if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
- cellDesiredWidth, specifiedCellWidth);
- cellDesiredWidth = specifiedCellWidth; // TODO: some math needed here for colspans
+ cellDesiredWidth, specifiedCellWidth/colSpan);
+ cellDesiredWidth = specifiedCellWidth/colSpan; // TODO: some math needed here for colspans
}
}
if (PR_TRUE==gsDebug)
printf("factoring in cell %d with colSpan=%d\n factoring in min=%d and desired=%d\n",
- cellIndex, colSpan, cellMinWidth, cellDesiredWidth);
+ rowIndex, colSpan, cellMinWidth, cellDesiredWidth);
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
if (maxColWidth < cellDesiredWidth)
@@ -750,10 +835,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
effectiveColumnWidths[colIndex] = cellDesiredWidth;
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
- cellIndex, minColWidth, maxColWidth,
+ rowIndex, minColWidth, maxColWidth,
colIndex, effectiveColumnWidths[colIndex]);
- if (1GetColIndex()==colIndex))
+ { // add this cell to span list iff we are currently processing the column the cell starts in
SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
if (nsnull==spanList)
spanList = new nsVoidArray();
@@ -863,7 +948,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
if (-1==percentage)
{
- percentage = 100/numCols;
+ percentage = 100/mNumCols;
// base the % on the remaining available width
mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100);
if (gsDebug==PR_TRUE)
@@ -879,7 +964,11 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
}
}
- tableWidth += mTableFrame->GetColumnWidth(colIndex);
+ else
+ { // need to maintain this so we know how much we have left over at the end
+ widthOfFixedTableColumns += mTableFrame->GetColumnWidth(colIndex) + colInset;
+ }
+ tableWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
}
/* --- post-process if necessary --- */
@@ -938,9 +1027,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
// next, if the specified width of the table is greater than the table's computed width, expand the
// table's computed width to match the specified width, giving the extra space to proportionately-sized
// columns if possible.
- if ((PR_FALSE==aTableIsAutoWidth) && (aAvailWidth > tableWidth))
+ if ((PR_FALSE==aTableIsAutoWidth) && (aAvailWidth > (tableWidth-widthOfFixedTableColumns)))
{
- DistributeExcessSpace(aAvailWidth, tableWidth, effectiveColumnWidths);
+ DistributeExcessSpace(aAvailWidth, tableWidth, widthOfFixedTableColumns, effectiveColumnWidths);
}
// today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
if (nsnull!=effectiveColumnWidths)
@@ -952,24 +1041,27 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
// take the extra space in the table and distribute it proportionately (based on desired width)
// give extra space to auto-width cells first, or if there are none to all cells
-void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
- nscoord aComputedTableWidth,
+void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
+ nscoord aTableWidth,
+ nscoord aWidthOfFixedTableColumns,
nscoord *aColWidths)
{
nscoord excess = 0;
- if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d\n",
- aTableFixedWidth, aComputedTableWidth);
+ if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d, woftc=%d\n",
+ aAvailWidth, aTableWidth, aWidthOfFixedTableColumns);
// if there are auto-sized columns, give them the extra space
+ // the trick here is to do the math excluding non-auto width columns
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0!=numAutoColumns)
{
+ nscoord computedTableWidth = aTableWidth - aWidthOfFixedTableColumns;
// there's at least one auto-width column, so give it (them) the extra space
// proportionately distributed extra space, based on the column's desired size
nscoord totalEffectiveWidthOfAutoColumns = 0;
if (gsDebug==PR_TRUE)
- printf(" aTableFixedWidth specified as %d, expanding columns by excess = %d\n", aTableFixedWidth, excess);
+ printf(" aAvailWidth specified as %d, expanding columns by excess = %d\n", aAvailWidth, excess);
// 1. first, get the total width of the auto columns
PRInt32 i;
for (i = 0; iGetColumnWidth(autoColumns[i]);
}
- excess = aTableFixedWidth - aComputedTableWidth;
+ excess = aAvailWidth - computedTableWidth;
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iGetColumnWidth(colIndex);//aColWidths[colIndex];
float percent;
if (0!=totalEffectiveWidthOfAutoColumns)
percent = ((float)(aColWidths[colIndex]))/((float)totalEffectiveWidthOfAutoColumns);
@@ -1002,25 +1094,25 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
// (they must be all fixed and percentage-width columns, or we would have gone into the block above)
else
{
- excess = aTableFixedWidth - aComputedTableWidth;
- nscoord excessPerColumn = excess/mNumCols;
+ excess = aAvailWidth - (aTableWidth-aWidthOfFixedTableColumns);
if (gsDebug==PR_TRUE)
- printf(" aTableFixedWidth specified as %d, expanding columns by excess = %d\n", aTableFixedWidth, excess);
+ printf(" aAvailWidth specified as %d, expanding columns by excess = %d\n",
+ aAvailWidth, excess);
for (PRInt32 colIndex = 0; colIndexGetColumnWidth(colIndex);
float percent;
- if (0!=aComputedTableWidth)
- percent = (float)oldColWidth/(float)aComputedTableWidth;
+ if (0!=aTableWidth)
+ percent = (float)oldColWidth/(float)aTableWidth;
else
percent = (float)1/(float)mNumCols;
nscoord excessForThisColumn = (nscoord)(excess*percent);
nscoord colWidth = excessForThisColumn+oldColWidth;
if (gsDebug==PR_TRUE)
- printf(" distribute excess to all columns: column %d was %d, now set to %d\n",
- colIndex, aColWidths[colIndex], colWidth);
+ printf(" distribute excess to all columns: column %d was %d, now set to %d from % = %f\n",
+ colIndex, oldColWidth, colWidth, percent);
mTableFrame->SetColumnWidth(colIndex, colWidth);
}
}
@@ -1051,29 +1143,40 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
// proportional-width columns are equal (if any are anything other than 1)
PRBool atLeastOneAutoWidthColumn = PR_FALSE; // true if at least one column is auto-width, requiring us to post-process
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
- nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData();
- PRInt32 numCols = columnLayoutData->Count();
- nscoord * effectiveMaxColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveMaxColumnWidths, 0, numCols*sizeof(PRInt32));
- nscoord * effectiveMinColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveMinColumnWidths, 0, numCols*sizeof(PRInt32));
- for (PRInt32 colIndex = 0; colIndexGetRowCount();
+
+ for (PRInt32 colIndex = 0; colIndexElementAt(colIndex));
- nsVoidArray *cells = colData->GetCells();
- PRInt32 numCells = cells->Count();
-
- // Get the columns's style
- nsTableColFrame *colFrame = colData->GetColFrame();
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
- nsIStyleContextPtr colSC;
- colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
- const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
+ // Get the columns's style and margins
+ PRInt32 rowIndex;
+ PRInt32 firstRowIndex = -1;
+ nsTableCellFrame * firstCellInColumn;
+ for (rowIndex=0; rowIndexGetCellAt(rowIndex, colIndex);
+ if (nsnull!=firstCellInColumn)
+ break;
+ }
+ nsMargin colMargin;
+ nscoord colInset = 0;
+ if (nsnull!=firstCellInColumn)
+ {
+ firstCellInColumn->GetMargin(colMargin);
+ colInset = colMargin.left + colMargin.right;
+ }
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
{
@@ -1100,33 +1203,30 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
}
}
- for (PRInt32 cellIndex = 0; cellIndexElementAt(cellIndex));
- if (nsnull == data) {
- // For cells that span rows there's only cell layout data for the first row
+ for (rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
+ if (nsnull==cellFrame)
+ { // there is no cell in this row that corresponds to this column
+ continue;
+ }
+ if (rowIndex!=cellFrame->GetRowIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
- PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
- nsSize * cellMinSize = data->GetMaxElementSize();
- NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
- nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
- NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
+ PRInt32 colSpan = cellFrame->GetColSpan();
+ nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
+ nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- nsMargin margin;
- nsresult result = data->GetMargin(margin);
- nscoord marginWidth = margin.left + margin.right;
-
- PRInt32 cellMinWidth = cellMinSize->width/colSpan + marginWidth;
+ PRInt32 cellMinWidth = cellMinSize.width/colSpan;
// first get the desired size info from reflow pass 1
- PRInt32 cellDesiredWidth = cellDesiredSize->width/colSpan + marginWidth;
+ PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
// then get the desired size info factoring in the cell style attributes
nscoord specifiedCellWidth=-1;
- nsIStyleContextPtr cellSC;
- data->GetCellFrame()->GetStyleContext(aPresContext, cellSC.AssignRef());
- const nsStylePosition* cellPosition = (const nsStylePosition*)
- cellSC->GetStyleData(eStyleStruct_Position);
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition);
switch (cellPosition->mWidth.GetUnit()) {
case eStyleUnit_Coord:
specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
@@ -1164,7 +1264,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
if (PR_TRUE==gsDebug)
printf("factoring in cell %d with colSpan=%d\n factoring in min=%d and desired=%d\n",
- cellIndex, colSpan, cellMinWidth, cellDesiredWidth);
+ rowIndex, colSpan, cellMinWidth, cellDesiredWidth);
// remember the widest min cell width
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
@@ -1179,7 +1279,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
effectiveMaxColumnWidths[colIndex] = cellDesiredWidth;
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
- cellIndex, minColWidth, maxColWidth,
+ rowIndex, minColWidth, maxColWidth,
colIndex, effectiveMaxColumnWidths[colIndex], effectiveMaxColumnWidths[colIndex]);
if (1GetColumnWidth(colIndex));
}
- else if (1==numCols)
+ else if (1==mNumCols)
{ // there is only one column, and we know that it's desired width doesn't fit
// so the column should be as wide as the available space allows it to be
if (gsDebug==PR_TRUE) printf (" 4 one-column: col %d set to width = %d\n", colIndex, aAvailWidth);
@@ -1300,7 +1400,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
if (-1==percentage)
{
- percentage = 100/numCols;
+ percentage = 100/mNumCols;
// base the % on the remaining available width
mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100);
if (gsDebug==PR_TRUE)
@@ -1417,16 +1517,52 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableFixedWidt
else
percent = ((float)1)/((float)numAutoColumns);
nscoord colWidth = (nscoord)(availWidth*percent);
- if (colWidthSetColumnWidth(colIndex, colWidth);
}
+ EnsureCellMinWidths(aMinColWidths);
+ }
+}
+
+void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
+{
+ PRBool atLeastOne = PR_TRUE;
+ while (PR_TRUE==atLeastOne)
+ {
+ atLeastOne=PR_FALSE;
+ PRInt32 colIndex;
+ nscoord addedWidth = 0;
+ // first, bump up cells that are below their min to their min width
+ for (colIndex=0; colIndexGetColumnWidth(colIndex);
+ if (colWidthSetColumnWidth(colIndex, aMinColWidths[colIndex]);
+ atLeastOne=PR_TRUE;
+ }
+ }
+ // second, remove the added space from cells that can afford to slim down
+ //QQQ boy is this slow! there has to be a faster way that is still guaranteed to be accurate...
+ while ((addedWidth>0))
+ { // while we still have some extra space, and last time we were able to take some off...
+ for (colIndex=0; colIndexGetColumnWidth(colIndex);
+ if (colWidth>aMinColWidths[colIndex])
+ {
+ mTableFrame->SetColumnWidth(colIndex, colWidth-1);
+ addedWidth--;
+ }
+ }
+ }
+ if (0/* XXX */ // for printf
-
-
-nsCellLayoutData::nsCellLayoutData(nsTableCellFrame *aCellFrame,
- nsReflowMetrics * aDesiredSize, nsSize * aMaxElementSize)
- : mDesiredSize(nsnull)
-{
- // IMPORTANT: Always intialize instance variables to null
- mColLayoutData = nsnull;
- mCellFrame = nsnull;
- mMargin.top = mMargin.bottom = mMargin.left = mMargin.right = 0;
-
- for (PRInt32 i = 0; i < 4; i++)
- mBorderFrame[i] = nsnull;
-
- // IMPORTANT: call setters: this
- // guarentees addrefs/releases are called if needed - gpk
- SetCellFrame(aCellFrame);
- SetDesiredSize(aDesiredSize);
- SetMaxElementSize(aMaxElementSize);
-
- mCalculated = NS_ERROR_NOT_INITIALIZED;
-}
-
-// don't delete mCellFrame, I didn't allocate it
-nsCellLayoutData::~nsCellLayoutData()
-{
- mCellFrame = nsnull;
- mColLayoutData = nsnull;
-}
-
-/**
- * Get the style context for this object (determined, by
- * asking for the frame
- *
- **/
-nsIStyleContext* nsCellLayoutData::GetStyleContext()
-{
- if (mCellFrame != nsnull) {
- nsIStyleContext* styleContext;
- mCellFrame->GetStyleContext(nsnull, styleContext);
- return styleContext;
- }
- return nsnull;
-}
-
-/**
- * Given a list of nsCellLayoutData and a index, get the style context for
- * that element in the list
- *
- **/
-nsIFrame* nsCellLayoutData::GetFrameAt(nsVoidArray* aList, PRInt32 aIndex)
-{
- nsIFrame* result = nsnull;
-
- if (aList != nsnull)
- {
- nsCellLayoutData* data = (nsCellLayoutData*)aList->ElementAt(aIndex);
- if (data != nsnull)
- result = data->GetCellFrame();
- }
- return result;
-}
-
-/**
- * Given a frame and an edge, find the margin
- *
- **/
-nscoord nsCellLayoutData::GetMargin(nsIFrame* aFrame, PRUint8 aEdge) const
-{
- nscoord result = 0;
-
- if (aFrame)
- {
- const nsStyleSpacing* spacing;
- aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
- nsMargin margin;
- spacing->CalcMarginFor(aFrame, margin);
- switch (aEdge)
- {
- case NS_SIDE_TOP:
- result = margin.top;
- break;
-
- case NS_SIDE_RIGHT:
- result = margin.right;
- break;
-
- case NS_SIDE_BOTTOM:
- result = margin.bottom;
- break;
-
- case NS_SIDE_LEFT:
- result = margin.left;
- break;
-
- }
- }
- return result;
-}
-
-
-/**
- * Given a style context and an edge, find the border width
- *
- **/
-nscoord nsCellLayoutData::GetBorderWidth(nsIFrame* aFrame, PRUint8 aEdge) const
-{
- nscoord result = 0;
-
- if (aFrame)
- {
- const nsStyleSpacing* spacing;
- aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
- nsMargin border;
- spacing->CalcBorderFor(aFrame, border);
- switch (aEdge)
- {
- case NS_SIDE_TOP:
- result = border.top;
- break;
-
- case NS_SIDE_RIGHT:
- result = border.right;
- break;
-
- case NS_SIDE_BOTTOM:
- result = border.bottom;
- break;
-
- case NS_SIDE_LEFT:
- result = border.left;
- break;
-
- }
- }
- return result;
-}
-
-
-/**
- * Given a style context and an edge, find the padding
- *
- **/
-nscoord nsCellLayoutData::GetPadding(nsIFrame* aFrame, PRUint8 aEdge) const
-{
- nscoord result = 0;
-
- if (aFrame)
- {
- const nsStyleSpacing* spacing;
- aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
- nsMargin padding;
- spacing->CalcPaddingFor(aFrame, padding);
- switch (aEdge)
- {
- case NS_SIDE_TOP:
- result = padding.top;
- break;
-
- case NS_SIDE_RIGHT:
- result = padding.right;
- break;
-
- case NS_SIDE_BOTTOM:
- result = padding.bottom;
- break;
-
- case NS_SIDE_LEFT:
- result = padding.left;
- break;
-
- }
- }
- return result;
-}
-
-
-
-/**
- * Given an Edge, find the opposing edge (top<-->bottom, left<-->right)
- *
- **/
-PRUint8 nsCellLayoutData::GetOpposingEdge(PRUint8 aEdge)
-{
- PRUint8 result;
-
- switch (aEdge)
- {
- case NS_SIDE_LEFT:
- result = NS_SIDE_RIGHT;
- break;
-
- case NS_SIDE_RIGHT:
- result = NS_SIDE_LEFT;
- break;
-
- case NS_SIDE_TOP:
- result = NS_SIDE_BOTTOM;
- break;
-
- case NS_SIDE_BOTTOM:
- result = NS_SIDE_TOP;
- break;
-
- default:
- result = NS_SIDE_TOP;
- }
- return result;
-}
-
-
-/*
-*
-* Determine border style for two cells.
-*
- 1.If the adjacent elements are of the same type, the wider of the two borders is used.
- "Wider" takes into account the border-style of 'none', so a "1px solid" border
- will take precedence over a "20px none" border.
-
- 2.If there are two or more with the same width, but different style,
- then the one with a style near the start of the following list will be drawn:
-
- 'blank', 'double', 'solid', 'dashed', 'dotted', 'ridge', 'groove', 'none'
-
- 3.If the borders are of the same width, the border on the element occurring first is used.
-
- First is defined as aStyle for this method.
-
- NOTE: This assumes left-to-right, top-to-bottom bias. -- gpk
-
-*
-*/
-
-
-nsIFrame* nsCellLayoutData::CompareCellBorders(nsIFrame* aFrame1,
- PRUint8 aEdge1,
- nsIFrame* aFrame2,
- PRUint8 aEdge2)
-{
- PRInt32 width1 = GetBorderWidth(aFrame1,aEdge1);
- PRInt32 width2 = GetBorderWidth(aFrame2,aEdge2);
-
- nsIFrame* result = nsnull;
-
- if (width1 > width2)
- result = aFrame1;
- else if (width1 < width2)
- result = aFrame2;
- else // width1 == width2
- {
- const nsStyleSpacing* border1;
- const nsStyleSpacing* border2;
- aFrame1->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)border1);
- aFrame2->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)border2);
- if (border1->mBorderStyle[aEdge1] >= border2->mBorderStyle[aEdge2])
- result = aFrame1;
- else
- result = aFrame2;
- }
- return result;
-}
-
-
-/**
- * Given a List of cell layout data, compare the edges to see which has the
- * border with the highest precidence.
- *
- **/
-
-nsIFrame* nsCellLayoutData::FindHighestPrecedentBorder(nsVoidArray* aList,
- PRUint8 aEdge)
-{
- nsIFrame* result = nsnull;
- PRInt32 index = 0;
- PRInt32 count = 0;
-
-
- NS_ASSERTION(aList,"a List must be valid");
- count = aList->Count();
- if (count)
- {
- nsIFrame* frame1;
- nsIFrame* frame2;
-
- frame1 = GetFrameAt(aList,index++);
- while (index < count)
- {
- frame2 = GetFrameAt(aList,index++);
- if (GetMargin(frame2,aEdge) == 0) {
- frame1 = CompareCellBorders(frame1, aEdge, frame2, aEdge);
- }
- }
- if ((nsnull != frame1) && (GetMargin(frame1, aEdge) != 0))
- result = frame1;
- }
- return result;
-}
-
-
-
-
-nsIFrame* nsCellLayoutData::FindInnerBorder(nsVoidArray* aList, PRUint8 aEdge)
-{
- nsIFrame* result = nsnull;
- PRUint8 opposite = GetOpposingEdge(aEdge);
-
- if (GetMargin(mCellFrame, aEdge) == 0)
- {
- nsIFrame* altFrame = FindHighestPrecedentBorder(aList,opposite);
- if (nsnull != altFrame)
- result = CompareCellBorders(mCellFrame, aEdge, altFrame, opposite);
- else
- result = mCellFrame;
- }
-
- return result;
-}
-
-
-/*
-*
-* FindRelevantBorder recursively searches up the frame hierarchy for the border
-* style that is applicable to the cell. If at any point the frame has a margin
-* or the parent frame has padding, then the outer frame for this object takes
-* presendence over the inner frame.
-
-1.Borders on 'table' elements take precedence over borders on any other table elements.
-2.Borders on 'row-groups' take precedence over borders on 'rows',
- and likewise borders on 'column-groups' take precedence over borders on 'columns'.
-3.Borders on any other type of table element take precedence over 'table-cell' elements.
-
-*
-* NOTE: This method assumes that the table cell potentially shares a border.
-* It should not be called for internal cells
-*
-* NOTE: COLUMNS AND COLGROUPS NEED TO BE FIGURED INTO THE ALGORITHM -- GPK!!!
-*
-*
-*/
-nsIFrame* nsCellLayoutData::FindOuterBorder( nsTableFrame* aTableFrame,
- PRUint8 aEdge)
-{
- nsIFrame* frame = mCellFrame; // By default, return our frame
- PRBool done = PR_FALSE;
-
-
- // The table frame is the outer most frame we test against
- while (done == PR_FALSE)
- {
- done = PR_TRUE; // where done unless the frame's margin is zero
- // and the parent's padding is zero
-
- nscoord margin = GetMargin(frame,aEdge);
-
- // if the margin for this style is zero then check to see if the paddding
- // for the parent frame is also zero
- if (margin == 0)
- {
- nsIFrame* parentFrame;
-
- frame->GetGeometricParent(parentFrame);
-
- // if the padding for the parent style is zero just
- // recursively call this routine
- PRInt32 padding = GetPadding(parentFrame,aEdge);
- if ((nsnull != parentFrame) && (padding == 0))
- {
- frame = parentFrame;
- // If this frame represents the table frame then
- // the table style is used
- done = PRBool(frame != (nsIFrame*)aTableFrame);
- continue;
- }
-
- }
- }
- return frame;
-}
-
-
-
-/*
-
- Border Resolution
- 1.Borders on 'table' elements take precedence over borders on any other table elements.
- 2.Borders on 'row-groups' take precedence over borders on 'rows', and likewise borders on 'column-groups' take
- precedence over borders on 'columns'.
- 3.Borders on any other type of table element take precedence over 'table-cell' elements.
- 4.If the adjacent elements are of the same type, the wider of the two borders is used. "Wider" takes into account
- the border-style of 'none', so a "1px solid" border will take precedence over a "20px none" border.
- 5.If the borders are of the same width, the border on the element occurring first is used.
-
-
- How to compare
- 1.Those of the one or two cells that have an edge here.
- Less than two can occur at the edge of the table, but also
- at the edges of "holes" (unoccupied grid cells).
- 2.Those of the columns that have an edge here.
- 3.Those of the column groups that have an edge here.
- 4.Those of the rows that have an edge here.
- 5.Those of the row groups that have an edge here.
- 6.Those of the table, if this is the edge of the table.
-
-*
-* @param aIsFirst -- TRUE if this is the first cell in the row
-* @param aIsLast -- TRUE if this is the last cell in the row
-* @param aIsTop -- TRUE if this is the top cell in the column
-* @param aIsBottom -- TRUE if this is the last cell in the column
-*/
-
-nsIFrame* nsCellLayoutData::FindBorderFrame(nsTableFrame* aTableFrame,
- nsVoidArray* aList,
- PRUint8 aEdge)
-{
- nsIFrame* frame = nsnull;
-
- if (aList && aList->Count() == 0)
- frame = FindOuterBorder(aTableFrame, aEdge);
- else
- frame = FindInnerBorder(aList, aEdge);
-
- if (! frame)
- frame = mCellFrame;
-
- return frame;
-}
-
-
-/**
- * Given a List of cell layout data, compare the edges to see which has the
- * border with the highest precidence.
- *
- **/
-nscoord nsCellLayoutData::FindLargestMargin(nsVoidArray* aList,PRUint8 aEdge)
-{
- nscoord result = 0;
- PRInt32 index = 0;
- PRInt32 count = 0;
-
-
- NS_ASSERTION(aList,"a List must be valid");
- count = aList->Count();
- if (count)
- {
- nsIFrame* frame;
-
- nscoord value = 0;
- while (index < count)
- {
- frame = GetFrameAt(aList,index++);
- value = GetMargin(frame, aEdge);
- if (value > result)
- result = value;
- }
- }
- return result;
-}
-
-
-
-
-void nsCellLayoutData::CalculateMargins(nsTableFrame* aTableFrame,
- nsVoidArray* aBoundaryCells[4])
-{
- // By default the margin is just the margin found in the
- // table cells style
- const nsStyleSpacing* spacing;
- mCellFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
- spacing->CalcMarginFor(mCellFrame, mMargin);
-
- // Left and Top Margins are collapsed with their neightbors
- // Right and Bottom Margins are simple left as they are
- nscoord value;
-
- // The left and top sides margins are the difference between
- // their inherint value and the value of the margin of the
- // object to the left or right of them.
-
- value = FindLargestMargin(aBoundaryCells[NS_SIDE_LEFT],NS_SIDE_RIGHT);
- if (value > mMargin.left)
- mMargin.left = 0;
- else
- mMargin.left -= value;
-
- value = FindLargestMargin(aBoundaryCells[NS_SIDE_TOP],NS_SIDE_BOTTOM);
- if (value > mMargin.top)
- mMargin.top = 0;
- else
- mMargin.top -= value;
-}
-
-
-void nsCellLayoutData::RecalcLayoutData(nsTableFrame* aTableFrame,
- nsVoidArray* aBoundaryCells[4])
-
-{
- CalculateBorders(aTableFrame, aBoundaryCells);
- CalculateMargins(aTableFrame, aBoundaryCells);
- mCalculated = NS_OK;
-}
-
-void nsCellLayoutData::List(FILE* out, PRInt32 aIndent) const
-{
- PRInt32 indent;
-
- nsIContent* cell;
-
- mCellFrame->GetContent(cell);
- if (cell != nsnull)
- {
- /*
- for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
- fprintf(out,"RowSpan = %d ColSpan = %d \n",cell->GetRowSpan(),cell->GetColSpan());
- */
- for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
- fprintf(out,"Margin -- Top: %d Left: %d Bottom: %d Right: %d \n",
- NS_TWIPS_TO_POINTS_INT(mMargin.top),
- NS_TWIPS_TO_POINTS_INT(mMargin.left),
- NS_TWIPS_TO_POINTS_INT(mMargin.bottom),
- NS_TWIPS_TO_POINTS_INT(mMargin.right));
-
-
- for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
-
- nscoord top,left,bottom,right;
-
- top = (mBorderFrame[NS_SIDE_TOP] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_TOP], NS_SIDE_TOP) : 0);
- left = (mBorderFrame[NS_SIDE_LEFT] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_LEFT], NS_SIDE_LEFT) : 0);
- bottom = (mBorderFrame[NS_SIDE_BOTTOM] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_BOTTOM], NS_SIDE_BOTTOM) : 0);
- right = (mBorderFrame[NS_SIDE_RIGHT] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_RIGHT], NS_SIDE_RIGHT) : 0);
-
-
- fprintf(out,"Border -- Top: %d Left: %d Bottom: %d Right: %d \n",
- NS_TWIPS_TO_POINTS_INT(top),
- NS_TWIPS_TO_POINTS_INT(left),
- NS_TWIPS_TO_POINTS_INT(bottom),
- NS_TWIPS_TO_POINTS_INT(right));
-
-
-
- cell->List(out,aIndent);
- NS_RELEASE(cell);
- }
-}
-
diff --git a/mozilla/layout/html/table/src/nsCellLayoutData.h b/mozilla/layout/html/table/src/nsCellLayoutData.h
deleted file mode 100644
index 8d7d9eda77c..00000000000
--- a/mozilla/layout/html/table/src/nsCellLayoutData.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-#ifndef nsCellLayoutData_h__
-#define nsCellLayoutData_h__
-
-#include "nscore.h"
-#include "nsSize.h"
-#include "nsIFrame.h"
-
-class nsTableCellFrame;
-class nsColLayoutData;
-class nsTableFrame;
-class nsIStyleContext;
-class nsVoidArray;
-struct nsStyleSpacing;
-
-
-/** Simple data class that represents in-process reflow information about a cell.
- * Each cell is represented by a nsTableCellFrame together with the results
- * of the "first pass" layout results (where "first pass" means the cell was told
- * to lay itself out with unrestricted height and width.)
- * There is one nsCellLayoutData object per nsTableFrame for each cell.
- *
- * TODO: All methods will be inline.
- */
-class nsCellLayoutData
-{
-public:
-
- /** public constructor. Does not allocate any of its own data.
- * @param aCellFrame the frame representing the cell
- * @param aDesiredSize the max size of the cell if given infinite height and width
- * @param aMaxElementSize the min size of the largest indivisible element within the cell
- */
- nsCellLayoutData(nsTableCellFrame *aCellFrame,
- nsReflowMetrics * aDesiredSize, nsSize * aMaxElementSize);
-
- /** destructor, not responsible for destroying any of the stored data */
- virtual ~nsCellLayoutData();
-
- /** return the frame mapping the cell */
- nsTableCellFrame * GetCellFrame();
-
- /** set the frame mapping the cell */
- void SetCellFrame(nsTableCellFrame * aCellFrame);
-
- /** return the max size of the cell if given infinite height and width */
- nsReflowMetrics * GetDesiredSize();
-
- /** set the max size of the cell if given infinite height and width.
- * called after pass 1 of table reflow is complete.
- */
- void SetDesiredSize(nsReflowMetrics * aDesiredSize);
-
- /** get the min size of the largest indivisible element within the cell */
- nsSize * GetMaxElementSize();
-
- /** set the min size of the largest indivisible element within the cell.
- * called after pass 1 of table reflow is complete.
- */
- void SetMaxElementSize(nsSize * aMaxElementSize);
-
- /** debug method outputs data about this cell to FILE *out */
- void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
-
- /** returns the style context associated with this cell */
- nsIStyleContext* GetStyleContext();
-
-private:
-
- // All these methods are support methods for RecalcLayoutData
- nsIFrame* GetFrameAt(nsVoidArray* aList, PRInt32 aIndex);
-
- nscoord GetMargin(nsIFrame* aFrame, PRUint8 aEdge) const;
-
- nscoord GetBorderWidth(nsIFrame* aFrame, PRUint8 aEdge) const;
-
- nscoord GetPadding(nsIFrame* aFrame, PRUint8 aEdge) const;
-
- PRUint8 GetOpposingEdge(PRUint8 aEdge);
-
- nsIFrame* CompareCellBorders(nsIFrame* aFrame1,
- PRUint8 aEdge1,
- nsIFrame* aFrame2,
- PRUint8 aEdge2);
-
-
- nsIFrame* FindHighestPrecedentBorder(nsVoidArray* aList,
- PRUint8 aEdge);
-
-
-
- nsIFrame* FindInnerBorder( nsVoidArray* aList,
- PRUint8 aEdge);
-
- nsIFrame* FindOuterBorder( nsTableFrame* aTableFrame,
- PRUint8 aEdge);
-
- nsIFrame* FindBorderFrame(nsTableFrame* aTableFrame,
- nsVoidArray* aCellList,
- PRUint8 aEdge);
-
- void CalculateBorders(nsTableFrame* aTableFrame,
- nsVoidArray* aBoundaryCells[4]);
-
- nscoord FindLargestMargin(nsVoidArray* aList,PRUint8 aEdge);
-
-
- void CalculateMargins(nsTableFrame* aTableFrame,
- nsVoidArray* aBoundaryCells[4]);
-
-public:
- void RecalcLayoutData(nsTableFrame* aTableFrame,
- nsVoidArray* aBoundaryCells[4]);
-
-
- NS_IMETHOD GetMargin(nsMargin& aMargin);
-
-
-
-private:
-#if 0 // these come on line when we do character-based cell content alignment
- /** the kinds of width information stored */
- enum {WIDTH_NORMAL=0, WIDTH_LEFT_ALIGNED=1, WIDTH_RIGHT_ALIGNED=2};
-
- /** the width information for a cell */
- PRInt32 mWidth[3];
-#endif
-
- nsColLayoutData *mColLayoutData;
- nsTableCellFrame *mCellFrame;
- nsReflowMetrics mDesiredSize;
- nsSize mMaxElementSize;
-
- nsresult mCalculated;
- nsMargin mMargin;
- nsIFrame* mBorderFrame[4]; // the frame whose border is used
-};
-
-inline nsTableCellFrame * nsCellLayoutData::GetCellFrame()
-{ return mCellFrame; }
-
-inline void nsCellLayoutData::SetCellFrame(nsTableCellFrame * aCellFrame)
-{ mCellFrame = aCellFrame; }
-
-inline nsReflowMetrics * nsCellLayoutData::GetDesiredSize()
-{ return &mDesiredSize; }
-
-inline void nsCellLayoutData::SetDesiredSize(nsReflowMetrics * aDesiredSize)
-{
- if (nsnull!=aDesiredSize)
- mDesiredSize = *aDesiredSize;
-}
-
-inline nsSize * nsCellLayoutData::GetMaxElementSize()
-{ return &mMaxElementSize; }
-
-inline void nsCellLayoutData::SetMaxElementSize(nsSize * aMaxElementSize)
-{
- if (nsnull!=aMaxElementSize)
- mMaxElementSize = *aMaxElementSize;
-}
-
-inline void nsCellLayoutData::CalculateBorders(nsTableFrame* aTableFrame,
- nsVoidArray* aBoundaryCells[4])
-{
-
- for (PRInt32 edge = 0; edge < 4; edge++)
- mBorderFrame[edge] = FindBorderFrame(aTableFrame, aBoundaryCells[edge], edge);
-}
-
-inline NS_METHOD nsCellLayoutData::GetMargin(nsMargin& aMargin)
-{
- if (mCalculated == NS_OK)
- {
- aMargin = mMargin;
- return NS_OK;
- }
- return NS_ERROR_NOT_INITIALIZED;
-}
-
-#endif
diff --git a/mozilla/layout/html/table/src/nsCellMap.cpp b/mozilla/layout/html/table/src/nsCellMap.cpp
index 3098842597e..21c9569e049 100644
--- a/mozilla/layout/html/table/src/nsCellMap.cpp
+++ b/mozilla/layout/html/table/src/nsCellMap.cpp
@@ -15,7 +15,9 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
+
#include "nsCRT.h"
+#include "nsVoidArray.h"
#include "nsCellMap.h"
#include "nsTableFrame.h"
@@ -25,38 +27,50 @@ static PRBool gsDebug1 = PR_FALSE;
static const PRBool gsDebug1 = PR_FALSE;
#endif
-static PRInt32 gBytesPerPointer = sizeof(PRInt32);
+static const PRInt32 gBytesPerPointer = sizeof(PRInt32);
nsCellMap::nsCellMap(int aRows, int aColumns)
: mRowCount(aRows),
mColCount(aColumns)
{
mCells = nsnull;
+ mColFrames = nsnull;
Reset(aRows, aColumns);
}
nsCellMap::~nsCellMap()
{
- for (int i=0;iElementAt(aColIndex));
+}
+
diff --git a/mozilla/layout/html/table/src/nsCellMap.h b/mozilla/layout/html/table/src/nsCellMap.h
index 15f9e6c441a..998b53feac9 100644
--- a/mozilla/layout/html/table/src/nsCellMap.h
+++ b/mozilla/layout/html/table/src/nsCellMap.h
@@ -19,8 +19,11 @@
#define nsCellMap_h__
#include "nscore.h"
+#include "CellData.h"
-class CellData;
+class nsVoidArray;
+class nsTableColFrame;
+class nsTableCellFrame;
/** nsCellMap is a support class for nsTablePart.
* It maintains an Rows x Columns grid onto which the cells of the table are mapped.
@@ -40,55 +43,94 @@ protected:
/** storage for CellData pointers */
PRInt32 *mCells; ///XXX CellData *?
+ /** a cache of the column frames, by col index */
+ nsVoidArray * mColFrames;
+
/** the number of rows */
- int mRowCount; // in java, we could just do fCellMap.length;
+ PRInt32 mRowCount; // in java, we could just do fCellMap.length;
/** the number of columns (the max of all row lengths) */
- int mColCount; // in java, we could just do fCellMap[i].length
+ PRInt32 mColCount;
public:
- nsCellMap(int aRows, int aColumns);
+ nsCellMap(PRInt32 aRows, PRInt32 aColumns);
// NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
~nsCellMap();
/** initialize the CellMap to (aRows x aColumns) */
- void Reset(int aRows, int aColumns);
+ void Reset(PRInt32 aRows, PRInt32 aColumns);
- /** return the CellData for the cell at (aRow,aColumn) */
- CellData * GetCellAt(int aRow, int aColumn) const;
+ /** return the CellData for the cell at (aRowIndex,aColIndex) */
+ CellData * GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex) const;
+
+ /** return the nsTableCellFrame for the cell at (aRowIndex, aColIndex) */
+ nsTableCellFrame * GetCellFrameAt(PRInt32 aRowIndex, PRInt32 aColIndex) const;
/** assign aCellData to the cell at (aRow,aColumn) */
- void SetCellAt(CellData *aCellData, int aRow, int aColumn);
+ void SetCellAt(CellData *aCellData, PRInt32 aRow, PRInt32 aColumn);
/** expand the CellMap to have aColCount columns. The number of rows remains the same */
- void GrowTo(int aColCount);
+ void GrowTo(PRInt32 aColCount);
/** return the total number of columns in the table represented by this CellMap */
- int GetColCount() const;
+ PRInt32 GetColCount() const;
/** return the total number of rows in the table represented by this CellMap */
- int GetRowCount() const;
+ PRInt32 GetRowCount() const;
- /** for debugging, print out this CellMap */
+ nsTableColFrame * GetColumnFrame(PRInt32 aColIndex);
+
+ void AppendColumnFrame(nsTableColFrame *aColFrame);
+
+ PRBool RowImpactedBySpanningCell(PRInt32 aRowIndex);
+
+ PRBool ColumnImpactedBySpanningCell(PRInt32 aColIndex);
+
+ /** for debugging */
void DumpCellMap() const;
};
-inline CellData * nsCellMap::GetCellAt(int aRow, int aColumn) const
+/* ----- inline methods ----- */
+
+inline CellData * nsCellMap::GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex) const
{
- int index = (aRow*mColCount)+aColumn;
+ NS_PRECONDITION(0<=aRowIndex && aRowIndex < mRowCount, "bad aRowIndex arg");
+ NS_PRECONDITION(0<=aColIndex && aColIndex < mColCount, "bad aColIndex arg");
+
+ PRInt32 index = (aRowIndex*mColCount)+aColIndex;
return (CellData *)mCells[index];
}
-inline int nsCellMap::GetColCount() const
+inline nsTableCellFrame * nsCellMap::GetCellFrameAt(PRInt32 aRowIndex, PRInt32 aColIndex) const
+{
+ NS_PRECONDITION(0<=aRowIndex && aRowIndex < mRowCount, "bad aRowIndex arg");
+ NS_PRECONDITION(0<=aColIndex && aColIndex < mColCount, "bad aColIndex arg");
+
+ nsTableCellFrame *result = nsnull;
+ CellData * cellData = GetCellAt(aRowIndex, aColIndex);
+ if (nsnull!=cellData)
+ result = cellData->mCell;
+ return result;
+}
+
+inline PRInt32 nsCellMap::GetColCount() const
{
return mColCount;
}
-inline int nsCellMap::GetRowCount() const
+inline PRInt32 nsCellMap::GetRowCount() const
{
return mRowCount;
}
+inline void nsCellMap::AppendColumnFrame(nsTableColFrame *aColFrame)
+{
+ mColFrames->AppendElement(aColFrame);
+ // sanity check
+ NS_ASSERTION(mColFrames->Count()<=mColCount, "too many columns appended to CellMap");
+}
+
+
#endif
diff --git a/mozilla/layout/html/table/src/nsColLayoutData.cpp b/mozilla/layout/html/table/src/nsColLayoutData.cpp
deleted file mode 100644
index 5a64d0944af..00000000000
--- a/mozilla/layout/html/table/src/nsColLayoutData.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-#include "nsColLayoutData.h"
-#include "nsVoidArray.h"
-#include "nsCellLayoutData.h"
-#include "nsTableCellFrame.h"
-
-nsColLayoutData::nsColLayoutData(nsTableColFrame* aColFrame, PRInt32 aNumRows)
-{
- mColFrame = aColFrame;
- mCells = new nsVoidArray(aNumRows);
-}
-
-nsColLayoutData::~nsColLayoutData()
-{
- if (nsnull!=mCells)
- {
- PRInt32 count = mCells->Count();
- for (PRInt32 i = 0; i < count; i++)
- {
- nsCellLayoutData *data = (nsCellLayoutData *)(mCells->ElementAt(i));
- delete data;
- }
- delete mCells;
- }
- mCells = 0;
-}
-
-PRInt32 nsColLayoutData::IndexOf(nsIContent* aCell) const
-{
- PRInt32 count = this->Count();
- PRInt32 result = -1;
- if (aCell != nsnull)
- {
- for (PRInt32 index = 0; index < count; index++)
- {
- nsCellLayoutData* cellData = ElementAt(index);
- if (cellData != nsnull)
- {
- nsTableCellFrame* frame = cellData->GetCellFrame();
- if (frame != nsnull)
- {
- nsIContent* cell;
-
- frame->GetContent(cell);
- if (cell == aCell)
- {
- result = index;
- NS_RELEASE(cell);
- break;
- }
- NS_IF_RELEASE(cell);
- }
- }
- }
- }
- return result;
-}
-
-
-nsCellLayoutData* nsColLayoutData::GetNext(nsCellLayoutData* aCellLayoutData) const
-{
- PRInt32 index = IndexOf(aCellLayoutData);
- if (index != -1)
- return ElementAt(index+1);
- return (nsCellLayoutData*)nsnull;
-}
-
-nsCellLayoutData* nsColLayoutData::GetPrevious(nsCellLayoutData* aCellLayoutData) const
-{
- PRInt32 index = IndexOf(aCellLayoutData);
- if (index != -1)
- return ElementAt(index-1);
- return (nsCellLayoutData*)nsnull;
-}
-
-
-void nsColLayoutData::List(FILE* out, PRInt32 aIndent) const
-{
- if (nsnull!=mCells)
- {
- PRInt32 count = mCells->Count();
- for (PRInt32 i = 0; i < count; i++)
- {
- for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
- fprintf(out,"Cell Data [%d] \n",i);
-
- nsCellLayoutData *data = (nsCellLayoutData *)(mCells->ElementAt(i));
- data->List(out,aIndent+1);
- }
- }
-}
-
-
diff --git a/mozilla/layout/html/table/src/nsColLayoutData.h b/mozilla/layout/html/table/src/nsColLayoutData.h
deleted file mode 100644
index f9059469da9..00000000000
--- a/mozilla/layout/html/table/src/nsColLayoutData.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-#ifndef nsColLayoutData_h__
-#define nsColLayoutData_h__
-
-#include "nscore.h"
-#include "nsSize.h"
-#include "nsIFrame.h"
-#include "nsVoidArray.h"
-
-class nsCellLayoutData;
-class nsTableFrame;
-class nsTableColFrame;
-class nsIContent;
-
-
-/** Simple data class that represents in-process reflow information about a column.
- */
-class nsColLayoutData
-{
-public:
- nsColLayoutData(nsTableColFrame* aColFrame, PRInt32 aNumRows);
-
- // NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
- ~nsColLayoutData();
-
- nsTableColFrame *GetColFrame();
-
- nsVoidArray * GetCells();
-
- PRInt32 Count() const;
-
- nsCellLayoutData* ElementAt(PRInt32 aIndex) const;
-
- PRInt32 IndexOf(nsCellLayoutData* aCellLayoutData) const;
- PRInt32 IndexOf(nsIContent* aTableCell) const;
-
- nsCellLayoutData* GetNext(nsCellLayoutData* aCellLayoutData) const;
-
- nsCellLayoutData* GetPrevious(nsCellLayoutData* aCellLayoutData) const;
-
-
-
- PRBool AppendElement(nsCellLayoutData* aCellLayoutData);
-
- PRBool ReplaceElementAt(nsCellLayoutData* aCellLayoutData, PRInt32 aIndex);
-
- void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
-
-
-private:
-
- nsTableColFrame *mColFrame;
- nsVoidArray *mCells;
-
-};
-
-/* ---------- inlines ---------- */
-
-inline nsTableColFrame * nsColLayoutData::GetColFrame()
-{ return mColFrame;}
-
-inline nsCellLayoutData* nsColLayoutData::ElementAt(PRInt32 aIndex) const
-{ return (nsCellLayoutData*)mCells->ElementAt(aIndex);}
-
-inline PRBool nsColLayoutData::AppendElement(nsCellLayoutData* aCellLayoutData)
-{ return mCells->AppendElement((void*)aCellLayoutData);}
-
-inline PRBool nsColLayoutData::ReplaceElementAt(nsCellLayoutData* aCellLayoutData, PRInt32 aIndex)
-{ return mCells->ReplaceElementAt((void*)aCellLayoutData,aIndex);}
-
-inline nsVoidArray * nsColLayoutData::GetCells()
-{ return mCells; }
-
-inline PRInt32 nsColLayoutData::Count() const
-{ return mCells->Count(); }
-
-
-inline PRInt32 nsColLayoutData::IndexOf(nsCellLayoutData* aCellLayoutData) const
-{ return mCells->IndexOf((void*)aCellLayoutData);}
-
-
-
-#endif
diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
index 3e3c60a90cd..6c19957a4fb 100644
--- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
@@ -16,7 +16,6 @@
* Reserved.
*/
#include "nsTableCellFrame.h"
-#include "nsCellLayoutData.h"
#include "nsBodyFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
@@ -53,21 +52,24 @@ static const PRBool gsDebugNT = PR_FALSE;
*/
nsTableCellFrame::nsTableCellFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
- : nsContainerFrame(aContent, aParentFrame),
- mCellLayoutData(nsnull)
+ : nsContainerFrame(aContent, aParentFrame)
{
mRowSpan=1;
mColSpan=1;
mColIndex=0;
mPriorAvailWidth=0;
- mPriorDesiredSize.width=0;
- mPriorDesiredSize.height=0;
+ mDesiredSize.width=0;
+ mDesiredSize.height=0;
+ mMaxElementSize.width=0;
+ mMaxElementSize.height=0;
+ mPass1DesiredSize.width=0;
+ mPass1DesiredSize.height=0;
+ mPass1MaxElementSize.width=0;
+ mPass1MaxElementSize.height=0;
}
nsTableCellFrame::~nsTableCellFrame()
{
- if (nsnull!=mCellLayoutData)
- delete mCellLayoutData;
}
NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext,
@@ -291,7 +293,6 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
mFirstChild->WillReflow(*aPresContext);
mFirstChild->MoveTo(leftInset, topInset);
aStatus = ReflowChild(mFirstChild, aPresContext, kidSize, kidReflowState);
- SetPriorDesiredSize(kidSize);
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugNT)
{
@@ -325,10 +326,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
// first, compute the height
// the height can be set w/o being restricted by aMaxSize.height
nscoord cellHeight = kidSize.height;
- if (NS_UNCONSTRAINEDSIZE!=aReflowState.maxSize.height)
- {
- cellHeight += topInset + bottomInset;
- }
+ cellHeight += topInset + bottomInset;
if (PR_TRUE==gsDebugNT)
printf(" %p cellFrame height set to %d from kidSize=%d and insets %d,%d\n",
this, cellHeight, kidSize.height, topInset, bottomInset);
@@ -369,6 +367,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize->height += topInset + bottomInset;
aDesiredSize.maxElementSize->width += leftInset + rightInset;
}
+ SetDesiredSize(aDesiredSize);
+ if (nsnull!=aDesiredSize.maxElementSize)
+ SetMaxElementSize(*(aDesiredSize.maxElementSize));
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugNT)
printf(" %p cellFrame returning aDesiredSize=%d,%d\n",
@@ -590,6 +591,505 @@ nsresult nsTableCellFrame::NewFrame(nsIFrame** aInstancePtrResult,
}
+
+/* ----- methods from CellLayoutData ----- */
+
+/**
+ * Given a frame and an edge, find the margin
+ *
+ **/
+nscoord nsTableCellFrame::GetMargin(nsIFrame* aFrame, PRUint8 aEdge) const
+{
+ nscoord result = 0;
+
+ if (aFrame)
+ {
+ const nsStyleSpacing* spacing;
+ aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
+ nsMargin margin;
+ spacing->CalcMarginFor(aFrame, margin);
+ switch (aEdge)
+ {
+ case NS_SIDE_TOP:
+ result = margin.top;
+ break;
+
+ case NS_SIDE_RIGHT:
+ result = margin.right;
+ break;
+
+ case NS_SIDE_BOTTOM:
+ result = margin.bottom;
+ break;
+
+ case NS_SIDE_LEFT:
+ result = margin.left;
+ break;
+
+ }
+ }
+ return result;
+}
+
+
+/**
+ * Given a style context and an edge, find the border width
+ *
+ **/
+nscoord nsTableCellFrame::GetBorderWidth(nsIFrame* aFrame, PRUint8 aEdge) const
+{
+ nscoord result = 0;
+
+ if (aFrame)
+ {
+ const nsStyleSpacing* spacing;
+ aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
+ nsMargin border;
+ spacing->CalcBorderFor(aFrame, border);
+ switch (aEdge)
+ {
+ case NS_SIDE_TOP:
+ result = border.top;
+ break;
+
+ case NS_SIDE_RIGHT:
+ result = border.right;
+ break;
+
+ case NS_SIDE_BOTTOM:
+ result = border.bottom;
+ break;
+
+ case NS_SIDE_LEFT:
+ result = border.left;
+ break;
+
+ }
+ }
+ return result;
+}
+
+
+/**
+ * Given a style context and an edge, find the padding
+ *
+ **/
+nscoord nsTableCellFrame::GetPadding(nsIFrame* aFrame, PRUint8 aEdge) const
+{
+ nscoord result = 0;
+
+ if (aFrame)
+ {
+ const nsStyleSpacing* spacing;
+ aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
+ nsMargin padding;
+ spacing->CalcPaddingFor(aFrame, padding);
+ switch (aEdge)
+ {
+ case NS_SIDE_TOP:
+ result = padding.top;
+ break;
+
+ case NS_SIDE_RIGHT:
+ result = padding.right;
+ break;
+
+ case NS_SIDE_BOTTOM:
+ result = padding.bottom;
+ break;
+
+ case NS_SIDE_LEFT:
+ result = padding.left;
+ break;
+
+ }
+ }
+ return result;
+}
+
+
+
+/**
+ * Given an Edge, find the opposing edge (top<-->bottom, left<-->right)
+ *
+ **/
+PRUint8 nsTableCellFrame::GetOpposingEdge(PRUint8 aEdge)
+{
+ PRUint8 result;
+
+ switch (aEdge)
+ {
+ case NS_SIDE_LEFT:
+ result = NS_SIDE_RIGHT;
+ break;
+
+ case NS_SIDE_RIGHT:
+ result = NS_SIDE_LEFT;
+ break;
+
+ case NS_SIDE_TOP:
+ result = NS_SIDE_BOTTOM;
+ break;
+
+ case NS_SIDE_BOTTOM:
+ result = NS_SIDE_TOP;
+ break;
+
+ default:
+ result = NS_SIDE_TOP;
+ }
+ return result;
+}
+
+
+/*
+*
+* Determine border style for two cells.
+*
+ 1.If the adjacent elements are of the same type, the wider of the two borders is used.
+ "Wider" takes into account the border-style of 'none', so a "1px solid" border
+ will take precedence over a "20px none" border.
+
+ 2.If there are two or more with the same width, but different style,
+ then the one with a style near the start of the following list will be drawn:
+
+ 'blank', 'double', 'solid', 'dashed', 'dotted', 'ridge', 'groove', 'none'
+
+ 3.If the borders are of the same width, the border on the element occurring first is used.
+
+ First is defined as aStyle for this method.
+
+ NOTE: This assumes left-to-right, top-to-bottom bias. -- gpk
+
+*
+*/
+
+
+nsIFrame* nsTableCellFrame::CompareCellBorders(nsIFrame* aFrame1,
+ PRUint8 aEdge1,
+ nsIFrame* aFrame2,
+ PRUint8 aEdge2)
+{
+ PRInt32 width1 = GetBorderWidth(aFrame1,aEdge1);
+ PRInt32 width2 = GetBorderWidth(aFrame2,aEdge2);
+
+ nsIFrame* result = nsnull;
+
+ if (width1 > width2)
+ result = aFrame1;
+ else if (width1 < width2)
+ result = aFrame2;
+ else // width1 == width2
+ {
+ const nsStyleSpacing* border1;
+ const nsStyleSpacing* border2;
+ aFrame1->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)border1);
+ aFrame2->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)border2);
+ if (border1->mBorderStyle[aEdge1] >= border2->mBorderStyle[aEdge2])
+ result = aFrame1;
+ else
+ result = aFrame2;
+ }
+ return result;
+}
+
+
+/**
+ * Given a List of cell layout data, compare the edges to see which has the
+ * border with the highest precidence.
+ *
+ **/
+
+nsIFrame* nsTableCellFrame::FindHighestPrecedentBorder(nsVoidArray* aList,
+ PRUint8 aEdge)
+{
+ nsIFrame* result = nsnull;
+ PRInt32 index = 0;
+ PRInt32 count = 0;
+
+
+ NS_ASSERTION(aList,"a List must be valid");
+ count = aList->Count();
+ if (count)
+ {
+ nsIFrame* frame1;
+ nsIFrame* frame2;
+
+ frame1 = (nsIFrame*)(aList->ElementAt(index++));
+ while (index < count)
+ {
+ frame2 = (nsIFrame*)(aList->ElementAt(index++));
+ if (GetMargin(frame2,aEdge) == 0) {
+ frame1 = CompareCellBorders(frame1, aEdge, frame2, aEdge);
+ }
+ }
+ if ((nsnull != frame1) && (GetMargin(frame1, aEdge) != 0))
+ result = frame1;
+ }
+ return result;
+}
+
+
+
+
+nsIFrame* nsTableCellFrame::FindInnerBorder(nsVoidArray* aList, PRUint8 aEdge)
+{
+ nsIFrame* result = nsnull;
+ PRUint8 opposite = GetOpposingEdge(aEdge);
+
+ if (GetMargin(this, aEdge) == 0)
+ {
+ nsIFrame* altFrame = FindHighestPrecedentBorder(aList,opposite);
+ if (nsnull != altFrame)
+ result = CompareCellBorders(this, aEdge, altFrame, opposite);
+ else
+ result = this;
+ }
+
+ return result;
+}
+
+
+/*
+*
+* FindRelevantBorder recursively searches up the frame hierarchy for the border
+* style that is applicable to the cell. If at any point the frame has a margin
+* or the parent frame has padding, then the outer frame for this object takes
+* presendence over the inner frame.
+
+1.Borders on 'table' elements take precedence over borders on any other table elements.
+2.Borders on 'row-groups' take precedence over borders on 'rows',
+ and likewise borders on 'column-groups' take precedence over borders on 'columns'.
+3.Borders on any other type of table element take precedence over 'table-cell' elements.
+
+*
+* NOTE: This method assumes that the table cell potentially shares a border.
+* It should not be called for internal cells
+*
+* NOTE: COLUMNS AND COLGROUPS NEED TO BE FIGURED INTO THE ALGORITHM -- GPK!!!
+*
+*
+*/
+nsIFrame* nsTableCellFrame::FindOuterBorder( nsTableFrame* aTableFrame,
+ PRUint8 aEdge)
+{
+ nsIFrame* frame = this; // By default, return our frame
+ PRBool done = PR_FALSE;
+
+
+ // The table frame is the outer most frame we test against
+ while (done == PR_FALSE)
+ {
+ done = PR_TRUE; // where done unless the frame's margin is zero
+ // and the parent's padding is zero
+
+ nscoord margin = GetMargin(frame,aEdge);
+
+ // if the margin for this style is zero then check to see if the paddding
+ // for the parent frame is also zero
+ if (margin == 0)
+ {
+ nsIFrame* parentFrame;
+
+ frame->GetGeometricParent(parentFrame);
+
+ // if the padding for the parent style is zero just
+ // recursively call this routine
+ PRInt32 padding = GetPadding(parentFrame,aEdge);
+ if ((nsnull != parentFrame) && (padding == 0))
+ {
+ frame = parentFrame;
+ // If this frame represents the table frame then
+ // the table style is used
+ done = PRBool(frame != (nsIFrame*)aTableFrame);
+ continue;
+ }
+
+ }
+ }
+ return frame;
+}
+
+
+
+/*
+
+ Border Resolution
+ 1.Borders on 'table' elements take precedence over borders on any other table elements.
+ 2.Borders on 'row-groups' take precedence over borders on 'rows', and likewise borders on 'column-groups' take
+ precedence over borders on 'columns'.
+ 3.Borders on any other type of table element take precedence over 'table-cell' elements.
+ 4.If the adjacent elements are of the same type, the wider of the two borders is used. "Wider" takes into account
+ the border-style of 'none', so a "1px solid" border will take precedence over a "20px none" border.
+ 5.If the borders are of the same width, the border on the element occurring first is used.
+
+
+ How to compare
+ 1.Those of the one or two cells that have an edge here.
+ Less than two can occur at the edge of the table, but also
+ at the edges of "holes" (unoccupied grid cells).
+ 2.Those of the columns that have an edge here.
+ 3.Those of the column groups that have an edge here.
+ 4.Those of the rows that have an edge here.
+ 5.Those of the row groups that have an edge here.
+ 6.Those of the table, if this is the edge of the table.
+
+*
+* @param aIsFirst -- TRUE if this is the first cell in the row
+* @param aIsLast -- TRUE if this is the last cell in the row
+* @param aIsTop -- TRUE if this is the top cell in the column
+* @param aIsBottom -- TRUE if this is the last cell in the column
+*/
+
+nsIFrame* nsTableCellFrame::FindBorderFrame(nsTableFrame* aTableFrame,
+ nsVoidArray* aList,
+ PRUint8 aEdge)
+{
+ nsIFrame* frame = nsnull;
+
+ if (aList && aList->Count() == 0)
+ frame = FindOuterBorder(aTableFrame, aEdge);
+ else
+ frame = FindInnerBorder(aList, aEdge);
+
+ if (! frame)
+ frame = this;
+
+ return frame;
+}
+
+
+/**
+ * Given a List of cell layout data, compare the edges to see which has the
+ * border with the highest precidence.
+ *
+ **/
+nscoord nsTableCellFrame::FindLargestMargin(nsVoidArray* aList,PRUint8 aEdge)
+{
+ nscoord result = 0;
+ PRInt32 index = 0;
+ PRInt32 count = 0;
+
+
+ NS_ASSERTION(aList,"a List must be valid");
+ count = aList->Count();
+ if (count)
+ {
+ nsIFrame* frame;
+
+ nscoord value = 0;
+ while (index < count)
+ {
+ frame = (nsIFrame*)(aList->ElementAt(index++));
+ value = GetMargin(frame, aEdge);
+ if (value > result)
+ result = value;
+ }
+ }
+ return result;
+}
+
+
+
+
+void nsTableCellFrame::CalculateMargins(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4])
+{
+ // By default the margin is just the margin found in the
+ // table cells style
+ const nsStyleSpacing* spacing;
+ GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
+ spacing->CalcMarginFor(this, mMargin);
+
+ // Left and Top Margins are collapsed with their neightbors
+ // Right and Bottom Margins are simple left as they are
+ nscoord value;
+
+ // The left and top sides margins are the difference between
+ // their inherint value and the value of the margin of the
+ // object to the left or right of them.
+
+ value = FindLargestMargin(aBoundaryCells[NS_SIDE_LEFT],NS_SIDE_RIGHT);
+ if (value > mMargin.left)
+ mMargin.left = 0;
+ else
+ mMargin.left -= value;
+
+ value = FindLargestMargin(aBoundaryCells[NS_SIDE_TOP],NS_SIDE_BOTTOM);
+ if (value > mMargin.top)
+ mMargin.top = 0;
+ else
+ mMargin.top -= value;
+}
+
+
+void nsTableCellFrame::RecalcLayoutData(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4])
+
+{
+ CalculateBorders(aTableFrame, aBoundaryCells);
+ CalculateMargins(aTableFrame, aBoundaryCells);
+ mCalculated = NS_OK;
+}
+
+#if 0 //QQQ
+void nsTableCellFrame::List(FILE* out, PRInt32 aIndent) const
+{
+ PRInt32 indent;
+
+ nsIContent* cell;
+
+ this->GetContent(cell);
+ if (cell != nsnull)
+ {
+ /*
+ for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
+ fprintf(out,"RowSpan = %d ColSpan = %d \n",cell->GetRowSpan(),cell->GetColSpan());
+ */
+ for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
+ fprintf(out,"Margin -- Top: %d Left: %d Bottom: %d Right: %d \n",
+ NS_TWIPS_TO_POINTS_INT(mMargin.top),
+ NS_TWIPS_TO_POINTS_INT(mMargin.left),
+ NS_TWIPS_TO_POINTS_INT(mMargin.bottom),
+ NS_TWIPS_TO_POINTS_INT(mMargin.right));
+
+
+ for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
+
+ nscoord top,left,bottom,right;
+
+ top = (mBorderFrame[NS_SIDE_TOP] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_TOP], NS_SIDE_TOP) : 0);
+ left = (mBorderFrame[NS_SIDE_LEFT] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_LEFT], NS_SIDE_LEFT) : 0);
+ bottom = (mBorderFrame[NS_SIDE_BOTTOM] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_BOTTOM], NS_SIDE_BOTTOM) : 0);
+ right = (mBorderFrame[NS_SIDE_RIGHT] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_RIGHT], NS_SIDE_RIGHT) : 0);
+
+
+ fprintf(out,"Border -- Top: %d Left: %d Bottom: %d Right: %d \n",
+ NS_TWIPS_TO_POINTS_INT(top),
+ NS_TWIPS_TO_POINTS_INT(left),
+ NS_TWIPS_TO_POINTS_INT(bottom),
+ NS_TWIPS_TO_POINTS_INT(right));
+
+
+
+ cell->List(out,aIndent);
+ NS_RELEASE(cell);
+ }
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+/* ----- debug only methods, to be removed ----- */
+
+
// For Debugging ONLY
NS_METHOD nsTableCellFrame::MoveTo(nscoord aX, nscoord aY)
{
diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.h b/mozilla/layout/html/table/src/nsTableCellFrame.h
index ecdf04fce00..514edc5d33f 100644
--- a/mozilla/layout/html/table/src/nsTableCellFrame.h
+++ b/mozilla/layout/html/table/src/nsTableCellFrame.h
@@ -21,8 +21,8 @@
#include "nscore.h"
#include "nsContainerFrame.h"
#include "nsTableFrame.h"
+#include "nsTableRowFrame.h" // need to actually include this here to inline GetRowIndex
-class nsCellLayoutData;
struct nsStyleSpacing;
/* eb42f7b0-079e-11d2-8f37-006008159b0c */
@@ -72,34 +72,124 @@ public:
/** return the mapped cell's row span. Always >= 1. */
virtual PRInt32 GetRowSpan();
+ // there is no set row index because row index depends on the cell's parent row only
+
+ /** return the mapped cell's row index (starting at 0 for the first row) */
+ virtual PRInt32 GetRowIndex();
+
/** return the mapped cell's col span. Always >= 1. */
virtual PRInt32 GetColSpan();
-
+
/** return the mapped cell's column index (starting at 0 for the first column) */
virtual PRInt32 GetColIndex();
+ /** set the index of the column belonging to this cell */
+ // XXX should be removed, use cell map?
virtual void SetColIndex (int aColIndex);
+ /** return the available width given to this frame during its last reflow */
virtual nscoord GetPriorAvailWidth();
+ /** set the available width given to this frame during its last reflow */
virtual void SetPriorAvailWidth(nscoord aPriorAvailWidth);
- virtual nsSize GetPriorDesiredSize();
+ /** return the desired size returned by this frame during its last reflow */
+ virtual nsSize GetDesiredSize();
- virtual void SetPriorDesiredSize(const nsReflowMetrics & aDesiredSize);
+ /** set the desired size returned by this frame during its last reflow */
+ virtual void SetDesiredSize(const nsReflowMetrics & aDesiredSize);
- virtual ~nsTableCellFrame();
+ /** return the MaxElement size returned by this frame during its last reflow
+ * not counting reflows where MaxElementSize is not requested.
+ * That is, the cell frame will always remember the last non-null MaxElementSize
+ */
+ virtual nsSize GetMaxElementSize();
- // Get the TableFrame that contains this cell frame
+ /** set the MaxElement size returned by this frame during its last reflow.
+ * should never be called with a null MaxElementSize
+ */
+ virtual void SetMaxElementSize(const nsSize & aMaxElementSize);
+
+ /** return the desired size returned by this frame during its last reflow */
+ virtual nsSize GetPass1DesiredSize();
+
+ /** set the desired size returned by this frame during its last reflow */
+ virtual void SetPass1DesiredSize(const nsReflowMetrics & aDesiredSize);
+
+ /** return the MaxElement size returned by this frame during its last reflow
+ * not counting reflows where MaxElementSize is not requested.
+ * That is, the cell frame will always remember the last non-null MaxElementSize
+ */
+ virtual nsSize GetPass1MaxElementSize();
+
+ /** set the MaxElement size returned by this frame during its last reflow.
+ * should never be called with a null MaxElementSize
+ */
+ virtual void SetPass1MaxElementSize(const nsSize & aMaxElementSize);
+
+
+
+ /** Get the TableFrame that contains this cell frame */
virtual nsTableFrame* GetTableFrame();
- nsCellLayoutData * GetCellLayoutData();
- void SetCellLayoutData(nsCellLayoutData *aData);
+ void RecalcLayoutData(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4]);
- // For DEBUGGING Purposes Only
+
+ NS_IMETHOD GetMargin(nsMargin& aMargin);
+
+
+ /** destructor */
+ virtual ~nsTableCellFrame();
+
+
+ // For DEBUGGING Purposes Only, to be removed
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
+private:
+
+ // All these methods are support methods for RecalcLayoutData
+ nsIFrame* GetFrameAt(nsVoidArray* aList, PRInt32 aIndex);
+
+ nscoord GetMargin(nsIFrame* aFrame, PRUint8 aEdge) const;
+
+ nscoord GetBorderWidth(nsIFrame* aFrame, PRUint8 aEdge) const;
+
+ nscoord GetPadding(nsIFrame* aFrame, PRUint8 aEdge) const;
+
+ PRUint8 GetOpposingEdge(PRUint8 aEdge);
+
+ nsIFrame* CompareCellBorders(nsIFrame* aFrame1,
+ PRUint8 aEdge1,
+ nsIFrame* aFrame2,
+ PRUint8 aEdge2);
+
+
+ nsIFrame* FindHighestPrecedentBorder(nsVoidArray* aList,
+ PRUint8 aEdge);
+
+
+
+ nsIFrame* FindInnerBorder( nsVoidArray* aList,
+ PRUint8 aEdge);
+
+ nsIFrame* FindOuterBorder( nsTableFrame* aTableFrame,
+ PRUint8 aEdge);
+
+ nsIFrame* FindBorderFrame(nsTableFrame* aTableFrame,
+ nsVoidArray* aCellList,
+ PRUint8 aEdge);
+
+ void CalculateBorders(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4]);
+
+ nscoord FindLargestMargin(nsVoidArray* aList,PRUint8 aEdge);
+
+
+ void CalculateMargins(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4]);
+
protected:
/** protected constructor.
@@ -132,9 +222,17 @@ protected:
/** the available width we were given in our previous reflow */
nscoord mPriorAvailWidth;
- nsSize mPriorDesiredSize;
+ /** these are the last computed desired and max element sizes */
+ nsSize mDesiredSize;
+ nsSize mMaxElementSize;
- nsCellLayoutData *mCellLayoutData;
+ /** these are the Pass 1 unconstrained desired and max element sizes */
+ nsSize mPass1DesiredSize;
+ nsSize mPass1MaxElementSize;
+
+ nsresult mCalculated;
+ nsMargin mMargin;
+ nsIFrame* mBorderFrame[4]; // the frame whose border is used
};
@@ -151,6 +249,16 @@ inline void nsTableCellFrame::Init(PRInt32 aRowSpan, PRInt32 aColSpan, PRInt32 a
inline PRInt32 nsTableCellFrame::GetRowSpan()
{ return mRowSpan;}
+inline PRInt32 nsTableCellFrame::GetRowIndex()
+{
+ nsTableRowFrame * row;
+ GetContentParent((nsIFrame *&)row);
+ if (nsnull!=row)
+ return row->GetRowIndex();
+ else
+ return 0;
+}
+
inline PRInt32 nsTableCellFrame::GetColSpan()
{ return mColSpan;}
@@ -163,25 +271,64 @@ inline void nsTableCellFrame::SetColIndex (int aColIndex)
mColIndex = aColIndex;
}
-inline nsCellLayoutData * nsTableCellFrame::GetCellLayoutData()
-{ return mCellLayoutData;}
-
-inline void nsTableCellFrame::SetCellLayoutData(nsCellLayoutData *aData)
-{ mCellLayoutData = aData;}
-
inline nscoord nsTableCellFrame::GetPriorAvailWidth()
{ return mPriorAvailWidth;}
inline void nsTableCellFrame::SetPriorAvailWidth(nscoord aPriorAvailWidth)
{ mPriorAvailWidth = aPriorAvailWidth;}
-inline nsSize nsTableCellFrame::GetPriorDesiredSize()
-{ return mPriorDesiredSize; }
+inline nsSize nsTableCellFrame::GetDesiredSize()
+{ return mDesiredSize; }
-inline void nsTableCellFrame::SetPriorDesiredSize(const nsReflowMetrics & aDesiredSize)
+inline void nsTableCellFrame::SetDesiredSize(const nsReflowMetrics & aDesiredSize)
{
- mPriorDesiredSize.width = aDesiredSize.width;
- mPriorDesiredSize.height = aDesiredSize.height;
+ mDesiredSize.width = aDesiredSize.width;
+ mDesiredSize.height = aDesiredSize.height;
}
+inline nsSize nsTableCellFrame::GetMaxElementSize()
+{ return mMaxElementSize; }
+
+inline void nsTableCellFrame::SetMaxElementSize(const nsSize & aMaxElementSize)
+{
+ mMaxElementSize.width = aMaxElementSize.width;
+ mMaxElementSize.height = aMaxElementSize.height;
+}
+
+inline nsSize nsTableCellFrame::GetPass1DesiredSize()
+{ return mPass1DesiredSize; }
+
+inline void nsTableCellFrame::SetPass1DesiredSize(const nsReflowMetrics & aDesiredSize)
+{
+ mPass1DesiredSize.width = aDesiredSize.width;
+ mPass1DesiredSize.height = aDesiredSize.height;
+}
+
+inline nsSize nsTableCellFrame::GetPass1MaxElementSize()
+{ return mPass1MaxElementSize; }
+
+inline void nsTableCellFrame::SetPass1MaxElementSize(const nsSize & aMaxElementSize)
+{
+ mPass1MaxElementSize.width = aMaxElementSize.width;
+ mPass1MaxElementSize.height = aMaxElementSize.height;
+}
+
+inline void nsTableCellFrame::CalculateBorders(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4])
+{
+ for (PRInt32 edge = 0; edge < 4; edge++)
+ mBorderFrame[edge] = FindBorderFrame(aTableFrame, aBoundaryCells[edge], edge);
+}
+
+inline NS_METHOD nsTableCellFrame::GetMargin(nsMargin& aMargin)
+{
+ if (mCalculated == NS_OK)
+ {
+ aMargin = mMargin;
+ return NS_OK;
+ }
+ return NS_ERROR_NOT_INITIALIZED;
+}
+
+
#endif
diff --git a/mozilla/layout/html/table/src/nsTableCol.cpp b/mozilla/layout/html/table/src/nsTableCol.cpp
index 157043324eb..9b966c09a43 100644
--- a/mozilla/layout/html/table/src/nsTableCol.cpp
+++ b/mozilla/layout/html/table/src/nsTableCol.cpp
@@ -21,8 +21,6 @@
#include "nsTablePart.h"
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
-#include "nsContainerFrame.h"
-#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
@@ -38,66 +36,6 @@ static const PRBool gsNoisyRefs = PR_FALSE;
#endif
-nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
- : nsFrame(aContent, aParentFrame)
-{
- mColIndex = 0;
- mRepeat = 0;
-}
-
-
-nsTableColFrame::~nsTableColFrame()
-{
-}
-
-NS_METHOD nsTableColFrame::Paint(nsIPresContext& aPresContext,
- nsIRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect)
-{
- if (gsDebug==PR_TRUE)
- printf("nsTableColFrame::Paint\n");
- return NS_OK;
-}
-
-
-NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext,
- nsReflowMetrics& aDesiredSize,
- const nsReflowState& aReflowState,
- nsReflowStatus& aStatus)
-{
- NS_ASSERTION(nsnull!=aPresContext, "bad arg");
- aDesiredSize.width=0;
- aDesiredSize.height=0;
- if (nsnull!=aDesiredSize.maxElementSize)
- {
- aDesiredSize.maxElementSize->width=0;
- aDesiredSize.maxElementSize->height=0;
- }
- aStatus = NS_FRAME_COMPLETE;
- return NS_OK;
-}
-
-
-/* ----- static methods ------ */
-
-nsresult nsTableColFrame::NewFrame(nsIFrame** aInstancePtrResult,
- nsIContent* aContent,
- nsIFrame* aParent)
-{
- NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
- if (nsnull == aInstancePtrResult) {
- return NS_ERROR_NULL_POINTER;
- }
- nsIFrame* it = new nsTableColFrame(aContent, aParent);
- if (nsnull == it) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- *aInstancePtrResult = it;
- return NS_OK;
-}
-
-//---------------------- nsTableCol implementation -----------------------------------
-
nsTableCol::nsTableCol(nsIAtom* aTag)
: nsTableContent(aTag),
mColGroup(0),
diff --git a/mozilla/layout/html/table/src/nsTableColFrame.cpp b/mozilla/layout/html/table/src/nsTableColFrame.cpp
new file mode 100644
index 00000000000..c628ea33e86
--- /dev/null
+++ b/mozilla/layout/html/table/src/nsTableColFrame.cpp
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "nsTableColFrame.h"
+#include "nsContainerFrame.h"
+#include "nsIReflowCommand.h"
+#include "nsIStyleContext.h"
+#include "nsStyleConsts.h"
+#include "nsIPresContext.h"
+#include "nsHTMLIIDs.h"
+#include "nsHTMLAtoms.h"
+
+#ifdef NS_DEBUG
+static PRBool gsDebug = PR_FALSE;
+static PRBool gsNoisyRefs = PR_FALSE;
+#else
+static const PRBool gsDebug = PR_FALSE;
+static const PRBool gsNoisyRefs = PR_FALSE;
+#endif
+
+
+nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
+ : nsFrame(aContent, aParentFrame)
+{
+ mColIndex = 0;
+ mRepeat = 0;
+}
+
+
+nsTableColFrame::~nsTableColFrame()
+{
+}
+
+NS_METHOD nsTableColFrame::Paint(nsIPresContext& aPresContext,
+ nsIRenderingContext& aRenderingContext,
+ const nsRect& aDirtyRect)
+{
+ if (gsDebug==PR_TRUE)
+ printf("nsTableColFrame::Paint\n");
+ return NS_OK;
+}
+
+
+NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext,
+ nsReflowMetrics& aDesiredSize,
+ const nsReflowState& aReflowState,
+ nsReflowStatus& aStatus)
+{
+ NS_ASSERTION(nsnull!=aPresContext, "bad arg");
+ aDesiredSize.width=0;
+ aDesiredSize.height=0;
+ if (nsnull!=aDesiredSize.maxElementSize)
+ {
+ aDesiredSize.maxElementSize->width=0;
+ aDesiredSize.maxElementSize->height=0;
+ }
+ aStatus = NS_FRAME_COMPLETE;
+ return NS_OK;
+}
+
+
+/* ----- static methods ------ */
+
+nsresult nsTableColFrame::NewFrame(nsIFrame** aInstancePtrResult,
+ nsIContent* aContent,
+ nsIFrame* aParent)
+{
+ NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
+ if (nsnull == aInstancePtrResult) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ nsIFrame* it = new nsTableColFrame(aContent, aParent);
+ if (nsnull == it) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ *aInstancePtrResult = it;
+ return NS_OK;
+}
+
diff --git a/mozilla/layout/html/table/src/nsTableColFrame.h b/mozilla/layout/html/table/src/nsTableColFrame.h
index e06d27b313f..ed72fb5a4a6 100644
--- a/mozilla/layout/html/table/src/nsTableColFrame.h
+++ b/mozilla/layout/html/table/src/nsTableColFrame.h
@@ -48,6 +48,12 @@ public:
/** set the index of the column this content object represents. must be >= 0 */
virtual void SetColumnIndex (int aColIndex);
+ /** convenience method, calls into cellmap */
+ nsVoidArray * GetCells();
+
+ /** convenience method, calls into cellmap */
+ PRInt32 Count() const;
+
protected:
nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame);
@@ -55,10 +61,16 @@ protected:
~nsTableColFrame();
/** the starting index of the column (starting at 0) that this col object represents */
- PRInt32 mColIndex;
+ PRInt32 mColIndex;
/** the number of columns that the attributes of this column extend to */
- PRInt32 mRepeat;
+ PRInt32 mRepeat;
+
+ nscoord mMaxWidth;
+ nscoord mMinWidth;
+
+ nscoord mMaxEffectiveWidth;
+ nscoord mMinEffectiveWidth;
};
diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp
index c983dd63f94..95b9a970da0 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableFrame.cpp
@@ -29,14 +29,12 @@
#include "nsTableColGroupFrame.h"
#include "nsTableRowFrame.h"
#include "nsTableRowGroupFrame.h"
-#include "nsColLayoutData.h"
#include "BasicTableLayoutStrategy.h"
#include "nsIPresContext.h"
#include "nsCSSRendering.h"
#include "nsStyleConsts.h"
-#include "nsCellLayoutData.h"
#include "nsVoidArray.h"
#include "nsIPtr.h"
#include "nsIView.h"
@@ -269,7 +267,6 @@ void ColumnInfoCache::GetColumnsByType(const nsStyleUnit aType,
nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsContainerFrame(aContent, aParentFrame),
mCellMap(nsnull),
- mColumnLayoutData(nsnull),
mColCache(nsnull),
mColumnWidths(nsnull),
mTableLayoutStrategy(nsnull),
@@ -279,32 +276,11 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
{
}
-/**
- * Method to delete all owned objects assoicated
- * with the ColumnLayoutObject instance variable
- */
-void nsTableFrame::DeleteColumnLayoutData()
-{
- if (nsnull!=mColumnLayoutData)
- {
- PRInt32 numCols = mColumnLayoutData->Count();
- for (PRInt32 i = 0; iElementAt(i));
- delete colData;
- }
- delete mColumnLayoutData;
- mColumnLayoutData = nsnull;
- }
-}
-
nsTableFrame::~nsTableFrame()
{
if (nsnull!=mCellMap)
delete mCellMap;
- DeleteColumnLayoutData();
-
if (nsnull!=mColumnWidths)
delete [] mColumnWidths;
@@ -351,8 +327,7 @@ nsTableRowGroupFrame* nsTableFrame::NextRowGroupFrame(nsTableRowGroupFrame* aRow
PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
{
mColCount=0;
- nsIFrame * colGroup;
- ChildAt (0, (nsIFrame *&)colGroup);
+ nsIFrame * colGroup = mFirstChild;
while (nsnull!=colGroup)
{
const nsStyleDisplay *childDisplay;
@@ -379,8 +354,7 @@ PRInt32 nsTableFrame::GetRowCount ()
if (nsnull != mCellMap)
return mCellMap->GetRowCount();
- nsIFrame *child=nsnull;
- ChildAt(0, child);
+ nsIFrame *child=mFirstChild;
while (nsnull!=child)
{
const nsStyleDisplay *childDisplay;
@@ -393,6 +367,35 @@ PRInt32 nsTableFrame::GetRowCount ()
}
return rowCount;
}
+
+nsTableColFrame * nsTableFrame::GetColFrame(PRInt32 aColIndex)
+{
+ nsTableColFrame *result = nsnull;
+ if (nsnull!=mCellMap)
+ {
+ result = mCellMap->GetColumnFrame(aColIndex);
+ }
+ return result;
+}
+
+// can return nsnull
+nsTableCellFrame * nsTableFrame::GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex)
+{
+ nsTableCellFrame *result = nsnull;
+ if (nsnull!=mCellMap)
+ {
+ CellData * cellData = mCellMap->GetCellAt(aRowIndex, aColIndex);
+ if (nsnull!=cellData)
+ {
+ result = cellData->mCell;
+ if (nsnull==result)
+ result = cellData->mRealCell->mCell;
+ }
+ }
+ return result;
+}
+
+
// return the rows spanned by aCell starting at aRowIndex
// note that this is different from just the rowspan of aCell
// (that would be GetEffectiveRowSpan (indexOfRowThatContains_aCell, aCell)
@@ -413,13 +416,6 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
return rowSpan;
}
-
-// returns the actual cell map, not a copy, so don't mess with it!
-nsCellMap* nsTableFrame::GetCellMap() const
-{
- return mCellMap;
-}
-
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTableFrame::ResetCellMap ()
{
@@ -449,10 +445,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
PRInt32 actualColumns = 0;
nsTableColGroupFrame *lastColGroupFrame = nsnull;
- nsIFrame * childFrame=nsnull;
nsIFrame * firstRowGroupFrame=nsnull;
nsIFrame * prevSibFrame=nsnull;
- ChildAt (0, (nsIFrame *&)childFrame);
+ nsIFrame * childFrame=mFirstChild;
while (nsnull!=childFrame)
{
const nsStyleDisplay *childDisplay;
@@ -795,35 +790,67 @@ void nsTableFrame::GrowCellMap (PRInt32 aColCount)
*/
void nsTableFrame::ListColumnLayoutData(FILE* out, PRInt32 aIndent) const
{
- // if this is a continuing frame, there will be no output
- if (nsnull!=mColumnLayoutData)
+ nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
+ if (this!=firstInFlow)
+ {
+ firstInFlow->ListColumnLayoutData(out, aIndent);
+ return;
+ }
+
+ if (nsnull!=mCellMap)
{
fprintf(out,"Column Layout Data \n");
- PRInt32 numCols = mColumnLayoutData->Count();
- for (PRInt32 i = 0; iGetColCount();
+ PRInt32 numRows = mCellMap->GetRowCount();
+ for (PRInt32 colIndex = 0; colIndexElementAt(i));
+ for (PRInt32 indent = aIndent; --indent >= 0; )
+ fputs(" ", out);
+ fprintf(out,"Column Data [%d] \n",colIndex);
+ for (PRInt32 rowIndex = 0; rowIndex < numRows; rowIndex++)
+ {
+ nsTableCellFrame *cellFrame = mCellMap->GetCellFrameAt(rowIndex, colIndex);
+ PRInt32 rowIndent;
+ for (rowIndent = aIndent+2; --rowIndent >= 0; ) fputs(" ", out);
+ fprintf(out,"Cell Data [%d] \n",rowIndex);
+ for (rowIndent = aIndent+2; --rowIndent >= 0; ) fputs(" ", out);
+ nsMargin margin;
+ cellFrame->GetMargin(margin);
+ fprintf(out,"Margin -- Top: %d Left: %d Bottom: %d Right: %d \n",
+ NS_TWIPS_TO_POINTS_INT(margin.top),
+ NS_TWIPS_TO_POINTS_INT(margin.left),
+ NS_TWIPS_TO_POINTS_INT(margin.bottom),
+ NS_TWIPS_TO_POINTS_INT(margin.right));
+
+ for (rowIndent = aIndent+2; --rowIndent >= 0; ) fputs(" ", out);
- for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
- fprintf(out,"Column Data [%d] \n",i);
- colData->List(out,aIndent+2);
+ nscoord top,left,bottom,right;
+ /*
+ top = (mBorderFrame[NS_SIDE_TOP] ? cellFrame->GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_TOP], NS_SIDE_TOP) : 0);
+ left = (mBorderFrame[NS_SIDE_LEFT] ? cellFrame->GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_LEFT], NS_SIDE_LEFT) : 0);
+ bottom = (mBorderFrame[NS_SIDE_BOTTOM] ? cellFrame->GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_BOTTOM], NS_SIDE_BOTTOM) : 0);
+ right = (mBorderFrame[NS_SIDE_RIGHT] ? cellFrame->GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_RIGHT], NS_SIDE_RIGHT) : 0);
+ */
+
+ fprintf(out,"Border -- Top: %d Left: %d Bottom: %d Right: %d \n",
+ NS_TWIPS_TO_POINTS_INT(top),
+ NS_TWIPS_TO_POINTS_INT(left),
+ NS_TWIPS_TO_POINTS_INT(bottom),
+ NS_TWIPS_TO_POINTS_INT(right));
+ }
}
}
}
/**
- * For the TableCell in CellData, find the CellLayoutData assocated
- * and add it to the list
-**/
+ * For the TableCell in CellData, add it to the list
+ */
void nsTableFrame::AppendLayoutData(nsVoidArray* aList, nsTableCellFrame* aTableCell)
{
-
if (aTableCell != nsnull)
{
- nsCellLayoutData* layoutData = GetCellLayoutData(aTableCell);
- if (layoutData != nsnull)
- aList->AppendElement((void*)layoutData);
+ aList->AppendElement((void*)aTableCell);
}
}
@@ -996,9 +1023,7 @@ void nsTableFrame::RecalcLayoutData()
r++;
}
- nsCellLayoutData* cellLayoutData = GetCellLayoutData(cell);
- if (cellLayoutData != nsnull)
- cellLayoutData->RecalcLayoutData(this,boundaryCells);
+ cell->RecalcLayoutData(this,boundaryCells);
}
}
}
@@ -1310,7 +1335,7 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
if (nsnull!=prevKidFrame)
prevKidFrame->GetNextSibling(kidFrame); // no need to check for an error, just see if it returned null...
else
- ChildAt(0, kidFrame);
+ kidFrame=mFirstChild;
// if this is the first time, allocate the frame
if (nsnull==kidFrame)
@@ -2210,11 +2235,10 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
if (gsDebug)
printf ("BalanceColumnWidths...\n");
- nsVoidArray *columnLayoutData = GetColumnLayoutData();
- if (nsnull==columnLayoutData)
+ if (nsnull==mCellMap)
return; // we don't have any information yet, so we can't do any useful work
- PRInt32 numCols = columnLayoutData->Count();
+ PRInt32 numCols = mCellMap->GetColCount();
if (nsnull==mColumnWidths)
{
mColumnWidths = new PRInt32[numCols];
@@ -2233,9 +2257,22 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
// need to figure out the overall table width constraint
// default case, get 100% of available space
+
+ // begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED!
+ nsIFrame * outerTableFrame = nsnull;
+ const nsStylePosition* position;
+ GetGeometricParent(outerTableFrame);
+ outerTableFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)position));
+ // end REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED
+
+
+
PRInt32 maxWidth;
+ /*
const nsStylePosition* position =
(const nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position);
+ use this line when tableFrame contains its own position style info
+ */
switch (position->mWidth.GetUnit()) {
case eStyleUnit_Coord:
maxWidth = position->mWidth.GetCoordValue();
@@ -2251,7 +2288,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
// XXX for now these fall through
default:
-
maxWidth = aMaxSize.width;
break;
}
@@ -2293,16 +2329,20 @@ void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext)
if (gsDebug==PR_TRUE) printf ("SetTableWidth...");
PRInt32 tableWidth = 0;
- nsVoidArray *columnLayoutData = GetColumnLayoutData();
- if (nsnull==columnLayoutData)
+ if (nsnull==mCellMap)
return; // no info, so nothing to do
- PRInt32 numCols = columnLayoutData->Count();
- for (PRInt32 i = 0; iGetColCount();
+ for (PRInt32 colIndex = 0; colIndexmColumnLayoutData)
+ if (nsnull!=firstInFlow->mCellMap)
{ // hooray, we get to do this the easy way because the info is cached
- nsColLayoutData * colData = (nsColLayoutData *)
- (firstInFlow->mColumnLayoutData->ElementAt(aColIndex));
- NS_ASSERTION(nsnull != colData, "bad column data");
- aColFrame = colData->GetColFrame();
+ aColFrame = firstInFlow->mCellMap->GetColumnFrame(aColIndex);
NS_ASSERTION(nsnull!=aColFrame, "bad col frame");
}
else
@@ -2443,31 +2480,46 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
mColCache = new ColumnInfoCache(mColCount);
nsIFrame * childFrame = mFirstChild;
while (nsnull!=childFrame)
- { // for every child, if it's a col group then get the columns
+ { // in this loop, we cache column info and set column style info from cells in first row
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
- if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
+
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ { // if it's a col group then get the columns and cache them in the CellMap
+ nsTableColFrame *colFrame=nsnull;
+ childFrame->FirstChild((nsIFrame *&)colFrame);
+ while (nsnull!=colFrame)
+ {
+ mCellMap->AppendColumnFrame(colFrame);
+ colFrame->GetNextSibling((nsIFrame *&)colFrame);
+ }
+ }
+ else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
- { // for every cell in every row, call SetCellLayoutData with the cached info
- // QQQ we can probably just leave the info in the table cell frame, not cache it here
+ { // if it's a row group, get the cells and set the column style if appropriate
nsIFrame *rowFrame;
- childFrame->ChildAt(0, rowFrame);
- nsIFrame *cellFrame;
- rowFrame->ChildAt(0, cellFrame);
- while (nsnull!=cellFrame)
+ childFrame->FirstChild(rowFrame);
+ if (nsnull!=rowFrame)
{
- /* this is the first time we are guaranteed to have both the cell frames
- * and the column frames, so it's a good time to
- * set the column style from the cell's width attribute (if this is the first row)
- */
- SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
- cellFrame->GetNextSibling(cellFrame);
+ nsIFrame *cellFrame;
+ rowFrame->FirstChild(cellFrame);
+ while (nsnull!=cellFrame)
+ {
+ /* this is the first time we are guaranteed to have both the cell frames
+ * and the column frames, so it's a good time to
+ * set the column style from the cell's width attribute (if this is the first row)
+ */
+ SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
+ cellFrame->GetNextSibling(cellFrame);
+ }
}
}
childFrame->GetNextSibling(childFrame);
}
+
// second time through, set column cache info for each column
+ // we can't do this until the loop above has set the column style info from the cells in the first row
childFrame = mFirstChild;
while (nsnull!=childFrame)
{ // for every child, if it's a col group then get the columns
@@ -2476,7 +2528,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
{
nsTableColFrame *colFrame=nsnull;
- childFrame->ChildAt(0, (nsIFrame *&)colFrame);
+ childFrame->FirstChild((nsIFrame *&)colFrame);
while (nsnull!=colFrame)
{ // for every column, create an entry in the column cache
// assumes that the col style has been twiddled to account for first cell width attribute
@@ -2489,176 +2541,14 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
- { // for every cell in every row, call SetCellLayoutData with the cached info
- // QQQ we can probably just leave the info in the table cell frame, not cache it here
- nsIFrame *rowFrame;
- childFrame->ChildAt(0, rowFrame);
- while (nsnull!=rowFrame)
- {
- nsIFrame *cellFrame;
- rowFrame->ChildAt(0, cellFrame);
- while (nsnull!=cellFrame)
- {
- nsCellLayoutData *cld = ((nsTableCellFrame*)cellFrame)->GetCellLayoutData();
- SetCellLayoutData(aPresContext, cld, (nsTableCellFrame*)cellFrame);
- cellFrame->GetNextSibling(cellFrame);
- }
- rowFrame->GetNextSibling(rowFrame);
- }
+ {
+ break; // once we hit a row group, we're done
}
childFrame->GetNextSibling(childFrame);
}
}
}
-// nsnull is a valid return value. This is for empty tables.
-nsVoidArray * nsTableFrame::GetColumnLayoutData()
-{
- nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
- NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
- return firstInFlow->mColumnLayoutData;
-}
-
-/** Associate aData with the cell at (aRow,aCol)
- * @return PR_TRUE if the data was successfully associated with a Cell
- * PR_FALSE if there was an error, such as aRow or aCol being invalid
- */
-PRBool nsTableFrame::SetCellLayoutData(nsIPresContext* aPresContext,
- nsCellLayoutData * aData, nsTableCellFrame *aCell)
-{
- NS_ASSERTION(nsnull != aPresContext, "bad arg aPresContext");
- NS_ASSERTION(nsnull != aData, "bad arg aData");
- NS_ASSERTION(nsnull != aCell, "bad arg aCell");
-
- PRBool result = PR_TRUE;
-
- nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
- NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
- if (this!=firstInFlow)
- result = firstInFlow->SetCellLayoutData(aPresContext, aData, aCell);
- else
- {
- if ((kPASS_FIRST==GetReflowPass()) || (kPASS_INCREMENTAL==GetReflowPass()))
- {
- if (nsnull==mColumnLayoutData)
- {
- PRInt32 rows = GetRowCount();
- mColumnLayoutData = new nsVoidArray();
- NS_ASSERTION(nsnull != mColumnLayoutData, "bad alloc");
- PRInt32 tableKidCount = mContent->ChildCount();
- nsIFrame * colGroupFrame = mFirstChild;
- for (PRInt32 i=0; iGetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
- if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
- {
- nsTableColFrame *colFrame=nsnull;
- colGroupFrame->ChildAt(0, (nsIFrame *&)colFrame);
- while (nsnull!=colFrame)
- {
- // TODO: unify these 2 kinds of column data
- // TODO: cache more column data, like the mWidth.GetUnit and what its value
- nsColLayoutData *colData = new nsColLayoutData(colFrame, rows);
- mColumnLayoutData->AppendElement((void *)colData);
- colFrame->GetNextSibling((nsIFrame *&)colFrame);
- }
- }
- // can't have col groups after row groups, so stop if you find a row group
- else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
- NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
- NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
- {
- break;
- }
- i++;
- ChildAt(i, colGroupFrame); // can't use colGroupFrame->GetNextSibling because it hasn't been set yet
- }
- }
-
- PRInt32 firstColIndex = aCell->GetColIndex();
- nsTableRowFrame *row;
- aCell->GetGeometricParent((nsIFrame*&)row);
- PRInt32 rowIndex = row->GetRowIndex();
- PRInt32 colSpan = aCell->GetColSpan();
- nsColLayoutData * colData = (nsColLayoutData *)(mColumnLayoutData->ElementAt(firstColIndex));
- nsVoidArray *col = colData->GetCells();
- if (gsDebugCLD) printf (" ~ SetCellLayoutData with row = %d, firstCol = %d, colSpan = %d, colData = %ld, col=%ld\n",
- rowIndex, firstColIndex, colSpan, colData, col);
- /* this logic looks wrong wrong wrong
- it seems to add an entries in col (the array of cells for a column) for aCell
- based on colspan. This is weird, because you would expect one entry in each
- column spanned for aCell, not multiple entries in the same col.
- */
- for (PRInt32 i=0; iGetMaxElementSize();
- nsSize partialCellSize(*cellSize);
- partialCellSize.width = (cellSize->width)/colSpan;
- // This method will copy the nsReflowMetrics pointed at by aData->GetDesiredSize()
- nsCellLayoutData * kidLayoutData = new nsCellLayoutData(aData->GetCellFrame(),
- aData->GetDesiredSize(),
- &partialCellSize);
- NS_ASSERTION(col->Count() > rowIndex, "unexpected count");
- if (gsDebugCLD) printf (" ~ replacing rowIndex = %d\n", rowIndex);
- nsCellLayoutData* data = (nsCellLayoutData*)col->ElementAt(rowIndex);
- col->ReplaceElementAt((void *)kidLayoutData, rowIndex);
- if (data != nsnull) {
- delete data;
- }
- }
- }
- else
- result = PR_FALSE;
- }
-
- return result;
-}
-
-/** Get the layout data associated with the cell at (aRow,aCol)
- * @return nsnull if there was an error, such as aRow or aCol being invalid
- * otherwise, the data is returned.
- */
-nsCellLayoutData * nsTableFrame::GetCellLayoutData(nsTableCellFrame *aCell)
-{
- NS_ASSERTION(nsnull != aCell, "bad arg");
-
- nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
- NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
- nsCellLayoutData *result = nsnull;
- if (this!=firstInFlow)
- result = firstInFlow->GetCellLayoutData(aCell);
- else
- {
- if (nsnull!=mColumnLayoutData)
- {
- PRInt32 firstColIndex = aCell->GetColIndex();
- nsColLayoutData * colData = (nsColLayoutData *)(mColumnLayoutData->ElementAt(firstColIndex));
- nsTableRowFrame *rowFrame;
- aCell->GetGeometricParent((nsIFrame *&)rowFrame);
- PRInt32 rowIndex = rowFrame->GetRowIndex();
- result = colData->ElementAt(rowIndex);
-
-#ifdef NS_DEBUG
- // Do some sanity checking
- if (nsnull != result) {
- nsIContent* inputContent;
- nsIContent* resultContent;
- result->GetCellFrame()->GetContent(resultContent);
- aCell->GetContent(inputContent);
- NS_ASSERTION(resultContent == inputContent, "unexpected cell");
- NS_IF_RELEASE(inputContent);
- NS_IF_RELEASE(resultContent);
- }
-#endif
-
- }
- }
- return result;
-}
-
-
-
PRInt32 nsTableFrame::GetReflowPass() const
{
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
@@ -2698,7 +2588,7 @@ nsTableFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
// add headers and footers to cf
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
nsIFrame * rg = nsnull;
- firstInFlow->ChildAt(0, rg);
+ firstInFlow->FirstChild(rg);
NS_ASSERTION (nsnull!=rg, "previous frame has no children");
nsIAtom * tHeadTag = NS_NewAtom(nsTablePart::kRowGroupHeadTagString); // tHeadTag: REFCNT++
nsIAtom * tFootTag = NS_NewAtom(nsTablePart::kRowGroupFootTagString); // tFootTag: REFCNT++
@@ -2758,9 +2648,8 @@ PRInt32 nsTableFrame::GetColumnWidth(PRInt32 aColIndex)
{
NS_ASSERTION(nsnull!=mColumnWidths, "illegal state");
#ifdef DEBUG
- nsVoidArray *cld = GetColumnLayoutData();
- NS_ASSERTION(nsnull!=cld, "no column layout data");
- PRInt32 numCols = cld->Count();
+ NS_ASSERTION(nsnull!=mCellMap, "no column layout data");
+ PRInt32 numCols = mCellMap->GetColCount();
NS_ASSERTION (numCols > aColIndex, "bad arg, col index out of bounds");
#endif
if (nsnull!=mColumnWidths)
@@ -2770,11 +2659,6 @@ PRInt32 nsTableFrame::GetColumnWidth(PRInt32 aColIndex)
//printf("GET_COL_WIDTH: %p, FIF=%p getting col %d and returning %d\n", this, firstInFlow, aColIndex, result);
// XXX hack
-#if 0
- if (result <= 0) {
- result = 100;
- }
-#endif
return result;
}
@@ -2936,9 +2820,7 @@ NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin&
if (nsnull != aKidFrame)
{
- nsCellLayoutData* layoutData = GetCellLayoutData(aKidFrame);
- if (layoutData)
- result = layoutData->GetMargin(aMargin);
+ result = aKidFrame->GetMargin(aMargin);
}
return result;
@@ -3218,37 +3100,6 @@ PRBool nsTableFrame::TableIsAutoWidth(nsTableFrame *aTableFrame,
return result;
}
-/* valuable code not yet used anywhere
-
- // since the table is a specified width, we need to expand the columns to fill the table
- nsVoidArray *columnLayoutData = GetColumnLayoutData();
- PRInt32 numCols = columnLayoutData->Count();
- PRInt32 spaceUsed = 0;
- for (PRInt32 colIndex = 0; colIndexElementAt(colIndex));
- nsTableColPtr col = colData->GetCol(); // col: ADDREF++
- nsStyleMolecule* colStyle =
- (nsStyleMolecule*)mStyleContext->GetData(eStyleStruct_Molecule);
- if (PR_TRUE==IsProportionalWidth(colStyle))
- {
- PRInt32 percentage = (100*mColumnWidths[colIndex]) / aMaxWidth;
- PRInt32 additionalSpace = (spaceRemaining*percentage)/100;
- mColumnWidths[colIndex] += additionalSpace;
- additionalSpaceAdded += additionalSpace;
- }
- }
- if (spaceUsed+additionalSpaceAdded < aMaxTableWidth)
- mColumnWidths[numCols-1] += (aMaxTableWidth - (spaceUsed+additionalSpaceAdded));
- }
-*/
-
// For Debugging ONLY
NS_METHOD nsTableFrame::MoveTo(nscoord aX, nscoord aY)
{
diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h
index 9d15f173543..a87477a86e6 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.h
+++ b/mozilla/layout/html/table/src/nsTableFrame.h
@@ -23,7 +23,6 @@
#include "nsStyleCoord.h"
class nsCellMap;
-class nsCellLayoutData;
class nsVoidArray;
class nsTableCellFrame;
class nsTableColFrame;
@@ -42,29 +41,6 @@ struct nsStyleSpacing;
extern const nsIID kTableFrameCID;
-/** Data stored by nsCellMap to rationalize rowspan and colspan cells.
- * if mCell is null then mRealCell will be the rowspan/colspan source
- * in addition, if fOverlap is non-null then it will point to the
- * other cell that overlaps this position
- * @see nsCellMap
- * @see nsTableFrame::BuildCellMap
- * @see nsTableFrame::GrowCellMap
- * @see nsTableFrame::BuildCellIntoMap
- *
- */
-class CellData
-{
-public:
- nsTableCellFrame *mCell;
- CellData *mRealCell;
- CellData *mOverlap;
-
- CellData();
-
- ~CellData();
-};
-
-
/* ============================================================================ */
/** nsTableFrame maps the inner portion of a table (everything except captions.)
@@ -153,36 +129,12 @@ public:
*/
NS_METHOD GetColumnFrame(PRInt32 aColIndex, nsTableColFrame *&aColFrame);
- /** return the column layout data for this inner table frame.
- * if this is a continuing frame, return the first-in-flow's column layout data.
- * @return the column layout data array, or null if there is no info yet.
- */
- virtual nsVoidArray *GetColumnLayoutData();
-
- /** Associate aData with the cell at (aRow,aCol)
- *
- * @param aPresContext -- used to resolve style when initializing caches
- * @param aData -- the info to cache
- * @param aCell -- the content object for which layout info is being cached
- *
- * @return PR_TRUE if the data was successfully associated with a Cell
- * PR_FALSE if there was an error, such as aRow or aCol being invalid
- */
- virtual PRBool SetCellLayoutData(nsIPresContext * aPresContext,
- nsCellLayoutData * aData,
- nsTableCellFrame * aCell);
-
- /** Get the layout data associated with the cell at (aRow,aCol)
- * @return PR_NULL if there was an error, such as aRow or aCol being invalid
- * otherwise, the data is returned.
- */
- virtual nsCellLayoutData * GetCellLayoutData(nsTableCellFrame *aCell);
-
+
/**
* DEBUG METHOD
*
*/
- virtual void ListColumnLayoutData(FILE* out = stdout, PRInt32 aIndent = 0) const;
+ //virtual void ListColumnLayoutData(FILE* out = stdout, PRInt32 aIndent = 0) const;
/** return the width of the column at aColIndex */
@@ -236,11 +188,6 @@ protected:
/** destructor, responsible for mColumnLayoutData and mColumnWidths */
virtual ~nsTableFrame();
- /** helper method to delete contents of mColumnLayoutData
- * should be called with care (ie, only by destructor)
- */
- virtual void DeleteColumnLayoutData();
-
/** first pass of ResizeReflow.
* lays out all table content with aMaxSize(NS_UNCONSTRAINEDSIZE,NS_UNCONSTRAINEDSIZE) and
* a non-null aMaxElementSize so we get all the metrics we need to do column balancing.
@@ -380,6 +327,16 @@ protected:
*/
virtual void ResetCellMap ();
+ /** for debugging only
+ * prints out information about the cell map
+ */
+ void DumpCellMap() const;
+
+ /** for debugging only
+ * prints out info about the table layout state, printing columns and their cells
+ */
+ void ListColumnLayoutData(FILE* out, PRInt32 aIndent) const;
+
/** ResetColumns is called when the column structure of the table is changed.
* Call with caution, only when adding or removing columns, changing
* column attributes, changing the rowspan or colspan attribute of a cell, etc.
@@ -418,13 +375,6 @@ protected:
*/
virtual nsTableRowGroupFrame* NextRowGroupFrame (nsTableRowGroupFrame*);
- /** returns the number of rows in this table.
- * if mCellMap has been created, it is asked for the number of rows.
- * otherwise, the content is enumerated and the rows are counted.
- */
- virtual PRInt32 GetRowCount();
-
-
/** return the number of columns as specified by the input.
* has 2 side effects:
* calls SetStartColumnIndex on each nsTableColumn
@@ -432,9 +382,18 @@ protected:
*/
virtual PRInt32 GetSpecifiedColumnCount ();
-public:
- virtual void DumpCellMap() const;
- virtual nsCellMap* GetCellMap() const;
+public: /* ----- Cell Map public methods ----- */
+
+ /** returns the number of rows in this table.
+ * if mCellMap has been created, it is asked for the number of rows.
+ * otherwise, the content is enumerated and the rows are counted.
+ */
+ virtual PRInt32 GetRowCount();
+
+ nsTableColFrame * GetColFrame(PRInt32 aColIndex);
+
+ nsTableCellFrame * GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex);
+
private:
@@ -446,9 +405,7 @@ private:
*/
enum {kPASS_UNDEFINED=0, kPASS_FIRST=1, kPASS_SECOND=2, kPASS_THIRD=3, kPASS_INCREMENTAL=4};
- nsVoidArray *mColumnLayoutData; // array of array of cellLayoutData's
PRInt32 *mColumnWidths; // widths of each column
- //TODO: move all column info into this object
ColumnInfoCache *mColCache; // cached information about the table columns
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit
PRInt32 mPass; // which Reflow pass are we currently in?
diff --git a/mozilla/layout/html/table/src/nsTableRow.cpp b/mozilla/layout/html/table/src/nsTableRow.cpp
index 0c07cf1c1c9..d4cf2ea67f2 100644
--- a/mozilla/layout/html/table/src/nsTableRow.cpp
+++ b/mozilla/layout/html/table/src/nsTableRow.cpp
@@ -20,7 +20,6 @@
#include "nsTableRowGroup.h"
#include "nsTableCell.h"
#include "nsTableFrame.h"
-#include "nsCellLayoutData.h"
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsTableRowFrame.h"
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
index 8505f4a296d..06480059afc 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
@@ -25,8 +25,6 @@
#include "nsTableFrame.h"
#include "nsTableColFrame.h"
#include "nsTableCellFrame.h"
-#include "nsCellLayoutData.h"
-#include "nsColLayoutData.h"
#include "nsIView.h"
#include "nsIPtr.h"
#include "nsIReflowCommand.h"
@@ -37,6 +35,7 @@ NS_DEF_PTR(nsIStyleContext);
static PRBool gsDebug1 = PR_FALSE;
static PRBool gsDebug2 = PR_FALSE;
//#define NOISY
+//#define NOISY_FLOW
#else
static const PRBool gsDebug1 = PR_FALSE;
static const PRBool gsDebug2 = PR_FALSE;
@@ -51,6 +50,9 @@ struct RowReflowState {
// The body's available size (computed from the body's parent)
nsSize availSize;
+ // the running x-offset
+ nscoord x;
+
// Height of tallest cell (excluding cells with rowspan > 1)
nscoord maxCellHeight; // just the height of the cell frame
nscoord maxCellVertSpace; // the maximum MAX(cellheight + topMargin + bottomMargin)
@@ -68,6 +70,7 @@ struct RowReflowState {
maxCellHeight = 0;
maxCellVertSpace = 0;
tableFrame = aTableFrame;
+ x=0;
}
~RowReflowState() {
@@ -111,12 +114,12 @@ nsTableRowFrame::DidReflow(nsIPresContext& aPresContext,
PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(mRowIndex, cellFrame);
if (1==rowSpan)
{
- // Resize the cell's height
+ // resize the cell's height
nsSize cellFrameSize;
cellFrame->GetSize(cellFrameSize);
cellFrame->SizeTo(cellFrameSize.width, cellHeight);
- // Realign cell content based on the new height
+ // realign cell content based on the new height
cellFrame->VerticallyAlignChild(&aPresContext);
}
@@ -287,6 +290,9 @@ void nsTableRowFrame::PlaceChild(nsIPresContext* aPresContext,
// Place and size the child
aKidFrame->SetRect(aKidRect);
+ // update the running total for the row width
+ aState.x += aKidRect.width;
+
// Update the maximum element size
PRInt32 rowSpan = ((nsTableCellFrame*)aKidFrame)->GetRowSpan();
if (nsnull != aMaxElementSize)
@@ -328,6 +334,8 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
NS_PRECONDITION(nsnull != mFirstChild, "no children");
nsSize kidMaxElementSize;
+ PRBool result = PR_TRUE;
+ PRInt32 prevColIndex = -1; // remember the col index of the previous cell to handle rowspans into this row
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
&kidMaxElementSize : nsnull;
nscoord maxCellTopMargin = 0;
@@ -335,6 +343,13 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
// Reflow each of our existing cell frames
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
+ nsSize kidAvailSize(aState.availSize);
+ if (0>=kidAvailSize.height)
+ kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
+
+ nsReflowMetrics desiredSize(pKidMaxElementSize);
+ desiredSize.width=desiredSize.height=desiredSize.ascent=desiredSize.descent=0;
+
// Get the frame's margins, and compare the top and bottom margin
// against our current max values
nsMargin kidMargin;
@@ -344,15 +359,49 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
if (kidMargin.bottom > maxCellBottomMargin)
maxCellBottomMargin = kidMargin.bottom;
+ // Figure out the amount of available size for the child (subtract
+ // off the top margin we are going to apply to it)
+
+ //XXX TROY??? unconstrainedHeight was removed from aState, what should happen here?
+ /*
+ if (PR_FALSE == aState.unconstrainedHeight)
+ {
+ kidAvailSize.height -= kidMargin.top + kidMargin.bottom;
+ }
+ */
+
// left and right margins already taken into account by table layout strategy
- // Compute the x-origin for the child
- //
- // XXX Having to re-compute the value each time from scratch is very inefficent...
- nscoord x = ComputeCellXOffset(aState, kidFrame, kidMargin);
+ // Compute the x-origin for the child, taking into account straddlers (cells from prior
+ // rows with rowspans > 1)
+ PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
+ if (prevColIndex != (cellColIndex-1))
+ { // if this cell is not immediately adjacent to the previous cell, factor in missing col info
+ for (PRInt32 colIndex=prevColIndex+1; colIndexGetColumnWidth(colIndex);
+ aState.x += kidMargin.left + kidMargin.right;
+ }
+ }
+ aState.x += kidMargin.left;
+
+ // at this point, we know the column widths.
+ // so we get the avail width from the known column widths
+ PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
+ nscoord availWidth = 0;
+ for (PRInt32 numColSpan=0; numColSpanGetColumnWidth(cellColIndex+numColSpan);
+ if (0GetPriorAvailWidth())
{
// Always let the cell be as high as it wants. We ignore the height that's
// passed in and always place the entire row. Let the row group decide
// whether we fit or wehther the entire row is pushed
nsSize kidAvailSize(availWidth, NS_UNCONSTRAINEDSIZE);
-
+
// Reflow the child
kidFrame->WillReflow(*aPresContext);
- kidFrame->MoveTo(x, kidMargin.top);
+ kidFrame->MoveTo(aState.x, kidMargin.top);
kidAvailSize.width = availWidth;
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize,
eReflowReason_Resize);
@@ -393,12 +441,12 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
}
else
{
- nsSize priorSize = ((nsTableCellFrame *)kidFrame)->GetPriorDesiredSize();
+ nsSize priorSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
desiredSize.width = priorSize.width;
desiredSize.height = priorSize.height;
}
- // Place the child after taking into account its margin and attributes
+ // Place the child after taking into account it's margin and attributes
nscoord specifiedHeight = 0;
nscoord cellHeight = desiredSize.height;
nsIStyleContextPtr kidSC;
@@ -423,19 +471,20 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
// begin special Nav4 compatibility code
if (0==cellWidth)
{
- PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
}
// end special Nav4 compatibility code
// Place the child
- nsRect kidRect (x, kidMargin.top, cellWidth, cellHeight);
+ nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
pKidMaxElementSize);
+ aState.x += kidMargin.right; // add in right margin only after cell has been placed
// Get the next child
kidFrame->GetNextSibling(kidFrame);
+
}
SetMaxChildHeight(aState.maxCellHeight,maxCellTopMargin, maxCellBottomMargin); // remember height of tallest child who doesn't have a row span
@@ -448,42 +497,6 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
return NS_OK;
}
-// Compute the x-origin for the child by summing up the width of each
-// prior column. This correctly handles cells from prior rows with rowspans
-// > 1
-nscoord nsTableRowFrame::ComputeCellXOffset(const RowReflowState& aState,
- nsIFrame* aKidFrame,
- const nsMargin& aKidMargin) const
-{
- nscoord x = aKidMargin.left;
- PRInt32 cellColIndex = ((nsTableCellFrame *)aKidFrame)->GetColIndex();
-
- for (PRInt32 colIndex = 0; colIndex < cellColIndex; colIndex++)
- {
- x += aState.tableFrame->GetColumnWidth(colIndex);
- }
-
- return x;
-}
-
-// Computes the avail width for the cell. Takes into account column
-// spans
-nscoord nsTableRowFrame::ComputeCellAvailWidth(const RowReflowState& aState,
- nsIFrame* aKidFrame) const
-{
- nscoord availWidth = 0;
- nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame *)aKidFrame);
- PRInt32 cellStartingCol = ((nsTableCellFrame *)aKidFrame)->GetColIndex();
- PRInt32 cellColSpan = ((nsTableCellFrame *)aKidFrame)->GetColSpan();
-
- for (PRInt32 numColSpan = 0; numColSpan < cellColSpan; numColSpan++)
- {
- availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol + numColSpan);
- }
-
- return availWidth;
-}
-
/**
* Called for the initial reflow. Creates each table cell frame, and
* reflows it to gets its minimum and maximum sizes
@@ -570,13 +583,10 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
kidFrame->WillReflow(*aPresContext);
status = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState);
+ ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize);
+ ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "unexpected child reflow status");
- // Allocate and set the cell layout data
- nsCellLayoutData *kidLayoutData = new nsCellLayoutData((nsTableCellFrame *)kidFrame,
- &kidSize, &kidMaxElementSize);
- ((nsTableCellFrame *)kidFrame)->SetCellLayoutData(kidLayoutData);
-
if (gsDebug1)
{
printf("reflow of cell returned result = %s with desired=%d,%d, min = %d,%d\n",
@@ -630,13 +640,12 @@ nsresult nsTableRowFrame::RecoverState(RowReflowState& aState,
for (nsIFrame* frame = mFirstChild; frame != aKidFrame;) {
PRInt32 rowSpan = ((nsTableCellFrame*)frame)->GetRowSpan();
if (mMinRowSpan == rowSpan) {
- // XXX This isn't quite right. We also need to check whether the cell
- // has a height property that affects the cell...
- nsSize desiredSize = ((nsTableCellFrame *)frame)->GetPriorDesiredSize();
-
+ nsRect rect;
+ frame->GetRect(rect);
+
// Update maxCellHeight
- if (desiredSize.height > aState.maxCellHeight) {
- aState.maxCellHeight = desiredSize.height;
+ if (rect.height > aState.maxCellHeight) {
+ aState.maxCellHeight = rect.height;
}
// Update maxCellVertHeight
@@ -644,18 +653,14 @@ nsresult nsTableRowFrame::RecoverState(RowReflowState& aState,
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, margin) == NS_OK)
{
- nscoord height = desiredSize.height + margin.top + margin.bottom;
+ nscoord height = rect.height + margin.top + margin.bottom;
if (height > aState.maxCellVertSpace) {
aState.maxCellVertSpace = height;
}
}
}
- // XXX We also need to recover the max element size if requested by the
- // caller...
- //
- // We should be using GetReflowMetrics() to get information from the
- // table cell, and that will include the max element size...
+ // XXX We also need to recover the max element size...
// Remember the frame that precedes aKidFrame
prevKidFrame = frame;
@@ -687,20 +692,30 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// Recover our reflow state
RecoverState(aState, kidFrame);
- // Get the frame's margins
+ // Figure out the amount of available space for the child
nsMargin kidMargin;
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
// Figure out the amount of available space for the child
// XXX Shakey...
- nsSize kidAvailSize(aState.availSize);
+ nsSize kidAvailSize(aState.availSize); // XXX: top and bottom margins?
- // Compute the x-origin for the child, taking into account straddlers (cells
- // from prior rows with rowspans > 1)
- nscoord x = ComputeCellXOffset(aState, kidFrame, kidMargin);
+ // Compute the x-origin for the child, taking into account straddlers (cells from prior
+ // rows with rowspans > 1)
+ nscoord x = kidMargin.left;
+ PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
+ for (PRInt32 colIndex=0; colIndexGetColumnWidth(colIndex);
+ }
- // Compute the cell avail width from the column widths
- nscoord availWidth = ComputeCellAvailWidth(aState, kidFrame);
+ // at this point, we know the column widths.
+ // so we get the avail width from the known column widths
+ PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
+ PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
+ nscoord availWidth = 0;
+ for (PRInt32 numColSpan=0; numColSpanGetColumnWidth(cellStartingCol+numColSpan);
kidAvailSize.width = availWidth;
// Pass along the reflow command. Reflow the child with an unconstrained
@@ -726,23 +741,16 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
kidReflowState.maxSize.width = NS_UNCONSTRAINEDSIZE;
status = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState);
- // Update the cell layout data. Note that we need to do this for both
- // the data the cell maintains AND the data the table maintains...
- nsCellLayoutData *kidLayoutData = ((nsTableCellFrame *)kidFrame)->GetCellLayoutData();
-
- kidLayoutData->SetDesiredSize(&desiredSize);
- kidLayoutData->SetMaxElementSize(&kidMaxElementSize);
-
- kidLayoutData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame*)kidFrame);
- kidLayoutData->SetDesiredSize(&desiredSize);
- kidLayoutData->SetMaxElementSize(&kidMaxElementSize);
+ // Update the cell layout data.
+ ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(desiredSize);
+ ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
// Now reflow the cell again this time constraining the width
// XXX Ignore for now the possibility that the column width has changed...
kidReflowState.maxSize.width = availWidth;
status = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState);
- // Place the child after taking into account its margin and attributes
+ // Place the child after taking into account it's margin and attributes
nscoord specifiedHeight = 0;
nscoord cellHeight = desiredSize.height;
nsIStyleContextPtr kidSC;
@@ -767,7 +775,6 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// begin special Nav4 compatibility code
if (0==cellWidth)
{
- PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
}
// end special Nav4 compatibility code
@@ -781,8 +788,8 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// Now iterate over the remaining cells, and update our max cell
// height and our running x-offset
//
- // We don't have to re-position the x-origin of any of the child frames
- // that follow, because the column width hasn't changed...
+ // We don't have to re-position any of the child frames that follow, because
+ // the column width hasn't changed...
nscoord maxCellTopMargin = 0;
nscoord maxCellBottomMargin = 0;
kidFrame->GetNextSibling((nsIFrame*&)kidFrame);
@@ -791,11 +798,9 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsRect rect;
kidFrame->GetRect(rect);
if (mMinRowSpan == rowSpan) {
- nsSize desiredSize = ((nsTableCellFrame *)kidFrame)->GetPriorDesiredSize();
-
// Update maxCellHeight
- if (desiredSize.height > aState.maxCellHeight) {
- aState.maxCellHeight = desiredSize.height;
+ if (rect.height > aState.maxCellHeight) {
+ aState.maxCellHeight = rect.height;
}
// Update maxCellVertHeight
@@ -803,7 +808,7 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
{
- nscoord height = desiredSize.height + margin.top + margin.bottom;
+ nscoord height = rect.height + margin.top + margin.bottom;
if (height > aState.maxCellVertSpace) {
aState.maxCellVertSpace = height;
}
@@ -899,16 +904,22 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
return result;
}
+
+
NS_METHOD
nsTableRowFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIStyleContext* aStyleContext,
nsIFrame*& aContinuingFrame)
{
- // Because rows are always complete we should never be asked to create
- // a continuing frame
- NS_ERROR("Unexpected request");
- return NS_ERROR_NOT_IMPLEMENTED;
+ if (gsDebug1==PR_TRUE) printf("nsTableRowFrame::CreateContinuingFrame\n");
+ nsTableRowFrame* cf = new nsTableRowFrame(mContent, aParent);
+ if (nsnull == cf) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ PrepareContinuingFrame(aPresContext, aParent, aStyleContext, cf);
+ aContinuingFrame = cf;
+ return NS_OK;
}
nsresult nsTableRowFrame::NewFrame( nsIFrame** aInstancePtrResult,
diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
index 8c977341c19..f2b547638d2 100644
--- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
@@ -29,13 +29,11 @@
#include "nsIReflowCommand.h"
#ifdef NS_DEBUG
-static PRBool gsDebug1 = PR_FALSE;
-static PRBool gsDebug2 = PR_FALSE;
+static PRBool gsDebug = PR_FALSE;
//#define NOISY
//#define NOISY_FLOW
#else
-static const PRBool gsDebug1 = PR_FALSE;
-static const PRBool gsDebug2 = PR_FALSE;
+static const PRBool gsDebug = PR_FALSE;
#endif
NS_DEF_PTR(nsIStyleContext);
@@ -195,7 +193,7 @@ void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize)
{
- if (PR_TRUE==gsDebug1)
+ if (PR_TRUE==gsDebug)
printf ("rowgroup: placing row at %d, %d, %d, %d\n",
aKidRect.x, aKidRect.y, aKidRect.width, aKidRect.height);
@@ -256,7 +254,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
#endif
#endif
NS_PRECONDITION(nsnull != mFirstChild, "no children");
-
+if (gsDebug) printf("\n\nREFLOWMAPPED FOR ROW GROUP FRAME\n");
PRInt32 childCount = 0;
nsIFrame* prevKidFrame = nsnull;
@@ -1039,7 +1037,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
- if (gsDebug1==PR_TRUE)
+ if (gsDebug==PR_TRUE)
printf("nsTableRowGroupFrame::Reflow - aMaxSize = %d, %d\n",
aReflowState.maxSize.width, aReflowState.maxSize.height);
#ifdef NS_DEBUG
@@ -1153,7 +1151,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
PostReflowCheck(aStatus);
#endif
- if (gsDebug1==PR_TRUE)
+ if (gsDebug==PR_TRUE)
{
if (nsnull!=aDesiredSize.maxElementSize)
printf("nsTableRowGroupFrame::RR returning: %s with aDesiredSize=%d,%d, aMES=%d,%d\n",
@@ -1181,7 +1179,7 @@ nsTableRowGroupFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
return NS_ERROR_OUT_OF_MEMORY;
}
PrepareContinuingFrame(aPresContext, aParent, aStyleContext, cf);
- if (PR_TRUE==gsDebug1) printf("nsTableRowGroupFrame::CCF parent = %p, this=%p, cf=%p\n", aParent, this, cf);
+ if (PR_TRUE==gsDebug) printf("nsTableRowGroupFrame::CCF parent = %p, this=%p, cf=%p\n", aParent, this, cf);
aContinuingFrame = cf;
return NS_OK;
}
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
index baadba77204..1101961df05 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
@@ -19,16 +19,13 @@
#include "BasicTableLayoutStrategy.h"
#include "nsTableFrame.h"
#include "nsTableColFrame.h"
-#include "nsColLayoutData.h"
-#include "nsCellLayoutData.h"
-#include "nsTableCol.h"
#include "nsTableCellFrame.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
+#include "nsVoidArray.h"
#include "nsIPtr.h"
#include "nsHTMLIIDs.h"
-NS_DEF_PTR(nsTableCol);
NS_DEF_PTR(nsIStyleContext);
@@ -64,6 +61,23 @@ struct ProportionalColumnLayoutStruct
};
+/* ---------- ColSpanStruct ---------- */
+struct ColSpanStruct
+{
+ PRInt32 colIndex;
+ PRInt32 colSpan;
+ nscoord width;
+
+ ColSpanStruct(PRInt32 aSpan, PRInt32 aIndex, nscoord aWidth)
+ {
+ colSpan = aSpan;
+ colIndex = aIndex;
+ width = aWidth;
+ }
+};
+
+
+
/* ---------- BasicTableLayoutStrategy ---------- */
@@ -228,7 +242,9 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
if (gsDebug==PR_TRUE) printf (" AssignFixedColumnWidths\n");
nsVoidArray *spanList=nsnull;
-
+ nsVoidArray *colSpanList=nsnull;
+ nscoord * effectiveColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
+ nsCRT::memset (effectiveColumnWidths, 0, mNumCols*sizeof(PRInt32));
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
@@ -240,26 +256,24 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
maxColWidthArray = new PRInt32[mNumCols];
}
+ PRInt32 numRows = mTableFrame->GetRowCount();
+
// for every column, determine it's min and max width, and keep track of the table width
for (PRInt32 colIndex = 0; colIndexGetColumnLayoutData();
- nsColLayoutData * colData = (nsColLayoutData *)(columnLayoutData->ElementAt(colIndex));
- NS_ASSERTION(nsnull != colData, "bad column data");
- nsTableColFrame *colFrame = colData->GetColFrame();
- NS_ASSERTION(nsnull!=colFrame, "bad col frame");
-
// need to track min/max column width for setting min/max table widths
+ // QQQ: Eventually, this will be cached in col frame
+ // We'll just ask the column frame to compute this, and it'll use cached info if available
PRInt32 minColWidth = 0;
PRInt32 maxColWidth = 0;
- nsVoidArray *cells = colData->GetCells();
- PRInt32 numCells = cells->Count();
- if (gsDebug==PR_TRUE) printf (" for column %d numCells = %d\n", colIndex, numCells);
+
+ // Get column information
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ NS_ASSERTION(nsnull!=colFrame, "bad col frame");
// Get the columns's style
- nsIStyleContextPtr colSC;
- colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
- const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
// Get column width if it has one
PRBool haveColWidth = PR_FALSE;
@@ -268,7 +282,7 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
case eStyleUnit_Coord:
haveColWidth = PR_TRUE;
specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
- mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth); //QQQ add in margins?
+ mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth);
break;
default:
@@ -303,38 +317,49 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
}
}
- for (PRInt32 cellIndex = 0; cellIndexElementAt(cellIndex));
- if (nsnull == data) {
- // For cells that span rows there's only cell layout data for the first row
+ nsTableCellFrame * cellFrame = mTableFrame->GetCellAt(rowIndex, colIndex);
+ if (nsnull==cellFrame)
+ { // there is no cell in this row that corresponds to this column
+ continue;
+ }
+ if (-1==firstRowIndex)
+ firstRowIndex = rowIndex;
+ if (rowIndex!=cellFrame->GetRowIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
+ continue;
+ }
+ if (colIndex!=cellFrame->GetColIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
continue;
}
-
- nsMargin margin;
- nsresult result = data->GetMargin(margin);
- nsSize * cellMinSize = data->GetMaxElementSize();
- nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
- NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
- PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
+ nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
+ nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
+ PRInt32 colSpan = cellFrame->GetColSpan();
if (gsDebug==PR_TRUE)
- printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d, margins %d %d\n",
- cellIndex, colSpan, cellMinSize->width, cellMinSize->height,
- cellDesiredSize->width, cellDesiredSize->height,
- margin.left, margin.right);
+ printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
+ rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
+ cellDesiredSize.width, cellDesiredSize.height);
- switch (colPosition->mWidth.GetUnit()) {
+ switch (colPosition->mWidth.GetUnit())
+ {
case eStyleUnit_Coord:
{
// This col has a fixed width, so set the cell's width to the
// larger of (specified width, largest max_element_size of the
// cells in the column)
- PRInt32 widthForThisCell = PR_MAX(cellMinSize->width, colPosition->mWidth.GetCoordValue());
- if (mTableFrame->GetColumnWidth(colIndex) < widthForThisCell)
+ nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
+ widthForThisCell = widthForThisCell/colSpan;
+ nscoord widthFromCol = mTableFrame->GetColumnWidth(colIndex);
+ if (widthFromCol < widthForThisCell)
{
if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell);
- mTableFrame->SetColumnWidth(colIndex, widthForThisCell); //QQQ add in margins?
+ mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
maxColWidth = widthForThisCell;
}
}
@@ -347,24 +372,24 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
// regardless of the width specification, keep track of the
// min/max column widths
- nscoord cellMinWidth = cellMinSize->width/colSpan;
- nscoord cellDesiredWidth = cellDesiredSize->width/colSpan;
-
- if (aMaxWidth!=cellDesiredSize->width)
- {
- if (NS_UNCONSTRAINEDSIZE!=cellMinWidth)
- cellMinWidth += margin.left + margin.right;
- if (NS_UNCONSTRAINEDSIZE!=cellDesiredWidth)
- cellDesiredWidth += margin.left + margin.right;
- }
-
+ nscoord cellMinWidth = cellMinSize.width/colSpan;
+ nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
if (maxColWidth < cellDesiredWidth)
maxColWidth = cellDesiredWidth;
+ // effectiveColumnWidth is the width as if no cells with colspans existed
+ if ((1==colSpan) && (effectiveColumnWidths[colIndex] < maxColWidth))
+ effectiveColumnWidths[colIndex] = cellDesiredWidth;
if (1AppendElement(colSpanInfo);
+
+ // add the cell to our list of spanning cells
SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
if (nsnull==spanList)
spanList = new nsVoidArray();
@@ -372,26 +397,30 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
}
if (gsDebug) {
printf (" after cell %d, minColWidth = %d and maxColWidth = %d\n",
- cellIndex, minColWidth, maxColWidth);
+ rowIndex, minColWidth, maxColWidth);
}
}
+ // do all the global bookkeeping, factoring in margins
+ nsTableCellFrame * firstCellInColumn = mTableFrame->GetCellAt(firstRowIndex, colIndex);
+ nsMargin colMargin;
+ firstCellInColumn->GetMargin(colMargin);
+ nscoord colInset = colMargin.left + colMargin.right;
// keep a running total of the amount of space taken up by all fixed-width columns
if (PR_TRUE==haveColWidth)
- aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex);
+ aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
if (gsDebug) {
printf (" after col %d, aTotalFixedWidth = %d\n",
colIndex, aTotalFixedWidth);
}
-
// add col[i] metrics to the running totals for the table min/max width
if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth)
- aMinTableWidth += minColWidth; // SEC: insets!
+ aMinTableWidth += minColWidth + colInset;
if (aMinTableWidth<=0)
aMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (NS_UNCONSTRAINEDSIZE!=aMaxTableWidth)
- aMaxTableWidth += maxColWidth; // SEC: insets!
+ aMaxTableWidth += maxColWidth + colInset;
if (aMaxTableWidth<=0)
aMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
if (PR_TRUE==hasColsAttribute)
@@ -441,15 +470,59 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
delete [] minColWidthArray;
delete [] maxColWidthArray;
}
+ if (nsnull!=colSpanList)
+ DistributeFixedSpace(colSpanList, effectiveColumnWidths);
+ // today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
+ if (nsnull!=effectiveColumnWidths)
+ delete [] effectiveColumnWidths;
if (PR_TRUE==gsDebug)
printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, aMinTableWidth, aMaxTableWidth);
if (nsnull!=spanList)
delete spanList;
+ if (nsnull!=colSpanList)
+ delete colSpanList;
return PR_TRUE;
}
+// take the fixed space spanned by the columns in aColSpanList
+// and distribute it proportionately (based on desired width)
+void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths)
+{
+ nscoord excess = 0;
+ if (PR_TRUE==gsDebug) printf ("DistributeFixedSpace:\n");
+ // for all fixed-width columns, determine the amount of the specified width each column spanned recieves
+ PRInt32 numSpanningCells = aColSpanList->Count();
+ for (PRInt32 nextSpanningCell=0; nextSpanningCellElementAt(nextSpanningCell);
+ PRInt32 colIndex = colInfo->colIndex;
+ PRInt32 colSpan = colInfo->colSpan;
+ nscoord totalColWidth = colInfo->width;
+
+ // 1. get the sum of the effective widths of the columns in the span
+ nscoord totalEffectiveWidth=0;
+ PRInt32 i;
+ for (i = 0; iSetColumnWidth(colIndex+i, colWidth);
+ }
+ }
+}
+
PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nscoord aAvailWidth,
@@ -529,35 +602,37 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
minColWidthArray = new PRInt32[mNumCols];
}
- nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData();
- PRInt32 numCols = columnLayoutData->Count();
- for (PRInt32 colIndex = 0; colIndexGetRowCount();
+ for (PRInt32 colIndex = 0; colIndexElementAt(colIndex));
- nsVoidArray *cells = colData->GetCells();
PRInt32 minColWidth = 0;
PRInt32 maxColWidth = 0;
- PRInt32 numCells = cells->Count();
if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex);
- // XXX need column frame to ask this question
- const nsStylePosition* colPosition = nsnull;
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
+ NS_ASSERTION(nsnull!=colFrame, "bad col frame");
+ // Get the columns's style
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
{
- for (PRInt32 cellIndex = 0; cellIndexElementAt(cellIndex));
- if (nsnull==data)
- { // For cells that span rows there's only cell layout data for the first row
+ for (PRInt32 rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
+ if (nsnull==cellFrame)
+ { // there is no cell in this row that corresponds to this column
continue;
}
- nsMargin margin;
- data->GetMargin(margin);
- nsSize * cellMinSize = data->GetMaxElementSize();
- NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
- nscoord cellMinWidth = cellMinSize->width; // do we need to take into account colSpan here?
- cellMinWidth += margin.left + margin.right;
+ if (rowIndex!=cellFrame->GetRowIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
+ continue;
+ }
+
+ nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
+ PRInt32 colSpan = cellFrame->GetColSpan();
+ nscoord cellMinWidth = cellMinSize.width/colSpan;
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
}
@@ -624,32 +699,42 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
PRBool result = PR_TRUE;
nscoord tableWidth=0; // the width of the table as a result of setting column widths
+ nscoord widthOfFixedTableColumns=0; // the sum of the width of all fixed-width columns
+ // tableWidth - widthOfFixedTableColumns is the width of columns computed in this method
PRInt32 totalSlices=0; // the total number of slices the proportional-width columns request
nsVoidArray *proportionalColumnsList=nsnull; // a list of the columns that are proportional-width
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
- nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData();
- PRInt32 numCols = columnLayoutData->Count();
- nscoord * effectiveColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveColumnWidths, 0, numCols*sizeof(PRInt32));
- for (PRInt32 colIndex = 0; colIndexGetRowCount();
+
+ for (PRInt32 colIndex = 0; colIndexElementAt(colIndex));
- nsVoidArray *cells = colData->GetCells();
- PRInt32 numCells = cells->Count();
-
- // Get the columns's style
- nsTableColFrame *colFrame = colData->GetColFrame();
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
- nsIStyleContextPtr colSC;
- colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
- const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
- if (gsDebug) printf("col %d has frame %p with style %p and pos %p\n",
- colIndex, colFrame, (nsIStyleContext *)colSC, colPosition);
+ PRInt32 rowIndex;
+ PRInt32 firstRowIndex = -1;
+ nsTableCellFrame * firstCellInColumn;
+ for (rowIndex=0; rowIndexGetCellAt(rowIndex, colIndex);
+ if (nsnull!=firstCellInColumn)
+ break;
+ }
+ nsMargin colMargin;
+ nscoord colInset = 0;
+ if (nsnull!=firstCellInColumn)
+ {
+ firstCellInColumn->GetMargin(colMargin);
+ colInset = colMargin.left + colMargin.right;
+ }
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
{
// first, deal with any cells that span into this column from a pervious column
@@ -676,33 +761,33 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
}
- for (PRInt32 cellIndex = 0; cellIndexElementAt(cellIndex));
- if (nsnull == data) {
- // For cells that span columns there's only cell layout data for the first column
+ nsTableCellFrame * cellFrame = mTableFrame->GetCellAt(rowIndex, colIndex);
+ if (nsnull==cellFrame)
+ { // there is no cell in this row that corresponds to this column
+ continue;
+ }
+ if (-1==firstRowIndex)
+ firstRowIndex = rowIndex;
+ if (rowIndex!=cellFrame->GetRowIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
- PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
+ PRInt32 colSpan = cellFrame->GetColSpan();
// distribute a portion of the spanning cell's min and max width to this column
- nsSize * cellMinSize = data->GetMaxElementSize();
- NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
- nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
- NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
+ nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
+ nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- nsMargin margin;
- nsresult result = data->GetMargin(margin);
- nscoord marginWidth = margin.left + margin.right;
- PRInt32 cellMinWidth = cellMinSize->width/colSpan + marginWidth;
+ PRInt32 cellMinWidth = cellMinSize.width/colSpan;
// first get the desired size info from reflow pass 1
- PRInt32 cellDesiredWidth = cellDesiredSize->width/colSpan + marginWidth;
+ PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
// then get the desired size info factoring in the cell style attributes
nscoord specifiedCellWidth=-1;
- nsIStyleContextPtr cellSC;
- data->GetCellFrame()->GetStyleContext(aPresContext, cellSC.AssignRef());
- const nsStylePosition* cellPosition = (const nsStylePosition*)
- cellSC->GetStyleData(eStyleStruct_Position);
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
switch (cellPosition->mWidth.GetUnit()) {
case eStyleUnit_Coord:
specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
@@ -730,17 +815,17 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
if (-1!=specifiedCellWidth)
{
- if (specifiedCellWidth>cellMinWidth)
+ if (specifiedCellWidth/colSpan>cellMinWidth)
{
if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
- cellDesiredWidth, specifiedCellWidth);
- cellDesiredWidth = specifiedCellWidth; // TODO: some math needed here for colspans
+ cellDesiredWidth, specifiedCellWidth/colSpan);
+ cellDesiredWidth = specifiedCellWidth/colSpan; // TODO: some math needed here for colspans
}
}
if (PR_TRUE==gsDebug)
printf("factoring in cell %d with colSpan=%d\n factoring in min=%d and desired=%d\n",
- cellIndex, colSpan, cellMinWidth, cellDesiredWidth);
+ rowIndex, colSpan, cellMinWidth, cellDesiredWidth);
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
if (maxColWidth < cellDesiredWidth)
@@ -750,10 +835,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
effectiveColumnWidths[colIndex] = cellDesiredWidth;
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
- cellIndex, minColWidth, maxColWidth,
+ rowIndex, minColWidth, maxColWidth,
colIndex, effectiveColumnWidths[colIndex]);
- if (1GetColIndex()==colIndex))
+ { // add this cell to span list iff we are currently processing the column the cell starts in
SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
if (nsnull==spanList)
spanList = new nsVoidArray();
@@ -863,7 +948,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
if (-1==percentage)
{
- percentage = 100/numCols;
+ percentage = 100/mNumCols;
// base the % on the remaining available width
mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100);
if (gsDebug==PR_TRUE)
@@ -879,7 +964,11 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
}
}
}
- tableWidth += mTableFrame->GetColumnWidth(colIndex);
+ else
+ { // need to maintain this so we know how much we have left over at the end
+ widthOfFixedTableColumns += mTableFrame->GetColumnWidth(colIndex) + colInset;
+ }
+ tableWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
}
/* --- post-process if necessary --- */
@@ -938,9 +1027,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
// next, if the specified width of the table is greater than the table's computed width, expand the
// table's computed width to match the specified width, giving the extra space to proportionately-sized
// columns if possible.
- if ((PR_FALSE==aTableIsAutoWidth) && (aAvailWidth > tableWidth))
+ if ((PR_FALSE==aTableIsAutoWidth) && (aAvailWidth > (tableWidth-widthOfFixedTableColumns)))
{
- DistributeExcessSpace(aAvailWidth, tableWidth, effectiveColumnWidths);
+ DistributeExcessSpace(aAvailWidth, tableWidth, widthOfFixedTableColumns, effectiveColumnWidths);
}
// today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
if (nsnull!=effectiveColumnWidths)
@@ -952,24 +1041,27 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
// take the extra space in the table and distribute it proportionately (based on desired width)
// give extra space to auto-width cells first, or if there are none to all cells
-void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
- nscoord aComputedTableWidth,
+void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
+ nscoord aTableWidth,
+ nscoord aWidthOfFixedTableColumns,
nscoord *aColWidths)
{
nscoord excess = 0;
- if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d\n",
- aTableFixedWidth, aComputedTableWidth);
+ if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d, woftc=%d\n",
+ aAvailWidth, aTableWidth, aWidthOfFixedTableColumns);
// if there are auto-sized columns, give them the extra space
+ // the trick here is to do the math excluding non-auto width columns
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
if (0!=numAutoColumns)
{
+ nscoord computedTableWidth = aTableWidth - aWidthOfFixedTableColumns;
// there's at least one auto-width column, so give it (them) the extra space
// proportionately distributed extra space, based on the column's desired size
nscoord totalEffectiveWidthOfAutoColumns = 0;
if (gsDebug==PR_TRUE)
- printf(" aTableFixedWidth specified as %d, expanding columns by excess = %d\n", aTableFixedWidth, excess);
+ printf(" aAvailWidth specified as %d, expanding columns by excess = %d\n", aAvailWidth, excess);
// 1. first, get the total width of the auto columns
PRInt32 i;
for (i = 0; iGetColumnWidth(autoColumns[i]);
}
- excess = aTableFixedWidth - aComputedTableWidth;
+ excess = aAvailWidth - computedTableWidth;
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iGetColumnWidth(colIndex);//aColWidths[colIndex];
float percent;
if (0!=totalEffectiveWidthOfAutoColumns)
percent = ((float)(aColWidths[colIndex]))/((float)totalEffectiveWidthOfAutoColumns);
@@ -1002,25 +1094,25 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
// (they must be all fixed and percentage-width columns, or we would have gone into the block above)
else
{
- excess = aTableFixedWidth - aComputedTableWidth;
- nscoord excessPerColumn = excess/mNumCols;
+ excess = aAvailWidth - (aTableWidth-aWidthOfFixedTableColumns);
if (gsDebug==PR_TRUE)
- printf(" aTableFixedWidth specified as %d, expanding columns by excess = %d\n", aTableFixedWidth, excess);
+ printf(" aAvailWidth specified as %d, expanding columns by excess = %d\n",
+ aAvailWidth, excess);
for (PRInt32 colIndex = 0; colIndexGetColumnWidth(colIndex);
float percent;
- if (0!=aComputedTableWidth)
- percent = (float)oldColWidth/(float)aComputedTableWidth;
+ if (0!=aTableWidth)
+ percent = (float)oldColWidth/(float)aTableWidth;
else
percent = (float)1/(float)mNumCols;
nscoord excessForThisColumn = (nscoord)(excess*percent);
nscoord colWidth = excessForThisColumn+oldColWidth;
if (gsDebug==PR_TRUE)
- printf(" distribute excess to all columns: column %d was %d, now set to %d\n",
- colIndex, aColWidths[colIndex], colWidth);
+ printf(" distribute excess to all columns: column %d was %d, now set to %d from % = %f\n",
+ colIndex, oldColWidth, colWidth, percent);
mTableFrame->SetColumnWidth(colIndex, colWidth);
}
}
@@ -1051,29 +1143,40 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
// proportional-width columns are equal (if any are anything other than 1)
PRBool atLeastOneAutoWidthColumn = PR_FALSE; // true if at least one column is auto-width, requiring us to post-process
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
- nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData();
- PRInt32 numCols = columnLayoutData->Count();
- nscoord * effectiveMaxColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveMaxColumnWidths, 0, numCols*sizeof(PRInt32));
- nscoord * effectiveMinColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveMinColumnWidths, 0, numCols*sizeof(PRInt32));
- for (PRInt32 colIndex = 0; colIndexGetRowCount();
+
+ for (PRInt32 colIndex = 0; colIndexElementAt(colIndex));
- nsVoidArray *cells = colData->GetCells();
- PRInt32 numCells = cells->Count();
-
- // Get the columns's style
- nsTableColFrame *colFrame = colData->GetColFrame();
+ nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
- nsIStyleContextPtr colSC;
- colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
- const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
+ // Get the columns's style and margins
+ PRInt32 rowIndex;
+ PRInt32 firstRowIndex = -1;
+ nsTableCellFrame * firstCellInColumn;
+ for (rowIndex=0; rowIndexGetCellAt(rowIndex, colIndex);
+ if (nsnull!=firstCellInColumn)
+ break;
+ }
+ nsMargin colMargin;
+ nscoord colInset = 0;
+ if (nsnull!=firstCellInColumn)
+ {
+ firstCellInColumn->GetMargin(colMargin);
+ colInset = colMargin.left + colMargin.right;
+ }
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
if (PR_FALSE==IsFixedWidth(colPosition))
{
@@ -1100,33 +1203,30 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
}
}
- for (PRInt32 cellIndex = 0; cellIndexElementAt(cellIndex));
- if (nsnull == data) {
- // For cells that span rows there's only cell layout data for the first row
+ for (rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex);
+ if (nsnull==cellFrame)
+ { // there is no cell in this row that corresponds to this column
+ continue;
+ }
+ if (rowIndex!=cellFrame->GetRowIndex()) {
+ // For cells that span rows, we only figure it in once
+ NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
continue;
}
- PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
- nsSize * cellMinSize = data->GetMaxElementSize();
- NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
- nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
- NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
+ PRInt32 colSpan = cellFrame->GetColSpan();
+ nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
+ nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
- nsMargin margin;
- nsresult result = data->GetMargin(margin);
- nscoord marginWidth = margin.left + margin.right;
-
- PRInt32 cellMinWidth = cellMinSize->width/colSpan + marginWidth;
+ PRInt32 cellMinWidth = cellMinSize.width/colSpan;
// first get the desired size info from reflow pass 1
- PRInt32 cellDesiredWidth = cellDesiredSize->width/colSpan + marginWidth;
+ PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
// then get the desired size info factoring in the cell style attributes
nscoord specifiedCellWidth=-1;
- nsIStyleContextPtr cellSC;
- data->GetCellFrame()->GetStyleContext(aPresContext, cellSC.AssignRef());
- const nsStylePosition* cellPosition = (const nsStylePosition*)
- cellSC->GetStyleData(eStyleStruct_Position);
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition);
switch (cellPosition->mWidth.GetUnit()) {
case eStyleUnit_Coord:
specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
@@ -1164,7 +1264,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
if (PR_TRUE==gsDebug)
printf("factoring in cell %d with colSpan=%d\n factoring in min=%d and desired=%d\n",
- cellIndex, colSpan, cellMinWidth, cellDesiredWidth);
+ rowIndex, colSpan, cellMinWidth, cellDesiredWidth);
// remember the widest min cell width
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
@@ -1179,7 +1279,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
effectiveMaxColumnWidths[colIndex] = cellDesiredWidth;
if (gsDebug==PR_TRUE)
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
- cellIndex, minColWidth, maxColWidth,
+ rowIndex, minColWidth, maxColWidth,
colIndex, effectiveMaxColumnWidths[colIndex], effectiveMaxColumnWidths[colIndex]);
if (1GetColumnWidth(colIndex));
}
- else if (1==numCols)
+ else if (1==mNumCols)
{ // there is only one column, and we know that it's desired width doesn't fit
// so the column should be as wide as the available space allows it to be
if (gsDebug==PR_TRUE) printf (" 4 one-column: col %d set to width = %d\n", colIndex, aAvailWidth);
@@ -1300,7 +1400,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
if (-1==percentage)
{
- percentage = 100/numCols;
+ percentage = 100/mNumCols;
// base the % on the remaining available width
mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100);
if (gsDebug==PR_TRUE)
@@ -1417,16 +1517,52 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableFixedWidt
else
percent = ((float)1)/((float)numAutoColumns);
nscoord colWidth = (nscoord)(availWidth*percent);
- if (colWidthSetColumnWidth(colIndex, colWidth);
}
+ EnsureCellMinWidths(aMinColWidths);
+ }
+}
+
+void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
+{
+ PRBool atLeastOne = PR_TRUE;
+ while (PR_TRUE==atLeastOne)
+ {
+ atLeastOne=PR_FALSE;
+ PRInt32 colIndex;
+ nscoord addedWidth = 0;
+ // first, bump up cells that are below their min to their min width
+ for (colIndex=0; colIndexGetColumnWidth(colIndex);
+ if (colWidthSetColumnWidth(colIndex, aMinColWidths[colIndex]);
+ atLeastOne=PR_TRUE;
+ }
+ }
+ // second, remove the added space from cells that can afford to slim down
+ //QQQ boy is this slow! there has to be a faster way that is still guaranteed to be accurate...
+ while ((addedWidth>0))
+ { // while we still have some extra space, and last time we were able to take some off...
+ for (colIndex=0; colIndexGetColumnWidth(colIndex);
+ if (colWidth>aMinColWidths[colIndex])
+ {
+ mTableFrame->SetColumnWidth(colIndex, colWidth-1);
+ addedWidth--;
+ }
+ }
+ }
+ if (0ElementAt(aColIndex));
+}
+
diff --git a/mozilla/layout/tables/nsCellMap.h b/mozilla/layout/tables/nsCellMap.h
index 15f9e6c441a..998b53feac9 100644
--- a/mozilla/layout/tables/nsCellMap.h
+++ b/mozilla/layout/tables/nsCellMap.h
@@ -19,8 +19,11 @@
#define nsCellMap_h__
#include "nscore.h"
+#include "CellData.h"
-class CellData;
+class nsVoidArray;
+class nsTableColFrame;
+class nsTableCellFrame;
/** nsCellMap is a support class for nsTablePart.
* It maintains an Rows x Columns grid onto which the cells of the table are mapped.
@@ -40,55 +43,94 @@ protected:
/** storage for CellData pointers */
PRInt32 *mCells; ///XXX CellData *?
+ /** a cache of the column frames, by col index */
+ nsVoidArray * mColFrames;
+
/** the number of rows */
- int mRowCount; // in java, we could just do fCellMap.length;
+ PRInt32 mRowCount; // in java, we could just do fCellMap.length;
/** the number of columns (the max of all row lengths) */
- int mColCount; // in java, we could just do fCellMap[i].length
+ PRInt32 mColCount;
public:
- nsCellMap(int aRows, int aColumns);
+ nsCellMap(PRInt32 aRows, PRInt32 aColumns);
// NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
~nsCellMap();
/** initialize the CellMap to (aRows x aColumns) */
- void Reset(int aRows, int aColumns);
+ void Reset(PRInt32 aRows, PRInt32 aColumns);
- /** return the CellData for the cell at (aRow,aColumn) */
- CellData * GetCellAt(int aRow, int aColumn) const;
+ /** return the CellData for the cell at (aRowIndex,aColIndex) */
+ CellData * GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex) const;
+
+ /** return the nsTableCellFrame for the cell at (aRowIndex, aColIndex) */
+ nsTableCellFrame * GetCellFrameAt(PRInt32 aRowIndex, PRInt32 aColIndex) const;
/** assign aCellData to the cell at (aRow,aColumn) */
- void SetCellAt(CellData *aCellData, int aRow, int aColumn);
+ void SetCellAt(CellData *aCellData, PRInt32 aRow, PRInt32 aColumn);
/** expand the CellMap to have aColCount columns. The number of rows remains the same */
- void GrowTo(int aColCount);
+ void GrowTo(PRInt32 aColCount);
/** return the total number of columns in the table represented by this CellMap */
- int GetColCount() const;
+ PRInt32 GetColCount() const;
/** return the total number of rows in the table represented by this CellMap */
- int GetRowCount() const;
+ PRInt32 GetRowCount() const;
- /** for debugging, print out this CellMap */
+ nsTableColFrame * GetColumnFrame(PRInt32 aColIndex);
+
+ void AppendColumnFrame(nsTableColFrame *aColFrame);
+
+ PRBool RowImpactedBySpanningCell(PRInt32 aRowIndex);
+
+ PRBool ColumnImpactedBySpanningCell(PRInt32 aColIndex);
+
+ /** for debugging */
void DumpCellMap() const;
};
-inline CellData * nsCellMap::GetCellAt(int aRow, int aColumn) const
+/* ----- inline methods ----- */
+
+inline CellData * nsCellMap::GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex) const
{
- int index = (aRow*mColCount)+aColumn;
+ NS_PRECONDITION(0<=aRowIndex && aRowIndex < mRowCount, "bad aRowIndex arg");
+ NS_PRECONDITION(0<=aColIndex && aColIndex < mColCount, "bad aColIndex arg");
+
+ PRInt32 index = (aRowIndex*mColCount)+aColIndex;
return (CellData *)mCells[index];
}
-inline int nsCellMap::GetColCount() const
+inline nsTableCellFrame * nsCellMap::GetCellFrameAt(PRInt32 aRowIndex, PRInt32 aColIndex) const
+{
+ NS_PRECONDITION(0<=aRowIndex && aRowIndex < mRowCount, "bad aRowIndex arg");
+ NS_PRECONDITION(0<=aColIndex && aColIndex < mColCount, "bad aColIndex arg");
+
+ nsTableCellFrame *result = nsnull;
+ CellData * cellData = GetCellAt(aRowIndex, aColIndex);
+ if (nsnull!=cellData)
+ result = cellData->mCell;
+ return result;
+}
+
+inline PRInt32 nsCellMap::GetColCount() const
{
return mColCount;
}
-inline int nsCellMap::GetRowCount() const
+inline PRInt32 nsCellMap::GetRowCount() const
{
return mRowCount;
}
+inline void nsCellMap::AppendColumnFrame(nsTableColFrame *aColFrame)
+{
+ mColFrames->AppendElement(aColFrame);
+ // sanity check
+ NS_ASSERTION(mColFrames->Count()<=mColCount, "too many columns appended to CellMap");
+}
+
+
#endif
diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp
index 3e3c60a90cd..6c19957a4fb 100644
--- a/mozilla/layout/tables/nsTableCellFrame.cpp
+++ b/mozilla/layout/tables/nsTableCellFrame.cpp
@@ -16,7 +16,6 @@
* Reserved.
*/
#include "nsTableCellFrame.h"
-#include "nsCellLayoutData.h"
#include "nsBodyFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
@@ -53,21 +52,24 @@ static const PRBool gsDebugNT = PR_FALSE;
*/
nsTableCellFrame::nsTableCellFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
- : nsContainerFrame(aContent, aParentFrame),
- mCellLayoutData(nsnull)
+ : nsContainerFrame(aContent, aParentFrame)
{
mRowSpan=1;
mColSpan=1;
mColIndex=0;
mPriorAvailWidth=0;
- mPriorDesiredSize.width=0;
- mPriorDesiredSize.height=0;
+ mDesiredSize.width=0;
+ mDesiredSize.height=0;
+ mMaxElementSize.width=0;
+ mMaxElementSize.height=0;
+ mPass1DesiredSize.width=0;
+ mPass1DesiredSize.height=0;
+ mPass1MaxElementSize.width=0;
+ mPass1MaxElementSize.height=0;
}
nsTableCellFrame::~nsTableCellFrame()
{
- if (nsnull!=mCellLayoutData)
- delete mCellLayoutData;
}
NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext,
@@ -291,7 +293,6 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
mFirstChild->WillReflow(*aPresContext);
mFirstChild->MoveTo(leftInset, topInset);
aStatus = ReflowChild(mFirstChild, aPresContext, kidSize, kidReflowState);
- SetPriorDesiredSize(kidSize);
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugNT)
{
@@ -325,10 +326,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
// first, compute the height
// the height can be set w/o being restricted by aMaxSize.height
nscoord cellHeight = kidSize.height;
- if (NS_UNCONSTRAINEDSIZE!=aReflowState.maxSize.height)
- {
- cellHeight += topInset + bottomInset;
- }
+ cellHeight += topInset + bottomInset;
if (PR_TRUE==gsDebugNT)
printf(" %p cellFrame height set to %d from kidSize=%d and insets %d,%d\n",
this, cellHeight, kidSize.height, topInset, bottomInset);
@@ -369,6 +367,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize->height += topInset + bottomInset;
aDesiredSize.maxElementSize->width += leftInset + rightInset;
}
+ SetDesiredSize(aDesiredSize);
+ if (nsnull!=aDesiredSize.maxElementSize)
+ SetMaxElementSize(*(aDesiredSize.maxElementSize));
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugNT)
printf(" %p cellFrame returning aDesiredSize=%d,%d\n",
@@ -590,6 +591,505 @@ nsresult nsTableCellFrame::NewFrame(nsIFrame** aInstancePtrResult,
}
+
+/* ----- methods from CellLayoutData ----- */
+
+/**
+ * Given a frame and an edge, find the margin
+ *
+ **/
+nscoord nsTableCellFrame::GetMargin(nsIFrame* aFrame, PRUint8 aEdge) const
+{
+ nscoord result = 0;
+
+ if (aFrame)
+ {
+ const nsStyleSpacing* spacing;
+ aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
+ nsMargin margin;
+ spacing->CalcMarginFor(aFrame, margin);
+ switch (aEdge)
+ {
+ case NS_SIDE_TOP:
+ result = margin.top;
+ break;
+
+ case NS_SIDE_RIGHT:
+ result = margin.right;
+ break;
+
+ case NS_SIDE_BOTTOM:
+ result = margin.bottom;
+ break;
+
+ case NS_SIDE_LEFT:
+ result = margin.left;
+ break;
+
+ }
+ }
+ return result;
+}
+
+
+/**
+ * Given a style context and an edge, find the border width
+ *
+ **/
+nscoord nsTableCellFrame::GetBorderWidth(nsIFrame* aFrame, PRUint8 aEdge) const
+{
+ nscoord result = 0;
+
+ if (aFrame)
+ {
+ const nsStyleSpacing* spacing;
+ aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
+ nsMargin border;
+ spacing->CalcBorderFor(aFrame, border);
+ switch (aEdge)
+ {
+ case NS_SIDE_TOP:
+ result = border.top;
+ break;
+
+ case NS_SIDE_RIGHT:
+ result = border.right;
+ break;
+
+ case NS_SIDE_BOTTOM:
+ result = border.bottom;
+ break;
+
+ case NS_SIDE_LEFT:
+ result = border.left;
+ break;
+
+ }
+ }
+ return result;
+}
+
+
+/**
+ * Given a style context and an edge, find the padding
+ *
+ **/
+nscoord nsTableCellFrame::GetPadding(nsIFrame* aFrame, PRUint8 aEdge) const
+{
+ nscoord result = 0;
+
+ if (aFrame)
+ {
+ const nsStyleSpacing* spacing;
+ aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
+ nsMargin padding;
+ spacing->CalcPaddingFor(aFrame, padding);
+ switch (aEdge)
+ {
+ case NS_SIDE_TOP:
+ result = padding.top;
+ break;
+
+ case NS_SIDE_RIGHT:
+ result = padding.right;
+ break;
+
+ case NS_SIDE_BOTTOM:
+ result = padding.bottom;
+ break;
+
+ case NS_SIDE_LEFT:
+ result = padding.left;
+ break;
+
+ }
+ }
+ return result;
+}
+
+
+
+/**
+ * Given an Edge, find the opposing edge (top<-->bottom, left<-->right)
+ *
+ **/
+PRUint8 nsTableCellFrame::GetOpposingEdge(PRUint8 aEdge)
+{
+ PRUint8 result;
+
+ switch (aEdge)
+ {
+ case NS_SIDE_LEFT:
+ result = NS_SIDE_RIGHT;
+ break;
+
+ case NS_SIDE_RIGHT:
+ result = NS_SIDE_LEFT;
+ break;
+
+ case NS_SIDE_TOP:
+ result = NS_SIDE_BOTTOM;
+ break;
+
+ case NS_SIDE_BOTTOM:
+ result = NS_SIDE_TOP;
+ break;
+
+ default:
+ result = NS_SIDE_TOP;
+ }
+ return result;
+}
+
+
+/*
+*
+* Determine border style for two cells.
+*
+ 1.If the adjacent elements are of the same type, the wider of the two borders is used.
+ "Wider" takes into account the border-style of 'none', so a "1px solid" border
+ will take precedence over a "20px none" border.
+
+ 2.If there are two or more with the same width, but different style,
+ then the one with a style near the start of the following list will be drawn:
+
+ 'blank', 'double', 'solid', 'dashed', 'dotted', 'ridge', 'groove', 'none'
+
+ 3.If the borders are of the same width, the border on the element occurring first is used.
+
+ First is defined as aStyle for this method.
+
+ NOTE: This assumes left-to-right, top-to-bottom bias. -- gpk
+
+*
+*/
+
+
+nsIFrame* nsTableCellFrame::CompareCellBorders(nsIFrame* aFrame1,
+ PRUint8 aEdge1,
+ nsIFrame* aFrame2,
+ PRUint8 aEdge2)
+{
+ PRInt32 width1 = GetBorderWidth(aFrame1,aEdge1);
+ PRInt32 width2 = GetBorderWidth(aFrame2,aEdge2);
+
+ nsIFrame* result = nsnull;
+
+ if (width1 > width2)
+ result = aFrame1;
+ else if (width1 < width2)
+ result = aFrame2;
+ else // width1 == width2
+ {
+ const nsStyleSpacing* border1;
+ const nsStyleSpacing* border2;
+ aFrame1->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)border1);
+ aFrame2->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)border2);
+ if (border1->mBorderStyle[aEdge1] >= border2->mBorderStyle[aEdge2])
+ result = aFrame1;
+ else
+ result = aFrame2;
+ }
+ return result;
+}
+
+
+/**
+ * Given a List of cell layout data, compare the edges to see which has the
+ * border with the highest precidence.
+ *
+ **/
+
+nsIFrame* nsTableCellFrame::FindHighestPrecedentBorder(nsVoidArray* aList,
+ PRUint8 aEdge)
+{
+ nsIFrame* result = nsnull;
+ PRInt32 index = 0;
+ PRInt32 count = 0;
+
+
+ NS_ASSERTION(aList,"a List must be valid");
+ count = aList->Count();
+ if (count)
+ {
+ nsIFrame* frame1;
+ nsIFrame* frame2;
+
+ frame1 = (nsIFrame*)(aList->ElementAt(index++));
+ while (index < count)
+ {
+ frame2 = (nsIFrame*)(aList->ElementAt(index++));
+ if (GetMargin(frame2,aEdge) == 0) {
+ frame1 = CompareCellBorders(frame1, aEdge, frame2, aEdge);
+ }
+ }
+ if ((nsnull != frame1) && (GetMargin(frame1, aEdge) != 0))
+ result = frame1;
+ }
+ return result;
+}
+
+
+
+
+nsIFrame* nsTableCellFrame::FindInnerBorder(nsVoidArray* aList, PRUint8 aEdge)
+{
+ nsIFrame* result = nsnull;
+ PRUint8 opposite = GetOpposingEdge(aEdge);
+
+ if (GetMargin(this, aEdge) == 0)
+ {
+ nsIFrame* altFrame = FindHighestPrecedentBorder(aList,opposite);
+ if (nsnull != altFrame)
+ result = CompareCellBorders(this, aEdge, altFrame, opposite);
+ else
+ result = this;
+ }
+
+ return result;
+}
+
+
+/*
+*
+* FindRelevantBorder recursively searches up the frame hierarchy for the border
+* style that is applicable to the cell. If at any point the frame has a margin
+* or the parent frame has padding, then the outer frame for this object takes
+* presendence over the inner frame.
+
+1.Borders on 'table' elements take precedence over borders on any other table elements.
+2.Borders on 'row-groups' take precedence over borders on 'rows',
+ and likewise borders on 'column-groups' take precedence over borders on 'columns'.
+3.Borders on any other type of table element take precedence over 'table-cell' elements.
+
+*
+* NOTE: This method assumes that the table cell potentially shares a border.
+* It should not be called for internal cells
+*
+* NOTE: COLUMNS AND COLGROUPS NEED TO BE FIGURED INTO THE ALGORITHM -- GPK!!!
+*
+*
+*/
+nsIFrame* nsTableCellFrame::FindOuterBorder( nsTableFrame* aTableFrame,
+ PRUint8 aEdge)
+{
+ nsIFrame* frame = this; // By default, return our frame
+ PRBool done = PR_FALSE;
+
+
+ // The table frame is the outer most frame we test against
+ while (done == PR_FALSE)
+ {
+ done = PR_TRUE; // where done unless the frame's margin is zero
+ // and the parent's padding is zero
+
+ nscoord margin = GetMargin(frame,aEdge);
+
+ // if the margin for this style is zero then check to see if the paddding
+ // for the parent frame is also zero
+ if (margin == 0)
+ {
+ nsIFrame* parentFrame;
+
+ frame->GetGeometricParent(parentFrame);
+
+ // if the padding for the parent style is zero just
+ // recursively call this routine
+ PRInt32 padding = GetPadding(parentFrame,aEdge);
+ if ((nsnull != parentFrame) && (padding == 0))
+ {
+ frame = parentFrame;
+ // If this frame represents the table frame then
+ // the table style is used
+ done = PRBool(frame != (nsIFrame*)aTableFrame);
+ continue;
+ }
+
+ }
+ }
+ return frame;
+}
+
+
+
+/*
+
+ Border Resolution
+ 1.Borders on 'table' elements take precedence over borders on any other table elements.
+ 2.Borders on 'row-groups' take precedence over borders on 'rows', and likewise borders on 'column-groups' take
+ precedence over borders on 'columns'.
+ 3.Borders on any other type of table element take precedence over 'table-cell' elements.
+ 4.If the adjacent elements are of the same type, the wider of the two borders is used. "Wider" takes into account
+ the border-style of 'none', so a "1px solid" border will take precedence over a "20px none" border.
+ 5.If the borders are of the same width, the border on the element occurring first is used.
+
+
+ How to compare
+ 1.Those of the one or two cells that have an edge here.
+ Less than two can occur at the edge of the table, but also
+ at the edges of "holes" (unoccupied grid cells).
+ 2.Those of the columns that have an edge here.
+ 3.Those of the column groups that have an edge here.
+ 4.Those of the rows that have an edge here.
+ 5.Those of the row groups that have an edge here.
+ 6.Those of the table, if this is the edge of the table.
+
+*
+* @param aIsFirst -- TRUE if this is the first cell in the row
+* @param aIsLast -- TRUE if this is the last cell in the row
+* @param aIsTop -- TRUE if this is the top cell in the column
+* @param aIsBottom -- TRUE if this is the last cell in the column
+*/
+
+nsIFrame* nsTableCellFrame::FindBorderFrame(nsTableFrame* aTableFrame,
+ nsVoidArray* aList,
+ PRUint8 aEdge)
+{
+ nsIFrame* frame = nsnull;
+
+ if (aList && aList->Count() == 0)
+ frame = FindOuterBorder(aTableFrame, aEdge);
+ else
+ frame = FindInnerBorder(aList, aEdge);
+
+ if (! frame)
+ frame = this;
+
+ return frame;
+}
+
+
+/**
+ * Given a List of cell layout data, compare the edges to see which has the
+ * border with the highest precidence.
+ *
+ **/
+nscoord nsTableCellFrame::FindLargestMargin(nsVoidArray* aList,PRUint8 aEdge)
+{
+ nscoord result = 0;
+ PRInt32 index = 0;
+ PRInt32 count = 0;
+
+
+ NS_ASSERTION(aList,"a List must be valid");
+ count = aList->Count();
+ if (count)
+ {
+ nsIFrame* frame;
+
+ nscoord value = 0;
+ while (index < count)
+ {
+ frame = (nsIFrame*)(aList->ElementAt(index++));
+ value = GetMargin(frame, aEdge);
+ if (value > result)
+ result = value;
+ }
+ }
+ return result;
+}
+
+
+
+
+void nsTableCellFrame::CalculateMargins(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4])
+{
+ // By default the margin is just the margin found in the
+ // table cells style
+ const nsStyleSpacing* spacing;
+ GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
+ spacing->CalcMarginFor(this, mMargin);
+
+ // Left and Top Margins are collapsed with their neightbors
+ // Right and Bottom Margins are simple left as they are
+ nscoord value;
+
+ // The left and top sides margins are the difference between
+ // their inherint value and the value of the margin of the
+ // object to the left or right of them.
+
+ value = FindLargestMargin(aBoundaryCells[NS_SIDE_LEFT],NS_SIDE_RIGHT);
+ if (value > mMargin.left)
+ mMargin.left = 0;
+ else
+ mMargin.left -= value;
+
+ value = FindLargestMargin(aBoundaryCells[NS_SIDE_TOP],NS_SIDE_BOTTOM);
+ if (value > mMargin.top)
+ mMargin.top = 0;
+ else
+ mMargin.top -= value;
+}
+
+
+void nsTableCellFrame::RecalcLayoutData(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4])
+
+{
+ CalculateBorders(aTableFrame, aBoundaryCells);
+ CalculateMargins(aTableFrame, aBoundaryCells);
+ mCalculated = NS_OK;
+}
+
+#if 0 //QQQ
+void nsTableCellFrame::List(FILE* out, PRInt32 aIndent) const
+{
+ PRInt32 indent;
+
+ nsIContent* cell;
+
+ this->GetContent(cell);
+ if (cell != nsnull)
+ {
+ /*
+ for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
+ fprintf(out,"RowSpan = %d ColSpan = %d \n",cell->GetRowSpan(),cell->GetColSpan());
+ */
+ for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
+ fprintf(out,"Margin -- Top: %d Left: %d Bottom: %d Right: %d \n",
+ NS_TWIPS_TO_POINTS_INT(mMargin.top),
+ NS_TWIPS_TO_POINTS_INT(mMargin.left),
+ NS_TWIPS_TO_POINTS_INT(mMargin.bottom),
+ NS_TWIPS_TO_POINTS_INT(mMargin.right));
+
+
+ for (indent = aIndent; --indent >= 0; ) fputs(" ", out);
+
+ nscoord top,left,bottom,right;
+
+ top = (mBorderFrame[NS_SIDE_TOP] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_TOP], NS_SIDE_TOP) : 0);
+ left = (mBorderFrame[NS_SIDE_LEFT] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_LEFT], NS_SIDE_LEFT) : 0);
+ bottom = (mBorderFrame[NS_SIDE_BOTTOM] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_BOTTOM], NS_SIDE_BOTTOM) : 0);
+ right = (mBorderFrame[NS_SIDE_RIGHT] ? GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_RIGHT], NS_SIDE_RIGHT) : 0);
+
+
+ fprintf(out,"Border -- Top: %d Left: %d Bottom: %d Right: %d \n",
+ NS_TWIPS_TO_POINTS_INT(top),
+ NS_TWIPS_TO_POINTS_INT(left),
+ NS_TWIPS_TO_POINTS_INT(bottom),
+ NS_TWIPS_TO_POINTS_INT(right));
+
+
+
+ cell->List(out,aIndent);
+ NS_RELEASE(cell);
+ }
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+/* ----- debug only methods, to be removed ----- */
+
+
// For Debugging ONLY
NS_METHOD nsTableCellFrame::MoveTo(nscoord aX, nscoord aY)
{
diff --git a/mozilla/layout/tables/nsTableCellFrame.h b/mozilla/layout/tables/nsTableCellFrame.h
index ecdf04fce00..514edc5d33f 100644
--- a/mozilla/layout/tables/nsTableCellFrame.h
+++ b/mozilla/layout/tables/nsTableCellFrame.h
@@ -21,8 +21,8 @@
#include "nscore.h"
#include "nsContainerFrame.h"
#include "nsTableFrame.h"
+#include "nsTableRowFrame.h" // need to actually include this here to inline GetRowIndex
-class nsCellLayoutData;
struct nsStyleSpacing;
/* eb42f7b0-079e-11d2-8f37-006008159b0c */
@@ -72,34 +72,124 @@ public:
/** return the mapped cell's row span. Always >= 1. */
virtual PRInt32 GetRowSpan();
+ // there is no set row index because row index depends on the cell's parent row only
+
+ /** return the mapped cell's row index (starting at 0 for the first row) */
+ virtual PRInt32 GetRowIndex();
+
/** return the mapped cell's col span. Always >= 1. */
virtual PRInt32 GetColSpan();
-
+
/** return the mapped cell's column index (starting at 0 for the first column) */
virtual PRInt32 GetColIndex();
+ /** set the index of the column belonging to this cell */
+ // XXX should be removed, use cell map?
virtual void SetColIndex (int aColIndex);
+ /** return the available width given to this frame during its last reflow */
virtual nscoord GetPriorAvailWidth();
+ /** set the available width given to this frame during its last reflow */
virtual void SetPriorAvailWidth(nscoord aPriorAvailWidth);
- virtual nsSize GetPriorDesiredSize();
+ /** return the desired size returned by this frame during its last reflow */
+ virtual nsSize GetDesiredSize();
- virtual void SetPriorDesiredSize(const nsReflowMetrics & aDesiredSize);
+ /** set the desired size returned by this frame during its last reflow */
+ virtual void SetDesiredSize(const nsReflowMetrics & aDesiredSize);
- virtual ~nsTableCellFrame();
+ /** return the MaxElement size returned by this frame during its last reflow
+ * not counting reflows where MaxElementSize is not requested.
+ * That is, the cell frame will always remember the last non-null MaxElementSize
+ */
+ virtual nsSize GetMaxElementSize();
- // Get the TableFrame that contains this cell frame
+ /** set the MaxElement size returned by this frame during its last reflow.
+ * should never be called with a null MaxElementSize
+ */
+ virtual void SetMaxElementSize(const nsSize & aMaxElementSize);
+
+ /** return the desired size returned by this frame during its last reflow */
+ virtual nsSize GetPass1DesiredSize();
+
+ /** set the desired size returned by this frame during its last reflow */
+ virtual void SetPass1DesiredSize(const nsReflowMetrics & aDesiredSize);
+
+ /** return the MaxElement size returned by this frame during its last reflow
+ * not counting reflows where MaxElementSize is not requested.
+ * That is, the cell frame will always remember the last non-null MaxElementSize
+ */
+ virtual nsSize GetPass1MaxElementSize();
+
+ /** set the MaxElement size returned by this frame during its last reflow.
+ * should never be called with a null MaxElementSize
+ */
+ virtual void SetPass1MaxElementSize(const nsSize & aMaxElementSize);
+
+
+
+ /** Get the TableFrame that contains this cell frame */
virtual nsTableFrame* GetTableFrame();
- nsCellLayoutData * GetCellLayoutData();
- void SetCellLayoutData(nsCellLayoutData *aData);
+ void RecalcLayoutData(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4]);
- // For DEBUGGING Purposes Only
+
+ NS_IMETHOD GetMargin(nsMargin& aMargin);
+
+
+ /** destructor */
+ virtual ~nsTableCellFrame();
+
+
+ // For DEBUGGING Purposes Only, to be removed
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
+private:
+
+ // All these methods are support methods for RecalcLayoutData
+ nsIFrame* GetFrameAt(nsVoidArray* aList, PRInt32 aIndex);
+
+ nscoord GetMargin(nsIFrame* aFrame, PRUint8 aEdge) const;
+
+ nscoord GetBorderWidth(nsIFrame* aFrame, PRUint8 aEdge) const;
+
+ nscoord GetPadding(nsIFrame* aFrame, PRUint8 aEdge) const;
+
+ PRUint8 GetOpposingEdge(PRUint8 aEdge);
+
+ nsIFrame* CompareCellBorders(nsIFrame* aFrame1,
+ PRUint8 aEdge1,
+ nsIFrame* aFrame2,
+ PRUint8 aEdge2);
+
+
+ nsIFrame* FindHighestPrecedentBorder(nsVoidArray* aList,
+ PRUint8 aEdge);
+
+
+
+ nsIFrame* FindInnerBorder( nsVoidArray* aList,
+ PRUint8 aEdge);
+
+ nsIFrame* FindOuterBorder( nsTableFrame* aTableFrame,
+ PRUint8 aEdge);
+
+ nsIFrame* FindBorderFrame(nsTableFrame* aTableFrame,
+ nsVoidArray* aCellList,
+ PRUint8 aEdge);
+
+ void CalculateBorders(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4]);
+
+ nscoord FindLargestMargin(nsVoidArray* aList,PRUint8 aEdge);
+
+
+ void CalculateMargins(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4]);
+
protected:
/** protected constructor.
@@ -132,9 +222,17 @@ protected:
/** the available width we were given in our previous reflow */
nscoord mPriorAvailWidth;
- nsSize mPriorDesiredSize;
+ /** these are the last computed desired and max element sizes */
+ nsSize mDesiredSize;
+ nsSize mMaxElementSize;
- nsCellLayoutData *mCellLayoutData;
+ /** these are the Pass 1 unconstrained desired and max element sizes */
+ nsSize mPass1DesiredSize;
+ nsSize mPass1MaxElementSize;
+
+ nsresult mCalculated;
+ nsMargin mMargin;
+ nsIFrame* mBorderFrame[4]; // the frame whose border is used
};
@@ -151,6 +249,16 @@ inline void nsTableCellFrame::Init(PRInt32 aRowSpan, PRInt32 aColSpan, PRInt32 a
inline PRInt32 nsTableCellFrame::GetRowSpan()
{ return mRowSpan;}
+inline PRInt32 nsTableCellFrame::GetRowIndex()
+{
+ nsTableRowFrame * row;
+ GetContentParent((nsIFrame *&)row);
+ if (nsnull!=row)
+ return row->GetRowIndex();
+ else
+ return 0;
+}
+
inline PRInt32 nsTableCellFrame::GetColSpan()
{ return mColSpan;}
@@ -163,25 +271,64 @@ inline void nsTableCellFrame::SetColIndex (int aColIndex)
mColIndex = aColIndex;
}
-inline nsCellLayoutData * nsTableCellFrame::GetCellLayoutData()
-{ return mCellLayoutData;}
-
-inline void nsTableCellFrame::SetCellLayoutData(nsCellLayoutData *aData)
-{ mCellLayoutData = aData;}
-
inline nscoord nsTableCellFrame::GetPriorAvailWidth()
{ return mPriorAvailWidth;}
inline void nsTableCellFrame::SetPriorAvailWidth(nscoord aPriorAvailWidth)
{ mPriorAvailWidth = aPriorAvailWidth;}
-inline nsSize nsTableCellFrame::GetPriorDesiredSize()
-{ return mPriorDesiredSize; }
+inline nsSize nsTableCellFrame::GetDesiredSize()
+{ return mDesiredSize; }
-inline void nsTableCellFrame::SetPriorDesiredSize(const nsReflowMetrics & aDesiredSize)
+inline void nsTableCellFrame::SetDesiredSize(const nsReflowMetrics & aDesiredSize)
{
- mPriorDesiredSize.width = aDesiredSize.width;
- mPriorDesiredSize.height = aDesiredSize.height;
+ mDesiredSize.width = aDesiredSize.width;
+ mDesiredSize.height = aDesiredSize.height;
}
+inline nsSize nsTableCellFrame::GetMaxElementSize()
+{ return mMaxElementSize; }
+
+inline void nsTableCellFrame::SetMaxElementSize(const nsSize & aMaxElementSize)
+{
+ mMaxElementSize.width = aMaxElementSize.width;
+ mMaxElementSize.height = aMaxElementSize.height;
+}
+
+inline nsSize nsTableCellFrame::GetPass1DesiredSize()
+{ return mPass1DesiredSize; }
+
+inline void nsTableCellFrame::SetPass1DesiredSize(const nsReflowMetrics & aDesiredSize)
+{
+ mPass1DesiredSize.width = aDesiredSize.width;
+ mPass1DesiredSize.height = aDesiredSize.height;
+}
+
+inline nsSize nsTableCellFrame::GetPass1MaxElementSize()
+{ return mPass1MaxElementSize; }
+
+inline void nsTableCellFrame::SetPass1MaxElementSize(const nsSize & aMaxElementSize)
+{
+ mPass1MaxElementSize.width = aMaxElementSize.width;
+ mPass1MaxElementSize.height = aMaxElementSize.height;
+}
+
+inline void nsTableCellFrame::CalculateBorders(nsTableFrame* aTableFrame,
+ nsVoidArray* aBoundaryCells[4])
+{
+ for (PRInt32 edge = 0; edge < 4; edge++)
+ mBorderFrame[edge] = FindBorderFrame(aTableFrame, aBoundaryCells[edge], edge);
+}
+
+inline NS_METHOD nsTableCellFrame::GetMargin(nsMargin& aMargin)
+{
+ if (mCalculated == NS_OK)
+ {
+ aMargin = mMargin;
+ return NS_OK;
+ }
+ return NS_ERROR_NOT_INITIALIZED;
+}
+
+
#endif
diff --git a/mozilla/layout/tables/nsTableColFrame.cpp b/mozilla/layout/tables/nsTableColFrame.cpp
new file mode 100644
index 00000000000..c628ea33e86
--- /dev/null
+++ b/mozilla/layout/tables/nsTableColFrame.cpp
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+#include "nsTableColFrame.h"
+#include "nsContainerFrame.h"
+#include "nsIReflowCommand.h"
+#include "nsIStyleContext.h"
+#include "nsStyleConsts.h"
+#include "nsIPresContext.h"
+#include "nsHTMLIIDs.h"
+#include "nsHTMLAtoms.h"
+
+#ifdef NS_DEBUG
+static PRBool gsDebug = PR_FALSE;
+static PRBool gsNoisyRefs = PR_FALSE;
+#else
+static const PRBool gsDebug = PR_FALSE;
+static const PRBool gsNoisyRefs = PR_FALSE;
+#endif
+
+
+nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
+ : nsFrame(aContent, aParentFrame)
+{
+ mColIndex = 0;
+ mRepeat = 0;
+}
+
+
+nsTableColFrame::~nsTableColFrame()
+{
+}
+
+NS_METHOD nsTableColFrame::Paint(nsIPresContext& aPresContext,
+ nsIRenderingContext& aRenderingContext,
+ const nsRect& aDirtyRect)
+{
+ if (gsDebug==PR_TRUE)
+ printf("nsTableColFrame::Paint\n");
+ return NS_OK;
+}
+
+
+NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext,
+ nsReflowMetrics& aDesiredSize,
+ const nsReflowState& aReflowState,
+ nsReflowStatus& aStatus)
+{
+ NS_ASSERTION(nsnull!=aPresContext, "bad arg");
+ aDesiredSize.width=0;
+ aDesiredSize.height=0;
+ if (nsnull!=aDesiredSize.maxElementSize)
+ {
+ aDesiredSize.maxElementSize->width=0;
+ aDesiredSize.maxElementSize->height=0;
+ }
+ aStatus = NS_FRAME_COMPLETE;
+ return NS_OK;
+}
+
+
+/* ----- static methods ------ */
+
+nsresult nsTableColFrame::NewFrame(nsIFrame** aInstancePtrResult,
+ nsIContent* aContent,
+ nsIFrame* aParent)
+{
+ NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
+ if (nsnull == aInstancePtrResult) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ nsIFrame* it = new nsTableColFrame(aContent, aParent);
+ if (nsnull == it) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ *aInstancePtrResult = it;
+ return NS_OK;
+}
+
diff --git a/mozilla/layout/tables/nsTableColFrame.h b/mozilla/layout/tables/nsTableColFrame.h
index e06d27b313f..ed72fb5a4a6 100644
--- a/mozilla/layout/tables/nsTableColFrame.h
+++ b/mozilla/layout/tables/nsTableColFrame.h
@@ -48,6 +48,12 @@ public:
/** set the index of the column this content object represents. must be >= 0 */
virtual void SetColumnIndex (int aColIndex);
+ /** convenience method, calls into cellmap */
+ nsVoidArray * GetCells();
+
+ /** convenience method, calls into cellmap */
+ PRInt32 Count() const;
+
protected:
nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame);
@@ -55,10 +61,16 @@ protected:
~nsTableColFrame();
/** the starting index of the column (starting at 0) that this col object represents */
- PRInt32 mColIndex;
+ PRInt32 mColIndex;
/** the number of columns that the attributes of this column extend to */
- PRInt32 mRepeat;
+ PRInt32 mRepeat;
+
+ nscoord mMaxWidth;
+ nscoord mMinWidth;
+
+ nscoord mMaxEffectiveWidth;
+ nscoord mMinEffectiveWidth;
};
diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp
index c983dd63f94..95b9a970da0 100644
--- a/mozilla/layout/tables/nsTableFrame.cpp
+++ b/mozilla/layout/tables/nsTableFrame.cpp
@@ -29,14 +29,12 @@
#include "nsTableColGroupFrame.h"
#include "nsTableRowFrame.h"
#include "nsTableRowGroupFrame.h"
-#include "nsColLayoutData.h"
#include "BasicTableLayoutStrategy.h"
#include "nsIPresContext.h"
#include "nsCSSRendering.h"
#include "nsStyleConsts.h"
-#include "nsCellLayoutData.h"
#include "nsVoidArray.h"
#include "nsIPtr.h"
#include "nsIView.h"
@@ -269,7 +267,6 @@ void ColumnInfoCache::GetColumnsByType(const nsStyleUnit aType,
nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsContainerFrame(aContent, aParentFrame),
mCellMap(nsnull),
- mColumnLayoutData(nsnull),
mColCache(nsnull),
mColumnWidths(nsnull),
mTableLayoutStrategy(nsnull),
@@ -279,32 +276,11 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
{
}
-/**
- * Method to delete all owned objects assoicated
- * with the ColumnLayoutObject instance variable
- */
-void nsTableFrame::DeleteColumnLayoutData()
-{
- if (nsnull!=mColumnLayoutData)
- {
- PRInt32 numCols = mColumnLayoutData->Count();
- for (PRInt32 i = 0; iElementAt(i));
- delete colData;
- }
- delete mColumnLayoutData;
- mColumnLayoutData = nsnull;
- }
-}
-
nsTableFrame::~nsTableFrame()
{
if (nsnull!=mCellMap)
delete mCellMap;
- DeleteColumnLayoutData();
-
if (nsnull!=mColumnWidths)
delete [] mColumnWidths;
@@ -351,8 +327,7 @@ nsTableRowGroupFrame* nsTableFrame::NextRowGroupFrame(nsTableRowGroupFrame* aRow
PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
{
mColCount=0;
- nsIFrame * colGroup;
- ChildAt (0, (nsIFrame *&)colGroup);
+ nsIFrame * colGroup = mFirstChild;
while (nsnull!=colGroup)
{
const nsStyleDisplay *childDisplay;
@@ -379,8 +354,7 @@ PRInt32 nsTableFrame::GetRowCount ()
if (nsnull != mCellMap)
return mCellMap->GetRowCount();
- nsIFrame *child=nsnull;
- ChildAt(0, child);
+ nsIFrame *child=mFirstChild;
while (nsnull!=child)
{
const nsStyleDisplay *childDisplay;
@@ -393,6 +367,35 @@ PRInt32 nsTableFrame::GetRowCount ()
}
return rowCount;
}
+
+nsTableColFrame * nsTableFrame::GetColFrame(PRInt32 aColIndex)
+{
+ nsTableColFrame *result = nsnull;
+ if (nsnull!=mCellMap)
+ {
+ result = mCellMap->GetColumnFrame(aColIndex);
+ }
+ return result;
+}
+
+// can return nsnull
+nsTableCellFrame * nsTableFrame::GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex)
+{
+ nsTableCellFrame *result = nsnull;
+ if (nsnull!=mCellMap)
+ {
+ CellData * cellData = mCellMap->GetCellAt(aRowIndex, aColIndex);
+ if (nsnull!=cellData)
+ {
+ result = cellData->mCell;
+ if (nsnull==result)
+ result = cellData->mRealCell->mCell;
+ }
+ }
+ return result;
+}
+
+
// return the rows spanned by aCell starting at aRowIndex
// note that this is different from just the rowspan of aCell
// (that would be GetEffectiveRowSpan (indexOfRowThatContains_aCell, aCell)
@@ -413,13 +416,6 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
return rowSpan;
}
-
-// returns the actual cell map, not a copy, so don't mess with it!
-nsCellMap* nsTableFrame::GetCellMap() const
-{
- return mCellMap;
-}
-
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTableFrame::ResetCellMap ()
{
@@ -449,10 +445,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
PRInt32 actualColumns = 0;
nsTableColGroupFrame *lastColGroupFrame = nsnull;
- nsIFrame * childFrame=nsnull;
nsIFrame * firstRowGroupFrame=nsnull;
nsIFrame * prevSibFrame=nsnull;
- ChildAt (0, (nsIFrame *&)childFrame);
+ nsIFrame * childFrame=mFirstChild;
while (nsnull!=childFrame)
{
const nsStyleDisplay *childDisplay;
@@ -795,35 +790,67 @@ void nsTableFrame::GrowCellMap (PRInt32 aColCount)
*/
void nsTableFrame::ListColumnLayoutData(FILE* out, PRInt32 aIndent) const
{
- // if this is a continuing frame, there will be no output
- if (nsnull!=mColumnLayoutData)
+ nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
+ if (this!=firstInFlow)
+ {
+ firstInFlow->ListColumnLayoutData(out, aIndent);
+ return;
+ }
+
+ if (nsnull!=mCellMap)
{
fprintf(out,"Column Layout Data \n");
- PRInt32 numCols = mColumnLayoutData->Count();
- for (PRInt32 i = 0; iGetColCount();
+ PRInt32 numRows = mCellMap->GetRowCount();
+ for (PRInt32 colIndex = 0; colIndexElementAt(i));
+ for (PRInt32 indent = aIndent; --indent >= 0; )
+ fputs(" ", out);
+ fprintf(out,"Column Data [%d] \n",colIndex);
+ for (PRInt32 rowIndex = 0; rowIndex < numRows; rowIndex++)
+ {
+ nsTableCellFrame *cellFrame = mCellMap->GetCellFrameAt(rowIndex, colIndex);
+ PRInt32 rowIndent;
+ for (rowIndent = aIndent+2; --rowIndent >= 0; ) fputs(" ", out);
+ fprintf(out,"Cell Data [%d] \n",rowIndex);
+ for (rowIndent = aIndent+2; --rowIndent >= 0; ) fputs(" ", out);
+ nsMargin margin;
+ cellFrame->GetMargin(margin);
+ fprintf(out,"Margin -- Top: %d Left: %d Bottom: %d Right: %d \n",
+ NS_TWIPS_TO_POINTS_INT(margin.top),
+ NS_TWIPS_TO_POINTS_INT(margin.left),
+ NS_TWIPS_TO_POINTS_INT(margin.bottom),
+ NS_TWIPS_TO_POINTS_INT(margin.right));
+
+ for (rowIndent = aIndent+2; --rowIndent >= 0; ) fputs(" ", out);
- for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
- fprintf(out,"Column Data [%d] \n",i);
- colData->List(out,aIndent+2);
+ nscoord top,left,bottom,right;
+ /*
+ top = (mBorderFrame[NS_SIDE_TOP] ? cellFrame->GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_TOP], NS_SIDE_TOP) : 0);
+ left = (mBorderFrame[NS_SIDE_LEFT] ? cellFrame->GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_LEFT], NS_SIDE_LEFT) : 0);
+ bottom = (mBorderFrame[NS_SIDE_BOTTOM] ? cellFrame->GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_BOTTOM], NS_SIDE_BOTTOM) : 0);
+ right = (mBorderFrame[NS_SIDE_RIGHT] ? cellFrame->GetBorderWidth((nsIFrame*)mBorderFrame[NS_SIDE_RIGHT], NS_SIDE_RIGHT) : 0);
+ */
+
+ fprintf(out,"Border -- Top: %d Left: %d Bottom: %d Right: %d \n",
+ NS_TWIPS_TO_POINTS_INT(top),
+ NS_TWIPS_TO_POINTS_INT(left),
+ NS_TWIPS_TO_POINTS_INT(bottom),
+ NS_TWIPS_TO_POINTS_INT(right));
+ }
}
}
}
/**
- * For the TableCell in CellData, find the CellLayoutData assocated
- * and add it to the list
-**/
+ * For the TableCell in CellData, add it to the list
+ */
void nsTableFrame::AppendLayoutData(nsVoidArray* aList, nsTableCellFrame* aTableCell)
{
-
if (aTableCell != nsnull)
{
- nsCellLayoutData* layoutData = GetCellLayoutData(aTableCell);
- if (layoutData != nsnull)
- aList->AppendElement((void*)layoutData);
+ aList->AppendElement((void*)aTableCell);
}
}
@@ -996,9 +1023,7 @@ void nsTableFrame::RecalcLayoutData()
r++;
}
- nsCellLayoutData* cellLayoutData = GetCellLayoutData(cell);
- if (cellLayoutData != nsnull)
- cellLayoutData->RecalcLayoutData(this,boundaryCells);
+ cell->RecalcLayoutData(this,boundaryCells);
}
}
}
@@ -1310,7 +1335,7 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
if (nsnull!=prevKidFrame)
prevKidFrame->GetNextSibling(kidFrame); // no need to check for an error, just see if it returned null...
else
- ChildAt(0, kidFrame);
+ kidFrame=mFirstChild;
// if this is the first time, allocate the frame
if (nsnull==kidFrame)
@@ -2210,11 +2235,10 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
if (gsDebug)
printf ("BalanceColumnWidths...\n");
- nsVoidArray *columnLayoutData = GetColumnLayoutData();
- if (nsnull==columnLayoutData)
+ if (nsnull==mCellMap)
return; // we don't have any information yet, so we can't do any useful work
- PRInt32 numCols = columnLayoutData->Count();
+ PRInt32 numCols = mCellMap->GetColCount();
if (nsnull==mColumnWidths)
{
mColumnWidths = new PRInt32[numCols];
@@ -2233,9 +2257,22 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
// need to figure out the overall table width constraint
// default case, get 100% of available space
+
+ // begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED!
+ nsIFrame * outerTableFrame = nsnull;
+ const nsStylePosition* position;
+ GetGeometricParent(outerTableFrame);
+ outerTableFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)position));
+ // end REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED
+
+
+
PRInt32 maxWidth;
+ /*
const nsStylePosition* position =
(const nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position);
+ use this line when tableFrame contains its own position style info
+ */
switch (position->mWidth.GetUnit()) {
case eStyleUnit_Coord:
maxWidth = position->mWidth.GetCoordValue();
@@ -2251,7 +2288,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
// XXX for now these fall through
default:
-
maxWidth = aMaxSize.width;
break;
}
@@ -2293,16 +2329,20 @@ void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext)
if (gsDebug==PR_TRUE) printf ("SetTableWidth...");
PRInt32 tableWidth = 0;
- nsVoidArray *columnLayoutData = GetColumnLayoutData();
- if (nsnull==columnLayoutData)
+ if (nsnull==mCellMap)
return; // no info, so nothing to do
- PRInt32 numCols = columnLayoutData->Count();
- for (PRInt32 i = 0; iGetColCount();
+ for (PRInt32 colIndex = 0; colIndexmColumnLayoutData)
+ if (nsnull!=firstInFlow->mCellMap)
{ // hooray, we get to do this the easy way because the info is cached
- nsColLayoutData * colData = (nsColLayoutData *)
- (firstInFlow->mColumnLayoutData->ElementAt(aColIndex));
- NS_ASSERTION(nsnull != colData, "bad column data");
- aColFrame = colData->GetColFrame();
+ aColFrame = firstInFlow->mCellMap->GetColumnFrame(aColIndex);
NS_ASSERTION(nsnull!=aColFrame, "bad col frame");
}
else
@@ -2443,31 +2480,46 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
mColCache = new ColumnInfoCache(mColCount);
nsIFrame * childFrame = mFirstChild;
while (nsnull!=childFrame)
- { // for every child, if it's a col group then get the columns
+ { // in this loop, we cache column info and set column style info from cells in first row
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
- if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
+
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ { // if it's a col group then get the columns and cache them in the CellMap
+ nsTableColFrame *colFrame=nsnull;
+ childFrame->FirstChild((nsIFrame *&)colFrame);
+ while (nsnull!=colFrame)
+ {
+ mCellMap->AppendColumnFrame(colFrame);
+ colFrame->GetNextSibling((nsIFrame *&)colFrame);
+ }
+ }
+ else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
- { // for every cell in every row, call SetCellLayoutData with the cached info
- // QQQ we can probably just leave the info in the table cell frame, not cache it here
+ { // if it's a row group, get the cells and set the column style if appropriate
nsIFrame *rowFrame;
- childFrame->ChildAt(0, rowFrame);
- nsIFrame *cellFrame;
- rowFrame->ChildAt(0, cellFrame);
- while (nsnull!=cellFrame)
+ childFrame->FirstChild(rowFrame);
+ if (nsnull!=rowFrame)
{
- /* this is the first time we are guaranteed to have both the cell frames
- * and the column frames, so it's a good time to
- * set the column style from the cell's width attribute (if this is the first row)
- */
- SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
- cellFrame->GetNextSibling(cellFrame);
+ nsIFrame *cellFrame;
+ rowFrame->FirstChild(cellFrame);
+ while (nsnull!=cellFrame)
+ {
+ /* this is the first time we are guaranteed to have both the cell frames
+ * and the column frames, so it's a good time to
+ * set the column style from the cell's width attribute (if this is the first row)
+ */
+ SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
+ cellFrame->GetNextSibling(cellFrame);
+ }
}
}
childFrame->GetNextSibling(childFrame);
}
+
// second time through, set column cache info for each column
+ // we can't do this until the loop above has set the column style info from the cells in the first row
childFrame = mFirstChild;
while (nsnull!=childFrame)
{ // for every child, if it's a col group then get the columns
@@ -2476,7 +2528,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
{
nsTableColFrame *colFrame=nsnull;
- childFrame->ChildAt(0, (nsIFrame *&)colFrame);
+ childFrame->FirstChild((nsIFrame *&)colFrame);
while (nsnull!=colFrame)
{ // for every column, create an entry in the column cache
// assumes that the col style has been twiddled to account for first cell width attribute
@@ -2489,176 +2541,14 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
- { // for every cell in every row, call SetCellLayoutData with the cached info
- // QQQ we can probably just leave the info in the table cell frame, not cache it here
- nsIFrame *rowFrame;
- childFrame->ChildAt(0, rowFrame);
- while (nsnull!=rowFrame)
- {
- nsIFrame *cellFrame;
- rowFrame->ChildAt(0, cellFrame);
- while (nsnull!=cellFrame)
- {
- nsCellLayoutData *cld = ((nsTableCellFrame*)cellFrame)->GetCellLayoutData();
- SetCellLayoutData(aPresContext, cld, (nsTableCellFrame*)cellFrame);
- cellFrame->GetNextSibling(cellFrame);
- }
- rowFrame->GetNextSibling(rowFrame);
- }
+ {
+ break; // once we hit a row group, we're done
}
childFrame->GetNextSibling(childFrame);
}
}
}
-// nsnull is a valid return value. This is for empty tables.
-nsVoidArray * nsTableFrame::GetColumnLayoutData()
-{
- nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
- NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
- return firstInFlow->mColumnLayoutData;
-}
-
-/** Associate aData with the cell at (aRow,aCol)
- * @return PR_TRUE if the data was successfully associated with a Cell
- * PR_FALSE if there was an error, such as aRow or aCol being invalid
- */
-PRBool nsTableFrame::SetCellLayoutData(nsIPresContext* aPresContext,
- nsCellLayoutData * aData, nsTableCellFrame *aCell)
-{
- NS_ASSERTION(nsnull != aPresContext, "bad arg aPresContext");
- NS_ASSERTION(nsnull != aData, "bad arg aData");
- NS_ASSERTION(nsnull != aCell, "bad arg aCell");
-
- PRBool result = PR_TRUE;
-
- nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
- NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
- if (this!=firstInFlow)
- result = firstInFlow->SetCellLayoutData(aPresContext, aData, aCell);
- else
- {
- if ((kPASS_FIRST==GetReflowPass()) || (kPASS_INCREMENTAL==GetReflowPass()))
- {
- if (nsnull==mColumnLayoutData)
- {
- PRInt32 rows = GetRowCount();
- mColumnLayoutData = new nsVoidArray();
- NS_ASSERTION(nsnull != mColumnLayoutData, "bad alloc");
- PRInt32 tableKidCount = mContent->ChildCount();
- nsIFrame * colGroupFrame = mFirstChild;
- for (PRInt32 i=0; iGetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
- if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
- {
- nsTableColFrame *colFrame=nsnull;
- colGroupFrame->ChildAt(0, (nsIFrame *&)colFrame);
- while (nsnull!=colFrame)
- {
- // TODO: unify these 2 kinds of column data
- // TODO: cache more column data, like the mWidth.GetUnit and what its value
- nsColLayoutData *colData = new nsColLayoutData(colFrame, rows);
- mColumnLayoutData->AppendElement((void *)colData);
- colFrame->GetNextSibling((nsIFrame *&)colFrame);
- }
- }
- // can't have col groups after row groups, so stop if you find a row group
- else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
- NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
- NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
- {
- break;
- }
- i++;
- ChildAt(i, colGroupFrame); // can't use colGroupFrame->GetNextSibling because it hasn't been set yet
- }
- }
-
- PRInt32 firstColIndex = aCell->GetColIndex();
- nsTableRowFrame *row;
- aCell->GetGeometricParent((nsIFrame*&)row);
- PRInt32 rowIndex = row->GetRowIndex();
- PRInt32 colSpan = aCell->GetColSpan();
- nsColLayoutData * colData = (nsColLayoutData *)(mColumnLayoutData->ElementAt(firstColIndex));
- nsVoidArray *col = colData->GetCells();
- if (gsDebugCLD) printf (" ~ SetCellLayoutData with row = %d, firstCol = %d, colSpan = %d, colData = %ld, col=%ld\n",
- rowIndex, firstColIndex, colSpan, colData, col);
- /* this logic looks wrong wrong wrong
- it seems to add an entries in col (the array of cells for a column) for aCell
- based on colspan. This is weird, because you would expect one entry in each
- column spanned for aCell, not multiple entries in the same col.
- */
- for (PRInt32 i=0; iGetMaxElementSize();
- nsSize partialCellSize(*cellSize);
- partialCellSize.width = (cellSize->width)/colSpan;
- // This method will copy the nsReflowMetrics pointed at by aData->GetDesiredSize()
- nsCellLayoutData * kidLayoutData = new nsCellLayoutData(aData->GetCellFrame(),
- aData->GetDesiredSize(),
- &partialCellSize);
- NS_ASSERTION(col->Count() > rowIndex, "unexpected count");
- if (gsDebugCLD) printf (" ~ replacing rowIndex = %d\n", rowIndex);
- nsCellLayoutData* data = (nsCellLayoutData*)col->ElementAt(rowIndex);
- col->ReplaceElementAt((void *)kidLayoutData, rowIndex);
- if (data != nsnull) {
- delete data;
- }
- }
- }
- else
- result = PR_FALSE;
- }
-
- return result;
-}
-
-/** Get the layout data associated with the cell at (aRow,aCol)
- * @return nsnull if there was an error, such as aRow or aCol being invalid
- * otherwise, the data is returned.
- */
-nsCellLayoutData * nsTableFrame::GetCellLayoutData(nsTableCellFrame *aCell)
-{
- NS_ASSERTION(nsnull != aCell, "bad arg");
-
- nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
- NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
- nsCellLayoutData *result = nsnull;
- if (this!=firstInFlow)
- result = firstInFlow->GetCellLayoutData(aCell);
- else
- {
- if (nsnull!=mColumnLayoutData)
- {
- PRInt32 firstColIndex = aCell->GetColIndex();
- nsColLayoutData * colData = (nsColLayoutData *)(mColumnLayoutData->ElementAt(firstColIndex));
- nsTableRowFrame *rowFrame;
- aCell->GetGeometricParent((nsIFrame *&)rowFrame);
- PRInt32 rowIndex = rowFrame->GetRowIndex();
- result = colData->ElementAt(rowIndex);
-
-#ifdef NS_DEBUG
- // Do some sanity checking
- if (nsnull != result) {
- nsIContent* inputContent;
- nsIContent* resultContent;
- result->GetCellFrame()->GetContent(resultContent);
- aCell->GetContent(inputContent);
- NS_ASSERTION(resultContent == inputContent, "unexpected cell");
- NS_IF_RELEASE(inputContent);
- NS_IF_RELEASE(resultContent);
- }
-#endif
-
- }
- }
- return result;
-}
-
-
-
PRInt32 nsTableFrame::GetReflowPass() const
{
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
@@ -2698,7 +2588,7 @@ nsTableFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
// add headers and footers to cf
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
nsIFrame * rg = nsnull;
- firstInFlow->ChildAt(0, rg);
+ firstInFlow->FirstChild(rg);
NS_ASSERTION (nsnull!=rg, "previous frame has no children");
nsIAtom * tHeadTag = NS_NewAtom(nsTablePart::kRowGroupHeadTagString); // tHeadTag: REFCNT++
nsIAtom * tFootTag = NS_NewAtom(nsTablePart::kRowGroupFootTagString); // tFootTag: REFCNT++
@@ -2758,9 +2648,8 @@ PRInt32 nsTableFrame::GetColumnWidth(PRInt32 aColIndex)
{
NS_ASSERTION(nsnull!=mColumnWidths, "illegal state");
#ifdef DEBUG
- nsVoidArray *cld = GetColumnLayoutData();
- NS_ASSERTION(nsnull!=cld, "no column layout data");
- PRInt32 numCols = cld->Count();
+ NS_ASSERTION(nsnull!=mCellMap, "no column layout data");
+ PRInt32 numCols = mCellMap->GetColCount();
NS_ASSERTION (numCols > aColIndex, "bad arg, col index out of bounds");
#endif
if (nsnull!=mColumnWidths)
@@ -2770,11 +2659,6 @@ PRInt32 nsTableFrame::GetColumnWidth(PRInt32 aColIndex)
//printf("GET_COL_WIDTH: %p, FIF=%p getting col %d and returning %d\n", this, firstInFlow, aColIndex, result);
// XXX hack
-#if 0
- if (result <= 0) {
- result = 100;
- }
-#endif
return result;
}
@@ -2936,9 +2820,7 @@ NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin&
if (nsnull != aKidFrame)
{
- nsCellLayoutData* layoutData = GetCellLayoutData(aKidFrame);
- if (layoutData)
- result = layoutData->GetMargin(aMargin);
+ result = aKidFrame->GetMargin(aMargin);
}
return result;
@@ -3218,37 +3100,6 @@ PRBool nsTableFrame::TableIsAutoWidth(nsTableFrame *aTableFrame,
return result;
}
-/* valuable code not yet used anywhere
-
- // since the table is a specified width, we need to expand the columns to fill the table
- nsVoidArray *columnLayoutData = GetColumnLayoutData();
- PRInt32 numCols = columnLayoutData->Count();
- PRInt32 spaceUsed = 0;
- for (PRInt32 colIndex = 0; colIndexElementAt(colIndex));
- nsTableColPtr col = colData->GetCol(); // col: ADDREF++
- nsStyleMolecule* colStyle =
- (nsStyleMolecule*)mStyleContext->GetData(eStyleStruct_Molecule);
- if (PR_TRUE==IsProportionalWidth(colStyle))
- {
- PRInt32 percentage = (100*mColumnWidths[colIndex]) / aMaxWidth;
- PRInt32 additionalSpace = (spaceRemaining*percentage)/100;
- mColumnWidths[colIndex] += additionalSpace;
- additionalSpaceAdded += additionalSpace;
- }
- }
- if (spaceUsed+additionalSpaceAdded < aMaxTableWidth)
- mColumnWidths[numCols-1] += (aMaxTableWidth - (spaceUsed+additionalSpaceAdded));
- }
-*/
-
// For Debugging ONLY
NS_METHOD nsTableFrame::MoveTo(nscoord aX, nscoord aY)
{
diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h
index 9d15f173543..a87477a86e6 100644
--- a/mozilla/layout/tables/nsTableFrame.h
+++ b/mozilla/layout/tables/nsTableFrame.h
@@ -23,7 +23,6 @@
#include "nsStyleCoord.h"
class nsCellMap;
-class nsCellLayoutData;
class nsVoidArray;
class nsTableCellFrame;
class nsTableColFrame;
@@ -42,29 +41,6 @@ struct nsStyleSpacing;
extern const nsIID kTableFrameCID;
-/** Data stored by nsCellMap to rationalize rowspan and colspan cells.
- * if mCell is null then mRealCell will be the rowspan/colspan source
- * in addition, if fOverlap is non-null then it will point to the
- * other cell that overlaps this position
- * @see nsCellMap
- * @see nsTableFrame::BuildCellMap
- * @see nsTableFrame::GrowCellMap
- * @see nsTableFrame::BuildCellIntoMap
- *
- */
-class CellData
-{
-public:
- nsTableCellFrame *mCell;
- CellData *mRealCell;
- CellData *mOverlap;
-
- CellData();
-
- ~CellData();
-};
-
-
/* ============================================================================ */
/** nsTableFrame maps the inner portion of a table (everything except captions.)
@@ -153,36 +129,12 @@ public:
*/
NS_METHOD GetColumnFrame(PRInt32 aColIndex, nsTableColFrame *&aColFrame);
- /** return the column layout data for this inner table frame.
- * if this is a continuing frame, return the first-in-flow's column layout data.
- * @return the column layout data array, or null if there is no info yet.
- */
- virtual nsVoidArray *GetColumnLayoutData();
-
- /** Associate aData with the cell at (aRow,aCol)
- *
- * @param aPresContext -- used to resolve style when initializing caches
- * @param aData -- the info to cache
- * @param aCell -- the content object for which layout info is being cached
- *
- * @return PR_TRUE if the data was successfully associated with a Cell
- * PR_FALSE if there was an error, such as aRow or aCol being invalid
- */
- virtual PRBool SetCellLayoutData(nsIPresContext * aPresContext,
- nsCellLayoutData * aData,
- nsTableCellFrame * aCell);
-
- /** Get the layout data associated with the cell at (aRow,aCol)
- * @return PR_NULL if there was an error, such as aRow or aCol being invalid
- * otherwise, the data is returned.
- */
- virtual nsCellLayoutData * GetCellLayoutData(nsTableCellFrame *aCell);
-
+
/**
* DEBUG METHOD
*
*/
- virtual void ListColumnLayoutData(FILE* out = stdout, PRInt32 aIndent = 0) const;
+ //virtual void ListColumnLayoutData(FILE* out = stdout, PRInt32 aIndent = 0) const;
/** return the width of the column at aColIndex */
@@ -236,11 +188,6 @@ protected:
/** destructor, responsible for mColumnLayoutData and mColumnWidths */
virtual ~nsTableFrame();
- /** helper method to delete contents of mColumnLayoutData
- * should be called with care (ie, only by destructor)
- */
- virtual void DeleteColumnLayoutData();
-
/** first pass of ResizeReflow.
* lays out all table content with aMaxSize(NS_UNCONSTRAINEDSIZE,NS_UNCONSTRAINEDSIZE) and
* a non-null aMaxElementSize so we get all the metrics we need to do column balancing.
@@ -380,6 +327,16 @@ protected:
*/
virtual void ResetCellMap ();
+ /** for debugging only
+ * prints out information about the cell map
+ */
+ void DumpCellMap() const;
+
+ /** for debugging only
+ * prints out info about the table layout state, printing columns and their cells
+ */
+ void ListColumnLayoutData(FILE* out, PRInt32 aIndent) const;
+
/** ResetColumns is called when the column structure of the table is changed.
* Call with caution, only when adding or removing columns, changing
* column attributes, changing the rowspan or colspan attribute of a cell, etc.
@@ -418,13 +375,6 @@ protected:
*/
virtual nsTableRowGroupFrame* NextRowGroupFrame (nsTableRowGroupFrame*);
- /** returns the number of rows in this table.
- * if mCellMap has been created, it is asked for the number of rows.
- * otherwise, the content is enumerated and the rows are counted.
- */
- virtual PRInt32 GetRowCount();
-
-
/** return the number of columns as specified by the input.
* has 2 side effects:
* calls SetStartColumnIndex on each nsTableColumn
@@ -432,9 +382,18 @@ protected:
*/
virtual PRInt32 GetSpecifiedColumnCount ();
-public:
- virtual void DumpCellMap() const;
- virtual nsCellMap* GetCellMap() const;
+public: /* ----- Cell Map public methods ----- */
+
+ /** returns the number of rows in this table.
+ * if mCellMap has been created, it is asked for the number of rows.
+ * otherwise, the content is enumerated and the rows are counted.
+ */
+ virtual PRInt32 GetRowCount();
+
+ nsTableColFrame * GetColFrame(PRInt32 aColIndex);
+
+ nsTableCellFrame * GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex);
+
private:
@@ -446,9 +405,7 @@ private:
*/
enum {kPASS_UNDEFINED=0, kPASS_FIRST=1, kPASS_SECOND=2, kPASS_THIRD=3, kPASS_INCREMENTAL=4};
- nsVoidArray *mColumnLayoutData; // array of array of cellLayoutData's
PRInt32 *mColumnWidths; // widths of each column
- //TODO: move all column info into this object
ColumnInfoCache *mColCache; // cached information about the table columns
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit
PRInt32 mPass; // which Reflow pass are we currently in?
diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp
index 8505f4a296d..06480059afc 100644
--- a/mozilla/layout/tables/nsTableRowFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowFrame.cpp
@@ -25,8 +25,6 @@
#include "nsTableFrame.h"
#include "nsTableColFrame.h"
#include "nsTableCellFrame.h"
-#include "nsCellLayoutData.h"
-#include "nsColLayoutData.h"
#include "nsIView.h"
#include "nsIPtr.h"
#include "nsIReflowCommand.h"
@@ -37,6 +35,7 @@ NS_DEF_PTR(nsIStyleContext);
static PRBool gsDebug1 = PR_FALSE;
static PRBool gsDebug2 = PR_FALSE;
//#define NOISY
+//#define NOISY_FLOW
#else
static const PRBool gsDebug1 = PR_FALSE;
static const PRBool gsDebug2 = PR_FALSE;
@@ -51,6 +50,9 @@ struct RowReflowState {
// The body's available size (computed from the body's parent)
nsSize availSize;
+ // the running x-offset
+ nscoord x;
+
// Height of tallest cell (excluding cells with rowspan > 1)
nscoord maxCellHeight; // just the height of the cell frame
nscoord maxCellVertSpace; // the maximum MAX(cellheight + topMargin + bottomMargin)
@@ -68,6 +70,7 @@ struct RowReflowState {
maxCellHeight = 0;
maxCellVertSpace = 0;
tableFrame = aTableFrame;
+ x=0;
}
~RowReflowState() {
@@ -111,12 +114,12 @@ nsTableRowFrame::DidReflow(nsIPresContext& aPresContext,
PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(mRowIndex, cellFrame);
if (1==rowSpan)
{
- // Resize the cell's height
+ // resize the cell's height
nsSize cellFrameSize;
cellFrame->GetSize(cellFrameSize);
cellFrame->SizeTo(cellFrameSize.width, cellHeight);
- // Realign cell content based on the new height
+ // realign cell content based on the new height
cellFrame->VerticallyAlignChild(&aPresContext);
}
@@ -287,6 +290,9 @@ void nsTableRowFrame::PlaceChild(nsIPresContext* aPresContext,
// Place and size the child
aKidFrame->SetRect(aKidRect);
+ // update the running total for the row width
+ aState.x += aKidRect.width;
+
// Update the maximum element size
PRInt32 rowSpan = ((nsTableCellFrame*)aKidFrame)->GetRowSpan();
if (nsnull != aMaxElementSize)
@@ -328,6 +334,8 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
NS_PRECONDITION(nsnull != mFirstChild, "no children");
nsSize kidMaxElementSize;
+ PRBool result = PR_TRUE;
+ PRInt32 prevColIndex = -1; // remember the col index of the previous cell to handle rowspans into this row
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
&kidMaxElementSize : nsnull;
nscoord maxCellTopMargin = 0;
@@ -335,6 +343,13 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
// Reflow each of our existing cell frames
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
+ nsSize kidAvailSize(aState.availSize);
+ if (0>=kidAvailSize.height)
+ kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
+
+ nsReflowMetrics desiredSize(pKidMaxElementSize);
+ desiredSize.width=desiredSize.height=desiredSize.ascent=desiredSize.descent=0;
+
// Get the frame's margins, and compare the top and bottom margin
// against our current max values
nsMargin kidMargin;
@@ -344,15 +359,49 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
if (kidMargin.bottom > maxCellBottomMargin)
maxCellBottomMargin = kidMargin.bottom;
+ // Figure out the amount of available size for the child (subtract
+ // off the top margin we are going to apply to it)
+
+ //XXX TROY??? unconstrainedHeight was removed from aState, what should happen here?
+ /*
+ if (PR_FALSE == aState.unconstrainedHeight)
+ {
+ kidAvailSize.height -= kidMargin.top + kidMargin.bottom;
+ }
+ */
+
// left and right margins already taken into account by table layout strategy
- // Compute the x-origin for the child
- //
- // XXX Having to re-compute the value each time from scratch is very inefficent...
- nscoord x = ComputeCellXOffset(aState, kidFrame, kidMargin);
+ // Compute the x-origin for the child, taking into account straddlers (cells from prior
+ // rows with rowspans > 1)
+ PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
+ if (prevColIndex != (cellColIndex-1))
+ { // if this cell is not immediately adjacent to the previous cell, factor in missing col info
+ for (PRInt32 colIndex=prevColIndex+1; colIndexGetColumnWidth(colIndex);
+ aState.x += kidMargin.left + kidMargin.right;
+ }
+ }
+ aState.x += kidMargin.left;
+
+ // at this point, we know the column widths.
+ // so we get the avail width from the known column widths
+ PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
+ nscoord availWidth = 0;
+ for (PRInt32 numColSpan=0; numColSpanGetColumnWidth(cellColIndex+numColSpan);
+ if (0GetPriorAvailWidth())
{
// Always let the cell be as high as it wants. We ignore the height that's
// passed in and always place the entire row. Let the row group decide
// whether we fit or wehther the entire row is pushed
nsSize kidAvailSize(availWidth, NS_UNCONSTRAINEDSIZE);
-
+
// Reflow the child
kidFrame->WillReflow(*aPresContext);
- kidFrame->MoveTo(x, kidMargin.top);
+ kidFrame->MoveTo(aState.x, kidMargin.top);
kidAvailSize.width = availWidth;
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize,
eReflowReason_Resize);
@@ -393,12 +441,12 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
}
else
{
- nsSize priorSize = ((nsTableCellFrame *)kidFrame)->GetPriorDesiredSize();
+ nsSize priorSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
desiredSize.width = priorSize.width;
desiredSize.height = priorSize.height;
}
- // Place the child after taking into account its margin and attributes
+ // Place the child after taking into account it's margin and attributes
nscoord specifiedHeight = 0;
nscoord cellHeight = desiredSize.height;
nsIStyleContextPtr kidSC;
@@ -423,19 +471,20 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
// begin special Nav4 compatibility code
if (0==cellWidth)
{
- PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
}
// end special Nav4 compatibility code
// Place the child
- nsRect kidRect (x, kidMargin.top, cellWidth, cellHeight);
+ nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
pKidMaxElementSize);
+ aState.x += kidMargin.right; // add in right margin only after cell has been placed
// Get the next child
kidFrame->GetNextSibling(kidFrame);
+
}
SetMaxChildHeight(aState.maxCellHeight,maxCellTopMargin, maxCellBottomMargin); // remember height of tallest child who doesn't have a row span
@@ -448,42 +497,6 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
return NS_OK;
}
-// Compute the x-origin for the child by summing up the width of each
-// prior column. This correctly handles cells from prior rows with rowspans
-// > 1
-nscoord nsTableRowFrame::ComputeCellXOffset(const RowReflowState& aState,
- nsIFrame* aKidFrame,
- const nsMargin& aKidMargin) const
-{
- nscoord x = aKidMargin.left;
- PRInt32 cellColIndex = ((nsTableCellFrame *)aKidFrame)->GetColIndex();
-
- for (PRInt32 colIndex = 0; colIndex < cellColIndex; colIndex++)
- {
- x += aState.tableFrame->GetColumnWidth(colIndex);
- }
-
- return x;
-}
-
-// Computes the avail width for the cell. Takes into account column
-// spans
-nscoord nsTableRowFrame::ComputeCellAvailWidth(const RowReflowState& aState,
- nsIFrame* aKidFrame) const
-{
- nscoord availWidth = 0;
- nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame *)aKidFrame);
- PRInt32 cellStartingCol = ((nsTableCellFrame *)aKidFrame)->GetColIndex();
- PRInt32 cellColSpan = ((nsTableCellFrame *)aKidFrame)->GetColSpan();
-
- for (PRInt32 numColSpan = 0; numColSpan < cellColSpan; numColSpan++)
- {
- availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol + numColSpan);
- }
-
- return availWidth;
-}
-
/**
* Called for the initial reflow. Creates each table cell frame, and
* reflows it to gets its minimum and maximum sizes
@@ -570,13 +583,10 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
kidFrame->WillReflow(*aPresContext);
status = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState);
+ ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize);
+ ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "unexpected child reflow status");
- // Allocate and set the cell layout data
- nsCellLayoutData *kidLayoutData = new nsCellLayoutData((nsTableCellFrame *)kidFrame,
- &kidSize, &kidMaxElementSize);
- ((nsTableCellFrame *)kidFrame)->SetCellLayoutData(kidLayoutData);
-
if (gsDebug1)
{
printf("reflow of cell returned result = %s with desired=%d,%d, min = %d,%d\n",
@@ -630,13 +640,12 @@ nsresult nsTableRowFrame::RecoverState(RowReflowState& aState,
for (nsIFrame* frame = mFirstChild; frame != aKidFrame;) {
PRInt32 rowSpan = ((nsTableCellFrame*)frame)->GetRowSpan();
if (mMinRowSpan == rowSpan) {
- // XXX This isn't quite right. We also need to check whether the cell
- // has a height property that affects the cell...
- nsSize desiredSize = ((nsTableCellFrame *)frame)->GetPriorDesiredSize();
-
+ nsRect rect;
+ frame->GetRect(rect);
+
// Update maxCellHeight
- if (desiredSize.height > aState.maxCellHeight) {
- aState.maxCellHeight = desiredSize.height;
+ if (rect.height > aState.maxCellHeight) {
+ aState.maxCellHeight = rect.height;
}
// Update maxCellVertHeight
@@ -644,18 +653,14 @@ nsresult nsTableRowFrame::RecoverState(RowReflowState& aState,
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, margin) == NS_OK)
{
- nscoord height = desiredSize.height + margin.top + margin.bottom;
+ nscoord height = rect.height + margin.top + margin.bottom;
if (height > aState.maxCellVertSpace) {
aState.maxCellVertSpace = height;
}
}
}
- // XXX We also need to recover the max element size if requested by the
- // caller...
- //
- // We should be using GetReflowMetrics() to get information from the
- // table cell, and that will include the max element size...
+ // XXX We also need to recover the max element size...
// Remember the frame that precedes aKidFrame
prevKidFrame = frame;
@@ -687,20 +692,30 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// Recover our reflow state
RecoverState(aState, kidFrame);
- // Get the frame's margins
+ // Figure out the amount of available space for the child
nsMargin kidMargin;
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
// Figure out the amount of available space for the child
// XXX Shakey...
- nsSize kidAvailSize(aState.availSize);
+ nsSize kidAvailSize(aState.availSize); // XXX: top and bottom margins?
- // Compute the x-origin for the child, taking into account straddlers (cells
- // from prior rows with rowspans > 1)
- nscoord x = ComputeCellXOffset(aState, kidFrame, kidMargin);
+ // Compute the x-origin for the child, taking into account straddlers (cells from prior
+ // rows with rowspans > 1)
+ nscoord x = kidMargin.left;
+ PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
+ for (PRInt32 colIndex=0; colIndexGetColumnWidth(colIndex);
+ }
- // Compute the cell avail width from the column widths
- nscoord availWidth = ComputeCellAvailWidth(aState, kidFrame);
+ // at this point, we know the column widths.
+ // so we get the avail width from the known column widths
+ PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
+ PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
+ nscoord availWidth = 0;
+ for (PRInt32 numColSpan=0; numColSpanGetColumnWidth(cellStartingCol+numColSpan);
kidAvailSize.width = availWidth;
// Pass along the reflow command. Reflow the child with an unconstrained
@@ -726,23 +741,16 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
kidReflowState.maxSize.width = NS_UNCONSTRAINEDSIZE;
status = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState);
- // Update the cell layout data. Note that we need to do this for both
- // the data the cell maintains AND the data the table maintains...
- nsCellLayoutData *kidLayoutData = ((nsTableCellFrame *)kidFrame)->GetCellLayoutData();
-
- kidLayoutData->SetDesiredSize(&desiredSize);
- kidLayoutData->SetMaxElementSize(&kidMaxElementSize);
-
- kidLayoutData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame*)kidFrame);
- kidLayoutData->SetDesiredSize(&desiredSize);
- kidLayoutData->SetMaxElementSize(&kidMaxElementSize);
+ // Update the cell layout data.
+ ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(desiredSize);
+ ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
// Now reflow the cell again this time constraining the width
// XXX Ignore for now the possibility that the column width has changed...
kidReflowState.maxSize.width = availWidth;
status = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState);
- // Place the child after taking into account its margin and attributes
+ // Place the child after taking into account it's margin and attributes
nscoord specifiedHeight = 0;
nscoord cellHeight = desiredSize.height;
nsIStyleContextPtr kidSC;
@@ -767,7 +775,6 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// begin special Nav4 compatibility code
if (0==cellWidth)
{
- PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
}
// end special Nav4 compatibility code
@@ -781,8 +788,8 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// Now iterate over the remaining cells, and update our max cell
// height and our running x-offset
//
- // We don't have to re-position the x-origin of any of the child frames
- // that follow, because the column width hasn't changed...
+ // We don't have to re-position any of the child frames that follow, because
+ // the column width hasn't changed...
nscoord maxCellTopMargin = 0;
nscoord maxCellBottomMargin = 0;
kidFrame->GetNextSibling((nsIFrame*&)kidFrame);
@@ -791,11 +798,9 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsRect rect;
kidFrame->GetRect(rect);
if (mMinRowSpan == rowSpan) {
- nsSize desiredSize = ((nsTableCellFrame *)kidFrame)->GetPriorDesiredSize();
-
// Update maxCellHeight
- if (desiredSize.height > aState.maxCellHeight) {
- aState.maxCellHeight = desiredSize.height;
+ if (rect.height > aState.maxCellHeight) {
+ aState.maxCellHeight = rect.height;
}
// Update maxCellVertHeight
@@ -803,7 +808,7 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
{
- nscoord height = desiredSize.height + margin.top + margin.bottom;
+ nscoord height = rect.height + margin.top + margin.bottom;
if (height > aState.maxCellVertSpace) {
aState.maxCellVertSpace = height;
}
@@ -899,16 +904,22 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
return result;
}
+
+
NS_METHOD
nsTableRowFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIStyleContext* aStyleContext,
nsIFrame*& aContinuingFrame)
{
- // Because rows are always complete we should never be asked to create
- // a continuing frame
- NS_ERROR("Unexpected request");
- return NS_ERROR_NOT_IMPLEMENTED;
+ if (gsDebug1==PR_TRUE) printf("nsTableRowFrame::CreateContinuingFrame\n");
+ nsTableRowFrame* cf = new nsTableRowFrame(mContent, aParent);
+ if (nsnull == cf) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ PrepareContinuingFrame(aPresContext, aParent, aStyleContext, cf);
+ aContinuingFrame = cf;
+ return NS_OK;
}
nsresult nsTableRowFrame::NewFrame( nsIFrame** aInstancePtrResult,
diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp
index 8c977341c19..f2b547638d2 100644
--- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp
@@ -29,13 +29,11 @@
#include "nsIReflowCommand.h"
#ifdef NS_DEBUG
-static PRBool gsDebug1 = PR_FALSE;
-static PRBool gsDebug2 = PR_FALSE;
+static PRBool gsDebug = PR_FALSE;
//#define NOISY
//#define NOISY_FLOW
#else
-static const PRBool gsDebug1 = PR_FALSE;
-static const PRBool gsDebug2 = PR_FALSE;
+static const PRBool gsDebug = PR_FALSE;
#endif
NS_DEF_PTR(nsIStyleContext);
@@ -195,7 +193,7 @@ void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize)
{
- if (PR_TRUE==gsDebug1)
+ if (PR_TRUE==gsDebug)
printf ("rowgroup: placing row at %d, %d, %d, %d\n",
aKidRect.x, aKidRect.y, aKidRect.width, aKidRect.height);
@@ -256,7 +254,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
#endif
#endif
NS_PRECONDITION(nsnull != mFirstChild, "no children");
-
+if (gsDebug) printf("\n\nREFLOWMAPPED FOR ROW GROUP FRAME\n");
PRInt32 childCount = 0;
nsIFrame* prevKidFrame = nsnull;
@@ -1039,7 +1037,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
- if (gsDebug1==PR_TRUE)
+ if (gsDebug==PR_TRUE)
printf("nsTableRowGroupFrame::Reflow - aMaxSize = %d, %d\n",
aReflowState.maxSize.width, aReflowState.maxSize.height);
#ifdef NS_DEBUG
@@ -1153,7 +1151,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
PostReflowCheck(aStatus);
#endif
- if (gsDebug1==PR_TRUE)
+ if (gsDebug==PR_TRUE)
{
if (nsnull!=aDesiredSize.maxElementSize)
printf("nsTableRowGroupFrame::RR returning: %s with aDesiredSize=%d,%d, aMES=%d,%d\n",
@@ -1181,7 +1179,7 @@ nsTableRowGroupFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
return NS_ERROR_OUT_OF_MEMORY;
}
PrepareContinuingFrame(aPresContext, aParent, aStyleContext, cf);
- if (PR_TRUE==gsDebug1) printf("nsTableRowGroupFrame::CCF parent = %p, this=%p, cf=%p\n", aParent, this, cf);
+ if (PR_TRUE==gsDebug) printf("nsTableRowGroupFrame::CCF parent = %p, this=%p, cf=%p\n", aParent, this, cf);
aContinuingFrame = cf;
return NS_OK;
}