diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list
index 2dce0ebcaf56..d9dee3d69dd7 100644
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -301,7 +301,7 @@ fails-if(Android) != 192767-17.xul 192767-37.xul
== 283686-3.html about:blank
== 289384-1.xhtml 289384-ref.xhtml
fails-if(Android) random-if(d2d) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures
-asserts(1) == 290129-1.html 290129-1-ref.html # bug 315549/460637
+== 290129-1.html 290129-1-ref.html
== 291078-1.html 291078-1-ref.html
== 291078-2.html 291078-2-ref.html
== 291262-1.html 291262-1-ref.html
diff --git a/layout/tables/crashtests/460637-1.xhtml b/layout/tables/crashtests/460637-1.xhtml
new file mode 100644
index 000000000000..1063730e3292
--- /dev/null
+++ b/layout/tables/crashtests/460637-1.xhtml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
diff --git a/layout/tables/crashtests/460637-2.xhtml b/layout/tables/crashtests/460637-2.xhtml
new file mode 100644
index 000000000000..2bdaee93d16c
--- /dev/null
+++ b/layout/tables/crashtests/460637-2.xhtml
@@ -0,0 +1,24 @@
+
+
+
+
+
diff --git a/layout/tables/crashtests/460637-3.xhtml b/layout/tables/crashtests/460637-3.xhtml
new file mode 100644
index 000000000000..2d73a1e71853
--- /dev/null
+++ b/layout/tables/crashtests/460637-3.xhtml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
diff --git a/layout/tables/crashtests/crashtests.list b/layout/tables/crashtests/crashtests.list
index a0f82cbcb0d1..c3934945ce10 100644
--- a/layout/tables/crashtests/crashtests.list
+++ b/layout/tables/crashtests/crashtests.list
@@ -96,6 +96,9 @@ load 448988-1.xhtml
load 450311-1.html
load 456041.html
load 457115.html
+load 460637-1.xhtml
+load 460637-2.xhtml
+load 460637-3.xhtml
load 467141-1.html
load 488388-1.html
load 512749-1.html
diff --git a/layout/tables/nsCellMap.cpp b/layout/tables/nsCellMap.cpp
index ead2d23cf24e..6798989776ae 100644
--- a/layout/tables/nsCellMap.cpp
+++ b/layout/tables/nsCellMap.cpp
@@ -41,6 +41,24 @@
#include "nsTableCellFrame.h"
#include "nsTableRowGroupFrame.h"
+
+static void
+SetDamageArea(PRInt32 aXOrigin,
+ PRInt32 aYOrigin,
+ PRInt32 aWidth,
+ PRInt32 aHeight,
+ nsRect& aDamageArea)
+{
+ NS_ASSERTION(aXOrigin >= 0, "negative col index");
+ NS_ASSERTION(aYOrigin >= 0, "negative row index");
+ NS_ASSERTION(aWidth >= 0, "negative horizontal damage");
+ NS_ASSERTION(aHeight >= 0, "negative vertical damage");
+ aDamageArea.x = aXOrigin;
+ aDamageArea.y = aYOrigin;
+ aDamageArea.width = aWidth;
+ aDamageArea.height = aHeight;
+}
+
// Empty static array used for SafeElementAt() calls on mRows.
static nsCellMap::CellDataArray * sEmptyRow;
@@ -479,13 +497,13 @@ nsTableCellMap::InsertRows(nsTableRowGroupFrame* aParent,
if ((numNewRows <= 0) || (aFirstRowIndex < 0)) ABORT0();
PRInt32 rowIndex = aFirstRowIndex;
+ PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap;
while (cellMap) {
nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
if (rg == aParent) {
- cellMap->InsertRows(*this, aRows, rowIndex, aConsiderSpans, aDamageArea);
- aDamageArea.y = NS_MIN(aFirstRowIndex, aDamageArea.y);
- aDamageArea.height = NS_MAX(0, GetRowCount() - aDamageArea.y);
+ cellMap->InsertRows(*this, aRows, rowIndex, aConsiderSpans,
+ rgStartRowIndex, aDamageArea);
#ifdef DEBUG_TABLE_CELLMAP
Dump("after InsertRows");
#endif
@@ -507,7 +525,9 @@ nsTableCellMap::InsertRows(nsTableRowGroupFrame* aParent,
}
return;
}
- rowIndex -= cellMap->GetRowCount();
+ PRInt32 rowCount = cellMap->GetRowCount();
+ rgStartRowIndex += rowCount;
+ rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling();
}
@@ -521,13 +541,13 @@ nsTableCellMap::RemoveRows(PRInt32 aFirstRowIndex,
nsRect& aDamageArea)
{
PRInt32 rowIndex = aFirstRowIndex;
+ PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap;
while (cellMap) {
- if (cellMap->GetRowCount() > rowIndex) {
- cellMap->RemoveRows(*this, rowIndex, aNumRowsToRemove, aConsiderSpans, aDamageArea);
- nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
- aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
- aDamageArea.height = NS_MAX(0, GetRowCount() - aFirstRowIndex);
+ PRInt32 rowCount = cellMap->GetRowCount();
+ if (rowCount > rowIndex) {
+ cellMap->RemoveRows(*this, rowIndex, aNumRowsToRemove, aConsiderSpans,
+ rgStartRowIndex, aDamageArea);
if (mBCInfo) {
for (PRInt32 rowX = aFirstRowIndex + aNumRowsToRemove - 1; rowX >= aFirstRowIndex; rowX--) {
if (PRUint32(rowX) < mBCInfo->mRightBorders.Length()) {
@@ -537,7 +557,8 @@ nsTableCellMap::RemoveRows(PRInt32 aFirstRowIndex,
}
break;
}
- rowIndex -= cellMap->GetRowCount();
+ rgStartRowIndex += rowCount;
+ rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling();
}
#ifdef DEBUG_TABLE_CELLMAP
@@ -561,15 +582,18 @@ nsTableCellMap::AppendCell(nsTableCellFrame& aCellFrame,
CellData* result = nsnull;
PRInt32 rowIndex = aRowIndex;
+ PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap;
while (cellMap) {
if (cellMap->GetRowGroup() == rgFrame) {
- result = cellMap->AppendCell(*this, &aCellFrame, rowIndex, aRebuildIfNecessary, aDamageArea);
- nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
- aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
+ result = cellMap->AppendCell(*this, &aCellFrame, rowIndex,
+ aRebuildIfNecessary, rgStartRowIndex,
+ aDamageArea);
break;
}
- rowIndex -= cellMap->GetRowCount();
+ PRInt32 rowCount = cellMap->GetRowCount();
+ rgStartRowIndex += rowCount;
+ rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling();
}
#ifdef DEBUG_TABLE_CELLMAP
@@ -586,16 +610,17 @@ nsTableCellMap::InsertCells(nsTArray& aCellFrames,
nsRect& aDamageArea)
{
PRInt32 rowIndex = aRowIndex;
+ PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap;
while (cellMap) {
- if (cellMap->GetRowCount() > rowIndex) {
- cellMap->InsertCells(*this, aCellFrames, rowIndex, aColIndexBefore, aDamageArea);
- nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
- aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
- aDamageArea.width = NS_MAX(0, GetColCount() - aColIndexBefore - 1);
+ PRInt32 rowCount = cellMap->GetRowCount();
+ if (rowCount > rowIndex) {
+ cellMap->InsertCells(*this, aCellFrames, rowIndex, aColIndexBefore,
+ rgStartRowIndex, aDamageArea);
break;
}
- rowIndex -= cellMap->GetRowCount();
+ rgStartRowIndex += rowCount;
+ rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling();
}
#ifdef DEBUG_TABLE_CELLMAP
@@ -613,21 +638,20 @@ nsTableCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
NS_ASSERTION(aCellFrame == (nsTableCellFrame *)aCellFrame->GetFirstInFlow(),
"invalid call on continuing frame");
PRInt32 rowIndex = aRowIndex;
+ PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap;
while (cellMap) {
- if (cellMap->GetRowCount() > rowIndex) {
- cellMap->RemoveCell(*this, aCellFrame, rowIndex, aDamageArea);
- nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
- aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
- PRInt32 colIndex;
- aCellFrame->GetColIndex(colIndex);
- aDamageArea.width = NS_MAX(0, GetColCount() - colIndex - 1);
+ PRInt32 rowCount = cellMap->GetRowCount();
+ if (rowCount > rowIndex) {
+ cellMap->RemoveCell(*this, aCellFrame, rowIndex, rgStartRowIndex,
+ aDamageArea);
#ifdef DEBUG_TABLE_CELLMAP
Dump("after RemoveCell");
#endif
return;
}
- rowIndex -= cellMap->GetRowCount();
+ rgStartRowIndex += rowCount;
+ rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling();
}
// if we reach this point - the cell did not get removed, the caller of this routine
@@ -637,19 +661,6 @@ nsTableCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
NS_ERROR("nsTableCellMap::RemoveCell - could not remove cell");
}
-void
-SetDamageArea(PRInt32 aXOrigin,
- PRInt32 aYOrigin,
- PRInt32 aWidth,
- PRInt32 aHeight,
- nsRect& aDamageArea)
-{
- aDamageArea.x = aXOrigin;
- aDamageArea.y = aYOrigin;
- aDamageArea.width = NS_MAX(1, aWidth);
- aDamageArea.height = NS_MAX(1, aHeight);
-}
-
void
nsTableCellMap::RebuildConsideringCells(nsCellMap* aCellMap,
nsTArray* aCellFrames,
@@ -664,11 +675,12 @@ nsTableCellMap::RebuildConsideringCells(nsCellMap* aCellMap,
PRInt32 rowCount = 0;
while (cellMap) {
if (cellMap == aCellMap) {
- cellMap->RebuildConsideringCells(*this, numOrigCols, aCellFrames, aRowIndex, aColIndex, aInsert, aDamageArea);
-
+ cellMap->RebuildConsideringCells(*this, numOrigCols, aCellFrames,
+ aRowIndex, aColIndex, aInsert);
}
else {
- cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0, false, aDamageArea);
+ cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0,
+ false);
}
rowCount += cellMap->GetRowCount();
cellMap = cellMap->GetNextSibling();
@@ -692,10 +704,12 @@ nsTableCellMap::RebuildConsideringRows(nsCellMap* aCellMap,
PRInt32 rowCount = 0;
while (cellMap) {
if (cellMap == aCellMap) {
- cellMap->RebuildConsideringRows(*this, aStartRowIndex, aRowsToInsert, aNumRowsToRemove, aDamageArea);
+ cellMap->RebuildConsideringRows(*this, aStartRowIndex, aRowsToInsert,
+ aNumRowsToRemove);
}
else {
- cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0, false, aDamageArea);
+ cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0,
+ false);
}
rowCount += cellMap->GetRowCount();
cellMap = cellMap->GetNextSibling();
@@ -1015,7 +1029,9 @@ nsTableCellMap::SetBCBorderEdge(mozilla::css::Side aSide,
PRInt32 numRgRows = aCellMap.GetRowCount();
if (yPos < numRgRows) { // add a dead cell data
nsRect damageArea;
- cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos, false, damageArea); if (!cellData) ABORT0();
+ cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos,
+ false, 0, damageArea);
+ if (!cellData) ABORT0();
}
else {
NS_ASSERTION(aSide == NS_SIDE_BOTTOM, "program error");
@@ -1028,7 +1044,9 @@ nsTableCellMap::SetBCBorderEdge(mozilla::css::Side aSide,
cellData = (BCCellData*)cellMap->GetDataAt(0, xIndex);
if (!cellData) { // add a dead cell
nsRect damageArea;
- cellData = (BCCellData*)cellMap->AppendCell(*this, nsnull, 0, false, damageArea);
+ cellData = (BCCellData*)cellMap->AppendCell(*this, nsnull, 0,
+ false, 0,
+ damageArea);
}
}
else { // must be at the end of the table
@@ -1121,7 +1139,8 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner,
PRInt32 numRgRows = aCellMap.GetRowCount();
if (yPos < numRgRows) { // add a dead cell data
nsRect damageArea;
- cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos, false, damageArea);
+ cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos,
+ false, 0, damageArea);
}
else {
// try the next non empty row group
@@ -1133,7 +1152,8 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner,
cellData = (BCCellData*)cellMap->GetDataAt(0, xPos);
if (!cellData) { // add a dead cell
nsRect damageArea;
- cellData = (BCCellData*)cellMap->AppendCell(*this, nsnull, 0, false, damageArea);
+ cellData = (BCCellData*)cellMap->AppendCell(*this, nsnull, 0,
+ false, 0, damageArea);
}
}
else { // must be at the bottom of the table
@@ -1337,6 +1357,7 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
nsTArray& aRows,
PRInt32 aFirstRowIndex,
bool aConsiderSpans,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea)
{
PRInt32 numCols = aMap.GetColCount();
@@ -1352,7 +1373,7 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
if (!aConsiderSpans) {
// update mContentRowCount, since non-empty rows will be added
mContentRowCount = NS_MAX(aFirstRowIndex, mContentRowCount);
- ExpandWithRows(aMap, aRows, aFirstRowIndex, aDamageArea);
+ ExpandWithRows(aMap, aRows, aFirstRowIndex, aRgFirstRowIndex, aDamageArea);
return;
}
@@ -1368,12 +1389,11 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
if (!spansCauseRebuild && (PRUint32(aFirstRowIndex) < mRows.Length())) {
spansCauseRebuild = CellsSpanOut(aRows);
}
-
if (spansCauseRebuild) {
aMap.RebuildConsideringRows(this, aFirstRowIndex, &aRows, 0, aDamageArea);
}
else {
- ExpandWithRows(aMap, aRows, aFirstRowIndex, aDamageArea);
+ ExpandWithRows(aMap, aRows, aFirstRowIndex, aRgFirstRowIndex, aDamageArea);
}
}
@@ -1382,6 +1402,7 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
bool aConsiderSpans,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea)
{
PRInt32 numRows = mRows.Length();
@@ -1395,7 +1416,8 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
return;
}
if (!aConsiderSpans) {
- ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aDamageArea);
+ ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aRgFirstRowIndex,
+ aDamageArea);
return;
}
PRInt32 endRowIndex = aFirstRowIndex + aNumRowsToRemove - 1;
@@ -1405,12 +1427,13 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
}
bool spansCauseRebuild = CellsSpanInOrOut(aFirstRowIndex, endRowIndex,
0, numCols - 1);
-
if (spansCauseRebuild) {
- aMap.RebuildConsideringRows(this, aFirstRowIndex, nsnull, aNumRowsToRemove, aDamageArea);
+ aMap.RebuildConsideringRows(this, aFirstRowIndex, nsnull, aNumRowsToRemove,
+ aDamageArea);
}
else {
- ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aDamageArea);
+ ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aRgFirstRowIndex,
+ aDamageArea);
}
}
@@ -1422,6 +1445,7 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex,
bool aRebuildIfNecessary,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea,
PRInt32* aColToBeginSearch)
{
@@ -1514,7 +1538,15 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
SetDataAt(aMap, *origData, aRowIndex, startColIndex);
}
- SetDamageArea(startColIndex, aRowIndex, 1 + endColIndex - startColIndex, 1 + endRowIndex - aRowIndex, aDamageArea);
+ if (aRebuildIfNecessary) {
+ //the caller depends on the damageArea
+ // The special case for zeroRowSpan is to adjust for the '2' in
+ // GetRowSpanForNewCell.
+ PRUint32 height = zeroRowSpan ? endRowIndex - aRowIndex :
+ 1 + endRowIndex - aRowIndex;
+ SetDamageArea(startColIndex, aRgFirstRowIndex + aRowIndex,
+ 1 + endColIndex - startColIndex, height, aDamageArea);
+ }
if (!aCellFrame) {
return origData;
@@ -1723,6 +1755,7 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
nsTArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea)
{
if (aCellFrames.Length() == 0) return;
@@ -1779,12 +1812,13 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
spansCauseRebuild = CellsSpanInOrOut(aRowIndex, aRowIndex + rowSpan - 1,
startColIndex, numCols - 1);
}
-
if (spansCauseRebuild) {
- aMap.RebuildConsideringCells(this, &aCellFrames, aRowIndex, startColIndex, true, aDamageArea);
+ aMap.RebuildConsideringCells(this, &aCellFrames, aRowIndex, startColIndex,
+ true, aDamageArea);
}
else {
- ExpandWithCells(aMap, aCellFrames, aRowIndex, startColIndex, rowSpan, zeroRowSpan, aDamageArea);
+ ExpandWithCells(aMap, aCellFrames, aRowIndex, startColIndex, rowSpan,
+ zeroRowSpan, aRgFirstRowIndex, aDamageArea);
}
}
@@ -1792,6 +1826,7 @@ void
nsCellMap::ExpandWithRows(nsTableCellMap& aMap,
nsTArray& aRowFrames,
PRInt32 aStartRowIndexIn,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea)
{
PRInt32 startRowIndex = (aStartRowIndexIn >= 0) ? aStartRowIndexIn : 0;
@@ -1818,14 +1853,15 @@ nsCellMap::ExpandWithRows(nsTableCellMap& aMap,
while (cFrame) {
nsTableCellFrame *cellFrame = do_QueryFrame(cFrame);
if (cellFrame) {
- AppendCell(aMap, cellFrame, rowX, false, aDamageArea, &colIndex);
+ AppendCell(aMap, cellFrame, rowX, false, aRgFirstRowIndex, aDamageArea,
+ &colIndex);
}
cFrame = cFrame->GetNextSibling();
}
newRowIndex++;
}
-
- SetDamageArea(0, startRowIndex, aMap.GetColCount(), 1 + endRowIndex - startRowIndex, aDamageArea);
+ SetDamageArea(0, aRgFirstRowIndex + startRowIndex, aMap.GetColCount(),
+ 1 + endRowIndex - startRowIndex, aDamageArea);
}
void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
@@ -1834,6 +1870,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
PRInt32 aColIndex,
PRInt32 aRowSpan, // same for all cells
bool aRowSpanIsZero,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
@@ -1908,8 +1945,10 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
}
cellFrame->SetColIndex(startColIndex);
}
- PRInt32 damageHeight = NS_MIN(GetRowGroup()->GetRowCount() - aRowIndex, aRowSpan);
- SetDamageArea(aColIndex, aRowIndex, 1 + endColIndex - aColIndex, damageHeight, aDamageArea);
+ PRInt32 damageHeight = NS_MIN(GetRowGroup()->GetRowCount() - aRowIndex,
+ aRowSpan);
+ SetDamageArea(aColIndex, aRgFirstRowIndex + aRowIndex,
+ 1 + endColIndex - aColIndex, damageHeight, aDamageArea);
PRInt32 rowX;
@@ -1951,6 +1990,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
PRInt32 aStartRowIndex,
PRInt32 aNumRowsToRemove,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
@@ -1988,8 +2028,8 @@ void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
mContentRowCount--;
}
aMap.RemoveColsAtEnd();
-
- SetDamageArea(0, aStartRowIndex, aMap.GetColCount(), 0, aDamageArea);
+ SetDamageArea(0, aRgFirstRowIndex + aStartRowIndex, aMap.GetColCount(), 0,
+ aDamageArea);
}
PRInt32 nsCellMap::GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
@@ -2127,6 +2167,7 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellMap& aMap,
nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRInt32 aColIndex,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
@@ -2139,8 +2180,9 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellMap& aMap,
PRUint32 colSpan = GetEffectiveColSpan(aMap, aRowIndex, aColIndex, zeroColSpan);
PRUint32 endRowIndex = aRowIndex + rowSpan - 1;
PRUint32 endColIndex = aColIndex + colSpan - 1;
-
- SetDamageArea(aColIndex, aRowIndex, 1 + endColIndex - aColIndex, 1 + endRowIndex - aRowIndex, aDamageArea);
+ SetDamageArea(aColIndex, aRgFirstRowIndex + aRowIndex,
+ NS_MAX(0, aMap.GetColCount() - aColIndex - 1),
+ 1 + endRowIndex - aRowIndex, aDamageArea);
if (aMap.mTableFrame.HasZeroColSpans()) {
aMap.mTableFrame.SetNeedColSpanExpansion(true);
@@ -2217,8 +2259,7 @@ void
nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
PRInt32 aStartRowIndex,
nsTArray* aRowsToInsert,
- PRInt32 aNumRowsToRemove,
- nsRect& aDamageArea)
+ PRInt32 aNumRowsToRemove)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
// copy the old cell map into a new array
@@ -2252,7 +2293,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
// rowX keeps track of where we are in mRows while setting up the
// new cellmap.
PRUint32 rowX = 0;
-
+ nsRect damageArea;
// put back the rows before the affected ones just as before. Note that we
// can't just copy the old rows in bit-for-bit, because they might be
// spanning out into the rows we're adding/removing.
@@ -2263,7 +2304,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
// put in the original cell from the cell map
const CellData* data = row.ElementAt(colX);
if (data && data->IsOrig()) {
- AppendCell(aMap, data->GetCellFrame(), rowX, false, aDamageArea);
+ AppendCell(aMap, data->GetCellFrame(), rowX, false, 0, damageArea);
}
}
}
@@ -2280,7 +2321,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
while (cFrame) {
nsTableCellFrame *cellFrame = do_QueryFrame(cFrame);
if (cellFrame) {
- AppendCell(aMap, cellFrame, rowX, false, aDamageArea);
+ AppendCell(aMap, cellFrame, rowX, false, 0, damageArea);
}
cFrame = cFrame->GetNextSibling();
}
@@ -2303,7 +2344,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
// put in the original cell from the cell map
CellData* data = row.ElementAt(colX);
if (data && data->IsOrig()) {
- AppendCell(aMap, data->GetCellFrame(), rowX, false, aDamageArea);
+ AppendCell(aMap, data->GetCellFrame(), rowX, false, 0, damageArea);
}
}
rowX++;
@@ -2317,8 +2358,6 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
DestroyCellData(row[colX]);
}
}
-
- SetDamageArea(0, 0, aMap.GetColCount(), GetRowCount(), aDamageArea);
}
void
@@ -2327,8 +2366,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
nsTArray* aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
- bool aInsert,
- nsRect& aDamageArea)
+ bool aInsert)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
// copy the old cell map into a new array
@@ -2345,6 +2383,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
// build the new cell map. Hard to say what, if anything, we can preallocate
// here... Should come back to that sometime, perhaps.
PRInt32 rowX;
+ nsRect damageArea;
for (rowX = 0; rowX < numOrigRows; rowX++) {
const CellDataArray& row = origRows[rowX];
for (PRInt32 colX = 0; colX < numCols; colX++) {
@@ -2353,7 +2392,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
for (PRInt32 cellX = 0; cellX < numNewCells; cellX++) {
nsTableCellFrame* cell = aCellFrames->ElementAt(cellX);
if (cell) {
- AppendCell(aMap, cell, rowX, false, aDamageArea);
+ AppendCell(aMap, cell, rowX, false, 0, damageArea);
}
}
}
@@ -2364,7 +2403,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
// put in the original cell from the cell map
CellData* data = row.SafeElementAt(colX);
if (data && data->IsOrig()) {
- AppendCell(aMap, data->GetCellFrame(), rowX, false, aDamageArea);
+ AppendCell(aMap, data->GetCellFrame(), rowX, false, 0, damageArea);
}
}
}
@@ -2373,7 +2412,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
for (PRInt32 cellX = 0; cellX < numNewCells; cellX++) {
nsTableCellFrame* cell = aCellFrames->ElementAt(cellX);
if (cell) {
- AppendCell(aMap, cell, aRowIndex, false, aDamageArea);
+ AppendCell(aMap, cell, aRowIndex, false, 0, damageArea);
}
}
}
@@ -2396,6 +2435,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
void nsCellMap::RemoveCell(nsTableCellMap& aMap,
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea)
{
PRUint32 numRows = mRows.Length();
@@ -2429,10 +2469,12 @@ void nsCellMap::RemoveCell(nsTableCellMap& aMap,
spansCauseRebuild = true;
if (spansCauseRebuild) {
- aMap.RebuildConsideringCells(this, nsnull, aRowIndex, startColIndex, false, aDamageArea);
+ aMap.RebuildConsideringCells(this, nsnull, aRowIndex, startColIndex, false,
+ aDamageArea);
}
else {
- ShrinkWithoutCell(aMap, *aCellFrame, aRowIndex, startColIndex, aDamageArea);
+ ShrinkWithoutCell(aMap, *aCellFrame, aRowIndex, startColIndex,
+ aRgFirstRowIndex, aDamageArea);
}
}
diff --git a/layout/tables/nsCellMap.h b/layout/tables/nsCellMap.h
index 7792c9217309..8625668fcd3a 100644
--- a/layout/tables/nsCellMap.h
+++ b/layout/tables/nsCellMap.h
@@ -378,6 +378,7 @@ public:
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex,
bool aRebuildIfNecessary,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea,
PRInt32* aBeginSearchAtCol = nsnull);
@@ -401,23 +402,27 @@ public:
nsTArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea);
void RemoveCell(nsTableCellMap& aMap,
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea);
void InsertRows(nsTableCellMap& aMap,
nsTArray& aRows,
PRInt32 aFirstRowIndex,
bool aConsiderSpans,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea);
void RemoveRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
bool aConsiderSpans,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea);
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
@@ -499,6 +504,7 @@ protected:
void ExpandWithRows(nsTableCellMap& aMap,
nsTArray& aRowFrames,
PRInt32 aStartRowIndex,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea);
void ExpandWithCells(nsTableCellMap& aMap,
@@ -507,17 +513,20 @@ protected:
PRInt32 aColIndex,
PRInt32 aRowSpan,
bool aRowSpanIsZero,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea);
void ShrinkWithoutRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea);
void ShrinkWithoutCell(nsTableCellMap& aMap,
nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRInt32 aColIndex,
+ PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea);
/**
@@ -531,16 +540,14 @@ protected:
void RebuildConsideringRows(nsTableCellMap& aMap,
PRInt32 aStartRowIndex,
nsTArray* aRowsToInsert,
- PRInt32 aNumRowsToRemove,
- nsRect& aDamageArea);
+ PRInt32 aNumRowsToRemove);
void RebuildConsideringCells(nsTableCellMap& aMap,
PRInt32 aNumOrigCols,
nsTArray* aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
- bool aInsert,
- nsRect& aDamageArea);
+ bool aInsert);
bool CellsSpanOut(nsTArray& aNewRows) const;
diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp
index 35d80ed55793..bd5d1dcdcd35 100644
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -256,7 +256,7 @@ nsTableCellFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
GetColIndex(colIndex);
GetRowIndex(rowIndex);
nsRect damageArea(colIndex, rowIndex, GetColSpan(), GetRowSpan());
- tableFrame->SetBCDamageArea(damageArea);
+ tableFrame->AddBCDamageArea(damageArea);
}
}
diff --git a/layout/tables/nsTableColFrame.cpp b/layout/tables/nsTableColFrame.cpp
index 104236546c80..ff56d818c690 100644
--- a/layout/tables/nsTableColFrame.cpp
+++ b/layout/tables/nsTableColFrame.cpp
@@ -94,7 +94,7 @@ nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea = nsRect(GetColIndex(), 0, 1, tableFrame->GetRowCount());
- tableFrame->SetBCDamageArea(damageArea);
+ tableFrame->AddBCDamageArea(damageArea);
}
return;
}
diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp
index 5a9a0d1af246..98aa1d067dfa 100644
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -205,7 +205,7 @@ nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
return; // this is a degenerated colgroup
nsRect damageArea(GetFirstColumn()->GetColIndex(), 0, colCount,
tableFrame->GetRowCount());
- tableFrame->SetBCDamageArea(damageArea);
+ tableFrame->AddBCDamageArea(damageArea);
}
return;
}
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index a0451a60f4b5..ac6625362d49 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -148,11 +148,10 @@ struct nsTableReflowState {
struct BCPropertyData
{
- BCPropertyData() { mDamageArea.x = mDamageArea.y = mDamageArea.width =
- mDamageArea.height = mTopBorderWidth = mRightBorderWidth =
- mBottomBorderWidth = mLeftBorderWidth =
- mLeftCellBorderWidth = mRightCellBorderWidth = 0; }
- nsRect mDamageArea;
+ BCPropertyData() : mTopBorderWidth(0), mRightBorderWidth(0),
+ mBottomBorderWidth(0), mLeftBorderWidth(0),
+ mLeftCellBorderWidth(0), mRightCellBorderWidth(0) {}
+ nsRect mDamageArea;
BCPixelSize mTopBorderWidth;
BCPixelSize mRightBorderWidth;
BCPixelSize mBottomBorderWidth;
@@ -351,8 +350,7 @@ nsTableFrame::SetInitialChildList(ChildListID aListID,
InsertRowGroups(mFrames);
// calc collapsing borders
if (IsBorderCollapse()) {
- nsRect damageArea(0, 0, GetColCount(), GetRowCount());
- SetBCDamageArea(damageArea);
+ SetFullBCDamageArea();
}
}
@@ -604,8 +602,8 @@ void nsTableFrame::InsertCol(nsTableColFrame& aColFrame,
}
// for now, just bail and recalc all of the collapsing borders
if (IsBorderCollapse()) {
- nsRect damageArea(0, 0, NS_MAX(1, GetColCount()), NS_MAX(1, GetRowCount()));
- SetBCDamageArea(damageArea);
+ nsRect damageArea(aColIndex, 0, 1, GetRowCount());
+ AddBCDamageArea(damageArea);
}
}
@@ -626,7 +624,7 @@ void nsTableFrame::RemoveCol(nsTableColGroupFrame* aColGroupFrame,
// for now, just bail and recalc all of the collapsing borders
if (IsBorderCollapse()) {
nsRect damageArea(0, 0, GetColCount(), GetRowCount());
- SetBCDamageArea(damageArea);
+ AddBCDamageArea(damageArea);
}
}
@@ -799,7 +797,7 @@ nsTableFrame::AppendCell(nsTableCellFrame& aCellFrame,
cellMap->AppendCell(aCellFrame, aRowIndex, true, damageArea);
MatchCellMapToColCache(cellMap);
if (IsBorderCollapse()) {
- SetBCDamageArea(damageArea);
+ AddBCDamageArea(damageArea);
}
}
}
@@ -814,7 +812,7 @@ void nsTableFrame::InsertCells(nsTArray& aCellFrames,
cellMap->InsertCells(aCellFrames, aRowIndex, aColIndexBefore, damageArea);
MatchCellMapToColCache(cellMap);
if (IsBorderCollapse()) {
- SetBCDamageArea(damageArea);
+ AddBCDamageArea(damageArea);
}
}
}
@@ -854,7 +852,7 @@ void nsTableFrame::RemoveCell(nsTableCellFrame* aCellFrame,
cellMap->RemoveCell(aCellFrame, aRowIndex, damageArea);
MatchCellMapToColCache(cellMap);
if (IsBorderCollapse()) {
- SetBCDamageArea(damageArea);
+ AddBCDamageArea(damageArea);
}
}
}
@@ -919,7 +917,7 @@ nsTableFrame::InsertRows(nsTableRowGroupFrame* aRowGroupFrame,
rowFrame->SetRowIndex(aRowIndex + rowY);
}
if (IsBorderCollapse()) {
- SetBCDamageArea(damageArea);
+ AddBCDamageArea(damageArea);
}
}
#ifdef DEBUG_TABLE_CELLMAP
@@ -962,7 +960,7 @@ void nsTableFrame::RemoveRows(nsTableRowFrame& aFirstRowFrame,
cellMap->RemoveRows(firstRowIndex, aNumRowsToRemove, aConsiderSpans, damageArea);
MatchCellMapToColCache(cellMap);
if (IsBorderCollapse()) {
- SetBCDamageArea(damageArea);
+ AddBCDamageArea(damageArea);
}
}
AdjustRowIndices(firstRowIndex, -aNumRowsToRemove);
@@ -2049,8 +2047,7 @@ nsTableFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
if (IsBorderCollapse() &&
BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
- nsRect damageArea(0, 0, GetColCount(), GetRowCount());
- SetBCDamageArea(damageArea);
+ SetFullBCDamageArea();
}
//avoid this on init or nextinflow
@@ -2309,8 +2306,7 @@ nsTableFrame::RemoveFrame(ChildListID aListID,
// for now, just bail and recalc all of the collapsing borders
// as the cellmap changes we need to recalc
if (IsBorderCollapse()) {
- nsRect damageArea(0, 0, NS_MAX(1, GetColCount()), NS_MAX(1, GetRowCount()));
- SetBCDamageArea(damageArea);
+ SetFullBCDamageArea();
}
PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN);
@@ -2357,6 +2353,20 @@ DestroyBCProperty(void* aPropertyValue)
NS_DECLARE_FRAME_PROPERTY(TableBCProperty, DestroyBCProperty)
+BCPropertyData*
+nsTableFrame::GetBCProperty(bool aCreateIfNecessary) const
+{
+ FrameProperties props = Properties();
+ BCPropertyData* value = static_cast
+ (props.Get(TableBCProperty()));
+ if (!value && aCreateIfNecessary) {
+ value = new BCPropertyData();
+ props.Set(TableBCProperty(), value);
+ }
+
+ return value;
+}
+
static void
DivideBCBorderSize(BCPixelSize aPixelSize,
BCPixelSize& aSmallHalf,
@@ -2374,8 +2384,7 @@ nsTableFrame::GetOuterBCBorder() const
nsMargin border(0, 0, 0, 0);
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
- BCPropertyData* propData = static_cast
- (Properties().Get(TableBCProperty()));
+ BCPropertyData* propData = GetBCProperty();
if (propData) {
border.top = BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right = BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightBorderWidth);
@@ -2393,8 +2402,7 @@ nsTableFrame::GetIncludedOuterBCBorder() const
nsMargin border(0, 0, 0, 0);
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
- BCPropertyData* propData = static_cast
- (Properties().Get(TableBCProperty()));
+ BCPropertyData* propData = GetBCProperty();
if (propData) {
border.top += BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right += BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightCellBorderWidth);
@@ -3767,22 +3775,6 @@ nsTableFrame::ColumnHasCellSpacingBefore(PRInt32 aColIndex) const
return cellMap->GetNumCellsOriginatingInCol(aColIndex) > 0;
}
-static void
-CheckFixDamageArea(PRInt32 aNumRows,
- PRInt32 aNumCols,
- nsRect& aDamageArea)
-{
- if (((aDamageArea.XMost() > aNumCols) && (aDamageArea.width != 1) && (aNumCols != 0)) ||
- ((aDamageArea.YMost() > aNumRows) && (aDamageArea.height != 1) && (aNumRows != 0))) {
- // the damage area was set incorrectly, just be safe and make it the entire table
- NS_ASSERTION(false, "invalid BC damage area");
- aDamageArea.x = 0;
- aDamageArea.y = 0;
- aDamageArea.width = aNumCols;
- aDamageArea.height = aNumRows;
- }
-}
-
/********************************************************************************
* Collapsing Borders
*
@@ -3796,31 +3788,77 @@ CheckFixDamageArea(PRInt32 aNumRows,
* 5) if all border styles are NONE, then that's the computed border style.
*******************************************************************************/
-void
-nsTableFrame::SetBCDamageArea(const nsRect& aValue)
-{
- nsRect newRect(aValue);
- newRect.width = NS_MAX(1, newRect.width);
- newRect.height = NS_MAX(1, newRect.height);
+#ifdef DEBUG
+#define VerifyNonNegativeDamageRect(r) \
+ NS_ASSERTION((r).x >= 0, "negative col index"); \
+ NS_ASSERTION((r).y >= 0, "negative row index"); \
+ NS_ASSERTION((r).width >= 0, "negative horizontal damage"); \
+ NS_ASSERTION((r).height >= 0, "negative vertical damage");
+#define VerifyDamageRect(r) \
+ VerifyNonNegativeDamageRect(r); \
+ NS_ASSERTION((r).XMost() <= GetColCount(), \
+ "horizontal damage extends outside table"); \
+ NS_ASSERTION((r).YMost() <= GetRowCount(), \
+ "vertical damage extends outside table");
+#endif
+
+void
+nsTableFrame::AddBCDamageArea(const nsRect& aValue)
+{
+ NS_ASSERTION(IsBorderCollapse(), "invalid AddBCDamageArea call");
+#ifdef DEBUG
+ VerifyDamageRect(aValue);
+#endif
- if (!IsBorderCollapse()) {
- NS_ASSERTION(false, "invalid call - not border collapse model");
- return;
- }
SetNeedToCalcBCBorders(true);
// Get the property
- FrameProperties props = Properties();
- BCPropertyData* value = static_cast
- (props.Get(TableBCProperty()));
- if (!value) {
- value = new BCPropertyData();
- props.Set(TableBCProperty(), value);
+ BCPropertyData* value = GetBCProperty(true);
+ if (value) {
+#ifdef DEBUG
+ VerifyNonNegativeDamageRect(value->mDamageArea);
+#endif
+ // Clamp the old damage area to the current table area in case it shrunk.
+ PRInt32 cols = GetColCount();
+ if (value->mDamageArea.XMost() > cols) {
+ if (value->mDamageArea.x > cols) {
+ value->mDamageArea.x = cols;
+ value->mDamageArea.width = 0;
+ }
+ else {
+ value->mDamageArea.width = cols - value->mDamageArea.x;
+ }
+ }
+ PRInt32 rows = GetRowCount();
+ if (value->mDamageArea.YMost() > rows) {
+ if (value->mDamageArea.y > rows) {
+ value->mDamageArea.y = rows;
+ value->mDamageArea.height = 0;
+ }
+ else {
+ value->mDamageArea.height = rows - value->mDamageArea.y;
+ }
+ }
+
+ // Construct a union of the new and old damage areas.
+ value->mDamageArea.UnionRect(value->mDamageArea, aValue);
}
- // for now just construct a union of the new and old damage areas
- value->mDamageArea.UnionRect(value->mDamageArea, newRect);
- CheckFixDamageArea(GetRowCount(), GetColCount(), value->mDamageArea);
}
+
+void
+nsTableFrame::SetFullBCDamageArea()
+{
+ NS_ASSERTION(IsBorderCollapse(), "invalid SetFullBCDamageArea call");
+
+ SetNeedToCalcBCBorders(true);
+
+ BCPropertyData* value = GetBCProperty(true);
+ if (value) {
+ value->mDamageArea = nsRect(0, 0, GetColCount(), GetRowCount());
+ }
+}
+
+
/* BCCellBorder represents a border segment which can be either a horizontal
* or a vertical segment. For each segment we need to know the color, width,
* style, who owns it and how long it is in cellmap coordinates.
@@ -4216,7 +4254,9 @@ BCMapCellIterator::SetNewRow(nsTableRowFrame* aRow)
CellData* cellData = row.SafeElementAt(mColIndex);
if (!cellData) { // add a dead cell data
nsRect damageArea;
- cellData = mCellMap->AppendCell(*mTableCellMap, nsnull, rgRowIndex, false, damageArea); if (!cellData) ABORT1(false);
+ cellData = mCellMap->AppendCell(*mTableCellMap, nsnull, rgRowIndex,
+ false, 0, damageArea);
+ if (!cellData) ABORT1(false);
}
if (cellData && (cellData->IsOrig() || cellData->IsDead())) {
break;
@@ -4312,7 +4352,7 @@ BCMapCellIterator::Next(BCMapCellInfo& aMapInfo)
nsRect damageArea;
cellData =
static_cast(mCellMap->AppendCell(*mTableCellMap, nsnull,
- rgRowIndex, false,
+ rgRowIndex, false, 0,
damageArea));
if (!cellData) ABORT0();
}
@@ -4347,7 +4387,7 @@ BCMapCellIterator::PeekRight(BCMapCellInfo& aRefInfo,
nsRect damageArea;
cellData =
static_cast(mCellMap->AppendCell(*mTableCellMap, nsnull,
- rgRowIndex, false,
+ rgRowIndex, false, 0,
damageArea));
if (!cellData) ABORT0();
}
@@ -4405,7 +4445,7 @@ BCMapCellIterator::PeekBottom(BCMapCellInfo& aRefInfo,
nsRect damageArea;
cellData =
static_cast(cellMap->AppendCell(*mTableCellMap, nsnull,
- rgRowIndex, false,
+ rgRowIndex, false, 0,
damageArea));
if (!cellData) ABORT0();
}
@@ -5469,13 +5509,11 @@ nsTableFrame::CalcBCBorders()
return; // nothing to do
// Get the property holding the table damage area and border widths
- BCPropertyData* propData = static_cast
- (Properties().Get(TableBCProperty()));
+ BCPropertyData* propData = GetBCProperty();
if (!propData) ABORT0();
- CheckFixDamageArea(numRows, numCols, propData->mDamageArea);
// calculate an expanded damage area
nsRect damageArea(propData->mDamageArea);
ExpandBCDamageArea(damageArea);
diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h
index 60d671c89fd2..9df26667e630 100644
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -58,6 +58,7 @@ class nsStyleContext;
struct nsTableReflowState;
struct nsStylePosition;
+struct BCPropertyData;
static inline bool IS_TABLE_CELL(nsIAtom* frameType) {
return nsGkAtoms::tableCellFrame == frameType ||
@@ -291,7 +292,7 @@ public:
friend class nsDelayedCalcBCBorders;
- void SetBCDamageArea(const nsRect& aValue);
+ void AddBCDamageArea(const nsRect& aValue);
bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
nsStyleContext* aNewStyleContext);
void PaintBCBorders(nsRenderingContext& aRenderingContext,
@@ -688,10 +689,13 @@ public:
nsTArray& GetColCache();
+
protected:
void SetBorderCollapse(bool aValue);
+ BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const;
+ void SetFullBCDamageArea();
void CalcBCBorders();
void ExpandBCDamageArea(nsRect& aRect) const;
diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp
index 7508c2c5da3c..6835b1d968ca 100644
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -195,7 +195,7 @@ nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(0, GetRowIndex(), tableFrame->GetColCount(), 1);
- tableFrame->SetBCDamageArea(damageArea);
+ tableFrame->AddBCDamageArea(damageArea);
}
return;
}
diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp
index c6c64f49bc23..7f650ea3dd43 100644
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -1389,7 +1389,7 @@ nsTableRowGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(0, GetStartRowIndex(), tableFrame->GetColCount(),
GetRowCount());
- tableFrame->SetBCDamageArea(damageArea);
+ tableFrame->AddBCDamageArea(damageArea);
}
return;
}