diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index a5f18481854..e13fca1e765 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -3086,7 +3086,7 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState, if (LINE_REFLOW_REDO_NO_PULL == lineReflowStatus || LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) { if (lineLayout.NeedsBackup()) { - NS_ASSERTION(!forceBreakInContent, "Backuping up twice; this should never be necessary"); + NS_ASSERTION(!forceBreakInContent, "Backing up twice; this should never be necessary"); // If there is no saved break position, then this will set // set forceBreakInContent to null and we won't back up, which is // correct. @@ -3219,7 +3219,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, if (impactedByFloats) { // There is a soft break opportunity at the start of the line, because // we can always move this line down below float(s). - if (aLineLayout.NotifyOptionalBreakPosition(frame->GetContent(), 0)) { + if (aLineLayout.NotifyOptionalBreakPosition(frame->GetContent(), 0, PR_TRUE)) { lineReflowStatus = LINE_REFLOW_REDO_NEXT_BAND; } } @@ -3290,7 +3290,8 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, (lineReflowStatus == LINE_REFLOW_STOP || lineReflowStatus == LINE_REFLOW_OK); if (needsBackup && aLineLayout.HaveForcedBreakPosition()) { NS_WARNING("We shouldn't be backing up more than once! " - "Someone must have set a break opportunity beyond the available width"); + "Someone must have set a break opportunity beyond the available width, " + "even though there were better break opportunities before it"); needsBackup = PR_FALSE; } if (needsBackup) { diff --git a/mozilla/layout/generic/nsLineLayout.cpp b/mozilla/layout/generic/nsLineLayout.cpp index 5c4d8529a7a..3ca57aa4f1b 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -1048,7 +1048,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, // record soft break opportunity after this content that can't be // part of a text run. This is not a text frame so we know // that offset PR_INT32_MAX means "after the content". - if (NotifyOptionalBreakPosition(aFrame->GetContent(), PR_INT32_MAX)) { + if (NotifyOptionalBreakPosition(aFrame->GetContent(), PR_INT32_MAX, PR_TRUE)) { // If this returns true then we are being told to actually break here. aReflowStatus = NS_INLINE_LINE_BREAK_AFTER(aReflowStatus); } diff --git a/mozilla/layout/generic/nsLineLayout.h b/mozilla/layout/generic/nsLineLayout.h index e5c2fd2a5e6..a7eb4653d4d 100644 --- a/mozilla/layout/generic/nsLineLayout.h +++ b/mozilla/layout/generic/nsLineLayout.h @@ -321,8 +321,8 @@ public: * Record where an optional break could have been placed. During line reflow, * frames containing optional break points (e.g., whitespace in text frames) * can call SetLastOptionalBreakPosition to record where a break could - * have been made, but wasn't because there appeared to be enough room - * to place more content on the line. For non-text frames, offset 0 means + * have been made, but wasn't because we decided to place more content on + * the line. For non-text frames, offset 0 means * before the content, offset PR_INT32_MAX means after the content. * * Currently this is used to handle cases where a single word comprises @@ -332,17 +332,21 @@ public: * optional break position could be in a text frame or else after a frame * that cannot be part of a text run, so those are the positions we record. * - * It is imperative that this only gets called for break points that - * are within the available width. + * @param aFits set to true if the break position is within the available width. * * @return PR_TRUE if we are actually reflowing with forced break position and we * should break here */ - PRBool NotifyOptionalBreakPosition(nsIContent* aContent, PRInt32 aOffset) { + PRBool NotifyOptionalBreakPosition(nsIContent* aContent, PRInt32 aOffset, + PRBool aFits) { NS_ASSERTION(!GetFlag(LL_NEEDBACKUP), "Shouldn't be updating the break position after we've already flagged an overrun"); - mLastOptionalBreakContent = aContent; - mLastOptionalBreakContentOffset = aOffset; + // Remember the last break position that fits; if there was no break that fit, + // just remember the first break + if (aFits || !mLastOptionalBreakContent) { + mLastOptionalBreakContent = aContent; + mLastOptionalBreakContentOffset = aOffset; + } return aContent && mForceBreakContent == aContent && mForceBreakContentOffset == aOffset; } @@ -355,7 +359,11 @@ public: mLastOptionalBreakContent = aContent; mLastOptionalBreakContentOffset = aOffset; } + /** + * Signal that no backing up will be required after all. + */ void ClearOptionalBreakPosition() { + SetFlag(LL_NEEDBACKUP, PR_FALSE); mLastOptionalBreakContent = nsnull; mLastOptionalBreakContentOffset = -1; } diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index e0858746251..8f8dc34f014 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -5368,7 +5368,7 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, if (canBreak) { // Remember that we *could* have broken here, even if we choose not to PRBool forceBreak = - lineLayout.NotifyOptionalBreakPosition(GetContent(), aTextData.mOffset); + lineLayout.NotifyOptionalBreakPosition(GetContent(), aTextData.mOffset, PR_TRUE); // See if there is room for the text if (forceBreak || (aTextData.mX + dimensions.width > maxWidth)) { // The text will not fit, or a break was forced. @@ -5407,7 +5407,7 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, #ifdef DEBUG PRBool forceBreak = #endif - lineLayout.NotifyOptionalBreakPosition(GetContent(), aTextData.mOffset); + lineLayout.NotifyOptionalBreakPosition(GetContent(), aTextData.mOffset, PR_TRUE); NS_ASSERTION(!forceBreak, "If we're supposed to break, we should be " "really measuring"); } @@ -5530,7 +5530,8 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, endsInWhitespace ? lastSegment : lastSegment - 1; if (lastWhitespaceSegment >= 0) { lineLayout.NotifyOptionalBreakPosition(GetContent(), - aTextData.mOffset + textRun.mSegments[lastWhitespaceSegment].ContentLen()); + aTextData.mOffset + textRun.mSegments[lastWhitespaceSegment].ContentLen(), + PR_TRUE); } column += numCharsFit; @@ -5633,9 +5634,10 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, } if (rs == NS_FRAME_COMPLETE && 0 != aTextData.mX && endsInWhitespace && - aTextData.mWrapping && aTextData.mX <= maxWidth) { + aTextData.mWrapping) { // Remember the break opportunity at the end of this frame - if (lineLayout.NotifyOptionalBreakPosition(GetContent(), aTextData.mOffset)) + if (lineLayout.NotifyOptionalBreakPosition(GetContent(), aTextData.mOffset, + aTextData.mX <= maxWidth)) return NS_INLINE_LINE_BREAK_AFTER(rs); }