bug 460637 - the group cellmaps need to set the damageArea relative to the entire table, patch by Mats Palmgren, Randell Jesup and Bernd, r=mats, bernd

This commit is contained in:
Bernd 2011-10-27 09:58:44 -04:00
parent 62bb78ca2e
commit 844db3e17f
14 changed files with 346 additions and 161 deletions

View File

@ -301,7 +301,7 @@ fails-if(Android) != 192767-17.xul 192767-37.xul
== 283686-3.html about:blank == 283686-3.html about:blank
== 289384-1.xhtml 289384-ref.xhtml == 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 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-1.html 291078-1-ref.html
== 291078-2.html 291078-2-ref.html == 291078-2.html 291078-2-ref.html
== 291262-1.html 291262-1-ref.html == 291262-1.html 291262-1-ref.html

View File

@ -0,0 +1,41 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head><script type="text/javascript">
<![CDATA[
function boom() {
var HTML_NS = "http://www.w3.org/1999/xhtml";
var r = document.documentElement; while(r.firstChild) { r.removeChild(r.firstChild); }
var table = document.createElementNS(HTML_NS, "table");
table.setAttribute("border", "1");
var text = document.createTextNode("\n ");
table.appendChild(text);
var tr1 = document.createElementNS(HTML_NS, "tr");
table.appendChild(tr1);
var tr2 = document.createElementNS(HTML_NS, "tr");
var input = document.createElementNS(HTML_NS, "input");
tr2.appendChild(input);
table.appendChild(tr2);
document.documentElement.appendChild(table);
var tr3 = document.createElementNS(HTML_NS, 'tr');
table.insertBefore(tr3, text);
var td = document.createElementNS(HTML_NS, 'td');
td.setAttribute('rowspan', 0);
tr3.insertBefore(td, null);
table.removeAttribute('border');
var caption = document.createElementNS(HTML_NS, 'caption');
table.insertBefore(caption, tr2);
document.documentElement.removeAttribute("class");
}
function ol(e) {
window.removeEventListener("load", ol, false);
setTimeout(boom, 400);
}
window.addEventListener("load", ol, false);
]]></script>
</head>
<body></body>
</html>

View File

@ -0,0 +1,24 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head><script type="text/javascript">
<![CDATA[
function boom() {
var tr = document.getElementById('tr');
th = document.createElementNS("http://www.w3.org/1999/xhtml", 'th');
th.setAttribute('rowspan', 9);
tr.appendChild(th);
document.documentElement.removeAttribute("class");
}
function ol(e) {
window.removeEventListener("load", ol, false);
setTimeout(boom, 400);
}
window.addEventListener("load", ol, false);
]]></script>
</head>
<body><table style="border-collapse: collapse;"><tbody><tr id="tr"></tr></tbody></table></body>
</html>

View File

@ -0,0 +1,26 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head><script type="text/javascript">
<![CDATA[
function boom() {
const HTML_NS = "http://www.w3.org/1999/xhtml";
var tr4 = document.createElementNS(HTML_NS, 'tr');
document.getElementById('tbody1').appendChild(tr4);
var span1 = document.createElementNS(HTML_NS, 'td');
tr4.insertBefore(span1, null);
document.documentElement.removeAttribute("class");
}
function ol(e) {
window.removeEventListener("load", ol, false);
setTimeout(boom, 400);
}
window.addEventListener("load", ol, false);
]]>
</script>
</head>
<body><table><tbody id="tbody1"><tr><td rowspan="0"></td></tr></tbody></table></body>
</html>

View File

@ -96,6 +96,9 @@ load 448988-1.xhtml
load 450311-1.html load 450311-1.html
load 456041.html load 456041.html
load 457115.html load 457115.html
load 460637-1.xhtml
load 460637-2.xhtml
load 460637-3.xhtml
load 467141-1.html load 467141-1.html
load 488388-1.html load 488388-1.html
load 512749-1.html load 512749-1.html

View File

@ -41,6 +41,24 @@
#include "nsTableCellFrame.h" #include "nsTableCellFrame.h"
#include "nsTableRowGroupFrame.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. // Empty static array used for SafeElementAt() calls on mRows.
static nsCellMap::CellDataArray * sEmptyRow; static nsCellMap::CellDataArray * sEmptyRow;
@ -479,13 +497,13 @@ nsTableCellMap::InsertRows(nsTableRowGroupFrame* aParent,
if ((numNewRows <= 0) || (aFirstRowIndex < 0)) ABORT0(); if ((numNewRows <= 0) || (aFirstRowIndex < 0)) ABORT0();
PRInt32 rowIndex = aFirstRowIndex; PRInt32 rowIndex = aFirstRowIndex;
PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap; nsCellMap* cellMap = mFirstMap;
while (cellMap) { while (cellMap) {
nsTableRowGroupFrame* rg = cellMap->GetRowGroup(); nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
if (rg == aParent) { if (rg == aParent) {
cellMap->InsertRows(*this, aRows, rowIndex, aConsiderSpans, aDamageArea); cellMap->InsertRows(*this, aRows, rowIndex, aConsiderSpans,
aDamageArea.y = NS_MIN(aFirstRowIndex, aDamageArea.y); rgStartRowIndex, aDamageArea);
aDamageArea.height = NS_MAX(0, GetRowCount() - aDamageArea.y);
#ifdef DEBUG_TABLE_CELLMAP #ifdef DEBUG_TABLE_CELLMAP
Dump("after InsertRows"); Dump("after InsertRows");
#endif #endif
@ -507,7 +525,9 @@ nsTableCellMap::InsertRows(nsTableRowGroupFrame* aParent,
} }
return; return;
} }
rowIndex -= cellMap->GetRowCount(); PRInt32 rowCount = cellMap->GetRowCount();
rgStartRowIndex += rowCount;
rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling(); cellMap = cellMap->GetNextSibling();
} }
@ -521,13 +541,13 @@ nsTableCellMap::RemoveRows(PRInt32 aFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
PRInt32 rowIndex = aFirstRowIndex; PRInt32 rowIndex = aFirstRowIndex;
PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap; nsCellMap* cellMap = mFirstMap;
while (cellMap) { while (cellMap) {
if (cellMap->GetRowCount() > rowIndex) { PRInt32 rowCount = cellMap->GetRowCount();
cellMap->RemoveRows(*this, rowIndex, aNumRowsToRemove, aConsiderSpans, aDamageArea); if (rowCount > rowIndex) {
nsTableRowGroupFrame* rg = cellMap->GetRowGroup(); cellMap->RemoveRows(*this, rowIndex, aNumRowsToRemove, aConsiderSpans,
aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0; rgStartRowIndex, aDamageArea);
aDamageArea.height = NS_MAX(0, GetRowCount() - aFirstRowIndex);
if (mBCInfo) { if (mBCInfo) {
for (PRInt32 rowX = aFirstRowIndex + aNumRowsToRemove - 1; rowX >= aFirstRowIndex; rowX--) { for (PRInt32 rowX = aFirstRowIndex + aNumRowsToRemove - 1; rowX >= aFirstRowIndex; rowX--) {
if (PRUint32(rowX) < mBCInfo->mRightBorders.Length()) { if (PRUint32(rowX) < mBCInfo->mRightBorders.Length()) {
@ -537,7 +557,8 @@ nsTableCellMap::RemoveRows(PRInt32 aFirstRowIndex,
} }
break; break;
} }
rowIndex -= cellMap->GetRowCount(); rgStartRowIndex += rowCount;
rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling(); cellMap = cellMap->GetNextSibling();
} }
#ifdef DEBUG_TABLE_CELLMAP #ifdef DEBUG_TABLE_CELLMAP
@ -561,15 +582,18 @@ nsTableCellMap::AppendCell(nsTableCellFrame& aCellFrame,
CellData* result = nsnull; CellData* result = nsnull;
PRInt32 rowIndex = aRowIndex; PRInt32 rowIndex = aRowIndex;
PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap; nsCellMap* cellMap = mFirstMap;
while (cellMap) { while (cellMap) {
if (cellMap->GetRowGroup() == rgFrame) { if (cellMap->GetRowGroup() == rgFrame) {
result = cellMap->AppendCell(*this, &aCellFrame, rowIndex, aRebuildIfNecessary, aDamageArea); result = cellMap->AppendCell(*this, &aCellFrame, rowIndex,
nsTableRowGroupFrame* rg = cellMap->GetRowGroup(); aRebuildIfNecessary, rgStartRowIndex,
aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0; aDamageArea);
break; break;
} }
rowIndex -= cellMap->GetRowCount(); PRInt32 rowCount = cellMap->GetRowCount();
rgStartRowIndex += rowCount;
rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling(); cellMap = cellMap->GetNextSibling();
} }
#ifdef DEBUG_TABLE_CELLMAP #ifdef DEBUG_TABLE_CELLMAP
@ -586,16 +610,17 @@ nsTableCellMap::InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
PRInt32 rowIndex = aRowIndex; PRInt32 rowIndex = aRowIndex;
PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap; nsCellMap* cellMap = mFirstMap;
while (cellMap) { while (cellMap) {
if (cellMap->GetRowCount() > rowIndex) { PRInt32 rowCount = cellMap->GetRowCount();
cellMap->InsertCells(*this, aCellFrames, rowIndex, aColIndexBefore, aDamageArea); if (rowCount > rowIndex) {
nsTableRowGroupFrame* rg = cellMap->GetRowGroup(); cellMap->InsertCells(*this, aCellFrames, rowIndex, aColIndexBefore,
aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0; rgStartRowIndex, aDamageArea);
aDamageArea.width = NS_MAX(0, GetColCount() - aColIndexBefore - 1);
break; break;
} }
rowIndex -= cellMap->GetRowCount(); rgStartRowIndex += rowCount;
rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling(); cellMap = cellMap->GetNextSibling();
} }
#ifdef DEBUG_TABLE_CELLMAP #ifdef DEBUG_TABLE_CELLMAP
@ -613,21 +638,20 @@ nsTableCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
NS_ASSERTION(aCellFrame == (nsTableCellFrame *)aCellFrame->GetFirstInFlow(), NS_ASSERTION(aCellFrame == (nsTableCellFrame *)aCellFrame->GetFirstInFlow(),
"invalid call on continuing frame"); "invalid call on continuing frame");
PRInt32 rowIndex = aRowIndex; PRInt32 rowIndex = aRowIndex;
PRInt32 rgStartRowIndex = 0;
nsCellMap* cellMap = mFirstMap; nsCellMap* cellMap = mFirstMap;
while (cellMap) { while (cellMap) {
if (cellMap->GetRowCount() > rowIndex) { PRInt32 rowCount = cellMap->GetRowCount();
cellMap->RemoveCell(*this, aCellFrame, rowIndex, aDamageArea); if (rowCount > rowIndex) {
nsTableRowGroupFrame* rg = cellMap->GetRowGroup(); cellMap->RemoveCell(*this, aCellFrame, rowIndex, rgStartRowIndex,
aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0; aDamageArea);
PRInt32 colIndex;
aCellFrame->GetColIndex(colIndex);
aDamageArea.width = NS_MAX(0, GetColCount() - colIndex - 1);
#ifdef DEBUG_TABLE_CELLMAP #ifdef DEBUG_TABLE_CELLMAP
Dump("after RemoveCell"); Dump("after RemoveCell");
#endif #endif
return; return;
} }
rowIndex -= cellMap->GetRowCount(); rgStartRowIndex += rowCount;
rowIndex -= rowCount;
cellMap = cellMap->GetNextSibling(); cellMap = cellMap->GetNextSibling();
} }
// if we reach this point - the cell did not get removed, the caller of this routine // 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"); 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 void
nsTableCellMap::RebuildConsideringCells(nsCellMap* aCellMap, nsTableCellMap::RebuildConsideringCells(nsCellMap* aCellMap,
nsTArray<nsTableCellFrame*>* aCellFrames, nsTArray<nsTableCellFrame*>* aCellFrames,
@ -664,11 +675,12 @@ nsTableCellMap::RebuildConsideringCells(nsCellMap* aCellMap,
PRInt32 rowCount = 0; PRInt32 rowCount = 0;
while (cellMap) { while (cellMap) {
if (cellMap == aCellMap) { if (cellMap == aCellMap) {
cellMap->RebuildConsideringCells(*this, numOrigCols, aCellFrames, aRowIndex, aColIndex, aInsert, aDamageArea); cellMap->RebuildConsideringCells(*this, numOrigCols, aCellFrames,
aRowIndex, aColIndex, aInsert);
} }
else { else {
cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0, false, aDamageArea); cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0,
false);
} }
rowCount += cellMap->GetRowCount(); rowCount += cellMap->GetRowCount();
cellMap = cellMap->GetNextSibling(); cellMap = cellMap->GetNextSibling();
@ -692,10 +704,12 @@ nsTableCellMap::RebuildConsideringRows(nsCellMap* aCellMap,
PRInt32 rowCount = 0; PRInt32 rowCount = 0;
while (cellMap) { while (cellMap) {
if (cellMap == aCellMap) { if (cellMap == aCellMap) {
cellMap->RebuildConsideringRows(*this, aStartRowIndex, aRowsToInsert, aNumRowsToRemove, aDamageArea); cellMap->RebuildConsideringRows(*this, aStartRowIndex, aRowsToInsert,
aNumRowsToRemove);
} }
else { else {
cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0, false, aDamageArea); cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0,
false);
} }
rowCount += cellMap->GetRowCount(); rowCount += cellMap->GetRowCount();
cellMap = cellMap->GetNextSibling(); cellMap = cellMap->GetNextSibling();
@ -1015,7 +1029,9 @@ nsTableCellMap::SetBCBorderEdge(mozilla::css::Side aSide,
PRInt32 numRgRows = aCellMap.GetRowCount(); PRInt32 numRgRows = aCellMap.GetRowCount();
if (yPos < numRgRows) { // add a dead cell data if (yPos < numRgRows) { // add a dead cell data
nsRect damageArea; 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 { else {
NS_ASSERTION(aSide == NS_SIDE_BOTTOM, "program error"); NS_ASSERTION(aSide == NS_SIDE_BOTTOM, "program error");
@ -1028,7 +1044,9 @@ nsTableCellMap::SetBCBorderEdge(mozilla::css::Side aSide,
cellData = (BCCellData*)cellMap->GetDataAt(0, xIndex); cellData = (BCCellData*)cellMap->GetDataAt(0, xIndex);
if (!cellData) { // add a dead cell if (!cellData) { // add a dead cell
nsRect damageArea; 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 else { // must be at the end of the table
@ -1121,7 +1139,8 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner,
PRInt32 numRgRows = aCellMap.GetRowCount(); PRInt32 numRgRows = aCellMap.GetRowCount();
if (yPos < numRgRows) { // add a dead cell data if (yPos < numRgRows) { // add a dead cell data
nsRect damageArea; nsRect damageArea;
cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos, false, damageArea); cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos,
false, 0, damageArea);
} }
else { else {
// try the next non empty row group // try the next non empty row group
@ -1133,7 +1152,8 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner,
cellData = (BCCellData*)cellMap->GetDataAt(0, xPos); cellData = (BCCellData*)cellMap->GetDataAt(0, xPos);
if (!cellData) { // add a dead cell if (!cellData) { // add a dead cell
nsRect damageArea; 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 else { // must be at the bottom of the table
@ -1337,6 +1357,7 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
nsTArray<nsTableRowFrame*>& aRows, nsTArray<nsTableRowFrame*>& aRows,
PRInt32 aFirstRowIndex, PRInt32 aFirstRowIndex,
bool aConsiderSpans, bool aConsiderSpans,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
PRInt32 numCols = aMap.GetColCount(); PRInt32 numCols = aMap.GetColCount();
@ -1352,7 +1373,7 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
if (!aConsiderSpans) { if (!aConsiderSpans) {
// update mContentRowCount, since non-empty rows will be added // update mContentRowCount, since non-empty rows will be added
mContentRowCount = NS_MAX(aFirstRowIndex, mContentRowCount); mContentRowCount = NS_MAX(aFirstRowIndex, mContentRowCount);
ExpandWithRows(aMap, aRows, aFirstRowIndex, aDamageArea); ExpandWithRows(aMap, aRows, aFirstRowIndex, aRgFirstRowIndex, aDamageArea);
return; return;
} }
@ -1368,12 +1389,11 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
if (!spansCauseRebuild && (PRUint32(aFirstRowIndex) < mRows.Length())) { if (!spansCauseRebuild && (PRUint32(aFirstRowIndex) < mRows.Length())) {
spansCauseRebuild = CellsSpanOut(aRows); spansCauseRebuild = CellsSpanOut(aRows);
} }
if (spansCauseRebuild) { if (spansCauseRebuild) {
aMap.RebuildConsideringRows(this, aFirstRowIndex, &aRows, 0, aDamageArea); aMap.RebuildConsideringRows(this, aFirstRowIndex, &aRows, 0, aDamageArea);
} }
else { else {
ExpandWithRows(aMap, aRows, aFirstRowIndex, aDamageArea); ExpandWithRows(aMap, aRows, aFirstRowIndex, aRgFirstRowIndex, aDamageArea);
} }
} }
@ -1382,6 +1402,7 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex, PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove, PRInt32 aNumRowsToRemove,
bool aConsiderSpans, bool aConsiderSpans,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
PRInt32 numRows = mRows.Length(); PRInt32 numRows = mRows.Length();
@ -1395,7 +1416,8 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
return; return;
} }
if (!aConsiderSpans) { if (!aConsiderSpans) {
ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aDamageArea); ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aRgFirstRowIndex,
aDamageArea);
return; return;
} }
PRInt32 endRowIndex = aFirstRowIndex + aNumRowsToRemove - 1; PRInt32 endRowIndex = aFirstRowIndex + aNumRowsToRemove - 1;
@ -1405,12 +1427,13 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
} }
bool spansCauseRebuild = CellsSpanInOrOut(aFirstRowIndex, endRowIndex, bool spansCauseRebuild = CellsSpanInOrOut(aFirstRowIndex, endRowIndex,
0, numCols - 1); 0, numCols - 1);
if (spansCauseRebuild) { if (spansCauseRebuild) {
aMap.RebuildConsideringRows(this, aFirstRowIndex, nsnull, aNumRowsToRemove, aDamageArea); aMap.RebuildConsideringRows(this, aFirstRowIndex, nsnull, aNumRowsToRemove,
aDamageArea);
} }
else { else {
ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aDamageArea); ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aRgFirstRowIndex,
aDamageArea);
} }
} }
@ -1422,6 +1445,7 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
nsTableCellFrame* aCellFrame, nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex, PRInt32 aRowIndex,
bool aRebuildIfNecessary, bool aRebuildIfNecessary,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea, nsRect& aDamageArea,
PRInt32* aColToBeginSearch) PRInt32* aColToBeginSearch)
{ {
@ -1514,7 +1538,15 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
SetDataAt(aMap, *origData, aRowIndex, startColIndex); 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) { if (!aCellFrame) {
return origData; return origData;
@ -1723,6 +1755,7 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
nsTArray<nsTableCellFrame*>& aCellFrames, nsTArray<nsTableCellFrame*>& aCellFrames,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndexBefore, PRInt32 aColIndexBefore,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
if (aCellFrames.Length() == 0) return; if (aCellFrames.Length() == 0) return;
@ -1779,12 +1812,13 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
spansCauseRebuild = CellsSpanInOrOut(aRowIndex, aRowIndex + rowSpan - 1, spansCauseRebuild = CellsSpanInOrOut(aRowIndex, aRowIndex + rowSpan - 1,
startColIndex, numCols - 1); startColIndex, numCols - 1);
} }
if (spansCauseRebuild) { if (spansCauseRebuild) {
aMap.RebuildConsideringCells(this, &aCellFrames, aRowIndex, startColIndex, true, aDamageArea); aMap.RebuildConsideringCells(this, &aCellFrames, aRowIndex, startColIndex,
true, aDamageArea);
} }
else { 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, nsCellMap::ExpandWithRows(nsTableCellMap& aMap,
nsTArray<nsTableRowFrame*>& aRowFrames, nsTArray<nsTableRowFrame*>& aRowFrames,
PRInt32 aStartRowIndexIn, PRInt32 aStartRowIndexIn,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
PRInt32 startRowIndex = (aStartRowIndexIn >= 0) ? aStartRowIndexIn : 0; PRInt32 startRowIndex = (aStartRowIndexIn >= 0) ? aStartRowIndexIn : 0;
@ -1818,14 +1853,15 @@ nsCellMap::ExpandWithRows(nsTableCellMap& aMap,
while (cFrame) { while (cFrame) {
nsTableCellFrame *cellFrame = do_QueryFrame(cFrame); nsTableCellFrame *cellFrame = do_QueryFrame(cFrame);
if (cellFrame) { if (cellFrame) {
AppendCell(aMap, cellFrame, rowX, false, aDamageArea, &colIndex); AppendCell(aMap, cellFrame, rowX, false, aRgFirstRowIndex, aDamageArea,
&colIndex);
} }
cFrame = cFrame->GetNextSibling(); cFrame = cFrame->GetNextSibling();
} }
newRowIndex++; newRowIndex++;
} }
SetDamageArea(0, aRgFirstRowIndex + startRowIndex, aMap.GetColCount(),
SetDamageArea(0, startRowIndex, aMap.GetColCount(), 1 + endRowIndex - startRowIndex, aDamageArea); 1 + endRowIndex - startRowIndex, aDamageArea);
} }
void nsCellMap::ExpandWithCells(nsTableCellMap& aMap, void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
@ -1834,6 +1870,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
PRInt32 aColIndex, PRInt32 aColIndex,
PRInt32 aRowSpan, // same for all cells PRInt32 aRowSpan, // same for all cells
bool aRowSpanIsZero, bool aRowSpanIsZero,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch"); NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
@ -1908,8 +1945,10 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
} }
cellFrame->SetColIndex(startColIndex); cellFrame->SetColIndex(startColIndex);
} }
PRInt32 damageHeight = NS_MIN(GetRowGroup()->GetRowCount() - aRowIndex, aRowSpan); PRInt32 damageHeight = NS_MIN(GetRowGroup()->GetRowCount() - aRowIndex,
SetDamageArea(aColIndex, aRowIndex, 1 + endColIndex - aColIndex, damageHeight, aDamageArea); aRowSpan);
SetDamageArea(aColIndex, aRgFirstRowIndex + aRowIndex,
1 + endColIndex - aColIndex, damageHeight, aDamageArea);
PRInt32 rowX; PRInt32 rowX;
@ -1951,6 +1990,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap, void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
PRInt32 aStartRowIndex, PRInt32 aStartRowIndex,
PRInt32 aNumRowsToRemove, PRInt32 aNumRowsToRemove,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch"); NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
@ -1988,8 +2028,8 @@ void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
mContentRowCount--; mContentRowCount--;
} }
aMap.RemoveColsAtEnd(); aMap.RemoveColsAtEnd();
SetDamageArea(0, aRgFirstRowIndex + aStartRowIndex, aMap.GetColCount(), 0,
SetDamageArea(0, aStartRowIndex, aMap.GetColCount(), 0, aDamageArea); aDamageArea);
} }
PRInt32 nsCellMap::GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd, PRInt32 nsCellMap::GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
@ -2127,6 +2167,7 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellMap& aMap,
nsTableCellFrame& aCellFrame, nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex, PRInt32 aColIndex,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch"); 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 colSpan = GetEffectiveColSpan(aMap, aRowIndex, aColIndex, zeroColSpan);
PRUint32 endRowIndex = aRowIndex + rowSpan - 1; PRUint32 endRowIndex = aRowIndex + rowSpan - 1;
PRUint32 endColIndex = aColIndex + colSpan - 1; PRUint32 endColIndex = aColIndex + colSpan - 1;
SetDamageArea(aColIndex, aRgFirstRowIndex + aRowIndex,
SetDamageArea(aColIndex, aRowIndex, 1 + endColIndex - aColIndex, 1 + endRowIndex - aRowIndex, aDamageArea); NS_MAX(0, aMap.GetColCount() - aColIndex - 1),
1 + endRowIndex - aRowIndex, aDamageArea);
if (aMap.mTableFrame.HasZeroColSpans()) { if (aMap.mTableFrame.HasZeroColSpans()) {
aMap.mTableFrame.SetNeedColSpanExpansion(true); aMap.mTableFrame.SetNeedColSpanExpansion(true);
@ -2217,8 +2259,7 @@ void
nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap, nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
PRInt32 aStartRowIndex, PRInt32 aStartRowIndex,
nsTArray<nsTableRowFrame*>* aRowsToInsert, nsTArray<nsTableRowFrame*>* aRowsToInsert,
PRInt32 aNumRowsToRemove, PRInt32 aNumRowsToRemove)
nsRect& aDamageArea)
{ {
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch"); NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
// copy the old cell map into a new array // 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 // rowX keeps track of where we are in mRows while setting up the
// new cellmap. // new cellmap.
PRUint32 rowX = 0; PRUint32 rowX = 0;
nsRect damageArea;
// put back the rows before the affected ones just as before. Note that we // 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 // can't just copy the old rows in bit-for-bit, because they might be
// spanning out into the rows we're adding/removing. // 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 // put in the original cell from the cell map
const CellData* data = row.ElementAt(colX); const CellData* data = row.ElementAt(colX);
if (data && data->IsOrig()) { 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) { while (cFrame) {
nsTableCellFrame *cellFrame = do_QueryFrame(cFrame); nsTableCellFrame *cellFrame = do_QueryFrame(cFrame);
if (cellFrame) { if (cellFrame) {
AppendCell(aMap, cellFrame, rowX, false, aDamageArea); AppendCell(aMap, cellFrame, rowX, false, 0, damageArea);
} }
cFrame = cFrame->GetNextSibling(); cFrame = cFrame->GetNextSibling();
} }
@ -2303,7 +2344,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
// put in the original cell from the cell map // put in the original cell from the cell map
CellData* data = row.ElementAt(colX); CellData* data = row.ElementAt(colX);
if (data && data->IsOrig()) { if (data && data->IsOrig()) {
AppendCell(aMap, data->GetCellFrame(), rowX, false, aDamageArea); AppendCell(aMap, data->GetCellFrame(), rowX, false, 0, damageArea);
} }
} }
rowX++; rowX++;
@ -2317,8 +2358,6 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
DestroyCellData(row[colX]); DestroyCellData(row[colX]);
} }
} }
SetDamageArea(0, 0, aMap.GetColCount(), GetRowCount(), aDamageArea);
} }
void void
@ -2327,8 +2366,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
nsTArray<nsTableCellFrame*>* aCellFrames, nsTArray<nsTableCellFrame*>* aCellFrames,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex, PRInt32 aColIndex,
bool aInsert, bool aInsert)
nsRect& aDamageArea)
{ {
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch"); NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
// copy the old cell map into a new array // 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 // build the new cell map. Hard to say what, if anything, we can preallocate
// here... Should come back to that sometime, perhaps. // here... Should come back to that sometime, perhaps.
PRInt32 rowX; PRInt32 rowX;
nsRect damageArea;
for (rowX = 0; rowX < numOrigRows; rowX++) { for (rowX = 0; rowX < numOrigRows; rowX++) {
const CellDataArray& row = origRows[rowX]; const CellDataArray& row = origRows[rowX];
for (PRInt32 colX = 0; colX < numCols; colX++) { for (PRInt32 colX = 0; colX < numCols; colX++) {
@ -2353,7 +2392,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
for (PRInt32 cellX = 0; cellX < numNewCells; cellX++) { for (PRInt32 cellX = 0; cellX < numNewCells; cellX++) {
nsTableCellFrame* cell = aCellFrames->ElementAt(cellX); nsTableCellFrame* cell = aCellFrames->ElementAt(cellX);
if (cell) { 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 // put in the original cell from the cell map
CellData* data = row.SafeElementAt(colX); CellData* data = row.SafeElementAt(colX);
if (data && data->IsOrig()) { 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++) { for (PRInt32 cellX = 0; cellX < numNewCells; cellX++) {
nsTableCellFrame* cell = aCellFrames->ElementAt(cellX); nsTableCellFrame* cell = aCellFrames->ElementAt(cellX);
if (cell) { 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, void nsCellMap::RemoveCell(nsTableCellMap& aMap,
nsTableCellFrame* aCellFrame, nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea) nsRect& aDamageArea)
{ {
PRUint32 numRows = mRows.Length(); PRUint32 numRows = mRows.Length();
@ -2429,10 +2469,12 @@ void nsCellMap::RemoveCell(nsTableCellMap& aMap,
spansCauseRebuild = true; spansCauseRebuild = true;
if (spansCauseRebuild) { if (spansCauseRebuild) {
aMap.RebuildConsideringCells(this, nsnull, aRowIndex, startColIndex, false, aDamageArea); aMap.RebuildConsideringCells(this, nsnull, aRowIndex, startColIndex, false,
aDamageArea);
} }
else { else {
ShrinkWithoutCell(aMap, *aCellFrame, aRowIndex, startColIndex, aDamageArea); ShrinkWithoutCell(aMap, *aCellFrame, aRowIndex, startColIndex,
aRgFirstRowIndex, aDamageArea);
} }
} }

View File

@ -378,6 +378,7 @@ public:
nsTableCellFrame* aCellFrame, nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex, PRInt32 aRowIndex,
bool aRebuildIfNecessary, bool aRebuildIfNecessary,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea, nsRect& aDamageArea,
PRInt32* aBeginSearchAtCol = nsnull); PRInt32* aBeginSearchAtCol = nsnull);
@ -401,23 +402,27 @@ public:
nsTArray<nsTableCellFrame*>& aCellFrames, nsTArray<nsTableCellFrame*>& aCellFrames,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndexBefore, PRInt32 aColIndexBefore,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea); nsRect& aDamageArea);
void RemoveCell(nsTableCellMap& aMap, void RemoveCell(nsTableCellMap& aMap,
nsTableCellFrame* aCellFrame, nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea); nsRect& aDamageArea);
void InsertRows(nsTableCellMap& aMap, void InsertRows(nsTableCellMap& aMap,
nsTArray<nsTableRowFrame*>& aRows, nsTArray<nsTableRowFrame*>& aRows,
PRInt32 aFirstRowIndex, PRInt32 aFirstRowIndex,
bool aConsiderSpans, bool aConsiderSpans,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea); nsRect& aDamageArea);
void RemoveRows(nsTableCellMap& aMap, void RemoveRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex, PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove, PRInt32 aNumRowsToRemove,
bool aConsiderSpans, bool aConsiderSpans,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea); nsRect& aDamageArea);
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const; PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
@ -499,6 +504,7 @@ protected:
void ExpandWithRows(nsTableCellMap& aMap, void ExpandWithRows(nsTableCellMap& aMap,
nsTArray<nsTableRowFrame*>& aRowFrames, nsTArray<nsTableRowFrame*>& aRowFrames,
PRInt32 aStartRowIndex, PRInt32 aStartRowIndex,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea); nsRect& aDamageArea);
void ExpandWithCells(nsTableCellMap& aMap, void ExpandWithCells(nsTableCellMap& aMap,
@ -507,17 +513,20 @@ protected:
PRInt32 aColIndex, PRInt32 aColIndex,
PRInt32 aRowSpan, PRInt32 aRowSpan,
bool aRowSpanIsZero, bool aRowSpanIsZero,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea); nsRect& aDamageArea);
void ShrinkWithoutRows(nsTableCellMap& aMap, void ShrinkWithoutRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex, PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove, PRInt32 aNumRowsToRemove,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea); nsRect& aDamageArea);
void ShrinkWithoutCell(nsTableCellMap& aMap, void ShrinkWithoutCell(nsTableCellMap& aMap,
nsTableCellFrame& aCellFrame, nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex, PRInt32 aColIndex,
PRInt32 aRgFirstRowIndex,
nsRect& aDamageArea); nsRect& aDamageArea);
/** /**
@ -531,16 +540,14 @@ protected:
void RebuildConsideringRows(nsTableCellMap& aMap, void RebuildConsideringRows(nsTableCellMap& aMap,
PRInt32 aStartRowIndex, PRInt32 aStartRowIndex,
nsTArray<nsTableRowFrame*>* aRowsToInsert, nsTArray<nsTableRowFrame*>* aRowsToInsert,
PRInt32 aNumRowsToRemove, PRInt32 aNumRowsToRemove);
nsRect& aDamageArea);
void RebuildConsideringCells(nsTableCellMap& aMap, void RebuildConsideringCells(nsTableCellMap& aMap,
PRInt32 aNumOrigCols, PRInt32 aNumOrigCols,
nsTArray<nsTableCellFrame*>* aCellFrames, nsTArray<nsTableCellFrame*>* aCellFrames,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex, PRInt32 aColIndex,
bool aInsert, bool aInsert);
nsRect& aDamageArea);
bool CellsSpanOut(nsTArray<nsTableRowFrame*>& aNewRows) const; bool CellsSpanOut(nsTArray<nsTableRowFrame*>& aNewRows) const;

View File

@ -256,7 +256,7 @@ nsTableCellFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
GetColIndex(colIndex); GetColIndex(colIndex);
GetRowIndex(rowIndex); GetRowIndex(rowIndex);
nsRect damageArea(colIndex, rowIndex, GetColSpan(), GetRowSpan()); nsRect damageArea(colIndex, rowIndex, GetColSpan(), GetRowSpan());
tableFrame->SetBCDamageArea(damageArea); tableFrame->AddBCDamageArea(damageArea);
} }
} }

View File

@ -94,7 +94,7 @@ nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
if (tableFrame->IsBorderCollapse() && if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) { tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea = nsRect(GetColIndex(), 0, 1, tableFrame->GetRowCount()); nsRect damageArea = nsRect(GetColIndex(), 0, 1, tableFrame->GetRowCount());
tableFrame->SetBCDamageArea(damageArea); tableFrame->AddBCDamageArea(damageArea);
} }
return; return;
} }

View File

@ -205,7 +205,7 @@ nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
return; // this is a degenerated colgroup return; // this is a degenerated colgroup
nsRect damageArea(GetFirstColumn()->GetColIndex(), 0, colCount, nsRect damageArea(GetFirstColumn()->GetColIndex(), 0, colCount,
tableFrame->GetRowCount()); tableFrame->GetRowCount());
tableFrame->SetBCDamageArea(damageArea); tableFrame->AddBCDamageArea(damageArea);
} }
return; return;
} }

View File

@ -148,11 +148,10 @@ struct nsTableReflowState {
struct BCPropertyData struct BCPropertyData
{ {
BCPropertyData() { mDamageArea.x = mDamageArea.y = mDamageArea.width = BCPropertyData() : mTopBorderWidth(0), mRightBorderWidth(0),
mDamageArea.height = mTopBorderWidth = mRightBorderWidth = mBottomBorderWidth(0), mLeftBorderWidth(0),
mBottomBorderWidth = mLeftBorderWidth = mLeftCellBorderWidth(0), mRightCellBorderWidth(0) {}
mLeftCellBorderWidth = mRightCellBorderWidth = 0; } nsRect mDamageArea;
nsRect mDamageArea;
BCPixelSize mTopBorderWidth; BCPixelSize mTopBorderWidth;
BCPixelSize mRightBorderWidth; BCPixelSize mRightBorderWidth;
BCPixelSize mBottomBorderWidth; BCPixelSize mBottomBorderWidth;
@ -351,8 +350,7 @@ nsTableFrame::SetInitialChildList(ChildListID aListID,
InsertRowGroups(mFrames); InsertRowGroups(mFrames);
// calc collapsing borders // calc collapsing borders
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
nsRect damageArea(0, 0, GetColCount(), GetRowCount()); SetFullBCDamageArea();
SetBCDamageArea(damageArea);
} }
} }
@ -604,8 +602,8 @@ void nsTableFrame::InsertCol(nsTableColFrame& aColFrame,
} }
// for now, just bail and recalc all of the collapsing borders // for now, just bail and recalc all of the collapsing borders
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
nsRect damageArea(0, 0, NS_MAX(1, GetColCount()), NS_MAX(1, GetRowCount())); nsRect damageArea(aColIndex, 0, 1, GetRowCount());
SetBCDamageArea(damageArea); AddBCDamageArea(damageArea);
} }
} }
@ -626,7 +624,7 @@ void nsTableFrame::RemoveCol(nsTableColGroupFrame* aColGroupFrame,
// for now, just bail and recalc all of the collapsing borders // for now, just bail and recalc all of the collapsing borders
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
nsRect damageArea(0, 0, GetColCount(), GetRowCount()); nsRect damageArea(0, 0, GetColCount(), GetRowCount());
SetBCDamageArea(damageArea); AddBCDamageArea(damageArea);
} }
} }
@ -799,7 +797,7 @@ nsTableFrame::AppendCell(nsTableCellFrame& aCellFrame,
cellMap->AppendCell(aCellFrame, aRowIndex, true, damageArea); cellMap->AppendCell(aCellFrame, aRowIndex, true, damageArea);
MatchCellMapToColCache(cellMap); MatchCellMapToColCache(cellMap);
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
SetBCDamageArea(damageArea); AddBCDamageArea(damageArea);
} }
} }
} }
@ -814,7 +812,7 @@ void nsTableFrame::InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
cellMap->InsertCells(aCellFrames, aRowIndex, aColIndexBefore, damageArea); cellMap->InsertCells(aCellFrames, aRowIndex, aColIndexBefore, damageArea);
MatchCellMapToColCache(cellMap); MatchCellMapToColCache(cellMap);
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
SetBCDamageArea(damageArea); AddBCDamageArea(damageArea);
} }
} }
} }
@ -854,7 +852,7 @@ void nsTableFrame::RemoveCell(nsTableCellFrame* aCellFrame,
cellMap->RemoveCell(aCellFrame, aRowIndex, damageArea); cellMap->RemoveCell(aCellFrame, aRowIndex, damageArea);
MatchCellMapToColCache(cellMap); MatchCellMapToColCache(cellMap);
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
SetBCDamageArea(damageArea); AddBCDamageArea(damageArea);
} }
} }
} }
@ -919,7 +917,7 @@ nsTableFrame::InsertRows(nsTableRowGroupFrame* aRowGroupFrame,
rowFrame->SetRowIndex(aRowIndex + rowY); rowFrame->SetRowIndex(aRowIndex + rowY);
} }
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
SetBCDamageArea(damageArea); AddBCDamageArea(damageArea);
} }
} }
#ifdef DEBUG_TABLE_CELLMAP #ifdef DEBUG_TABLE_CELLMAP
@ -962,7 +960,7 @@ void nsTableFrame::RemoveRows(nsTableRowFrame& aFirstRowFrame,
cellMap->RemoveRows(firstRowIndex, aNumRowsToRemove, aConsiderSpans, damageArea); cellMap->RemoveRows(firstRowIndex, aNumRowsToRemove, aConsiderSpans, damageArea);
MatchCellMapToColCache(cellMap); MatchCellMapToColCache(cellMap);
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
SetBCDamageArea(damageArea); AddBCDamageArea(damageArea);
} }
} }
AdjustRowIndices(firstRowIndex, -aNumRowsToRemove); AdjustRowIndices(firstRowIndex, -aNumRowsToRemove);
@ -2049,8 +2047,7 @@ nsTableFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
if (IsBorderCollapse() && if (IsBorderCollapse() &&
BCRecalcNeeded(aOldStyleContext, GetStyleContext())) { BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(0, 0, GetColCount(), GetRowCount()); SetFullBCDamageArea();
SetBCDamageArea(damageArea);
} }
//avoid this on init or nextinflow //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 // for now, just bail and recalc all of the collapsing borders
// as the cellmap changes we need to recalc // as the cellmap changes we need to recalc
if (IsBorderCollapse()) { if (IsBorderCollapse()) {
nsRect damageArea(0, 0, NS_MAX(1, GetColCount()), NS_MAX(1, GetRowCount())); SetFullBCDamageArea();
SetBCDamageArea(damageArea);
} }
PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange, PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN); NS_FRAME_HAS_DIRTY_CHILDREN);
@ -2357,6 +2353,20 @@ DestroyBCProperty(void* aPropertyValue)
NS_DECLARE_FRAME_PROPERTY(TableBCProperty, DestroyBCProperty) NS_DECLARE_FRAME_PROPERTY(TableBCProperty, DestroyBCProperty)
BCPropertyData*
nsTableFrame::GetBCProperty(bool aCreateIfNecessary) const
{
FrameProperties props = Properties();
BCPropertyData* value = static_cast<BCPropertyData*>
(props.Get(TableBCProperty()));
if (!value && aCreateIfNecessary) {
value = new BCPropertyData();
props.Set(TableBCProperty(), value);
}
return value;
}
static void static void
DivideBCBorderSize(BCPixelSize aPixelSize, DivideBCBorderSize(BCPixelSize aPixelSize,
BCPixelSize& aSmallHalf, BCPixelSize& aSmallHalf,
@ -2374,8 +2384,7 @@ nsTableFrame::GetOuterBCBorder() const
nsMargin border(0, 0, 0, 0); nsMargin border(0, 0, 0, 0);
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel(); PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
BCPropertyData* propData = static_cast<BCPropertyData*> BCPropertyData* propData = GetBCProperty();
(Properties().Get(TableBCProperty()));
if (propData) { if (propData) {
border.top = BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth); border.top = BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right = BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightBorderWidth); border.right = BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightBorderWidth);
@ -2393,8 +2402,7 @@ nsTableFrame::GetIncludedOuterBCBorder() const
nsMargin border(0, 0, 0, 0); nsMargin border(0, 0, 0, 0);
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel(); PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
BCPropertyData* propData = static_cast<BCPropertyData*> BCPropertyData* propData = GetBCProperty();
(Properties().Get(TableBCProperty()));
if (propData) { if (propData) {
border.top += BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth); border.top += BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right += BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightCellBorderWidth); border.right += BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightCellBorderWidth);
@ -3767,22 +3775,6 @@ nsTableFrame::ColumnHasCellSpacingBefore(PRInt32 aColIndex) const
return cellMap->GetNumCellsOriginatingInCol(aColIndex) > 0; 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 * Collapsing Borders
* *
@ -3796,31 +3788,77 @@ CheckFixDamageArea(PRInt32 aNumRows,
* 5) if all border styles are NONE, then that's the computed border style. * 5) if all border styles are NONE, then that's the computed border style.
*******************************************************************************/ *******************************************************************************/
void #ifdef DEBUG
nsTableFrame::SetBCDamageArea(const nsRect& aValue) #define VerifyNonNegativeDamageRect(r) \
{ NS_ASSERTION((r).x >= 0, "negative col index"); \
nsRect newRect(aValue); NS_ASSERTION((r).y >= 0, "negative row index"); \
newRect.width = NS_MAX(1, newRect.width); NS_ASSERTION((r).width >= 0, "negative horizontal damage"); \
newRect.height = NS_MAX(1, newRect.height); 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); SetNeedToCalcBCBorders(true);
// Get the property // Get the property
FrameProperties props = Properties(); BCPropertyData* value = GetBCProperty(true);
BCPropertyData* value = static_cast<BCPropertyData*> if (value) {
(props.Get(TableBCProperty())); #ifdef DEBUG
if (!value) { VerifyNonNegativeDamageRect(value->mDamageArea);
value = new BCPropertyData(); #endif
props.Set(TableBCProperty(), value); // 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 /* 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, * 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. * 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); CellData* cellData = row.SafeElementAt(mColIndex);
if (!cellData) { // add a dead cell data if (!cellData) { // add a dead cell data
nsRect damageArea; 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())) { if (cellData && (cellData->IsOrig() || cellData->IsDead())) {
break; break;
@ -4312,7 +4352,7 @@ BCMapCellIterator::Next(BCMapCellInfo& aMapInfo)
nsRect damageArea; nsRect damageArea;
cellData = cellData =
static_cast<BCCellData*>(mCellMap->AppendCell(*mTableCellMap, nsnull, static_cast<BCCellData*>(mCellMap->AppendCell(*mTableCellMap, nsnull,
rgRowIndex, false, rgRowIndex, false, 0,
damageArea)); damageArea));
if (!cellData) ABORT0(); if (!cellData) ABORT0();
} }
@ -4347,7 +4387,7 @@ BCMapCellIterator::PeekRight(BCMapCellInfo& aRefInfo,
nsRect damageArea; nsRect damageArea;
cellData = cellData =
static_cast<BCCellData*>(mCellMap->AppendCell(*mTableCellMap, nsnull, static_cast<BCCellData*>(mCellMap->AppendCell(*mTableCellMap, nsnull,
rgRowIndex, false, rgRowIndex, false, 0,
damageArea)); damageArea));
if (!cellData) ABORT0(); if (!cellData) ABORT0();
} }
@ -4405,7 +4445,7 @@ BCMapCellIterator::PeekBottom(BCMapCellInfo& aRefInfo,
nsRect damageArea; nsRect damageArea;
cellData = cellData =
static_cast<BCCellData*>(cellMap->AppendCell(*mTableCellMap, nsnull, static_cast<BCCellData*>(cellMap->AppendCell(*mTableCellMap, nsnull,
rgRowIndex, false, rgRowIndex, false, 0,
damageArea)); damageArea));
if (!cellData) ABORT0(); if (!cellData) ABORT0();
} }
@ -5469,13 +5509,11 @@ nsTableFrame::CalcBCBorders()
return; // nothing to do return; // nothing to do
// Get the property holding the table damage area and border widths // Get the property holding the table damage area and border widths
BCPropertyData* propData = static_cast<BCPropertyData*> BCPropertyData* propData = GetBCProperty();
(Properties().Get(TableBCProperty()));
if (!propData) ABORT0(); if (!propData) ABORT0();
CheckFixDamageArea(numRows, numCols, propData->mDamageArea);
// calculate an expanded damage area // calculate an expanded damage area
nsRect damageArea(propData->mDamageArea); nsRect damageArea(propData->mDamageArea);
ExpandBCDamageArea(damageArea); ExpandBCDamageArea(damageArea);

View File

@ -58,6 +58,7 @@ class nsStyleContext;
struct nsTableReflowState; struct nsTableReflowState;
struct nsStylePosition; struct nsStylePosition;
struct BCPropertyData;
static inline bool IS_TABLE_CELL(nsIAtom* frameType) { static inline bool IS_TABLE_CELL(nsIAtom* frameType) {
return nsGkAtoms::tableCellFrame == frameType || return nsGkAtoms::tableCellFrame == frameType ||
@ -291,7 +292,7 @@ public:
friend class nsDelayedCalcBCBorders; friend class nsDelayedCalcBCBorders;
void SetBCDamageArea(const nsRect& aValue); void AddBCDamageArea(const nsRect& aValue);
bool BCRecalcNeeded(nsStyleContext* aOldStyleContext, bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
nsStyleContext* aNewStyleContext); nsStyleContext* aNewStyleContext);
void PaintBCBorders(nsRenderingContext& aRenderingContext, void PaintBCBorders(nsRenderingContext& aRenderingContext,
@ -688,10 +689,13 @@ public:
nsTArray<nsTableColFrame*>& GetColCache(); nsTArray<nsTableColFrame*>& GetColCache();
protected: protected:
void SetBorderCollapse(bool aValue); void SetBorderCollapse(bool aValue);
BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const;
void SetFullBCDamageArea();
void CalcBCBorders(); void CalcBCBorders();
void ExpandBCDamageArea(nsRect& aRect) const; void ExpandBCDamageArea(nsRect& aRect) const;

View File

@ -195,7 +195,7 @@ nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
if (tableFrame->IsBorderCollapse() && if (tableFrame->IsBorderCollapse() &&
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) { tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(0, GetRowIndex(), tableFrame->GetColCount(), 1); nsRect damageArea(0, GetRowIndex(), tableFrame->GetColCount(), 1);
tableFrame->SetBCDamageArea(damageArea); tableFrame->AddBCDamageArea(damageArea);
} }
return; return;
} }

View File

@ -1389,7 +1389,7 @@ nsTableRowGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) { tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
nsRect damageArea(0, GetStartRowIndex(), tableFrame->GetColCount(), nsRect damageArea(0, GetStartRowIndex(), tableFrame->GetColCount(),
GetRowCount()); GetRowCount());
tableFrame->SetBCDamageArea(damageArea); tableFrame->AddBCDamageArea(damageArea);
} }
return; return;
} }