зеркало из https://github.com/mozilla/pjs.git
Have a faster way of iterating down the columns of a table. Bug 352461,
r=bernd, sr=roc
This commit is contained in:
Родитель
cfe5a5a02b
Коммит
ff79c0a249
|
@ -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
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче