Bug 411870 backout again

This commit is contained in:
roc+@cs.cmu.edu 2008-01-28 11:10:26 -08:00
parent 61b709983c
commit 72c72d1d33
8 changed files with 59 additions and 60 deletions

View File

@ -90,5 +90,5 @@ load 405186-1.xhtml
load 408292.html
load 408299.html
load 409461-1.xhtml
load 411870-1.html
# load 411870-1.html

View File

@ -196,37 +196,29 @@ CreateBidiContinuation(nsIFrame* aFrame,
}
static PRBool
IsFrameInCurrentLine(nsBlockInFlowLineIterator* aLineIter,
nsIFrame* aPrevFrame, nsIFrame* aFrame)
{
nsIFrame* endFrame = aLineIter->IsLastLineInList() ? nsnull :
aLineIter->GetLine().next()->mFirstChild;
nsIFrame* startFrame = aPrevFrame ? aPrevFrame : aLineIter->GetLine()->mFirstChild;
return nsFrameList(startFrame).ContainsFrameBefore(aFrame, endFrame);
}
static void
AdvanceLineIteratorToFrame(nsIFrame* aFrame,
nsBlockInFlowLineIterator* aLineIter,
nsIFrame*& aPrevFrame)
nsIFrame* aBlockFrame,
nsBlockFrame::line_iterator& aLine,
nsIFrame*& aPrevFrame,
const nsBlockFrame::line_iterator& aEndLines)
{
// Advance aLine to the line containing aFrame
nsIFrame* child = aFrame;
nsIFrame* parent = child->GetParent();
while (parent && !nsLayoutUtils::GetAsBlock(parent)) {
while (parent && parent != aBlockFrame) {
if (parent->GetStyleDisplay()->IsBlockOutside())
return PR_FALSE;
child = parent;
parent = child->GetParent();
}
NS_ASSERTION (parent, "aFrame is not a descendent of aBlockFrame");
while (!IsFrameInCurrentLine(aLineIter, aPrevFrame, child)) {
#ifdef DEBUG
PRBool hasNext =
#endif
aLineIter->Next();
NS_ASSERTION(hasNext, "Can't find frame in lines!");
while (aLine != aEndLines && !aLine->ContainsAfter(aPrevFrame, child, aLine, aEndLines)) {
++aLine;
aPrevFrame = nsnull;
}
aPrevFrame = child;
NS_ASSERTION (aLine != aEndLines, "frame not found on any line");
return PR_TRUE;
}
/*
@ -353,11 +345,8 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame,
nsPropertyTable *propTable = presContext->PropertyTable();
nsBlockInFlowLineIterator lineIter(aBlockFrame, aBlockFrame->begin_lines(), PR_FALSE);
if (lineIter.GetLine() == aBlockFrame->end_lines()) {
// Advance to first valid line (might be in a next-continuation)
lineIter.Next();
}
nsBlockFrame::line_iterator line = aBlockFrame->begin_lines();
nsBlockFrame::line_iterator endLines = aBlockFrame->end_lines();
nsIFrame* prevFrame = nsnull;
PRBool lineNeedsUpdate = PR_FALSE;
@ -430,10 +419,12 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame,
break;
}
if (lineNeedsUpdate) {
AdvanceLineIteratorToFrame(frame, &lineIter, prevFrame);
lineNeedsUpdate = PR_FALSE;
if (AdvanceLineIteratorToFrame(frame, aBlockFrame, line,
prevFrame, endLines)) {
lineNeedsUpdate = PR_FALSE;
}
}
lineIter.GetLine()->MarkDirty();
line->MarkDirty();
frame = nextBidi;
contentOffset += runLength;
} // if (runLength < fragmentLength)
@ -443,10 +434,12 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame,
if (newIndex > frameIndex) {
RemoveBidiContinuation(frame, frameIndex, newIndex, temp);
if (lineNeedsUpdate) {
AdvanceLineIteratorToFrame(frame, &lineIter, prevFrame);
lineNeedsUpdate = PR_FALSE;
if (AdvanceLineIteratorToFrame(frame, aBlockFrame, line,
prevFrame, endLines)) {
lineNeedsUpdate = PR_FALSE;
}
}
lineIter.GetLine()->MarkDirty();
line->MarkDirty();
runLength -= temp;
fragmentLength -= temp;
lineOffset += temp;

View File

@ -5128,7 +5128,7 @@ nsBlockFrame::TryAllLines(nsLineList::iterator* aIterator,
}
nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
line_iterator aLine, PRBool aInOverflow)
line_iterator& aLine, PRBool aInOverflow)
: mFrame(aFrame), mLine(aLine), mInOverflowLines(nsnull)
{
if (aInOverflow) {
@ -5137,13 +5137,6 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
}
}
PRBool
nsBlockInFlowLineIterator::IsLastLineInList()
{
line_iterator end = mInOverflowLines ? mInOverflowLines->end() : mFrame->end_lines();
return mLine != end && mLine.next() == end;
}
PRBool
nsBlockInFlowLineIterator::Next()
{

View File

@ -674,10 +674,9 @@ private:
class nsBlockInFlowLineIterator {
public:
typedef nsBlockFrame::line_iterator line_iterator;
nsBlockInFlowLineIterator(nsBlockFrame* aFrame, line_iterator aLine, PRBool aInOverflow);
nsBlockInFlowLineIterator(nsBlockFrame* aFrame, line_iterator& aLine, PRBool aInOverflow);
line_iterator GetLine() { return mLine; }
PRBool IsLastLineInList();
nsBlockFrame* GetContainer() { return mFrame; }
PRBool GetInOverflow() { return mInOverflowLines != nsnull; }
/**

View File

@ -296,23 +296,6 @@ nsFrameList::ContainsFrame(const nsIFrame* aFrame) const
return PR_FALSE;
}
PRBool
nsFrameList::ContainsFrameBefore(const nsIFrame* aFrame, const nsIFrame* aEnd) const
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
nsIFrame* frame = mFirstChild;
while (frame) {
if (frame == aEnd) {
return PR_FALSE;
}
if (frame == aFrame) {
return PR_TRUE;
}
frame = frame->GetNextSibling();
}
return PR_FALSE;
}
PRInt32
nsFrameList::GetLength() const
{

View File

@ -153,7 +153,6 @@ public:
}
PRBool ContainsFrame(const nsIFrame* aFrame) const;
PRBool ContainsFrameBefore(const nsIFrame* aFrame, const nsIFrame* aEnd) const;
PRInt32 GetLength() const;

View File

@ -276,6 +276,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

@ -455,6 +455,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;