Bug 439004. Check whether there's logically empty content already placed on the line instead of just checking whether the line has advanced horizontally. r+sr=dbaron.

This commit is contained in:
Robert O'Callahan 2008-06-14 20:28:07 +12:00
Родитель 0babca0115
Коммит 849b8d073a
8 изменённых файлов: 32 добавлений и 23 удалений

Просмотреть файл

@ -127,11 +127,9 @@ BRFrame::Reflow(nsPresContext* aPresContext,
if (ll) { if (ll) {
// Note that the compatibility mode check excludes AlmostStandards // Note that the compatibility mode check excludes AlmostStandards
// mode, since this is the inline box model. See bug 161691. // mode, since this is the inline box model. See bug 161691.
if ( ll->CanPlaceFloatNow() || if ( ll->LineIsEmpty() ||
aPresContext->CompatibilityMode() == eCompatibility_FullStandards ) { aPresContext->CompatibilityMode() == eCompatibility_FullStandards ) {
// If we can place a float on the line now it means that the // The line is logically empty; any whitespace is trimmed away.
// line is effectively empty (there may be zero sized compressed
// white-space frames on the line, but they are to be ignored).
// //
// If this frame is going to terminate the line we know // If this frame is going to terminate the line we know
// that nothing else will go on the line. Therefore, in this // that nothing else will go on the line. Therefore, in this

Просмотреть файл

@ -578,7 +578,7 @@ nsBlockReflowState::AddFloat(nsLineLayout& aLineLayout,
// don't let this one go on the current line, since that would violate // don't let this one go on the current line, since that would violate
// float ordering. // float ordering.
if (mBelowCurrentLineFloats.IsEmpty() && if (mBelowCurrentLineFloats.IsEmpty() &&
(aLineLayout.CanPlaceFloatNow() || (aLineLayout.LineIsEmpty() ||
mBlock->ComputeFloatWidth(*this, aPlaceholder) <= aAvailableWidth)) { mBlock->ComputeFloatWidth(*this, aPlaceholder) <= aAvailableWidth)) {
// Because we are in the middle of reflowing a placeholder frame // Because we are in the middle of reflowing a placeholder frame
// within a line (and possibly nested in an inline frame or two // within a line (and possibly nested in an inline frame or two

Просмотреть файл

@ -206,7 +206,7 @@ nsLineLayout::BeginLineReflow(nscoord aX, nscoord aY,
mPlacedFloats = 0; mPlacedFloats = 0;
SetFlag(LL_IMPACTEDBYFLOATS, aImpactedByFloats); SetFlag(LL_IMPACTEDBYFLOATS, aImpactedByFloats);
mTotalPlacedFrames = 0; mTotalPlacedFrames = 0;
SetFlag(LL_CANPLACEFLOAT, PR_TRUE); SetFlag(LL_LINEISEMPTY, PR_TRUE);
SetFlag(LL_LINEENDSINBR, PR_FALSE); SetFlag(LL_LINEENDSINBR, PR_FALSE);
mSpanDepth = 0; mSpanDepth = 0;
mMaxTopBoxHeight = mMaxBottomBoxHeight = 0; mMaxTopBoxHeight = mMaxBottomBoxHeight = 0;
@ -628,15 +628,11 @@ nsLineLayout::NewPerFrameData(PerFrameData** aResult)
return NS_OK; return NS_OK;
} }
PRBool
nsLineLayout::CanPlaceFloatNow() const
{
return GetFlag(LL_CANPLACEFLOAT);
}
PRBool PRBool
nsLineLayout::LineIsBreakable() const nsLineLayout::LineIsBreakable() const
{ {
// XXX mTotalPlacedFrames should go away and we should just use
// LL_LINEISEMPTY here instead
if ((0 != mTotalPlacedFrames) || GetFlag(LL_IMPACTEDBYFLOATS)) { if ((0 != mTotalPlacedFrames) || GetFlag(LL_IMPACTEDBYFLOATS)) {
return PR_TRUE; return PR_TRUE;
} }
@ -816,7 +812,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
// Capture this state *before* we reflow the frame in case it clears // Capture this state *before* we reflow the frame in case it clears
// the state out. We need to know how to treat the current frame // the state out. We need to know how to treat the current frame
// when breaking. // when breaking.
PRBool notSafeToBreak = CanPlaceFloatNow() && !GetFlag(LL_IMPACTEDBYFLOATS); PRBool notSafeToBreak = LineIsEmpty() && !GetFlag(LL_IMPACTEDBYFLOATS);
// Apply start margins (as appropriate) to the frame computing the // Apply start margins (as appropriate) to the frame computing the
// new starting x,y coordinates for the frame. // new starting x,y coordinates for the frame.
@ -1014,6 +1010,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
aReflowStatus, &optionalBreakAfterFits)) { aReflowStatus, &optionalBreakAfterFits)) {
if (!isEmpty) { if (!isEmpty) {
psd->mHasNonemptyContent = PR_TRUE; psd->mHasNonemptyContent = PR_TRUE;
SetFlag(LL_LINEISEMPTY, PR_FALSE);
} }
// Place the frame, updating aBounds with the final size and // Place the frame, updating aBounds with the final size and
@ -1029,7 +1026,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
} }
if (!continuingTextRun) { if (!continuingTextRun) {
if (!psd->mNoWrap && (!CanPlaceFloatNow() || placedFloat)) { if (!psd->mNoWrap && (!LineIsEmpty() || placedFloat)) {
// record soft break opportunity after this content that can't be // 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 // part of a text run. This is not a text frame so we know
// that offset PR_INT32_MAX means "after the content". // that offset PR_INT32_MAX means "after the content".
@ -1315,11 +1312,6 @@ nsLineLayout::PlaceFrame(PerFrameData* pfd, nsHTMLReflowMetrics& aMetrics)
if (!emptyFrame) { if (!emptyFrame) {
mTotalPlacedFrames++; mTotalPlacedFrames++;
} }
if (psd->mX != psd->mLeftEdge || pfd->mBounds.x != psd->mLeftEdge) {
// As soon as a frame placed on the line advances an X coordinate
// of any span we can no longer place a float on the line.
SetFlag(LL_CANPLACEFLOAT, PR_FALSE);
}
} }
nsresult nsresult

Просмотреть файл

@ -155,10 +155,9 @@ public:
protected: protected:
#define LL_FIRSTLETTERSTYLEOK 0x00000008 #define LL_FIRSTLETTERSTYLEOK 0x00000008
#define LL_ISTOPOFPAGE 0x00000010 #define LL_ISTOPOFPAGE 0x00000010
#define LL_UPDATEDBAND 0x00000020
#define LL_IMPACTEDBYFLOATS 0x00000040 #define LL_IMPACTEDBYFLOATS 0x00000040
#define LL_LASTFLOATWASLETTERFRAME 0x00000080 #define LL_LASTFLOATWASLETTERFRAME 0x00000080
#define LL_CANPLACEFLOAT 0x00000100 #define LL_LINEISEMPTY 0x00000100
#define LL_LINEENDSINBR 0x00000200 #define LL_LINEENDSINBR 0x00000200
#define LL_NEEDBACKUP 0x00000400 #define LL_NEEDBACKUP 0x00000400
#define LL_INFIRSTLINE 0x00000800 #define LL_INFIRSTLINE 0x00000800
@ -194,7 +193,14 @@ public:
mTextJustificationNumLetters = aNumLetters; mTextJustificationNumLetters = aNumLetters;
} }
PRBool CanPlaceFloatNow() const; /**
* @return true if so far during reflow no non-empty content has been
* placed in the line
*/
PRBool LineIsEmpty() const
{
return GetFlag(LL_LINEISEMPTY);
}
PRBool LineIsBreakable() const; PRBool LineIsBreakable() const;

Просмотреть файл

@ -5453,7 +5453,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
const nsStyleText* textStyle = GetStyleText(); const nsStyleText* textStyle = GetStyleText();
PRBool atStartOfLine = lineLayout.CanPlaceFloatNow(); PRBool atStartOfLine = lineLayout.LineIsEmpty();
if (atStartOfLine) { if (atStartOfLine) {
AddStateBits(TEXT_START_OF_LINE); AddStateBits(TEXT_START_OF_LINE);
} }

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE HTML>
<html>
<body>
&nbsp;Hello
</body>
</html>

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE HTML>
<html>
<body>
<img src="mozilla-banner.gif" style="width:0"> Hello
</body>
</html>

Просмотреть файл

@ -844,3 +844,4 @@ random == 429849-1.html 429849-1-ref.html # bug 432288
== 430813-2.html 430813-2-ref.html == 430813-2.html 430813-2-ref.html
== 430813-3.html 430813-3-ref.html == 430813-3.html 430813-3-ref.html
== 433640-1.html 433640-1-ref.html == 433640-1.html 433640-1-ref.html
== 439004-1.html 439004-1-ref.html