Allow searching a line for a frame starting from a given point, to improve performance of forward-moving searches. Used in bidi resolution. bug=339935, r+sr=roc

git-svn-id: svn://10.0.0.236/trunk@199496 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
uriber%gmail.com 2006-06-08 08:41:51 +00:00
parent efac2e21e5
commit 8b9a1f9460
3 changed files with 39 additions and 3 deletions

View File

@ -188,6 +188,7 @@ static void
AdvanceLineIteratorToFrame(nsIFrame* aFrame,
nsIFrame* aBlockFrame,
nsBlockFrame::line_iterator& aLine,
nsIFrame*& aPrevFrame,
const nsBlockFrame::line_iterator& aEndLines)
{
// Advance aLine to the line containing aFrame
@ -198,9 +199,11 @@ AdvanceLineIteratorToFrame(nsIFrame* aFrame,
parent = child->GetParent();
}
NS_ASSERTION (parent, "aFrame is not a descendent of aBlockFrame");
while (aLine != aEndLines && !aLine->Contains(child)) {
while (aLine != aEndLines && !aLine->ContainsAfter(aPrevFrame, child, aLine, aEndLines)) {
++aLine;
aPrevFrame = nsnull;
}
aPrevFrame = child;
NS_ASSERTION (aLine != aEndLines, "frame not found on any line");
}
@ -331,6 +334,7 @@ nsBidiPresUtils::Resolve(nsPresContext* aPresContext,
nsBlockFrame::line_iterator line = aBlockFrame->begin_lines();
nsBlockFrame::line_iterator endLines = aBlockFrame->end_lines();
nsIFrame* prevFrame = nsnull;
PRBool lineNeedsUpdate = PR_FALSE;
for (; ;) {
@ -406,7 +410,7 @@ nsBidiPresUtils::Resolve(nsPresContext* aPresContext,
break;
}
if (lineNeedsUpdate) {
AdvanceLineIteratorToFrame(frame, aBlockFrame, line, endLines);
AdvanceLineIteratorToFrame(frame, aBlockFrame, line, prevFrame, endLines);
lineNeedsUpdate = PR_FALSE;
}
line->MarkDirty();
@ -422,7 +426,7 @@ nsBidiPresUtils::Resolve(nsPresContext* aPresContext,
RemoveBidiContinuation(aPresContext, frame,
frameIndex, newIndex, temp);
if (lineNeedsUpdate) {
AdvanceLineIteratorToFrame(frame, aBlockFrame, line, endLines);
AdvanceLineIteratorToFrame(frame, aBlockFrame, line, prevFrame, endLines);
lineNeedsUpdate = PR_FALSE;
}
line->MarkDirty();

View File

@ -282,6 +282,29 @@ nsLineBox::IndexOf(nsIFrame* aFrame) const
return -1;
}
PRBool
nsLineBox::ContainsAfter(nsIFrame* aFrameInLine,
nsIFrame* aFrameToFind,
nsLineList::iterator aLineIter,
const nsLineList::iterator& aEndLines) const
{
nsIFrame* firstFrameOnNextLine = nsnull;
++aLineIter;
if (aLineIter != aEndLines)
firstFrameOnNextLine = aLineIter->mFirstChild;
nsIFrame* frame = aFrameInLine;
if (!frame)
frame = mFirstChild;
while (frame && frame != firstFrameOnNextLine) {
if (frame == aFrameToFind)
return PR_TRUE;
frame = frame->GetNextSibling();
}
return PR_FALSE;
}
PRBool
nsLineBox::IsEmpty() const
{

View File

@ -441,6 +441,15 @@ public:
return IndexOf(aFrame) >= 0;
}
// Search the line for aFrameToFind, going forward from aFrameInLine
// (or from the beginning of the line, if aFrameInLine is null).
// aLineIterator is a line iterator pointing to the line.
// aEndLine should point to the block's end_lines.
PRBool ContainsAfter(nsIFrame* aFrameInLine,
nsIFrame* aFrameToFind,
nsLineList_iterator aLineIter,
const nsLineList_iterator& aEndLines) const;
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
PRBool IsEmpty() const;