diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index d4c5156cc92..df0021c75be 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -2421,20 +2421,11 @@ 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. - while (nextAncestor) { - if (NS_OK == nextAncestor->QueryInterface(kBlockFrameCID, - (void**)&blockParent)) { - break; - } - nextAncestor = nextAncestor->GetParent(); - } + nsBlockFrame* blockParent = nsLayoutUtils::FindNearestBlockAncestor(this); // Tell the enclosing block frame to renumber list items within // itself @@ -3110,7 +3101,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); + &aState.mReflowState, &aLine); lineLayout.Init(&aState, aState.mMinLineHeight, aState.mLineNumber); if (forceBreakInContent) { lineLayout.ForceBreakAtPosition(forceBreakInContent, forceBreakOffset); @@ -3322,8 +3313,11 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, } if ((lineReflowStatus == LINE_REFLOW_STOP || lineReflowStatus == LINE_REFLOW_OK) && - !aLineLayout.HaveForcedBreakPosition() && aLineLayout.NeedsBackup()) { + 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) { @@ -3828,7 +3822,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, aLineLayout.AddBulletFrame(mBullet, metrics); addedBullet = PR_TRUE; } - aLineLayout.VerticalAlignLine(aLine); + aLineLayout.VerticalAlignLine(); // 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 5607883a50c..aef54daae67 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); + nsLineLayout ll(aPresContext, nsnull, &aReflowState, nsnull); 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 262ed7758c4..a22768acbad 100644 --- a/mozilla/layout/generic/nsHTMLReflowState.cpp +++ b/mozilla/layout/generic/nsHTMLReflowState.cpp @@ -651,24 +651,6 @@ 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. @@ -776,7 +758,8 @@ 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 = FindImmediateChildOf(blockFrame, aPlaceholderFrame); + nsIFrame *blockChild = + nsLayoutUtils::FindChildContainingDescendant(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 ce0e4b5e761..1402ea49b78 100644 --- a/mozilla/layout/generic/nsInlineFrame.cpp +++ b/mozilla/layout/generic/nsInlineFrame.cpp @@ -914,7 +914,11 @@ 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 ab86b019242..8f37b5f5cbd 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -93,7 +93,8 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext, nsSpaceManager* aSpaceManager, - const nsHTMLReflowState* aOuterReflowState) + const nsHTMLReflowState* aOuterReflowState, + const nsLineList::iterator* aLine) : mPresContext(aPresContext), mSpaceManager(aSpaceManager), mBlockReflowState(aOuterReflowState), @@ -133,6 +134,11 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext, mCurrentSpan = mRootSpan = nsnull; mSpanDepth = 0; + if (aLine) { + SetFlag(LL_GOTLINEBOX, PR_TRUE); + mLineBox = *aLine; + } + mCompatMode = mPresContext->CompatibilityMode(); } @@ -808,7 +814,6 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, #endif // IBMBIDI nsIAtom* frameType = aFrame->GetType(); - PRInt32 savedOptionalBreakOffset; nsIContent* savedOptionalBreakContent = GetLastOptionalBreakPosition(&savedOptionalBreakOffset); @@ -1393,7 +1398,7 @@ PRBool IsPercentageAwareFrame(nsPresContext *aPresContext, nsIFrame *aFrame) void -nsLineLayout::VerticalAlignLine(nsLineBox* aLineBox) +nsLineLayout::VerticalAlignLine() { // Synthesize a PerFrameData for the block frame PerFrameData rootPFD; @@ -1402,7 +1407,6 @@ nsLineLayout::VerticalAlignLine(nsLineBox* aLineBox) 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 @@ -1507,32 +1511,31 @@ nsLineLayout::VerticalAlignLine(nsLineBox* aLineBox) } // 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==aLineBox->ResizeReflowOptimizationDisabled()) && + if ((PR_FALSE==mLineBox->ResizeReflowOptimizationDisabled()) && pfd->mFrameType & NS_CSS_FRAME_TYPE_INLINE) { if (IsPercentageAwareFrame(mPresContext, pfd->mFrame)) - aLineBox->DisableResizeReflowOptimization(); + mLineBox->DisableResizeReflowOptimization(); } } // Fill in returned line-box and max-element-width data - aLineBox->mBounds.x = psd->mLeftEdge; - aLineBox->mBounds.y = mTopEdge; - aLineBox->mBounds.width = psd->mX - psd->mLeftEdge; - aLineBox->mBounds.height = lineHeight; + mLineBox->mBounds.x = psd->mLeftEdge; + mLineBox->mBounds.y = mTopEdge; + mLineBox->mBounds.width = psd->mX - psd->mLeftEdge; + mLineBox->mBounds.height = lineHeight; mFinalLineHeight = lineHeight; - aLineBox->SetAscent(baselineY - mTopEdge); + mLineBox->SetAscent(baselineY - mTopEdge); #ifdef NOISY_VERTICAL_ALIGN printf( " [line]==> bounds{x,y,w,h}={%d,%d,%d,%d} lh=%d a=%d\n", - aLineBox->mBounds.x, aLineBox->mBounds.y, - aLineBox->mBounds.width, aLineBox->mBounds.height, - mFinalLineHeight, aLineBox->GetAscent()); + mLineBox->mBounds.x, mLineBox->mBounds.y, + mLineBox->mBounds.width, mLineBox->mBounds.height, + mFinalLineHeight, mLineBox->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 97ec22ef72b..c008cb3d857 100644 --- a/mozilla/layout/generic/nsLineLayout.h +++ b/mozilla/layout/generic/nsLineLayout.h @@ -66,7 +66,8 @@ class nsLineLayout { public: nsLineLayout(nsPresContext* aPresContext, nsSpaceManager* aSpaceManager, - const nsHTMLReflowState* aOuterReflowState); + const nsHTMLReflowState* aOuterReflowState, + const nsLineList::iterator* aLine); ~nsLineLayout(); void Init(nsBlockReflowState* aState, nscoord aMinLineHeight, @@ -126,7 +127,7 @@ public: PushFrame(aFrame); } - void VerticalAlignLine(nsLineBox* aLineBox); + void VerticalAlignLine(); PRBool TrimTrailingWhiteSpace(); @@ -161,7 +162,9 @@ protected: #define LL_LINEENDSINSOFTBR 0x00000400 #define LL_NEEDBACKUP 0x00000800 #define LL_LASTTEXTFRAME_WRAPPINGENABLED 0x00001000 -#define LL_LASTFLAG LL_LASTTEXTFRAME_WRAPPINGENABLED +#define LL_INFIRSTLINE 0x00002000 +#define LL_GOTLINEBOX 0x00004000 +#define LL_LASTFLAG LL_GOTLINEBOX PRUint16 mFlags; @@ -274,7 +277,7 @@ public: * @param aWrappingEnabled whether that text had word-wrapping enabled * (white-space:normal or -moz-pre-wrap) */ - nsIFrame* GetTrailingTextFrame(PRBool* aWrappingEnabled) { + nsIFrame* GetTrailingTextFrame(PRBool* aWrappingEnabled) const { *aWrappingEnabled = GetFlag(LL_LASTTEXTFRAME_WRAPPINGENABLED); return mTrailingTextFrame; } @@ -298,6 +301,14 @@ public: mFirstLetterFrame = aFrame; } + PRBool GetInFirstLine() const { + return GetFlag(LL_INFIRSTLINE); + } + + void SetInFirstLine(PRBool aSetting) { + SetFlag(LL_INFIRSTLINE, aSetting); + } + //---------------------------------------- static PRBool TreatFrameAsBlock(nsIFrame* aFrame); @@ -390,8 +401,11 @@ public: * some other kind of frame when inline frames are reflowed in a non-block * context (e.g. MathML). */ - nsIFrame* GetLineContainerFrame() { return mBlockReflowState->frame; } - + nsIFrame* GetLineContainerFrame() const { return mBlockReflowState->frame; } + const nsLineList::iterator* GetLine() const { + return GetFlag(LL_GOTLINEBOX) ? &mLineBox : nsnull; + } + protected: // This state is constant for a given block frame doing line layout nsSpaceManager* mSpaceManager; @@ -427,7 +441,7 @@ protected: PRInt32 mTextJustificationNumSpaces; PRInt32 mTextJustificationNumLetters; - nsLineBox* mLineBox; + nsLineList::iterator mLineBox; PRInt32 mTotalPlacedFrames; diff --git a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp index c12421a7d33..8015f773d61 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); + aReflowState.parentReflowState, nsnull); ll.BeginLineReflow(0, 0, availSize.width, availSize.height, PR_FALSE, PR_FALSE); PRBool pushedFrame; ll.ReflowFrame(aChildFrame, aStatus, &aDesiredSize, pushedFrame);