Bug 1235321 - Enable using line cursor to optimize reflowing absolute frames. r=bz

MozReview-Commit-ID: 4tVq5S4eTtS

--HG--
extra : rebase_source : 2162480e3d63c817fd63123d0bb5d299a97fdad6
This commit is contained in:
Xidorn Quan 2016-04-13 13:42:28 +10:00
Родитель a032db835b
Коммит e2164ce4a4
2 изменённых файлов: 30 добавлений и 19 удалений

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

@ -1396,10 +1396,16 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
if (cbHeightChanged) {
flags |= AbsPosReflowFlags::eCBHeightChanged;
}
// Setup the line cursor here to optimize line searching for
// calculating hypothetical position of absolutely-positioned
// frames. The line cursor is immediately cleared afterward to
// avoid affecting the display list generation.
SetupLineCursor();
absoluteContainer->Reflow(this, aPresContext, *reflowState,
state.mReflowStatus,
containingBlock, flags,
&aMetrics.mOverflowAreas);
ClearLineCursor();
}
}
@ -5491,21 +5497,14 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
if (!child)
return;
line_iterator line_end = aFrame->end_lines();
// Try to use the cursor if it exists, otherwise fall back to the first line
nsLineBox* cursor = aFrame->GetLineCursor();
if (!cursor) {
line_iterator iter = aFrame->begin_lines();
if (iter != aFrame->end_lines()) {
cursor = iter;
}
}
if (cursor) {
if (nsLineBox* const cursor = aFrame->GetLineCursor()) {
mLine = line_end;
// Perform a simultaneous forward and reverse search starting from the
// line cursor.
nsBlockFrame::line_iterator line = aFrame->line(cursor);
nsBlockFrame::reverse_line_iterator rline = aFrame->rline(cursor);
nsBlockFrame::line_iterator line_end = aFrame->end_lines();
nsBlockFrame::reverse_line_iterator rline_end = aFrame->rend_lines();
// rline is positioned on the line containing 'cursor', so it's not
// rline_end. So we can safely increment it (i.e. move it to one line
@ -5514,23 +5513,36 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
while (line != line_end || rline != rline_end) {
if (line != line_end) {
if (line->Contains(child)) {
*aFoundValidLine = true;
mLine = line;
return;
break;
}
++line;
}
if (rline != rline_end) {
if (rline->Contains(child)) {
*aFoundValidLine = true;
mLine = rline;
return;
break;
}
++rline;
}
}
// Didn't find the line
if (mLine != line_end) {
*aFoundValidLine = true;
if (mLine != cursor) {
aFrame->Properties().Set(nsBlockFrame::LineCursorProperty(), mLine);
}
return;
}
} else {
for (mLine = aFrame->begin_lines(); mLine != line_end; ++mLine) {
if (mLine->Contains(child)) {
*aFoundValidLine = true;
return;
}
}
}
// Didn't find the line
MOZ_ASSERT(mLine == line_end, "mLine should be line_end at this point");
// If we reach here, it means that we have not been able to find the
// desired frame in our in-flow lines. So we should start looking at
@ -5538,8 +5550,6 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
// iterator so that FindValidLine starts to look at overflow lines,
// if any.
mLine = aFrame->end_lines();
if (!FindValidLine())
return;

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

@ -172,8 +172,9 @@ public:
// to be before any line which does contain 'y'.
nsLineBox* GetFirstLineContaining(nscoord y);
// Set the line cursor to our first line. Only call this if you
// guarantee that the lines' combinedArea.ys and combinedArea.yMosts
// are non-decreasing.
// guarantee that either the lines' combinedArea.ys and combinedArea.
// yMosts are non-decreasing, or the line cursor is cleared before
// building the display list of this frame.
void SetupLineCursor();
virtual void ChildIsDirty(nsIFrame* aChild) override;