diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index df0021c75be..d4c5156cc92 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -2421,11 +2421,20 @@ nsBlockFrame::AttributeChanged(PRInt32 aNameSpaceID, else if (nsGkAtoms::value == aAttribute) { const nsStyleDisplay* styleDisplay = GetStyleDisplay(); if (NS_STYLE_DISPLAY_LIST_ITEM == styleDisplay->mDisplay) { + nsIFrame* nextAncestor = mParent; + nsBlockFrame* blockParent = nsnull; + // Search for the closest ancestor that's a block frame. We // make the assumption that all related list items share a // common block parent. // XXXldb I think that's a bad assumption. - nsBlockFrame* blockParent = nsLayoutUtils::FindNearestBlockAncestor(this); + while (nextAncestor) { + if (NS_OK == nextAncestor->QueryInterface(kBlockFrameCID, + (void**)&blockParent)) { + break; + } + nextAncestor = nextAncestor->GetParent(); + } // Tell the enclosing block frame to renumber list items within // itself @@ -3101,7 +3110,7 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState, // no longer makes sense. Now we always allocate on the stack nsLineLayout lineLayout(aState.mPresContext, aState.mReflowState.mSpaceManager, - &aState.mReflowState, &aLine); + &aState.mReflowState); lineLayout.Init(&aState, aState.mMinLineHeight, aState.mLineNumber); if (forceBreakInContent) { lineLayout.ForceBreakAtPosition(forceBreakInContent, forceBreakOffset); @@ -3313,11 +3322,8 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, } if ((lineReflowStatus == LINE_REFLOW_STOP || lineReflowStatus == LINE_REFLOW_OK) && - aLineLayout.NeedsBackup()) { + !aLineLayout.HaveForcedBreakPosition() && aLineLayout.NeedsBackup()) { // We need to try backing up to before a text run - NS_ASSERTION(!aLineLayout.HaveForcedBreakPosition(), - "We shouldn't be backing up more than once! " - "Someone must have set a break opportunity beyond the available width"); PRInt32 offset; nsIContent* breakContent = aLineLayout.GetLastOptionalBreakPosition(&offset); if (breakContent) { @@ -3822,7 +3828,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, aLineLayout.AddBulletFrame(mBullet, metrics); addedBullet = PR_TRUE; } - aLineLayout.VerticalAlignLine(); + aLineLayout.VerticalAlignLine(aLine); // Our ascent is the ascent of our first line (but if this line is all // whitespace we'll correct things in |ReflowBlockFrame|). if (aLine == mLines.front()) { diff --git a/mozilla/layout/generic/nsFirstLetterFrame.cpp b/mozilla/layout/generic/nsFirstLetterFrame.cpp index aef54daae67..5607883a50c 100644 --- a/mozilla/layout/generic/nsFirstLetterFrame.cpp +++ b/mozilla/layout/generic/nsFirstLetterFrame.cpp @@ -255,7 +255,7 @@ nsFirstLetterFrame::Reflow(nsPresContext* aPresContext, // only time that the first-letter-frame is not reflowing in a // line context is when its floating. nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize); - nsLineLayout ll(aPresContext, nsnull, &aReflowState, nsnull); + nsLineLayout ll(aPresContext, nsnull, &aReflowState); ll.BeginLineReflow(0, 0, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE, PR_FALSE, PR_TRUE); rs.mLineLayout = ≪ diff --git a/mozilla/layout/generic/nsHTMLReflowState.cpp b/mozilla/layout/generic/nsHTMLReflowState.cpp index 8c32a39ff9b..b9db1727e4f 100644 --- a/mozilla/layout/generic/nsHTMLReflowState.cpp +++ b/mozilla/layout/generic/nsHTMLReflowState.cpp @@ -651,6 +651,24 @@ nsHTMLReflowState::CalculateHorizBorderPaddingMargin(nscoord aContainingBlockWid margin.left + margin.right; } +static nsIFrame* +FindImmediateChildOf(nsIFrame* aParent, nsIFrame* aDescendantFrame) +{ + nsIFrame* result = aDescendantFrame; + + while (result) { + nsIFrame* parent = result->GetParent(); + if (parent == aParent) { + break; + } + + // The frame is not an immediate child of aParent so walk up another level + result = parent; + } + + return result; +} + /** * Returns PR_TRUE iff a pre-order traversal of the normal child * frames rooted at aFrame finds no non-empty frame before aDescendant. @@ -758,8 +776,7 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, NS_REINTERPRET_CAST(void**, &blockFrame)))) { // We need the immediate child of the block frame, and that may not be // the placeholder frame - nsIFrame *blockChild = - nsLayoutUtils::FindChildContainingDescendant(blockFrame, aPlaceholderFrame); + nsIFrame *blockChild = FindImmediateChildOf(blockFrame, aPlaceholderFrame); nsBlockFrame::line_iterator lineBox = blockFrame->FindLineFor(blockChild); // How we determine the hypothetical box depends on whether the element diff --git a/mozilla/layout/generic/nsInlineFrame.cpp b/mozilla/layout/generic/nsInlineFrame.cpp index 1402ea49b78..ce0e4b5e761 100644 --- a/mozilla/layout/generic/nsInlineFrame.cpp +++ b/mozilla/layout/generic/nsInlineFrame.cpp @@ -914,11 +914,7 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext, } } - NS_ASSERTION(!aReflowState.mLineLayout->GetInFirstLine(), - "Nested first-line frames? BOGUS"); - aReflowState.mLineLayout->SetInFirstLine(PR_TRUE); rv = ReflowFrames(aPresContext, aReflowState, irs, aMetrics, aStatus); - aReflowState.mLineLayout->SetInFirstLine(PR_FALSE); // Note: the line layout code will properly compute our overflow state for us diff --git a/mozilla/layout/generic/nsLineLayout.cpp b/mozilla/layout/generic/nsLineLayout.cpp index 8f37b5f5cbd..ab86b019242 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -93,8 +93,7 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext, nsSpaceManager* aSpaceManager, - const nsHTMLReflowState* aOuterReflowState, - const nsLineList::iterator* aLine) + const nsHTMLReflowState* aOuterReflowState) : mPresContext(aPresContext), mSpaceManager(aSpaceManager), mBlockReflowState(aOuterReflowState), @@ -134,11 +133,6 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext, mCurrentSpan = mRootSpan = nsnull; mSpanDepth = 0; - if (aLine) { - SetFlag(LL_GOTLINEBOX, PR_TRUE); - mLineBox = *aLine; - } - mCompatMode = mPresContext->CompatibilityMode(); } @@ -814,6 +808,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, #endif // IBMBIDI nsIAtom* frameType = aFrame->GetType(); + PRInt32 savedOptionalBreakOffset; nsIContent* savedOptionalBreakContent = GetLastOptionalBreakPosition(&savedOptionalBreakOffset); @@ -1398,7 +1393,7 @@ PRBool IsPercentageAwareFrame(nsPresContext *aPresContext, nsIFrame *aFrame) void -nsLineLayout::VerticalAlignLine() +nsLineLayout::VerticalAlignLine(nsLineBox* aLineBox) { // Synthesize a PerFrameData for the block frame PerFrameData rootPFD; @@ -1407,6 +1402,7 @@ nsLineLayout::VerticalAlignLine() rootPFD.mAscent = 0; rootPFD.mDescent = 0; mRootSpan->mFrame = &rootPFD; + mLineBox = aLineBox; // Partially place the children of the block frame. The baseline for // this operation is set to zero so that the y coordinates for all @@ -1511,31 +1507,32 @@ nsLineLayout::VerticalAlignLine() } // check to see if the frame is an inline replace element // and if it is percent-aware. If so, mark the line. - if ((PR_FALSE==mLineBox->ResizeReflowOptimizationDisabled()) && + if ((PR_FALSE==aLineBox->ResizeReflowOptimizationDisabled()) && pfd->mFrameType & NS_CSS_FRAME_TYPE_INLINE) { if (IsPercentageAwareFrame(mPresContext, pfd->mFrame)) - mLineBox->DisableResizeReflowOptimization(); + aLineBox->DisableResizeReflowOptimization(); } } // Fill in returned line-box and max-element-width data - mLineBox->mBounds.x = psd->mLeftEdge; - mLineBox->mBounds.y = mTopEdge; - mLineBox->mBounds.width = psd->mX - psd->mLeftEdge; - mLineBox->mBounds.height = lineHeight; + aLineBox->mBounds.x = psd->mLeftEdge; + aLineBox->mBounds.y = mTopEdge; + aLineBox->mBounds.width = psd->mX - psd->mLeftEdge; + aLineBox->mBounds.height = lineHeight; mFinalLineHeight = lineHeight; - mLineBox->SetAscent(baselineY - mTopEdge); + aLineBox->SetAscent(baselineY - mTopEdge); #ifdef NOISY_VERTICAL_ALIGN printf( " [line]==> bounds{x,y,w,h}={%d,%d,%d,%d} lh=%d a=%d\n", - mLineBox->mBounds.x, mLineBox->mBounds.y, - mLineBox->mBounds.width, mLineBox->mBounds.height, - mFinalLineHeight, mLineBox->GetAscent()); + aLineBox->mBounds.x, aLineBox->mBounds.y, + aLineBox->mBounds.width, aLineBox->mBounds.height, + mFinalLineHeight, aLineBox->GetAscent()); #endif // Undo root-span mFrame pointer to prevent brane damage later on... mRootSpan->mFrame = nsnull; + mLineBox = nsnull; } void diff --git a/mozilla/layout/generic/nsLineLayout.h b/mozilla/layout/generic/nsLineLayout.h index c008cb3d857..97ec22ef72b 100644 --- a/mozilla/layout/generic/nsLineLayout.h +++ b/mozilla/layout/generic/nsLineLayout.h @@ -66,8 +66,7 @@ class nsLineLayout { public: nsLineLayout(nsPresContext* aPresContext, nsSpaceManager* aSpaceManager, - const nsHTMLReflowState* aOuterReflowState, - const nsLineList::iterator* aLine); + const nsHTMLReflowState* aOuterReflowState); ~nsLineLayout(); void Init(nsBlockReflowState* aState, nscoord aMinLineHeight, @@ -127,7 +126,7 @@ public: PushFrame(aFrame); } - void VerticalAlignLine(); + void VerticalAlignLine(nsLineBox* aLineBox); PRBool TrimTrailingWhiteSpace(); @@ -162,9 +161,7 @@ protected: #define LL_LINEENDSINSOFTBR 0x00000400 #define LL_NEEDBACKUP 0x00000800 #define LL_LASTTEXTFRAME_WRAPPINGENABLED 0x00001000 -#define LL_INFIRSTLINE 0x00002000 -#define LL_GOTLINEBOX 0x00004000 -#define LL_LASTFLAG LL_GOTLINEBOX +#define LL_LASTFLAG LL_LASTTEXTFRAME_WRAPPINGENABLED PRUint16 mFlags; @@ -277,7 +274,7 @@ public: * @param aWrappingEnabled whether that text had word-wrapping enabled * (white-space:normal or -moz-pre-wrap) */ - nsIFrame* GetTrailingTextFrame(PRBool* aWrappingEnabled) const { + nsIFrame* GetTrailingTextFrame(PRBool* aWrappingEnabled) { *aWrappingEnabled = GetFlag(LL_LASTTEXTFRAME_WRAPPINGENABLED); return mTrailingTextFrame; } @@ -301,14 +298,6 @@ public: mFirstLetterFrame = aFrame; } - PRBool GetInFirstLine() const { - return GetFlag(LL_INFIRSTLINE); - } - - void SetInFirstLine(PRBool aSetting) { - SetFlag(LL_INFIRSTLINE, aSetting); - } - //---------------------------------------- static PRBool TreatFrameAsBlock(nsIFrame* aFrame); @@ -401,11 +390,8 @@ public: * some other kind of frame when inline frames are reflowed in a non-block * context (e.g. MathML). */ - nsIFrame* GetLineContainerFrame() const { return mBlockReflowState->frame; } - const nsLineList::iterator* GetLine() const { - return GetFlag(LL_GOTLINEBOX) ? &mLineBox : nsnull; - } - + nsIFrame* GetLineContainerFrame() { return mBlockReflowState->frame; } + protected: // This state is constant for a given block frame doing line layout nsSpaceManager* mSpaceManager; @@ -441,7 +427,7 @@ protected: PRInt32 mTextJustificationNumSpaces; PRInt32 mTextJustificationNumLetters; - nsLineList::iterator mLineBox; + nsLineBox* mLineBox; PRInt32 mTotalPlacedFrames; diff --git a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp index 8015f773d61..c12421a7d33 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp @@ -985,7 +985,7 @@ nsMathMLContainerFrame::ReflowForeignChild(nsIFrame* aChildFrame, // provide a local, self-contained linelayout where to reflow the nsInlineFrame nsSize availSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); nsLineLayout ll(aPresContext, aReflowState.mSpaceManager, - aReflowState.parentReflowState, nsnull); + aReflowState.parentReflowState); ll.BeginLineReflow(0, 0, availSize.width, availSize.height, PR_FALSE, PR_FALSE); PRBool pushedFrame; ll.ReflowFrame(aChildFrame, aStatus, &aDesiredSize, pushedFrame);