Bug 407078. Don't allow a trailing break in a text run that is followed by a <br>. r=smontagu

This commit is contained in:
2007-12-10 17:19:20 -08:00
parent 7733ef5ba3
commit 2a6e806f11
4 changed files with 59 additions and 9 deletions

View File

@@ -594,7 +594,7 @@ public:
} }
void ScanFrame(nsIFrame* aFrame); void ScanFrame(nsIFrame* aFrame);
PRBool IsTextRunValidForMappedFlows(gfxTextRun* aTextRun); PRBool IsTextRunValidForMappedFlows(gfxTextRun* aTextRun);
void FlushFrames(PRBool aFlushLineBreaks); void FlushFrames(PRBool aFlushLineBreaks, PRBool aSuppressTrailingBreak);
void ResetRunInfo() { void ResetRunInfo() {
mLastFrame = nsnull; mLastFrame = nsnull;
mMappedFlows.Clear(); mMappedFlows.Clear();
@@ -864,7 +864,7 @@ BuildTextRuns(gfxContext* aContext, nsTextFrame* aForFrame,
} }
// Set mStartOfLine so FlushFrames knows its textrun ends a line // Set mStartOfLine so FlushFrames knows its textrun ends a line
scanner.SetAtStartOfLine(); scanner.SetAtStartOfLine();
scanner.FlushFrames(PR_TRUE); scanner.FlushFrames(PR_TRUE, PR_FALSE);
return; return;
} }
@@ -989,7 +989,7 @@ BuildTextRuns(gfxContext* aContext, nsTextFrame* aForFrame,
// Set mStartOfLine so FlushFrames knows its textrun ends a line // Set mStartOfLine so FlushFrames knows its textrun ends a line
scanner.SetAtStartOfLine(); scanner.SetAtStartOfLine();
scanner.FlushFrames(PR_TRUE); scanner.FlushFrames(PR_TRUE, PR_FALSE);
} }
static PRUnichar* static PRUnichar*
@@ -1028,7 +1028,7 @@ PRBool BuildTextRunsScanner::IsTextRunValidForMappedFlows(gfxTextRun* aTextRun)
* This gets called when we need to make a text run for the current list of * This gets called when we need to make a text run for the current list of
* frames. * frames.
*/ */
void BuildTextRunsScanner::FlushFrames(PRBool aFlushLineBreaks) void BuildTextRunsScanner::FlushFrames(PRBool aFlushLineBreaks, PRBool aSuppressTrailingBreak)
{ {
if (mMappedFlows.Length() == 0) if (mMappedFlows.Length() == 0)
return; return;
@@ -1059,7 +1059,7 @@ void BuildTextRunsScanner::FlushFrames(PRBool aFlushLineBreaks)
// textRun may be null for various reasons, including because we constructed // textRun may be null for various reasons, including because we constructed
// a partial textrun just to get the linebreaker and other state set up // a partial textrun just to get the linebreaker and other state set up
// to build the next textrun. // to build the next textrun.
if (NS_SUCCEEDED(rv) && trailingLineBreak && textRun) { if (NS_SUCCEEDED(rv) && trailingLineBreak && textRun && !aSuppressTrailingBreak) {
textRun->SetFlagBits(nsTextFrameUtils::TEXT_HAS_TRAILING_BREAK); textRun->SetFlagBits(nsTextFrameUtils::TEXT_HAS_TRAILING_BREAK);
} }
PRUint32 i; PRUint32 i;
@@ -1178,13 +1178,14 @@ void BuildTextRunsScanner::ScanFrame(nsIFrame* aFrame)
} }
} }
nsIAtom* frameType = aFrame->GetType();
// Now see if we can add a new set of frames to the current textrun // Now see if we can add a new set of frames to the current textrun
if (aFrame->GetType() == nsGkAtoms::textFrame) { if (frameType == nsGkAtoms::textFrame) {
nsTextFrame* frame = static_cast<nsTextFrame*>(aFrame); nsTextFrame* frame = static_cast<nsTextFrame*>(aFrame);
if (mLastFrame) { if (mLastFrame) {
if (!ContinueTextRunAcrossFrames(mLastFrame, frame)) { if (!ContinueTextRunAcrossFrames(mLastFrame, frame)) {
FlushFrames(PR_FALSE); FlushFrames(PR_FALSE, PR_FALSE);
} else { } else {
if (mLastFrame->GetContent() == frame->GetContent()) { if (mLastFrame->GetContent() == frame->GetContent()) {
AccumulateRunInfo(frame); AccumulateRunInfo(frame);
@@ -1210,8 +1211,11 @@ void BuildTextRunsScanner::ScanFrame(nsIFrame* aFrame)
PRBool continueTextRun = CanTextRunCrossFrameBoundary(aFrame); PRBool continueTextRun = CanTextRunCrossFrameBoundary(aFrame);
PRBool descendInto = PR_TRUE; PRBool descendInto = PR_TRUE;
PRBool isBR = frameType == nsGkAtoms::brFrame;
if (!continueTextRun) { if (!continueTextRun) {
FlushFrames(PR_TRUE); // BR frames are special. We do not need or want to record a break opportunity
// before a BR frame.
FlushFrames(PR_TRUE, isBR);
mCommonAncestorWithLastFrame = aFrame; mCommonAncestorWithLastFrame = aFrame;
mTrimNextRunLeadingWhitespace = PR_FALSE; mTrimNextRunLeadingWhitespace = PR_FALSE;
// XXX do we need this? are there frames we need to descend into that aren't // XXX do we need this? are there frames we need to descend into that aren't
@@ -1228,7 +1232,9 @@ void BuildTextRunsScanner::ScanFrame(nsIFrame* aFrame)
} }
if (!continueTextRun) { if (!continueTextRun) {
FlushFrames(PR_TRUE); // Really if we're a BR frame this is unnecessary since descendInto will be
// false. In fact this whole "if" statement should move into the descendInto.
FlushFrames(PR_TRUE, isBR);
mCommonAncestorWithLastFrame = aFrame; mCommonAncestorWithLastFrame = aFrame;
mTrimNextRunLeadingWhitespace = PR_FALSE; mTrimNextRunLeadingWhitespace = PR_FALSE;
} }

View File

@@ -0,0 +1,21 @@
<html><head>
<style>
body{
font:normal 13px Verdana;
}
div {
padding-right:7px;
font-size:11px;
}
</style></head>
<body>
<table><tbody><tr><td>
<div>
<span>m m </span>
</div>
<div>
<span>m</span>
</div>
</td></tr></tbody></table>
</body></html>

View File

@@ -0,0 +1,22 @@
<html><head>
<style>
body{
font:normal 13px Verdana;
}
div {
padding-right:7px;
font-size:11px;
}
</style></head>
<body>
<table><tbody><tr><td>
<div>
<span>m m </span>
<br>
</div>
<div>
<span>m</span>
</div>
</td></tr></tbody></table>
</body></html>

View File

@@ -509,6 +509,7 @@ random == 403134-1.html 403134-1-ref.html # bug 405377
== 405584-1.html 405584-1-ref.html == 405584-1.html 405584-1-ref.html
== 406484-1.html 406484-1-ref.html == 406484-1.html 406484-1-ref.html
== 406568-1.html 406568-1-ref.html == 406568-1.html 406568-1-ref.html
== 407078-1.html 407078-1-ref.html
== 407111-1.html 407111-1-ref.html == 407111-1.html 407111-1-ref.html
== 407227-1.html 407227-1-ref.html == 407227-1.html 407227-1-ref.html
== 407937-1.html 407937-1-ref.html == 407937-1.html 407937-1-ref.html