зеркало из https://github.com/mozilla/pjs.git
Space optimization for nsTableFrame. r=karnaze@netscape.com
- 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:
Родитель
a30cba0af1
Коммит
5e139f0234
|
@ -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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче