diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 5e7a24b55d6..90bcc0d0b95 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -3184,7 +3184,8 @@ nsIFrame::InlineMinWidthData::ForceBreak(nsIRenderingContext *aRenderingContext) } void -nsIFrame::InlineMinWidthData::OptionallyBreak(nsIRenderingContext *aRenderingContext) +nsIFrame::InlineMinWidthData::OptionallyBreak(nsIRenderingContext *aRenderingContext, + nscoord aHyphenWidth) { trailingTextFrame = nsnull; @@ -3193,8 +3194,9 @@ nsIFrame::InlineMinWidthData::OptionallyBreak(nsIRenderingContext *aRenderingCon // text-indent or negative margin), don't break. Otherwise, do the // same as ForceBreak. it doesn't really matter when we accumulate // floats. - if (currentLine < 0 || atStartOfLine) + if (currentLine + aHyphenWidth < 0 || atStartOfLine) return; + currentLine += aHyphenWidth; ForceBreak(aRenderingContext); } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 68ce2e9eef1..5e1cc76d4c9 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1465,7 +1465,11 @@ public: // optional breaks to prevent min-width from ending up bigger than // pref-width. void ForceBreak(nsIRenderingContext *aRenderingContext); - void OptionallyBreak(nsIRenderingContext *aRenderingContext); + + // If the break here is actually taken, aHyphenWidth must be added to the + // width of the current line. + void OptionallyBreak(nsIRenderingContext *aRenderingContext, + nscoord aHyphenWidth = 0); // The last text frame processed so far in the current line, when // the last characters in that text frame are relevant for line diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index 6ad2de7fb98..19dd117717a 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -6072,8 +6072,19 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext, // OK since we can't really handle tabs for intrinsic sizing anyway. const nsStyleText* textStyle = GetStyleText(); const nsTextFragment* frag = mContent->GetText(); + + // If we're hyphenating, the PropertyProvider needs the actual length; + // otherwise we can just pass PR_INT32_MAX to mean "all the text" + PRInt32 len = PR_INT32_MAX; + PRBool hyphenating = + (mTextRun->GetFlags() & gfxTextRunFactory::TEXT_ENABLE_HYPHEN_BREAKS) != 0; + if (hyphenating) { + gfxSkipCharsIterator tmp(iter); + len = + tmp.ConvertSkippedToOriginal(flowEndInTextRun) - iter.GetOriginalOffset(); + } PropertyProvider provider(mTextRun, textStyle, frag, this, - iter, PR_INT32_MAX, nsnull, 0); + iter, len, nsnull, 0); PRBool collapseWhitespace = !textStyle->WhiteSpaceIsSignificant(); PRBool preformatNewlines = textStyle->NewlineIsSignificant(); @@ -6082,7 +6093,16 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext, PRUint32 start = FindStartAfterSkippingWhitespace(&provider, aData, textStyle, &iter, flowEndInTextRun); - // XXX Should we consider hyphenation here? + nsAutoTArray hyphBuffer; + PRPackedBool *hyphBreakBefore = nsnull; + if (hyphenating) { + hyphBreakBefore = hyphBuffer.AppendElements(flowEndInTextRun - start); + if (hyphBreakBefore) { + provider.GetHyphenationBreaks(start, flowEndInTextRun - start, + hyphBreakBefore); + } + } + for (PRUint32 i = start, wordStart = start; i <= flowEndInTextRun; ++i) { PRBool preformattedNewline = PR_FALSE; PRBool preformattedTab = PR_FALSE; @@ -6092,8 +6112,11 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext, // starts? preformattedNewline = preformatNewlines && mTextRun->GetChar(i) == '\n'; preformattedTab = preformatTabs && mTextRun->GetChar(i) == '\t'; - if (!mTextRun->CanBreakLineBefore(i) && !preformattedNewline && - !preformattedTab) { + if (!mTextRun->CanBreakLineBefore(i) && + !preformattedNewline && + !preformattedTab && + (!hyphBreakBefore || !hyphBreakBefore[i - start])) + { // we can't break here (and it's not the end of the flow) continue; } @@ -6135,6 +6158,8 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext, (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TRAILING_BREAK))) { if (preformattedNewline) { aData->ForceBreak(aRenderingContext); + } else if (hyphBreakBefore && hyphBreakBefore[i - start]) { + aData->OptionallyBreak(aRenderingContext, provider.GetHyphenWidth()); } else { aData->OptionallyBreak(aRenderingContext); }