Have a faster way of iterating down the columns of a table. Bug 352461,

r=bernd, sr=roc
This commit is contained in:
bzbarsky%mit.edu 2007-01-22 04:32:33 +00:00
Родитель cfe5a5a02b
Коммит ff79c0a249
3 изменённых файлов: 136 добавлений и 9 удалений

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

@ -269,15 +269,10 @@ BasicTableLayoutStrategy::ComputeColumnIntrinsicWidths(nsIRenderingContext* aRen
// Consider the contents of and the widths on the cells without
// colspans.
for (PRInt32 row = 0, row_end = cellMap->GetRowCount();
row < row_end; ++row) {
PRBool originates;
PRInt32 colSpan;
nsTableCellFrame *cellFrame =
cellMap->GetCellInfoAt(row, col, &originates, &colSpan);
if (!cellFrame || !originates) {
continue;
}
nsCellMapColumnIterator columnIter(cellMap, col);
PRInt32 row, colSpan;
nsTableCellFrame* cellFrame;
while ((cellFrame = columnIter.GetNextFrame(&row, &colSpan))) {
if (colSpan > 1) {
spanningCells.AddCell(colSpan, row, col);
continue;

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

@ -2679,3 +2679,90 @@ CellData* nsCellMap::AllocCellData(nsTableCellFrame* aOrigCell)
}
return data;
}
void
nsCellMapColumnIterator::AdvanceRowGroup()
{
mCurMap = mCurMap->GetNextSibling();
/* mCurMap could now be null, if we just handled the last originating cell.
Future calls will end up with mFoundCells == mOrigCells, but for this
one mFoundCells was definitely not big enough if we got here... */
mCurMapRowCount = mCurMap ? mCurMap->GetRowCount() : 0;
// Set mRow to 0, since cells can't span across table row groups.
mRow = 0;
}
void
nsCellMapColumnIterator::IncrementRow(PRInt32 aIncrement)
{
NS_PRECONDITION(aIncrement >= 0, "Bogus increment");
NS_PRECONDITION(mCurMap, "Bogus mOrigCells?");
if (aIncrement == 0) {
// This will span to the end of the row group
AdvanceRowGroup();
}
else {
mRow += aIncrement;
if (mRow >= mCurMapRowCount) {
AdvanceRowGroup();
}
}
}
nsTableCellFrame*
nsCellMapColumnIterator::GetNextFrame(PRInt32* aRow, PRInt32* aColSpan)
{
// Fast-path for the case when we don't have anything left in the column and
// we know it.
if (mFoundCells == mOrigCells) {
*aRow = 0;
*aColSpan = 1;
return nsnull;
}
while (1) {
NS_ASSERTION(mRow < mCurMapRowCount, "Bogus mOrigCells?");
// Safe to just get the row (which is faster than calling GetDataAt(), but
// there may not be that many cells in it, so have to use SafeElementAt for
// the mCol.
const nsCellMap::CellDataArray& row = mCurMap->mRows[mRow];
CellData* cellData = row.SafeElementAt(mCol);
if (!cellData || cellData->IsDead()) {
// Could hit this if there are fewer cells in this row than others, for
// example.
IncrementRow(1);
continue;
}
if (cellData->IsColSpan()) {
// Look up the originating data for this cell, advance by its rowspan.
CellData* origData = row[mCol - cellData->GetColSpanOffset()];
NS_ASSERTION(origData && origData->IsOrig() && origData->GetCellFrame(),
"Must have usable originating data here");
IncrementRow(origData->GetCellFrame()->GetRowSpan());
continue;
}
NS_ASSERTION(cellData->IsOrig(),
"Must have originating cellData by this point. "
"See comment on mRow in header.");
nsTableCellFrame* cellFrame = cellData->GetCellFrame();
NS_ASSERTION(cellFrame, "Orig data without cellframe?");
*aRow = mRow;
PRBool ignoredZeroSpan;
*aColSpan = mCurMap->GetEffectiveColSpan(*mMap, mRow, mCol, ignoredZeroSpan);
IncrementRow(cellFrame->GetRowSpan());
++mFoundCells;
return cellFrame;
}
NS_NOTREACHED("Can't get here");
return nsnull;
}

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

@ -51,6 +51,7 @@ class nsTableRowGroupFrame;
class nsTableFrame;
class nsCellMap;
class nsPresContext;
class nsCellMapColumnIterator;
struct nsColInfo
{
@ -233,6 +234,8 @@ protected:
friend class nsCellMap;
friend class BCMapCellIterator;
friend class BCMapBorderIterator;
friend class nsCellMapColumnIterator;
/** Insert a row group cellmap after aPrevMap, if aPrefMap is null insert it
* at the beginning, the ordering of the cellmap corresponds to the ordering of
* rowgroups once OrderRowGroups has been called
@ -403,6 +406,7 @@ protected:
friend class BCMapCellIterator;
friend class BCMapBorderIterator;
friend class nsTableFrame;
friend class nsCellMapColumnIterator;
/**
* Increase the number of rows in this cellmap by aNumRows. Put the
@ -539,6 +543,47 @@ protected:
nsCOMPtr<nsPresContext> mPresContext;
};
/**
* A class for iterating the cells in a given column. Must be given a
* non-null nsTableCellMap and a column number valid for that cellmap.
*/
class nsCellMapColumnIterator
{
public:
nsCellMapColumnIterator(const nsTableCellMap* aMap, PRInt32 aCol) :
mMap(aMap), mCurMap(aMap->mFirstMap), mRow(0), mCol(aCol), mFoundCells(0)
{
NS_PRECONDITION(aMap, "Must have map");
NS_PRECONDITION(mCol < aMap->GetColCount(), "Invalid column");
mOrigCells = aMap->GetNumCellsOriginatingInCol(mCol);
if (mCurMap) {
mCurMapRowCount = mCurMap->GetRowCount();
}
}
nsTableCellFrame* GetNextFrame(PRInt32* aRow, PRInt32* aColSpan);
private:
void AdvanceRowGroup();
// Advance the row; aIncrement is considered to be a cell's rowspan,
// so if 0 is passed in we'll advance to the next rowgroup.
void IncrementRow(PRInt32 aIncrement);
const nsTableCellMap* mMap;
const nsCellMap* mCurMap;
// In steady-state mRow is the row in our current nsCellMap that we'll use
// the next time GetNextFrame() is called. Due to the way we skip over
// rowspans, the entry in mRow and mCol is either null, dead, originating, or
// a colspan. In particular, it cannot be a rowspan or overlap entry.
PRUint32 mRow;
const PRInt32 mCol;
PRUint32 mOrigCells;
PRUint32 mFoundCells;
PRUint32 mCurMapRowCount;
};
/* ----- inline methods ----- */
inline PRInt32 nsTableCellMap::GetColCount() const
{