mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 04:27:41 +00:00
Simplify PullFrame()/PullFrameFrom(). b=538525 r=roc
This commit is contained in:
parent
4db40a3534
commit
d637043263
@ -2454,79 +2454,46 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull frame from the next available location (one of our lines or
|
||||
* one of our next-in-flows lines).
|
||||
*/
|
||||
nsresult
|
||||
nsIFrame*
|
||||
nsBlockFrame::PullFrame(nsBlockReflowState& aState,
|
||||
line_iterator aLine,
|
||||
nsIFrame*& aFrameResult)
|
||||
line_iterator aLine)
|
||||
{
|
||||
aFrameResult = nsnull;
|
||||
|
||||
// First check our remaining lines
|
||||
// First check our remaining lines.
|
||||
if (end_lines() != aLine.next()) {
|
||||
#ifdef DEBUG
|
||||
PRBool retry =
|
||||
#endif
|
||||
PullFrameFrom(aState, aLine, this, PR_FALSE, aLine.next(), aFrameResult);
|
||||
NS_ASSERTION(!retry, "Shouldn't have to retry in the current block");
|
||||
return NS_OK;
|
||||
return PullFrameFrom(aState, aLine, this, PR_FALSE, aLine.next());
|
||||
}
|
||||
|
||||
NS_ASSERTION(!GetOverflowLines(),
|
||||
"Our overflow lines should have been removed at the start of reflow");
|
||||
|
||||
// Try each next in flows
|
||||
// Try each next-in-flow.
|
||||
nsBlockFrame* nextInFlow = aState.mNextInFlow;
|
||||
while (nextInFlow) {
|
||||
// first normal lines, then overflow lines
|
||||
if (!nextInFlow->mLines.empty()) {
|
||||
if (PullFrameFrom(aState, aLine, nextInFlow, PR_FALSE,
|
||||
nextInFlow->mLines.begin(), aFrameResult)) {
|
||||
// try again with the same value of nextInFlow
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
return PullFrameFrom(aState, aLine, nextInFlow, PR_FALSE,
|
||||
nextInFlow->mLines.begin());
|
||||
}
|
||||
|
||||
nsLineList* overflowLines = nextInFlow->GetOverflowLines();
|
||||
if (overflowLines) {
|
||||
if (PullFrameFrom(aState, aLine, nextInFlow, PR_TRUE,
|
||||
overflowLines->begin(), aFrameResult)) {
|
||||
// try again with the same value of nextInFlow
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
return PullFrameFrom(aState, aLine, nextInFlow, PR_TRUE,
|
||||
overflowLines->begin());
|
||||
}
|
||||
|
||||
nextInFlow = (nsBlockFrame*) nextInFlow->GetNextInFlow();
|
||||
nextInFlow = static_cast<nsBlockFrame*>(nextInFlow->GetNextInFlow());
|
||||
aState.mNextInFlow = nextInFlow;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to pull a frame out of a line pointed at by aFromLine.
|
||||
*
|
||||
* Note: pulling a frame from a line that is a place-holder frame
|
||||
* doesn't automatically remove the corresponding float from the
|
||||
* line's float array. This happens indirectly: either the line gets
|
||||
* emptied (and destroyed) or the line gets reflowed (because we mark
|
||||
* it dirty) and the code at the top of ReflowLine empties the
|
||||
* array. So eventually, it will be removed, just not right away.
|
||||
*
|
||||
* @return PR_TRUE to force retrying of the pull.
|
||||
*/
|
||||
PRBool
|
||||
nsBlockFrame::PullFrameFrom(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nsBlockFrame* aFromContainer,
|
||||
PRBool aFromOverflowLine,
|
||||
nsLineList::iterator aFromLine,
|
||||
nsIFrame*& aFrameResult)
|
||||
nsIFrame*
|
||||
nsBlockFrame::PullFrameFrom(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nsBlockFrame* aFromContainer,
|
||||
PRBool aFromOverflowLine,
|
||||
nsLineList::iterator aFromLine)
|
||||
{
|
||||
nsLineBox* fromLine = aFromLine;
|
||||
NS_ABORT_IF_FALSE(fromLine, "bad line to pull from");
|
||||
@ -2540,88 +2507,85 @@ nsBlockFrame::PullFrameFrom(nsBlockReflowState& aState,
|
||||
// If our line is not empty and the child in aFromLine is a block
|
||||
// then we cannot pull up the frame into this line. In this case
|
||||
// we stop pulling.
|
||||
aFrameResult = nsnull;
|
||||
return nsnull;
|
||||
}
|
||||
// Take frame from fromLine
|
||||
nsIFrame* frame = fromLine->mFirstChild;
|
||||
nsIFrame* newFirstChild = frame->GetNextSibling();
|
||||
|
||||
if (aFromContainer != this) {
|
||||
NS_ASSERTION(aState.mPrevChild == aLine->LastChild(),
|
||||
"mPrevChild should be the LastChild of the line we are adding to");
|
||||
// The frame is being pulled from a next-in-flow; therefore we
|
||||
// need to add it to our sibling list.
|
||||
if (NS_LIKELY(!aFromOverflowLine)) {
|
||||
NS_ASSERTION(aFromLine == aFromContainer->mLines.begin(),
|
||||
"should only pull from first line");
|
||||
// Pulling from the next-in-flow's normal line list
|
||||
aFromContainer->mFrames.RemoveFrame(frame);
|
||||
} else {
|
||||
// Pulling from the next-in-flow's overflow list
|
||||
// XXXbz If we switch overflow lines to nsFrameList, we should
|
||||
// change this SetNextSibling call.
|
||||
frame->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
NS_ASSERTION(frame->GetParent() == aFromContainer, "unexpected parent frame");
|
||||
|
||||
ReparentFrame(frame, aFromContainer, this);
|
||||
mFrames.InsertFrame(nsnull, aState.mPrevChild, frame);
|
||||
|
||||
// The frame might have (or contain) floats that need to be
|
||||
// brought over too.
|
||||
ReparentFloats(frame, aFromContainer, aFromOverflowLine, PR_TRUE);
|
||||
}
|
||||
// when aFromContainer is 'this', then aLine->LastChild()'s next sibling
|
||||
// is already set correctly.
|
||||
aLine->SetChildCount(aLine->GetChildCount() + 1);
|
||||
|
||||
PRInt32 fromLineChildCount = fromLine->GetChildCount();
|
||||
if (0 != --fromLineChildCount) {
|
||||
// Mark line dirty now that we pulled a child
|
||||
fromLine->SetChildCount(fromLineChildCount);
|
||||
fromLine->MarkDirty();
|
||||
fromLine->mFirstChild = newFirstChild;
|
||||
}
|
||||
else {
|
||||
// Take frame from fromLine
|
||||
nsIFrame* frame = fromLine->mFirstChild;
|
||||
nsIFrame* newFirstChild = frame->GetNextSibling();
|
||||
// Free up the fromLine now that it's empty
|
||||
// Its bounds might need to be redrawn, though.
|
||||
// XXX WHY do we invalidate the bounds AND the combined area? doesn't
|
||||
// the combined area always enclose the bounds?
|
||||
Invalidate(fromLine->mBounds);
|
||||
nsLineList* fromLineList = aFromOverflowLine
|
||||
? aFromContainer->RemoveOverflowLines()
|
||||
: &aFromContainer->mLines;
|
||||
if (aFromLine.next() != fromLineList->end())
|
||||
aFromLine.next()->MarkPreviousMarginDirty();
|
||||
|
||||
if (aFromContainer != this) {
|
||||
NS_ASSERTION(aState.mPrevChild == aLine->LastChild(),
|
||||
"mPrevChild should be the LastChild of the line we are adding to");
|
||||
// The frame is being pulled from a next-in-flow; therefore we
|
||||
// need to add it to our sibling list.
|
||||
if (NS_LIKELY(!aFromOverflowLine)) {
|
||||
NS_ASSERTION(aFromLine == aFromContainer->mLines.begin(),
|
||||
"should only pull from first line");
|
||||
// Pulling from the next-in-flow's normal line list
|
||||
aFromContainer->mFrames.RemoveFrame(frame);
|
||||
Invalidate(fromLine->GetCombinedArea());
|
||||
fromLineList->erase(aFromLine);
|
||||
// aFromLine is now invalid
|
||||
aState.FreeLineBox(fromLine);
|
||||
|
||||
// Put any remaining overflow lines back.
|
||||
if (aFromOverflowLine) {
|
||||
if (!fromLineList->empty()) {
|
||||
aFromContainer->SetOverflowLines(fromLineList);
|
||||
} else {
|
||||
// Pulling from the next-in-flow's overflow list
|
||||
// XXXbz If we switch overflow lines to nsFrameList, we should
|
||||
// change this SetNextSibling call.
|
||||
frame->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
NS_ASSERTION(frame->GetParent() == aFromContainer, "unexpected parent frame");
|
||||
|
||||
ReparentFrame(frame, aFromContainer, this);
|
||||
mFrames.InsertFrame(nsnull, aState.mPrevChild, frame);
|
||||
|
||||
// The frame might have (or contain) floats that need to be
|
||||
// brought over too.
|
||||
ReparentFloats(frame, aFromContainer, aFromOverflowLine, PR_TRUE);
|
||||
}
|
||||
// when aFromContainer is 'this', then aLine->LastChild()'s next sibling
|
||||
// is already set correctly.
|
||||
aLine->SetChildCount(aLine->GetChildCount() + 1);
|
||||
|
||||
PRInt32 fromLineChildCount = fromLine->GetChildCount();
|
||||
if (0 != --fromLineChildCount) {
|
||||
// Mark line dirty now that we pulled a child
|
||||
fromLine->SetChildCount(fromLineChildCount);
|
||||
fromLine->MarkDirty();
|
||||
fromLine->mFirstChild = newFirstChild;
|
||||
}
|
||||
else {
|
||||
// Free up the fromLine now that it's empty
|
||||
// Its bounds might need to be redrawn, though.
|
||||
// XXX WHY do we invalidate the bounds AND the combined area? doesn't
|
||||
// the combined area always enclose the bounds?
|
||||
Invalidate(fromLine->mBounds);
|
||||
nsLineList* fromLineList = aFromOverflowLine
|
||||
? aFromContainer->RemoveOverflowLines()
|
||||
: &aFromContainer->mLines;
|
||||
if (aFromLine.next() != fromLineList->end())
|
||||
aFromLine.next()->MarkPreviousMarginDirty();
|
||||
|
||||
Invalidate(fromLine->GetCombinedArea());
|
||||
fromLineList->erase(aFromLine);
|
||||
// aFromLine is now invalid
|
||||
aState.FreeLineBox(fromLine);
|
||||
|
||||
// Put any remaining overflow lines back.
|
||||
if (aFromOverflowLine) {
|
||||
if (!fromLineList->empty()) {
|
||||
aFromContainer->SetOverflowLines(fromLineList);
|
||||
} else {
|
||||
delete fromLineList;
|
||||
// Now any iterators into fromLineList are invalid (but
|
||||
// aFromLine already was invalidated above)
|
||||
}
|
||||
delete fromLineList;
|
||||
// Now any iterators into fromLineList are invalid (but
|
||||
// aFromLine already was invalidated above)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop pulling because we found a frame to pull
|
||||
aFrameResult = frame;
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
return PR_FALSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3571,9 +3535,8 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||
if (aAllowPullUp) {
|
||||
// Pull frames and reflow them until we can't
|
||||
while (LINE_REFLOW_OK == lineReflowStatus) {
|
||||
rv = PullFrame(aState, aLine, frame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (nsnull == frame) {
|
||||
frame = PullFrame(aState, aLine);
|
||||
if (!frame) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -621,16 +621,31 @@ protected:
|
||||
nsIFrame* aFrame,
|
||||
LineReflowStatus* aLineReflowStatus);
|
||||
|
||||
nsresult PullFrame(nsBlockReflowState& aState,
|
||||
line_iterator aLine,
|
||||
nsIFrame*& aFrameResult);
|
||||
/**
|
||||
* Pull a frame from the next available location (one of our lines or
|
||||
* one of our next-in-flows lines).
|
||||
* @return the pulled frame or nsnull
|
||||
*/
|
||||
nsIFrame* PullFrame(nsBlockReflowState& aState,
|
||||
line_iterator aLine);
|
||||
|
||||
PRBool PullFrameFrom(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nsBlockFrame* aFromContainer,
|
||||
PRBool aFromOverflowLine,
|
||||
nsLineList::iterator aFromLine,
|
||||
nsIFrame*& aFrameResult);
|
||||
/**
|
||||
* Try to pull a frame out of a line pointed at by aFromLine.
|
||||
*
|
||||
* Note: pulling a frame from a line that is a place-holder frame
|
||||
* doesn't automatically remove the corresponding float from the
|
||||
* line's float array. This happens indirectly: either the line gets
|
||||
* emptied (and destroyed) or the line gets reflowed (because we mark
|
||||
* it dirty) and the code at the top of ReflowLine empties the
|
||||
* array. So eventually, it will be removed, just not right away.
|
||||
*
|
||||
* @return the pulled frame or nsnull
|
||||
*/
|
||||
nsIFrame* PullFrameFrom(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nsBlockFrame* aFromContainer,
|
||||
PRBool aFromOverflowLine,
|
||||
nsLineList::iterator aFromLine);
|
||||
|
||||
void PushLines(nsBlockReflowState& aState,
|
||||
nsLineList::iterator aLineBefore);
|
||||
|
Loading…
x
Reference in New Issue
Block a user