diff --git a/mozilla/layout/generic/nsLineLayout.h b/mozilla/layout/generic/nsLineLayout.h index 30022312820..04945a49992 100644 --- a/mozilla/layout/generic/nsLineLayout.h +++ b/mozilla/layout/generic/nsLineLayout.h @@ -160,7 +160,13 @@ protected: #define LL_LASTFLOATWASLETTERFRAME 0x00000080 #define LL_CANPLACEFLOAT 0x00000100 #define LL_LINEENDSINBR 0x00000200 -#define LL_LASTFLAG LL_LINEENDSINBR +// The "soft-break" flag differs from the "hard-break" flag of
. The +// "soft-break" means that a whitespace has been trimmed at the end of the line, +// and therefore its width has not been accounted for (this width can actually be +// large, e.g., if a large word-spacing is set). LL should not be misled into +// placing something where the whitespace was trimmed. See bug 329987. +#define LL_LINEENDSINSOFTBR 0x00000400 +#define LL_LASTFLAG LL_LINEENDSINSOFTBR PRUint16 mFlags; @@ -239,6 +245,16 @@ public: SetFlag(LL_LINEENDSINBR, aOn); } + PRBool GetLineEndsInSoftBR() const + { + return GetFlag(LL_LINEENDSINSOFTBR); + } + + void SetLineEndsInSoftBR(PRBool aOn) + { + SetFlag(LL_LINEENDSINSOFTBR, aOn); + } + PRBool InStrictMode() const { return mCompatMode != eCompatibility_NavQuirks; diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index de7fa42cd9e..b1af9c21fd2 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -5417,7 +5417,7 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, // Note: word-spacing or letter-spacing can make the "space" really // wide. But since this space is left out from our width, linelayout // may still try to fit something narrower at the end of the line. - // So on return (see below), we flag a break-after status to ensure + // So on return (see below), we flag a soft-break status to ensure // that linelayout doesn't place something where the "space" should // be. break; @@ -5854,11 +5854,17 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, #endif // IBMBIDI ? NS_FRAME_COMPLETE : NS_FRAME_NOT_COMPLETE; - if (endsInNewline || aTextData.mTrailingSpaceTrimmed) { + if (endsInNewline) { rs = NS_INLINE_LINE_BREAK_AFTER(rs); - if (endsInNewline) { - lineLayout.SetLineEndsInBR(PR_TRUE); - } + lineLayout.SetLineEndsInBR(PR_TRUE); + } + else if (aTextData.mTrailingSpaceTrimmed && rs == NS_FRAME_COMPLETE) { + // Flag a soft-break that we can check (below) if we come back here + lineLayout.SetLineEndsInSoftBR(PR_TRUE); + } + else if (lineLayout.GetLineEndsInSoftBR() && !lineLayout.GetEndsInWhiteSpace()) { + // Break-before a word that follows the soft-break flagged earlier + rs = NS_INLINE_LINE_BREAK_BEFORE(); } else if ((aTextData.mOffset != contentLength) && (aTextData.mOffset == startingOffset)) { // Break-before a long-word that doesn't fit here