- changed mBorderEdges to be heap allocated (only needed for collapsing border model)
- made the 8 boolean data members into bitfields
- changed mColumnWidths to be as small as necessary instead of defaulting its size to 100 elements
This commit is contained in:
troy%netscape.com 1999-10-04 23:48:05 +00:00
Родитель a30cba0af1
Коммит 5e139f0234
6 изменённых файлов: 280 добавлений и 192 удалений

Просмотреть файл

@ -59,7 +59,7 @@ static NS_DEFINE_IID(kIHTMLElementIID, NS_IDOMHTMLELEMENT_IID);
static NS_DEFINE_IID(kIBodyElementIID, NS_IDOMHTMLBODYELEMENT_IID); static NS_DEFINE_IID(kIBodyElementIID, NS_IDOMHTMLBODYELEMENT_IID);
static NS_DEFINE_IID(kITableRowGroupFrameIID, NS_ITABLEROWGROUPFRAME_IID); static NS_DEFINE_IID(kITableRowGroupFrameIID, NS_ITABLEROWGROUPFRAME_IID);
static const PRInt32 kColumnWidthIncrement=100; static const PRInt32 kColumnWidthIncrement=10;
#if 1 #if 1
PRBool nsDebugTable::gRflTableOuter = PR_FALSE; PRBool nsDebugTable::gRflTableOuter = PR_FALSE;
@ -266,23 +266,21 @@ nsTableFrame::GetFrameType(nsIAtom** aType) const
nsTableFrame::nsTableFrame() nsTableFrame::nsTableFrame()
: nsHTMLContainerFrame(), : nsHTMLContainerFrame(),
mColumnWidthsValid(PR_FALSE),
mFirstPassValid(PR_FALSE),
mColumnCacheValid(PR_FALSE),
mCellMapValid(PR_TRUE),
mIsInvariantWidth(PR_FALSE),
mHasScrollableRowGroup(PR_FALSE),
mCellMap(nsnull), mCellMap(nsnull),
mColCache(nsnull), mColCache(nsnull),
mTableLayoutStrategy(nsnull), mTableLayoutStrategy(nsnull),
mPercentBasisForRows(0) mPercentBasisForRows(0)
{ {
mColumnWidthsSet=PR_FALSE; mBits.mColumnWidthsSet = PR_FALSE;
mColumnWidthsLength = kColumnWidthIncrement; mBits.mColumnWidthsValid = PR_FALSE;
mColumnWidths = new PRInt32[mColumnWidthsLength]; mBits.mFirstPassValid = PR_FALSE;
nsCRT::memset (mColumnWidths, 0, mColumnWidthsLength*sizeof(PRInt32)); mBits.mColumnCacheValid = PR_FALSE;
mBits.mCellMapValid = PR_TRUE;
mBits.mIsInvariantWidth = PR_FALSE;
mBits.mHasScrollableRowGroup = PR_FALSE;
mColumnWidthsLength = 0;
mColumnWidths = nsnull;
mCellMap = new nsCellMap(0, 0); mCellMap = new nsCellMap(0, 0);
mBorderEdges.mOutsideEdge=PR_TRUE;
} }
NS_IMPL_ADDREF_INHERITED(nsTableFrame, nsHTMLContainerFrame) NS_IMPL_ADDREF_INHERITED(nsTableFrame, nsHTMLContainerFrame)
@ -329,19 +327,20 @@ nsTableFrame::Init(nsIPresContext& aPresContext,
nsTableFrame::~nsTableFrame() nsTableFrame::~nsTableFrame()
{ {
if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle()) if ((NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle()) && mBorderEdges)
{ {
PRInt32 i=0; PRInt32 i=0;
for ( ; i<4; i++) for ( ; i<4; i++)
{ {
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[i].ElementAt(0)); nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[i].ElementAt(0));
while (border) while (border)
{ {
delete border; delete border;
mBorderEdges.mEdges[i].RemoveElementAt(0); mBorderEdges->mEdges[i].RemoveElementAt(0);
border = (nsBorderEdge *)(mBorderEdges.mEdges[i].ElementAt(0)); border = (nsBorderEdge *)(mBorderEdges->mEdges[i].ElementAt(0));
} }
} }
delete mBorderEdges;
} }
if (nsnull!=mCellMap) { if (nsnull!=mCellMap) {
@ -956,7 +955,7 @@ NS_METHOD nsTableFrame::ReBuildCellMap()
BuildCellMapForRowGroup(rowGroupFrame); BuildCellMapForRowGroup(rowGroupFrame);
} }
} }
mCellMapValid=PR_TRUE; mBits.mCellMapValid=PR_TRUE;
return rv; return rv;
} }
@ -1013,7 +1012,10 @@ void nsTableFrame::ListColumnLayoutData(FILE* out, PRInt32 aIndent)
void nsTableFrame::SetBorderEdgeLength(PRUint8 aSide, PRInt32 aIndex, nscoord aLength) void nsTableFrame::SetBorderEdgeLength(PRUint8 aSide, PRInt32 aIndex, nscoord aLength)
{ {
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[aSide].ElementAt(aIndex)); if (!mBorderEdges) {
mBorderEdges = new nsBorderEdges;
}
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[aSide].ElementAt(aIndex));
if (border) if (border)
{ {
border->mLength = aLength; border->mLength = aLength;
@ -1024,6 +1026,7 @@ void nsTableFrame::DidComputeHorizontalCollapsingBorders(nsIPresContext& aPresCo
PRInt32 aStartRowIndex, PRInt32 aStartRowIndex,
PRInt32 aEndRowIndex) PRInt32 aEndRowIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// XXX: for now, this only does table edges. May need to do interior edges also? Probably not. // XXX: for now, this only does table edges. May need to do interior edges also? Probably not.
nsCellMap *cellMap = GetCellMap(); nsCellMap *cellMap = GetCellMap();
PRInt32 lastRowIndex = cellMap->GetRowCount()-1; PRInt32 lastRowIndex = cellMap->GetRowCount()-1;
@ -1037,13 +1040,13 @@ void nsTableFrame::DidComputeHorizontalCollapsingBorders(nsIPresContext& aPresCo
nsIFrame *rowFrame; nsIFrame *rowFrame;
cellFrame->GetParent(&rowFrame); cellFrame->GetParent(&rowFrame);
rowFrame->GetRect(rowRect); rowFrame->GetRect(rowRect);
nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(0)); nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(0));
nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(0)); nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(0));
nsBorderEdge *topBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(0)); nsBorderEdge *topBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(0));
if (leftBorder) if (leftBorder)
leftBorder->mLength = rowRect.height + topBorder->mWidth; leftBorder->mLength = rowRect.height + topBorder->mWidth;
if (topBorder) if (topBorder)
topBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(lastColIndex)); topBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(lastColIndex));
if (rightBorder) if (rightBorder)
rightBorder->mLength = rowRect.height + topBorder->mWidth; rightBorder->mLength = rowRect.height + topBorder->mWidth;
} }
@ -1058,21 +1061,21 @@ void nsTableFrame::DidComputeHorizontalCollapsingBorders(nsIPresContext& aPresCo
nsIFrame *rowFrame; nsIFrame *rowFrame;
cellFrame->GetParent(&rowFrame); cellFrame->GetParent(&rowFrame);
rowFrame->GetRect(rowRect); rowFrame->GetRect(rowRect);
nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(lastRowIndex)); nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(lastRowIndex));
nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(lastRowIndex)); nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(lastRowIndex));
nsBorderEdge *bottomBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(0)); nsBorderEdge *bottomBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_BOTTOM].ElementAt(0));
if (leftBorder) if (leftBorder)
leftBorder->mLength = rowRect.height + bottomBorder->mWidth; leftBorder->mLength = rowRect.height + bottomBorder->mWidth;
if (bottomBorder) if (bottomBorder)
bottomBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(lastColIndex)); bottomBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_BOTTOM].ElementAt(lastColIndex));
if (rightBorder) if (rightBorder)
rightBorder->mLength = rowRect.height + bottomBorder->mWidth; rightBorder->mLength = rowRect.height + bottomBorder->mWidth;
} }
} }
//XXX this won't work if the constants are redefined, too bad //XXX this won't work if the constants are redefined, too bad
for (PRInt32 borderX = NS_SIDE_TOP; borderX <= NS_SIDE_LEFT; borderX++) { for (PRInt32 borderX = NS_SIDE_TOP; borderX <= NS_SIDE_LEFT; borderX++) {
if (!mBorderEdges.mEdges[borderX].ElementAt(0)) { if (!mBorderEdges->mEdges[borderX].ElementAt(0)) {
mBorderEdges.mEdges[borderX].AppendElement(new nsBorderEdge()); mBorderEdges->mEdges[borderX].AppendElement(new nsBorderEdge());
} }
} }
} }
@ -1130,6 +1133,10 @@ void nsTableFrame::ComputeVerticalCollapsingBorders(nsIPresContext& aPresContext
if (NS_STYLE_BORDER_COLLAPSE != GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE != GetBorderCollapseStyle())
return; return;
if (!mBorderEdges) {
mBorderEdges = new nsBorderEdges;
}
PRInt32 colCount = mCellMap->GetColCount(); PRInt32 colCount = mCellMap->GetColCount();
PRInt32 rowCount = mCellMap->GetRowCount(); PRInt32 rowCount = mCellMap->GetRowCount();
PRInt32 endRowIndex = aEndRowIndex; PRInt32 endRowIndex = aEndRowIndex;
@ -1159,16 +1166,17 @@ void nsTableFrame::ComputeLeftBorderForEdgeAt(nsIPresContext& aPresContext,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex) PRInt32 aColIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull
PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_LEFT].Count(); PRInt32 numSegments = mBorderEdges->mEdges[NS_SIDE_LEFT].Count();
while (numSegments<=aRowIndex) while (numSegments<=aRowIndex)
{ {
nsBorderEdge *borderToAdd = new nsBorderEdge(); nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges.mEdges[NS_SIDE_LEFT].AppendElement(borderToAdd); mBorderEdges->mEdges[NS_SIDE_LEFT].AppendElement(borderToAdd);
numSegments++; numSegments++;
} }
// "border" is the border segment we are going to set // "border" is the border segment we are going to set
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex));
if (!border) if (!border)
return; return;
@ -1231,20 +1239,21 @@ void nsTableFrame::ComputeLeftBorderForEdgeAt(nsIPresContext& aPresContext,
cellFrame->SetBorderEdge(NS_SIDE_LEFT, aRowIndex, aColIndex, border, 0); // set the left edge of the cell frame cellFrame->SetBorderEdge(NS_SIDE_LEFT, aRowIndex, aColIndex, border, 0); // set the left edge of the cell frame
} }
border->mWidth += widthToAdd; border->mWidth += widthToAdd;
mBorderEdges.mMaxBorderWidth.left = PR_MAX(border->mWidth, mBorderEdges.mMaxBorderWidth.left); mBorderEdges->mMaxBorderWidth.left = PR_MAX(border->mWidth, mBorderEdges->mMaxBorderWidth.left);
} }
void nsTableFrame::ComputeRightBorderForEdgeAt(nsIPresContext& aPresContext, void nsTableFrame::ComputeRightBorderForEdgeAt(nsIPresContext& aPresContext,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex) PRInt32 aColIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull
PRInt32 colCount = mCellMap->GetColCount(); PRInt32 colCount = mCellMap->GetColCount();
PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_RIGHT].Count(); PRInt32 numSegments = mBorderEdges->mEdges[NS_SIDE_RIGHT].Count();
while (numSegments<=aRowIndex) while (numSegments<=aRowIndex)
{ {
nsBorderEdge *borderToAdd = new nsBorderEdge(); nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges.mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd); mBorderEdges->mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd);
numSegments++; numSegments++;
} }
// "border" is the border segment we are going to set // "border" is the border segment we are going to set
@ -1353,10 +1362,10 @@ void nsTableFrame::ComputeRightBorderForEdgeAt(nsIPresContext& aPresContext,
} }
if (nsnull==rightNeighborFrame) if (nsnull==rightNeighborFrame)
{ {
nsBorderEdge * tableBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); nsBorderEdge * tableBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex));
*tableBorder = border; *tableBorder = border;
tableBorder->mInsideNeighbor = &cellFrame->mBorderEdges; tableBorder->mInsideNeighbor = &cellFrame->mBorderEdges;
mBorderEdges.mMaxBorderWidth.right = PR_MAX(border.mWidth, mBorderEdges.mMaxBorderWidth.right); mBorderEdges->mMaxBorderWidth.right = PR_MAX(border.mWidth, mBorderEdges->mMaxBorderWidth.right);
// since the table is our right neightbor, we need to factor in the table's horizontal borders. // since the table is our right neightbor, we need to factor in the table's horizontal borders.
// can't compute that length here because we don't know how thick top and bottom borders are // can't compute that length here because we don't know how thick top and bottom borders are
// see DidComputeHorizontalCollapsingBorders // see DidComputeHorizontalCollapsingBorders
@ -1371,16 +1380,17 @@ void nsTableFrame::ComputeTopBorderForEdgeAt(nsIPresContext& aPresContext,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex) PRInt32 aColIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull
PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_TOP].Count(); PRInt32 numSegments = mBorderEdges->mEdges[NS_SIDE_TOP].Count();
while (numSegments<=aColIndex) while (numSegments<=aColIndex)
{ {
nsBorderEdge *borderToAdd = new nsBorderEdge(); nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges.mEdges[NS_SIDE_TOP].AppendElement(borderToAdd); mBorderEdges->mEdges[NS_SIDE_TOP].AppendElement(borderToAdd);
numSegments++; numSegments++;
} }
// "border" is the border segment we are going to set // "border" is the border segment we are going to set
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(aColIndex)); nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(aColIndex));
if (!border) if (!border)
return; return;
@ -1435,13 +1445,13 @@ void nsTableFrame::ComputeTopBorderForEdgeAt(nsIPresContext& aPresContext,
border->mInsideNeighbor = &cellFrame->mBorderEdges; border->mInsideNeighbor = &cellFrame->mBorderEdges;
if (0==aColIndex) if (0==aColIndex)
{ // if we're the first column, factor in the thickness of the left table border { // if we're the first column, factor in the thickness of the left table border
nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(0)); nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(0));
if (leftBorder) if (leftBorder)
border->mLength += leftBorder->mWidth; border->mLength += leftBorder->mWidth;
} }
if ((mCellMap->GetColCount()-1)==aColIndex) if ((mCellMap->GetColCount()-1)==aColIndex)
{ // if we're the last column, factor in the thickness of the right table border { // if we're the last column, factor in the thickness of the right table border
nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(0)); nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(0));
if (rightBorder) if (rightBorder)
border->mLength += rightBorder->mWidth; border->mLength += rightBorder->mWidth;
} }
@ -1450,20 +1460,21 @@ void nsTableFrame::ComputeTopBorderForEdgeAt(nsIPresContext& aPresContext,
cellFrame->SetBorderEdge(NS_SIDE_TOP, aRowIndex, aColIndex, border, 0); // set the top edge of the cell frame cellFrame->SetBorderEdge(NS_SIDE_TOP, aRowIndex, aColIndex, border, 0); // set the top edge of the cell frame
} }
border->mWidth += widthToAdd; border->mWidth += widthToAdd;
mBorderEdges.mMaxBorderWidth.top = PR_MAX(border->mWidth, mBorderEdges.mMaxBorderWidth.top); mBorderEdges->mMaxBorderWidth.top = PR_MAX(border->mWidth, mBorderEdges->mMaxBorderWidth.top);
} }
void nsTableFrame::ComputeBottomBorderForEdgeAt(nsIPresContext& aPresContext, void nsTableFrame::ComputeBottomBorderForEdgeAt(nsIPresContext& aPresContext,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex) PRInt32 aColIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull
PRInt32 rowCount = mCellMap->GetRowCount(); PRInt32 rowCount = mCellMap->GetRowCount();
PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_BOTTOM].Count(); PRInt32 numSegments = mBorderEdges->mEdges[NS_SIDE_BOTTOM].Count();
while (numSegments<=aColIndex) while (numSegments<=aColIndex)
{ {
nsBorderEdge *borderToAdd = new nsBorderEdge(); nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges.mEdges[NS_SIDE_BOTTOM].AppendElement(borderToAdd); mBorderEdges->mEdges[NS_SIDE_BOTTOM].AppendElement(borderToAdd);
numSegments++; numSegments++;
} }
// "border" is the border segment we are going to set // "border" is the border segment we are going to set
@ -1570,21 +1581,21 @@ void nsTableFrame::ComputeBottomBorderForEdgeAt(nsIPresContext& aPresContext,
} }
if (nsnull==bottomNeighborFrame) if (nsnull==bottomNeighborFrame)
{ {
nsBorderEdge * tableBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(aColIndex)); nsBorderEdge * tableBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_BOTTOM].ElementAt(aColIndex));
*tableBorder = border; *tableBorder = border;
tableBorder->mInsideNeighbor = &cellFrame->mBorderEdges; tableBorder->mInsideNeighbor = &cellFrame->mBorderEdges;
mBorderEdges.mMaxBorderWidth.bottom = PR_MAX(border.mWidth, mBorderEdges.mMaxBorderWidth.bottom); mBorderEdges->mMaxBorderWidth.bottom = PR_MAX(border.mWidth, mBorderEdges->mMaxBorderWidth.bottom);
// since the table is our bottom neightbor, we need to factor in the table's vertical borders. // since the table is our bottom neightbor, we need to factor in the table's vertical borders.
PRInt32 lastColIndex = mCellMap->GetColCount()-1; PRInt32 lastColIndex = mCellMap->GetColCount()-1;
if (0==aColIndex) if (0==aColIndex)
{ // if we're the first column, factor in the thickness of the left table border { // if we're the first column, factor in the thickness of the left table border
nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(rowCount-1)); nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(rowCount-1));
if (leftBorder) if (leftBorder)
tableBorder->mLength += leftBorder->mWidth; tableBorder->mLength += leftBorder->mWidth;
} }
if (lastColIndex==aColIndex) if (lastColIndex==aColIndex)
{ // if we're the last column, factor in the thickness of the right table border { // if we're the last column, factor in the thickness of the right table border
nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(rowCount-1)); nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(rowCount-1));
if (rightBorder) if (rightBorder)
tableBorder->mLength += rightBorder->mWidth; tableBorder->mLength += rightBorder->mWidth;
} }
@ -1940,7 +1951,7 @@ NS_METHOD nsTableFrame::Paint(nsIPresContext& aPresContext,
{ {
//printf("paint table frame\n"); //printf("paint table frame\n");
nsCSSRendering::PaintBorderEdges(aPresContext, aRenderingContext, this, nsCSSRendering::PaintBorderEdges(aPresContext, aRenderingContext, this,
aDirtyRect, rect, &mBorderEdges, mStyleContext, skipSides); aDirtyRect, rect, mBorderEdges, mStyleContext, skipSides);
} }
} }
} }
@ -2008,7 +2019,7 @@ PRBool nsTableFrame::NeedsReflow(const nsHTMLReflowState& aReflowState)
{ {
PRBool result = PR_TRUE; PRBool result = PR_TRUE;
if (PR_TRUE == mIsInvariantWidth) { if (mBits.mIsInvariantWidth) {
result = PR_FALSE; result = PR_FALSE;
} else if ((eReflowReason_Incremental == aReflowState.reason) && } else if ((eReflowReason_Incremental == aReflowState.reason) &&
@ -2239,7 +2250,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
if (nsnull!=mTableLayoutStrategy) if (nsnull!=mTableLayoutStrategy)
{ {
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.mComputedWidth); mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.mComputedWidth);
mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below mBits.mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below
} }
} }
if (PR_FALSE==IsColumnWidthsValid()) if (PR_FALSE==IsColumnWidthsValid())
@ -2247,7 +2258,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
if (nsnull!=mTableLayoutStrategy) if (nsnull!=mTableLayoutStrategy)
{ {
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.mComputedWidth); mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.mComputedWidth);
mColumnWidthsValid=PR_TRUE; mBits.mColumnWidthsValid=PR_TRUE;
} }
} }
@ -2398,7 +2409,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
} }
aDesiredSize.width = kidSize.width; aDesiredSize.width = kidSize.width;
mFirstPassValid = PR_TRUE; mBits.mFirstPassValid = PR_TRUE;
return rv; return rv;
} }
@ -3790,18 +3801,23 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
{ {
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!"); NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!"); NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
NS_ASSERTION(nsnull!=mColumnWidths, "never ever call me until the col widths array is built!");
PRInt32 numCols = mCellMap->GetColCount(); PRInt32 numCols = mCellMap->GetColCount();
if (numCols>mColumnWidthsLength) if (numCols>mColumnWidthsLength)
{ {
PRInt32 priorColumnWidthsLength=mColumnWidthsLength; PRInt32 priorColumnWidthsLength=mColumnWidthsLength;
while (numCols>mColumnWidthsLength) if (0 == priorColumnWidthsLength) {
mColumnWidthsLength += kColumnWidthIncrement; mColumnWidthsLength = numCols;
} else {
while (numCols>mColumnWidthsLength)
mColumnWidthsLength += kColumnWidthIncrement;
}
PRInt32 * newColumnWidthsArray = new PRInt32[mColumnWidthsLength]; PRInt32 * newColumnWidthsArray = new PRInt32[mColumnWidthsLength];
nsCRT::memset (newColumnWidthsArray, 0, mColumnWidthsLength*sizeof(PRInt32)); nsCRT::memset (newColumnWidthsArray, 0, mColumnWidthsLength*sizeof(PRInt32));
nsCRT::memcpy (newColumnWidthsArray, mColumnWidths, priorColumnWidthsLength*sizeof(PRInt32)); if (mColumnWidths) {
delete [] mColumnWidths; nsCRT::memcpy (newColumnWidthsArray, mColumnWidths, priorColumnWidthsLength*sizeof(PRInt32));
delete [] mColumnWidths;
}
mColumnWidths = newColumnWidthsArray; mColumnWidths = newColumnWidthsArray;
} }
@ -3832,7 +3848,7 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
else else
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode); mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode);
mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount(), aReflowState.mComputedWidth); mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount(), aReflowState.mComputedWidth);
mColumnWidthsValid=PR_TRUE; mBits.mColumnWidthsValid=PR_TRUE;
} }
// fixed-layout tables need to reinitialize the layout strategy. When there are scroll bars // fixed-layout tables need to reinitialize the layout strategy. When there are scroll bars
// reflow gets called twice and the 2nd time has the correct space available. // reflow gets called twice and the 2nd time has the correct space available.
@ -3842,7 +3858,7 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth); mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
//Dump(PR_TRUE, PR_TRUE); //Dump(PR_TRUE, PR_TRUE);
mColumnWidthsSet=PR_TRUE; mBits.mColumnWidthsSet=PR_TRUE;
// if collapsing borders, compute the top and bottom edges now that we have column widths // if collapsing borders, compute the top and bottom edges now that we have column widths
if (NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle())
@ -3899,7 +3915,7 @@ void nsTableFrame::SetTableWidth(nsIPresContext& aPresContext)
tableSize.width = tableWidth; tableSize.width = tableWidth;
// account for scroll bars. XXX needs optimization/caching // account for scroll bars. XXX needs optimization/caching
if (mHasScrollableRowGroup) { if (mBits.mHasScrollableRowGroup) {
float sbWidth, sbHeight; float sbWidth, sbHeight;
nsCOMPtr<nsIDeviceContext> dc; nsCOMPtr<nsIDeviceContext> dc;
aPresContext.GetDeviceContext(getter_AddRefs(dc)); aPresContext.GetDeviceContext(getter_AddRefs(dc));
@ -4055,12 +4071,13 @@ void nsTableFrame::DistributeSpaceToRows(nsIPresContext& aPresContext,
rowFrame->SetRect(newRowRect); rowFrame->SetRect(newRowRect);
if (NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle())
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
nsBorderEdge *border = (nsBorderEdge *) nsBorderEdge *border = (nsBorderEdge *)
(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(((nsTableRowFrame*)rowFrame)->GetRowIndex())); (mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(((nsTableRowFrame*)rowFrame)->GetRowIndex()));
if (border) if (border)
border->mLength=newRowRect.height; border->mLength=newRowRect.height;
border = (nsBorderEdge *) border = (nsBorderEdge *)
(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(((nsTableRowFrame*)rowFrame)->GetRowIndex())); (mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(((nsTableRowFrame*)rowFrame)->GetRowIndex()));
if (border) if (border)
border->mLength=newRowRect.height; border->mLength=newRowRect.height;
} }
@ -4353,7 +4370,7 @@ PRBool nsTableFrame::IsColumnWidthsSet()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mColumnWidthsSet; return (PRBool)firstInFlow->mBits.mColumnWidthsSet;
} }
/* We have to go through our child list twice. /* We have to go through our child list twice.
@ -4458,7 +4475,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
} }
childFrame->GetNextSibling(&childFrame); childFrame->GetNextSibling(&childFrame);
} }
mColumnCacheValid=PR_TRUE; mBits.mColumnCacheValid=PR_TRUE;
} }
void nsTableFrame::CacheColFramesInCellMap() void nsTableFrame::CacheColFramesInCellMap()
@ -4520,49 +4537,49 @@ void nsTableFrame::InvalidateColumnWidths()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
firstInFlow->mColumnWidthsValid=PR_FALSE; firstInFlow->mBits.mColumnWidthsValid=PR_FALSE;
} }
PRBool nsTableFrame::IsColumnWidthsValid() const PRBool nsTableFrame::IsColumnWidthsValid() const
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mColumnWidthsValid; return (PRBool)firstInFlow->mBits.mColumnWidthsValid;
} }
PRBool nsTableFrame::IsFirstPassValid() const PRBool nsTableFrame::IsFirstPassValid() const
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mFirstPassValid; return (PRBool)firstInFlow->mBits.mFirstPassValid;
} }
void nsTableFrame::InvalidateFirstPassCache() void nsTableFrame::InvalidateFirstPassCache()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
firstInFlow->mFirstPassValid=PR_FALSE; firstInFlow->mBits.mFirstPassValid=PR_FALSE;
} }
PRBool nsTableFrame::IsColumnCacheValid() const PRBool nsTableFrame::IsColumnCacheValid() const
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mColumnCacheValid; return (PRBool)firstInFlow->mBits.mColumnCacheValid;
} }
void nsTableFrame::InvalidateColumnCache() void nsTableFrame::InvalidateColumnCache()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
firstInFlow->mColumnCacheValid=PR_FALSE; firstInFlow->mBits.mColumnCacheValid=PR_FALSE;
} }
PRBool nsTableFrame::IsCellMapValid() const PRBool nsTableFrame::IsCellMapValid() const
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mCellMapValid; return (PRBool)firstInFlow->mBits.mCellMapValid;
} }
static void InvalidateCellMapForRowGroup(nsIFrame* aRowGroupFrame) static void InvalidateCellMapForRowGroup(nsIFrame* aRowGroupFrame)
@ -4589,7 +4606,7 @@ void nsTableFrame::InvalidateCellMap()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
firstInFlow->mCellMapValid=PR_FALSE; firstInFlow->mBits.mCellMapValid=PR_FALSE;
// reset the state in each row // reset the state in each row
nsIFrame *rowGroupFrame=mFrames.FirstChild(); nsIFrame *rowGroupFrame=mFrames.FirstChild();
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(&rowGroupFrame)) for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(&rowGroupFrame))
@ -4638,10 +4655,18 @@ void nsTableFrame::SetColumnWidth(PRInt32 aColIndex, nscoord aWidth)
firstInFlow->SetColumnWidth(aColIndex, aWidth); firstInFlow->SetColumnWidth(aColIndex, aWidth);
else else
{ {
NS_ASSERTION(nsnull!=mColumnWidths, "illegal state, nsnull mColumnWidths"); // Note: in the case of incremental reflow sometimes the table layout
NS_ASSERTION(aColIndex<mColumnWidthsLength, "illegal state, aColIndex<mColumnWidthsLength"); // strategy will call to set a column width before we've allocated the
if (nsnull!=mColumnWidths && aColIndex<mColumnWidthsLength) // column width array
if (!mColumnWidths) {
mColumnWidthsLength = mCellMap->GetColCount();
mColumnWidths = new PRInt32[mColumnWidthsLength];
nsCRT::memset (mColumnWidths, 0, mColumnWidthsLength*sizeof(PRInt32));
}
if (nsnull!=mColumnWidths && aColIndex<mColumnWidthsLength) {
mColumnWidths[aColIndex] = aWidth; mColumnWidths[aColIndex] = aWidth;
}
} }
} }
@ -4783,7 +4808,7 @@ void nsTableFrame::GetTableBorder(nsMargin &aBorder)
{ {
if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle())
{ {
aBorder = mBorderEdges.mMaxBorderWidth; aBorder = mBorderEdges->mMaxBorderWidth;
} }
else else
{ {
@ -4803,16 +4828,16 @@ void nsTableFrame::GetTableBorderAt(nsMargin &aBorder, PRInt32 aRowIndex, PRInt3
{ {
if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle())
{ {
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex));
if (border) { if (border) {
aBorder.left = border->mWidth; aBorder.left = border->mWidth;
border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex));
if (border) if (border)
aBorder.right = border->mWidth; aBorder.right = border->mWidth;
border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(aColIndex)); border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(aColIndex));
if (border) if (border)
aBorder.top = border->mWidth; aBorder.top = border->mWidth;
border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(aColIndex)); border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(aColIndex));
if (border) if (border)
aBorder.bottom = border->mWidth; aBorder.bottom = border->mWidth;
} }
@ -5078,7 +5103,7 @@ nsTableFrame::GetRowGroupFrameFor(nsIFrame* aFrame, const nsStyleDisplay* aDispl
; ;
} else { // it is a scroll frame that contains the row group frame } else { // it is a scroll frame that contains the row group frame
aFrame->FirstChild(nsnull, &result); aFrame->FirstChild(nsnull, &result);
mHasScrollableRowGroup = PR_TRUE; mBits.mHasScrollableRowGroup = PR_TRUE;
} }
} }
@ -5478,6 +5503,11 @@ nsTableFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
// Add in the amount of space for the column width array // Add in the amount of space for the column width array
sum += mColumnWidthsLength * sizeof(PRInt32); sum += mColumnWidthsLength * sizeof(PRInt32);
// And the column info cache
if (mColCache) {
sum += sizeof(*mColCache);
}
// Add in size of cell map // Add in size of cell map
PRUint32 cellMapSize; PRUint32 cellMapSize;
mCellMap->SizeOf(aHandler, &cellMapSize); mCellMap->SizeOf(aHandler, &cellMapSize);

Просмотреть файл

@ -871,23 +871,28 @@ protected:
// data members // data members
PRInt32 *mColumnWidths; // widths of each column PRInt32 *mColumnWidths; // widths of each column
PRInt32 mColumnWidthsLength; // the number of column lengths this frame has allocated PRInt32 mColumnWidthsLength; // the number of column lengths this frame has allocated
PRBool mColumnWidthsSet; // PR_TRUE if column widths have been set at least once
PRBool mColumnWidthsValid; // PR_TRUE if column width data is still legit, PR_FALSE if it needs to be recalculated struct TableBits {
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit, PR_FALSE if it needs to be recalculated unsigned mColumnWidthsSet:1; // PR_TRUE if column widths have been set at least once
PRBool mColumnCacheValid; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated unsigned mColumnWidthsValid:1; // PR_TRUE if column width data is still legit, PR_FALSE if it needs to be recalculated
PRBool mCellMapValid; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated unsigned mFirstPassValid:1; // PR_TRUE if first pass data is still legit, PR_FALSE if it needs to be recalculated
PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change unsigned mColumnCacheValid:1; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated
PRBool mHasScrollableRowGroup; // PR_TRUE if any section has overflow == "auto" or "scroll" unsigned mCellMapValid:1; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated
unsigned mIsInvariantWidth:1; // PR_TRUE if table width cannot change
unsigned mHasScrollableRowGroup:1; // PR_TRUE if any section has overflow == "auto" or "scroll"
unsigned mNonPercentSpansPercent:1;
int : 24; // unused
} mBits;
PRInt32 mColCount; // the number of columns in this table PRInt32 mColCount; // the number of columns in this table
nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
ColumnInfoCache *mColCache; // cached information about the table columns ColumnInfoCache *mColCache; // cached information about the table columns
nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame
nsFrameList mColGroups; // the list of colgroup frames nsFrameList mColGroups; // the list of colgroup frames
nsBorderEdges mBorderEdges; // one list of border segments for each side of the table frame nsBorderEdges* mBorderEdges; // one list of border segments for each side of the table frame
// used only for the collapsing border model // used only for the collapsing border model
nscoord mPercentBasisForRows; nscoord mPercentBasisForRows;
PRPackedBool mNonPercentSpansPercent;
}; };
@ -905,12 +910,12 @@ inline nscoord nsTableFrame::GetPercentBasisForRows()
inline PRBool nsTableFrame::HasNonPercentSpanningPercent() const inline PRBool nsTableFrame::HasNonPercentSpanningPercent() const
{ {
return mNonPercentSpansPercent; return (PRBool)mBits.mNonPercentSpansPercent;
} }
inline void nsTableFrame::SetHasNonPercentSpanningPercent(PRBool aValue) inline void nsTableFrame::SetHasNonPercentSpanningPercent(PRBool aValue)
{ {
mNonPercentSpansPercent = aValue; mBits.mNonPercentSpansPercent = (unsigned)aValue;
} }
enum nsTableIteration { enum nsTableIteration {

Просмотреть файл

@ -843,9 +843,18 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
// Calculate the available width for the table cell using the known // Calculate the available width for the table cell using the known
// column widths // column widths
nscoord availWidth = CalculateCellAvailableWidth(aReflowState.tableFrame, nscoord availWidth;
kidFrame, cellColIndex, if (aDirtyOnly && (frameState & NS_FRAME_FIRST_REFLOW)) {
cellColSpan, cellSpacingX); // This is the initial reflow for the cell and so we do an unconstrained
// reflow.
// Note: don't assume that we have known column widths. If we don't, then
// CalculateCellAvailableWidth() may assert if called now...
availWidth = NS_UNCONSTRAINEDSIZE;
} else {
availWidth = CalculateCellAvailableWidth(aReflowState.tableFrame,
kidFrame, cellColIndex,
cellColSpan, cellSpacingX);
}
// remember the rightmost (ltr) or leftmost (rtl) column this cell spans into // remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex; prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;

Просмотреть файл

@ -59,7 +59,7 @@ static NS_DEFINE_IID(kIHTMLElementIID, NS_IDOMHTMLELEMENT_IID);
static NS_DEFINE_IID(kIBodyElementIID, NS_IDOMHTMLBODYELEMENT_IID); static NS_DEFINE_IID(kIBodyElementIID, NS_IDOMHTMLBODYELEMENT_IID);
static NS_DEFINE_IID(kITableRowGroupFrameIID, NS_ITABLEROWGROUPFRAME_IID); static NS_DEFINE_IID(kITableRowGroupFrameIID, NS_ITABLEROWGROUPFRAME_IID);
static const PRInt32 kColumnWidthIncrement=100; static const PRInt32 kColumnWidthIncrement=10;
#if 1 #if 1
PRBool nsDebugTable::gRflTableOuter = PR_FALSE; PRBool nsDebugTable::gRflTableOuter = PR_FALSE;
@ -266,23 +266,21 @@ nsTableFrame::GetFrameType(nsIAtom** aType) const
nsTableFrame::nsTableFrame() nsTableFrame::nsTableFrame()
: nsHTMLContainerFrame(), : nsHTMLContainerFrame(),
mColumnWidthsValid(PR_FALSE),
mFirstPassValid(PR_FALSE),
mColumnCacheValid(PR_FALSE),
mCellMapValid(PR_TRUE),
mIsInvariantWidth(PR_FALSE),
mHasScrollableRowGroup(PR_FALSE),
mCellMap(nsnull), mCellMap(nsnull),
mColCache(nsnull), mColCache(nsnull),
mTableLayoutStrategy(nsnull), mTableLayoutStrategy(nsnull),
mPercentBasisForRows(0) mPercentBasisForRows(0)
{ {
mColumnWidthsSet=PR_FALSE; mBits.mColumnWidthsSet = PR_FALSE;
mColumnWidthsLength = kColumnWidthIncrement; mBits.mColumnWidthsValid = PR_FALSE;
mColumnWidths = new PRInt32[mColumnWidthsLength]; mBits.mFirstPassValid = PR_FALSE;
nsCRT::memset (mColumnWidths, 0, mColumnWidthsLength*sizeof(PRInt32)); mBits.mColumnCacheValid = PR_FALSE;
mBits.mCellMapValid = PR_TRUE;
mBits.mIsInvariantWidth = PR_FALSE;
mBits.mHasScrollableRowGroup = PR_FALSE;
mColumnWidthsLength = 0;
mColumnWidths = nsnull;
mCellMap = new nsCellMap(0, 0); mCellMap = new nsCellMap(0, 0);
mBorderEdges.mOutsideEdge=PR_TRUE;
} }
NS_IMPL_ADDREF_INHERITED(nsTableFrame, nsHTMLContainerFrame) NS_IMPL_ADDREF_INHERITED(nsTableFrame, nsHTMLContainerFrame)
@ -329,19 +327,20 @@ nsTableFrame::Init(nsIPresContext& aPresContext,
nsTableFrame::~nsTableFrame() nsTableFrame::~nsTableFrame()
{ {
if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle()) if ((NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle()) && mBorderEdges)
{ {
PRInt32 i=0; PRInt32 i=0;
for ( ; i<4; i++) for ( ; i<4; i++)
{ {
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[i].ElementAt(0)); nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[i].ElementAt(0));
while (border) while (border)
{ {
delete border; delete border;
mBorderEdges.mEdges[i].RemoveElementAt(0); mBorderEdges->mEdges[i].RemoveElementAt(0);
border = (nsBorderEdge *)(mBorderEdges.mEdges[i].ElementAt(0)); border = (nsBorderEdge *)(mBorderEdges->mEdges[i].ElementAt(0));
} }
} }
delete mBorderEdges;
} }
if (nsnull!=mCellMap) { if (nsnull!=mCellMap) {
@ -956,7 +955,7 @@ NS_METHOD nsTableFrame::ReBuildCellMap()
BuildCellMapForRowGroup(rowGroupFrame); BuildCellMapForRowGroup(rowGroupFrame);
} }
} }
mCellMapValid=PR_TRUE; mBits.mCellMapValid=PR_TRUE;
return rv; return rv;
} }
@ -1013,7 +1012,10 @@ void nsTableFrame::ListColumnLayoutData(FILE* out, PRInt32 aIndent)
void nsTableFrame::SetBorderEdgeLength(PRUint8 aSide, PRInt32 aIndex, nscoord aLength) void nsTableFrame::SetBorderEdgeLength(PRUint8 aSide, PRInt32 aIndex, nscoord aLength)
{ {
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[aSide].ElementAt(aIndex)); if (!mBorderEdges) {
mBorderEdges = new nsBorderEdges;
}
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[aSide].ElementAt(aIndex));
if (border) if (border)
{ {
border->mLength = aLength; border->mLength = aLength;
@ -1024,6 +1026,7 @@ void nsTableFrame::DidComputeHorizontalCollapsingBorders(nsIPresContext& aPresCo
PRInt32 aStartRowIndex, PRInt32 aStartRowIndex,
PRInt32 aEndRowIndex) PRInt32 aEndRowIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// XXX: for now, this only does table edges. May need to do interior edges also? Probably not. // XXX: for now, this only does table edges. May need to do interior edges also? Probably not.
nsCellMap *cellMap = GetCellMap(); nsCellMap *cellMap = GetCellMap();
PRInt32 lastRowIndex = cellMap->GetRowCount()-1; PRInt32 lastRowIndex = cellMap->GetRowCount()-1;
@ -1037,13 +1040,13 @@ void nsTableFrame::DidComputeHorizontalCollapsingBorders(nsIPresContext& aPresCo
nsIFrame *rowFrame; nsIFrame *rowFrame;
cellFrame->GetParent(&rowFrame); cellFrame->GetParent(&rowFrame);
rowFrame->GetRect(rowRect); rowFrame->GetRect(rowRect);
nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(0)); nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(0));
nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(0)); nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(0));
nsBorderEdge *topBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(0)); nsBorderEdge *topBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(0));
if (leftBorder) if (leftBorder)
leftBorder->mLength = rowRect.height + topBorder->mWidth; leftBorder->mLength = rowRect.height + topBorder->mWidth;
if (topBorder) if (topBorder)
topBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(lastColIndex)); topBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(lastColIndex));
if (rightBorder) if (rightBorder)
rightBorder->mLength = rowRect.height + topBorder->mWidth; rightBorder->mLength = rowRect.height + topBorder->mWidth;
} }
@ -1058,21 +1061,21 @@ void nsTableFrame::DidComputeHorizontalCollapsingBorders(nsIPresContext& aPresCo
nsIFrame *rowFrame; nsIFrame *rowFrame;
cellFrame->GetParent(&rowFrame); cellFrame->GetParent(&rowFrame);
rowFrame->GetRect(rowRect); rowFrame->GetRect(rowRect);
nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(lastRowIndex)); nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(lastRowIndex));
nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(lastRowIndex)); nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(lastRowIndex));
nsBorderEdge *bottomBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(0)); nsBorderEdge *bottomBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_BOTTOM].ElementAt(0));
if (leftBorder) if (leftBorder)
leftBorder->mLength = rowRect.height + bottomBorder->mWidth; leftBorder->mLength = rowRect.height + bottomBorder->mWidth;
if (bottomBorder) if (bottomBorder)
bottomBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(lastColIndex)); bottomBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_BOTTOM].ElementAt(lastColIndex));
if (rightBorder) if (rightBorder)
rightBorder->mLength = rowRect.height + bottomBorder->mWidth; rightBorder->mLength = rowRect.height + bottomBorder->mWidth;
} }
} }
//XXX this won't work if the constants are redefined, too bad //XXX this won't work if the constants are redefined, too bad
for (PRInt32 borderX = NS_SIDE_TOP; borderX <= NS_SIDE_LEFT; borderX++) { for (PRInt32 borderX = NS_SIDE_TOP; borderX <= NS_SIDE_LEFT; borderX++) {
if (!mBorderEdges.mEdges[borderX].ElementAt(0)) { if (!mBorderEdges->mEdges[borderX].ElementAt(0)) {
mBorderEdges.mEdges[borderX].AppendElement(new nsBorderEdge()); mBorderEdges->mEdges[borderX].AppendElement(new nsBorderEdge());
} }
} }
} }
@ -1130,6 +1133,10 @@ void nsTableFrame::ComputeVerticalCollapsingBorders(nsIPresContext& aPresContext
if (NS_STYLE_BORDER_COLLAPSE != GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE != GetBorderCollapseStyle())
return; return;
if (!mBorderEdges) {
mBorderEdges = new nsBorderEdges;
}
PRInt32 colCount = mCellMap->GetColCount(); PRInt32 colCount = mCellMap->GetColCount();
PRInt32 rowCount = mCellMap->GetRowCount(); PRInt32 rowCount = mCellMap->GetRowCount();
PRInt32 endRowIndex = aEndRowIndex; PRInt32 endRowIndex = aEndRowIndex;
@ -1159,16 +1166,17 @@ void nsTableFrame::ComputeLeftBorderForEdgeAt(nsIPresContext& aPresContext,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex) PRInt32 aColIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull
PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_LEFT].Count(); PRInt32 numSegments = mBorderEdges->mEdges[NS_SIDE_LEFT].Count();
while (numSegments<=aRowIndex) while (numSegments<=aRowIndex)
{ {
nsBorderEdge *borderToAdd = new nsBorderEdge(); nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges.mEdges[NS_SIDE_LEFT].AppendElement(borderToAdd); mBorderEdges->mEdges[NS_SIDE_LEFT].AppendElement(borderToAdd);
numSegments++; numSegments++;
} }
// "border" is the border segment we are going to set // "border" is the border segment we are going to set
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex));
if (!border) if (!border)
return; return;
@ -1231,20 +1239,21 @@ void nsTableFrame::ComputeLeftBorderForEdgeAt(nsIPresContext& aPresContext,
cellFrame->SetBorderEdge(NS_SIDE_LEFT, aRowIndex, aColIndex, border, 0); // set the left edge of the cell frame cellFrame->SetBorderEdge(NS_SIDE_LEFT, aRowIndex, aColIndex, border, 0); // set the left edge of the cell frame
} }
border->mWidth += widthToAdd; border->mWidth += widthToAdd;
mBorderEdges.mMaxBorderWidth.left = PR_MAX(border->mWidth, mBorderEdges.mMaxBorderWidth.left); mBorderEdges->mMaxBorderWidth.left = PR_MAX(border->mWidth, mBorderEdges->mMaxBorderWidth.left);
} }
void nsTableFrame::ComputeRightBorderForEdgeAt(nsIPresContext& aPresContext, void nsTableFrame::ComputeRightBorderForEdgeAt(nsIPresContext& aPresContext,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex) PRInt32 aColIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull
PRInt32 colCount = mCellMap->GetColCount(); PRInt32 colCount = mCellMap->GetColCount();
PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_RIGHT].Count(); PRInt32 numSegments = mBorderEdges->mEdges[NS_SIDE_RIGHT].Count();
while (numSegments<=aRowIndex) while (numSegments<=aRowIndex)
{ {
nsBorderEdge *borderToAdd = new nsBorderEdge(); nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges.mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd); mBorderEdges->mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd);
numSegments++; numSegments++;
} }
// "border" is the border segment we are going to set // "border" is the border segment we are going to set
@ -1353,10 +1362,10 @@ void nsTableFrame::ComputeRightBorderForEdgeAt(nsIPresContext& aPresContext,
} }
if (nsnull==rightNeighborFrame) if (nsnull==rightNeighborFrame)
{ {
nsBorderEdge * tableBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); nsBorderEdge * tableBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex));
*tableBorder = border; *tableBorder = border;
tableBorder->mInsideNeighbor = &cellFrame->mBorderEdges; tableBorder->mInsideNeighbor = &cellFrame->mBorderEdges;
mBorderEdges.mMaxBorderWidth.right = PR_MAX(border.mWidth, mBorderEdges.mMaxBorderWidth.right); mBorderEdges->mMaxBorderWidth.right = PR_MAX(border.mWidth, mBorderEdges->mMaxBorderWidth.right);
// since the table is our right neightbor, we need to factor in the table's horizontal borders. // since the table is our right neightbor, we need to factor in the table's horizontal borders.
// can't compute that length here because we don't know how thick top and bottom borders are // can't compute that length here because we don't know how thick top and bottom borders are
// see DidComputeHorizontalCollapsingBorders // see DidComputeHorizontalCollapsingBorders
@ -1371,16 +1380,17 @@ void nsTableFrame::ComputeTopBorderForEdgeAt(nsIPresContext& aPresContext,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex) PRInt32 aColIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull
PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_TOP].Count(); PRInt32 numSegments = mBorderEdges->mEdges[NS_SIDE_TOP].Count();
while (numSegments<=aColIndex) while (numSegments<=aColIndex)
{ {
nsBorderEdge *borderToAdd = new nsBorderEdge(); nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges.mEdges[NS_SIDE_TOP].AppendElement(borderToAdd); mBorderEdges->mEdges[NS_SIDE_TOP].AppendElement(borderToAdd);
numSegments++; numSegments++;
} }
// "border" is the border segment we are going to set // "border" is the border segment we are going to set
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(aColIndex)); nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(aColIndex));
if (!border) if (!border)
return; return;
@ -1435,13 +1445,13 @@ void nsTableFrame::ComputeTopBorderForEdgeAt(nsIPresContext& aPresContext,
border->mInsideNeighbor = &cellFrame->mBorderEdges; border->mInsideNeighbor = &cellFrame->mBorderEdges;
if (0==aColIndex) if (0==aColIndex)
{ // if we're the first column, factor in the thickness of the left table border { // if we're the first column, factor in the thickness of the left table border
nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(0)); nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(0));
if (leftBorder) if (leftBorder)
border->mLength += leftBorder->mWidth; border->mLength += leftBorder->mWidth;
} }
if ((mCellMap->GetColCount()-1)==aColIndex) if ((mCellMap->GetColCount()-1)==aColIndex)
{ // if we're the last column, factor in the thickness of the right table border { // if we're the last column, factor in the thickness of the right table border
nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(0)); nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(0));
if (rightBorder) if (rightBorder)
border->mLength += rightBorder->mWidth; border->mLength += rightBorder->mWidth;
} }
@ -1450,20 +1460,21 @@ void nsTableFrame::ComputeTopBorderForEdgeAt(nsIPresContext& aPresContext,
cellFrame->SetBorderEdge(NS_SIDE_TOP, aRowIndex, aColIndex, border, 0); // set the top edge of the cell frame cellFrame->SetBorderEdge(NS_SIDE_TOP, aRowIndex, aColIndex, border, 0); // set the top edge of the cell frame
} }
border->mWidth += widthToAdd; border->mWidth += widthToAdd;
mBorderEdges.mMaxBorderWidth.top = PR_MAX(border->mWidth, mBorderEdges.mMaxBorderWidth.top); mBorderEdges->mMaxBorderWidth.top = PR_MAX(border->mWidth, mBorderEdges->mMaxBorderWidth.top);
} }
void nsTableFrame::ComputeBottomBorderForEdgeAt(nsIPresContext& aPresContext, void nsTableFrame::ComputeBottomBorderForEdgeAt(nsIPresContext& aPresContext,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex) PRInt32 aColIndex)
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
// this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull
PRInt32 rowCount = mCellMap->GetRowCount(); PRInt32 rowCount = mCellMap->GetRowCount();
PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_BOTTOM].Count(); PRInt32 numSegments = mBorderEdges->mEdges[NS_SIDE_BOTTOM].Count();
while (numSegments<=aColIndex) while (numSegments<=aColIndex)
{ {
nsBorderEdge *borderToAdd = new nsBorderEdge(); nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges.mEdges[NS_SIDE_BOTTOM].AppendElement(borderToAdd); mBorderEdges->mEdges[NS_SIDE_BOTTOM].AppendElement(borderToAdd);
numSegments++; numSegments++;
} }
// "border" is the border segment we are going to set // "border" is the border segment we are going to set
@ -1570,21 +1581,21 @@ void nsTableFrame::ComputeBottomBorderForEdgeAt(nsIPresContext& aPresContext,
} }
if (nsnull==bottomNeighborFrame) if (nsnull==bottomNeighborFrame)
{ {
nsBorderEdge * tableBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(aColIndex)); nsBorderEdge * tableBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_BOTTOM].ElementAt(aColIndex));
*tableBorder = border; *tableBorder = border;
tableBorder->mInsideNeighbor = &cellFrame->mBorderEdges; tableBorder->mInsideNeighbor = &cellFrame->mBorderEdges;
mBorderEdges.mMaxBorderWidth.bottom = PR_MAX(border.mWidth, mBorderEdges.mMaxBorderWidth.bottom); mBorderEdges->mMaxBorderWidth.bottom = PR_MAX(border.mWidth, mBorderEdges->mMaxBorderWidth.bottom);
// since the table is our bottom neightbor, we need to factor in the table's vertical borders. // since the table is our bottom neightbor, we need to factor in the table's vertical borders.
PRInt32 lastColIndex = mCellMap->GetColCount()-1; PRInt32 lastColIndex = mCellMap->GetColCount()-1;
if (0==aColIndex) if (0==aColIndex)
{ // if we're the first column, factor in the thickness of the left table border { // if we're the first column, factor in the thickness of the left table border
nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(rowCount-1)); nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(rowCount-1));
if (leftBorder) if (leftBorder)
tableBorder->mLength += leftBorder->mWidth; tableBorder->mLength += leftBorder->mWidth;
} }
if (lastColIndex==aColIndex) if (lastColIndex==aColIndex)
{ // if we're the last column, factor in the thickness of the right table border { // if we're the last column, factor in the thickness of the right table border
nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(rowCount-1)); nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(rowCount-1));
if (rightBorder) if (rightBorder)
tableBorder->mLength += rightBorder->mWidth; tableBorder->mLength += rightBorder->mWidth;
} }
@ -1940,7 +1951,7 @@ NS_METHOD nsTableFrame::Paint(nsIPresContext& aPresContext,
{ {
//printf("paint table frame\n"); //printf("paint table frame\n");
nsCSSRendering::PaintBorderEdges(aPresContext, aRenderingContext, this, nsCSSRendering::PaintBorderEdges(aPresContext, aRenderingContext, this,
aDirtyRect, rect, &mBorderEdges, mStyleContext, skipSides); aDirtyRect, rect, mBorderEdges, mStyleContext, skipSides);
} }
} }
} }
@ -2008,7 +2019,7 @@ PRBool nsTableFrame::NeedsReflow(const nsHTMLReflowState& aReflowState)
{ {
PRBool result = PR_TRUE; PRBool result = PR_TRUE;
if (PR_TRUE == mIsInvariantWidth) { if (mBits.mIsInvariantWidth) {
result = PR_FALSE; result = PR_FALSE;
} else if ((eReflowReason_Incremental == aReflowState.reason) && } else if ((eReflowReason_Incremental == aReflowState.reason) &&
@ -2239,7 +2250,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
if (nsnull!=mTableLayoutStrategy) if (nsnull!=mTableLayoutStrategy)
{ {
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.mComputedWidth); mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.mComputedWidth);
mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below mBits.mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below
} }
} }
if (PR_FALSE==IsColumnWidthsValid()) if (PR_FALSE==IsColumnWidthsValid())
@ -2247,7 +2258,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
if (nsnull!=mTableLayoutStrategy) if (nsnull!=mTableLayoutStrategy)
{ {
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.mComputedWidth); mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.mComputedWidth);
mColumnWidthsValid=PR_TRUE; mBits.mColumnWidthsValid=PR_TRUE;
} }
} }
@ -2398,7 +2409,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
} }
aDesiredSize.width = kidSize.width; aDesiredSize.width = kidSize.width;
mFirstPassValid = PR_TRUE; mBits.mFirstPassValid = PR_TRUE;
return rv; return rv;
} }
@ -3790,18 +3801,23 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
{ {
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!"); NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!"); NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
NS_ASSERTION(nsnull!=mColumnWidths, "never ever call me until the col widths array is built!");
PRInt32 numCols = mCellMap->GetColCount(); PRInt32 numCols = mCellMap->GetColCount();
if (numCols>mColumnWidthsLength) if (numCols>mColumnWidthsLength)
{ {
PRInt32 priorColumnWidthsLength=mColumnWidthsLength; PRInt32 priorColumnWidthsLength=mColumnWidthsLength;
while (numCols>mColumnWidthsLength) if (0 == priorColumnWidthsLength) {
mColumnWidthsLength += kColumnWidthIncrement; mColumnWidthsLength = numCols;
} else {
while (numCols>mColumnWidthsLength)
mColumnWidthsLength += kColumnWidthIncrement;
}
PRInt32 * newColumnWidthsArray = new PRInt32[mColumnWidthsLength]; PRInt32 * newColumnWidthsArray = new PRInt32[mColumnWidthsLength];
nsCRT::memset (newColumnWidthsArray, 0, mColumnWidthsLength*sizeof(PRInt32)); nsCRT::memset (newColumnWidthsArray, 0, mColumnWidthsLength*sizeof(PRInt32));
nsCRT::memcpy (newColumnWidthsArray, mColumnWidths, priorColumnWidthsLength*sizeof(PRInt32)); if (mColumnWidths) {
delete [] mColumnWidths; nsCRT::memcpy (newColumnWidthsArray, mColumnWidths, priorColumnWidthsLength*sizeof(PRInt32));
delete [] mColumnWidths;
}
mColumnWidths = newColumnWidthsArray; mColumnWidths = newColumnWidthsArray;
} }
@ -3832,7 +3848,7 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
else else
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode); mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode);
mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount(), aReflowState.mComputedWidth); mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount(), aReflowState.mComputedWidth);
mColumnWidthsValid=PR_TRUE; mBits.mColumnWidthsValid=PR_TRUE;
} }
// fixed-layout tables need to reinitialize the layout strategy. When there are scroll bars // fixed-layout tables need to reinitialize the layout strategy. When there are scroll bars
// reflow gets called twice and the 2nd time has the correct space available. // reflow gets called twice and the 2nd time has the correct space available.
@ -3842,7 +3858,7 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth); mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
//Dump(PR_TRUE, PR_TRUE); //Dump(PR_TRUE, PR_TRUE);
mColumnWidthsSet=PR_TRUE; mBits.mColumnWidthsSet=PR_TRUE;
// if collapsing borders, compute the top and bottom edges now that we have column widths // if collapsing borders, compute the top and bottom edges now that we have column widths
if (NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle())
@ -3899,7 +3915,7 @@ void nsTableFrame::SetTableWidth(nsIPresContext& aPresContext)
tableSize.width = tableWidth; tableSize.width = tableWidth;
// account for scroll bars. XXX needs optimization/caching // account for scroll bars. XXX needs optimization/caching
if (mHasScrollableRowGroup) { if (mBits.mHasScrollableRowGroup) {
float sbWidth, sbHeight; float sbWidth, sbHeight;
nsCOMPtr<nsIDeviceContext> dc; nsCOMPtr<nsIDeviceContext> dc;
aPresContext.GetDeviceContext(getter_AddRefs(dc)); aPresContext.GetDeviceContext(getter_AddRefs(dc));
@ -4055,12 +4071,13 @@ void nsTableFrame::DistributeSpaceToRows(nsIPresContext& aPresContext,
rowFrame->SetRect(newRowRect); rowFrame->SetRect(newRowRect);
if (NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle())
{ {
NS_PRECONDITION(mBorderEdges, "haven't allocated border edges struct");
nsBorderEdge *border = (nsBorderEdge *) nsBorderEdge *border = (nsBorderEdge *)
(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(((nsTableRowFrame*)rowFrame)->GetRowIndex())); (mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(((nsTableRowFrame*)rowFrame)->GetRowIndex()));
if (border) if (border)
border->mLength=newRowRect.height; border->mLength=newRowRect.height;
border = (nsBorderEdge *) border = (nsBorderEdge *)
(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(((nsTableRowFrame*)rowFrame)->GetRowIndex())); (mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(((nsTableRowFrame*)rowFrame)->GetRowIndex()));
if (border) if (border)
border->mLength=newRowRect.height; border->mLength=newRowRect.height;
} }
@ -4353,7 +4370,7 @@ PRBool nsTableFrame::IsColumnWidthsSet()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mColumnWidthsSet; return (PRBool)firstInFlow->mBits.mColumnWidthsSet;
} }
/* We have to go through our child list twice. /* We have to go through our child list twice.
@ -4458,7 +4475,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
} }
childFrame->GetNextSibling(&childFrame); childFrame->GetNextSibling(&childFrame);
} }
mColumnCacheValid=PR_TRUE; mBits.mColumnCacheValid=PR_TRUE;
} }
void nsTableFrame::CacheColFramesInCellMap() void nsTableFrame::CacheColFramesInCellMap()
@ -4520,49 +4537,49 @@ void nsTableFrame::InvalidateColumnWidths()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
firstInFlow->mColumnWidthsValid=PR_FALSE; firstInFlow->mBits.mColumnWidthsValid=PR_FALSE;
} }
PRBool nsTableFrame::IsColumnWidthsValid() const PRBool nsTableFrame::IsColumnWidthsValid() const
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mColumnWidthsValid; return (PRBool)firstInFlow->mBits.mColumnWidthsValid;
} }
PRBool nsTableFrame::IsFirstPassValid() const PRBool nsTableFrame::IsFirstPassValid() const
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mFirstPassValid; return (PRBool)firstInFlow->mBits.mFirstPassValid;
} }
void nsTableFrame::InvalidateFirstPassCache() void nsTableFrame::InvalidateFirstPassCache()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
firstInFlow->mFirstPassValid=PR_FALSE; firstInFlow->mBits.mFirstPassValid=PR_FALSE;
} }
PRBool nsTableFrame::IsColumnCacheValid() const PRBool nsTableFrame::IsColumnCacheValid() const
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mColumnCacheValid; return (PRBool)firstInFlow->mBits.mColumnCacheValid;
} }
void nsTableFrame::InvalidateColumnCache() void nsTableFrame::InvalidateColumnCache()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
firstInFlow->mColumnCacheValid=PR_FALSE; firstInFlow->mBits.mColumnCacheValid=PR_FALSE;
} }
PRBool nsTableFrame::IsCellMapValid() const PRBool nsTableFrame::IsCellMapValid() const
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
return firstInFlow->mCellMapValid; return (PRBool)firstInFlow->mBits.mCellMapValid;
} }
static void InvalidateCellMapForRowGroup(nsIFrame* aRowGroupFrame) static void InvalidateCellMapForRowGroup(nsIFrame* aRowGroupFrame)
@ -4589,7 +4606,7 @@ void nsTableFrame::InvalidateCellMap()
{ {
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow(); nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow"); NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
firstInFlow->mCellMapValid=PR_FALSE; firstInFlow->mBits.mCellMapValid=PR_FALSE;
// reset the state in each row // reset the state in each row
nsIFrame *rowGroupFrame=mFrames.FirstChild(); nsIFrame *rowGroupFrame=mFrames.FirstChild();
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(&rowGroupFrame)) for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(&rowGroupFrame))
@ -4638,10 +4655,18 @@ void nsTableFrame::SetColumnWidth(PRInt32 aColIndex, nscoord aWidth)
firstInFlow->SetColumnWidth(aColIndex, aWidth); firstInFlow->SetColumnWidth(aColIndex, aWidth);
else else
{ {
NS_ASSERTION(nsnull!=mColumnWidths, "illegal state, nsnull mColumnWidths"); // Note: in the case of incremental reflow sometimes the table layout
NS_ASSERTION(aColIndex<mColumnWidthsLength, "illegal state, aColIndex<mColumnWidthsLength"); // strategy will call to set a column width before we've allocated the
if (nsnull!=mColumnWidths && aColIndex<mColumnWidthsLength) // column width array
if (!mColumnWidths) {
mColumnWidthsLength = mCellMap->GetColCount();
mColumnWidths = new PRInt32[mColumnWidthsLength];
nsCRT::memset (mColumnWidths, 0, mColumnWidthsLength*sizeof(PRInt32));
}
if (nsnull!=mColumnWidths && aColIndex<mColumnWidthsLength) {
mColumnWidths[aColIndex] = aWidth; mColumnWidths[aColIndex] = aWidth;
}
} }
} }
@ -4783,7 +4808,7 @@ void nsTableFrame::GetTableBorder(nsMargin &aBorder)
{ {
if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle())
{ {
aBorder = mBorderEdges.mMaxBorderWidth; aBorder = mBorderEdges->mMaxBorderWidth;
} }
else else
{ {
@ -4803,16 +4828,16 @@ void nsTableFrame::GetTableBorderAt(nsMargin &aBorder, PRInt32 aRowIndex, PRInt3
{ {
if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle()) if (NS_STYLE_BORDER_COLLAPSE==GetBorderCollapseStyle())
{ {
nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex));
if (border) { if (border) {
aBorder.left = border->mWidth; aBorder.left = border->mWidth;
border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex));
if (border) if (border)
aBorder.right = border->mWidth; aBorder.right = border->mWidth;
border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(aColIndex)); border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(aColIndex));
if (border) if (border)
aBorder.top = border->mWidth; aBorder.top = border->mWidth;
border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(aColIndex)); border = (nsBorderEdge *)(mBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(aColIndex));
if (border) if (border)
aBorder.bottom = border->mWidth; aBorder.bottom = border->mWidth;
} }
@ -5078,7 +5103,7 @@ nsTableFrame::GetRowGroupFrameFor(nsIFrame* aFrame, const nsStyleDisplay* aDispl
; ;
} else { // it is a scroll frame that contains the row group frame } else { // it is a scroll frame that contains the row group frame
aFrame->FirstChild(nsnull, &result); aFrame->FirstChild(nsnull, &result);
mHasScrollableRowGroup = PR_TRUE; mBits.mHasScrollableRowGroup = PR_TRUE;
} }
} }
@ -5478,6 +5503,11 @@ nsTableFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
// Add in the amount of space for the column width array // Add in the amount of space for the column width array
sum += mColumnWidthsLength * sizeof(PRInt32); sum += mColumnWidthsLength * sizeof(PRInt32);
// And the column info cache
if (mColCache) {
sum += sizeof(*mColCache);
}
// Add in size of cell map // Add in size of cell map
PRUint32 cellMapSize; PRUint32 cellMapSize;
mCellMap->SizeOf(aHandler, &cellMapSize); mCellMap->SizeOf(aHandler, &cellMapSize);

Просмотреть файл

@ -871,23 +871,28 @@ protected:
// data members // data members
PRInt32 *mColumnWidths; // widths of each column PRInt32 *mColumnWidths; // widths of each column
PRInt32 mColumnWidthsLength; // the number of column lengths this frame has allocated PRInt32 mColumnWidthsLength; // the number of column lengths this frame has allocated
PRBool mColumnWidthsSet; // PR_TRUE if column widths have been set at least once
PRBool mColumnWidthsValid; // PR_TRUE if column width data is still legit, PR_FALSE if it needs to be recalculated struct TableBits {
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit, PR_FALSE if it needs to be recalculated unsigned mColumnWidthsSet:1; // PR_TRUE if column widths have been set at least once
PRBool mColumnCacheValid; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated unsigned mColumnWidthsValid:1; // PR_TRUE if column width data is still legit, PR_FALSE if it needs to be recalculated
PRBool mCellMapValid; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated unsigned mFirstPassValid:1; // PR_TRUE if first pass data is still legit, PR_FALSE if it needs to be recalculated
PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change unsigned mColumnCacheValid:1; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated
PRBool mHasScrollableRowGroup; // PR_TRUE if any section has overflow == "auto" or "scroll" unsigned mCellMapValid:1; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated
unsigned mIsInvariantWidth:1; // PR_TRUE if table width cannot change
unsigned mHasScrollableRowGroup:1; // PR_TRUE if any section has overflow == "auto" or "scroll"
unsigned mNonPercentSpansPercent:1;
int : 24; // unused
} mBits;
PRInt32 mColCount; // the number of columns in this table PRInt32 mColCount; // the number of columns in this table
nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
ColumnInfoCache *mColCache; // cached information about the table columns ColumnInfoCache *mColCache; // cached information about the table columns
nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame
nsFrameList mColGroups; // the list of colgroup frames nsFrameList mColGroups; // the list of colgroup frames
nsBorderEdges mBorderEdges; // one list of border segments for each side of the table frame nsBorderEdges* mBorderEdges; // one list of border segments for each side of the table frame
// used only for the collapsing border model // used only for the collapsing border model
nscoord mPercentBasisForRows; nscoord mPercentBasisForRows;
PRPackedBool mNonPercentSpansPercent;
}; };
@ -905,12 +910,12 @@ inline nscoord nsTableFrame::GetPercentBasisForRows()
inline PRBool nsTableFrame::HasNonPercentSpanningPercent() const inline PRBool nsTableFrame::HasNonPercentSpanningPercent() const
{ {
return mNonPercentSpansPercent; return (PRBool)mBits.mNonPercentSpansPercent;
} }
inline void nsTableFrame::SetHasNonPercentSpanningPercent(PRBool aValue) inline void nsTableFrame::SetHasNonPercentSpanningPercent(PRBool aValue)
{ {
mNonPercentSpansPercent = aValue; mBits.mNonPercentSpansPercent = (unsigned)aValue;
} }
enum nsTableIteration { enum nsTableIteration {

Просмотреть файл

@ -843,9 +843,18 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
// Calculate the available width for the table cell using the known // Calculate the available width for the table cell using the known
// column widths // column widths
nscoord availWidth = CalculateCellAvailableWidth(aReflowState.tableFrame, nscoord availWidth;
kidFrame, cellColIndex, if (aDirtyOnly && (frameState & NS_FRAME_FIRST_REFLOW)) {
cellColSpan, cellSpacingX); // This is the initial reflow for the cell and so we do an unconstrained
// reflow.
// Note: don't assume that we have known column widths. If we don't, then
// CalculateCellAvailableWidth() may assert if called now...
availWidth = NS_UNCONSTRAINEDSIZE;
} else {
availWidth = CalculateCellAvailableWidth(aReflowState.tableFrame,
kidFrame, cellColIndex,
cellColSpan, cellSpacingX);
}
// remember the rightmost (ltr) or leftmost (rtl) column this cell spans into // remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex; prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;