From f1bca53a79af9fb76be95237306ba67d242c78f2 Mon Sep 17 00:00:00 2001 From: "dholbert%cs.stanford.edu" Date: Thu, 26 Feb 2009 20:20:31 +0000 Subject: [PATCH] (Patch #2 to fix Bug 431260) Bug 455826 - Look into overflow-lists of inlines to find text when we're building textruns. Patch by Robert O'Callahan r=smontagu git-svn-id: svn://10.0.0.236/trunk@256332 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsTextFrameThebes.cpp | 67 +++++++++++++------ .../layout/reftests/bugs/455826-1-ref.html | 6 ++ mozilla/layout/reftests/bugs/455826-1.html | 4 ++ mozilla/layout/reftests/bugs/reftest.list | 1 + 4 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 mozilla/layout/reftests/bugs/455826-1-ref.html create mode 100644 mozilla/layout/reftests/bugs/455826-1.html diff --git a/mozilla/layout/generic/nsTextFrameThebes.cpp b/mozilla/layout/generic/nsTextFrameThebes.cpp index f7a2f36a1aa..0ae9247a449 100644 --- a/mozilla/layout/generic/nsTextFrameThebes.cpp +++ b/mozilla/layout/generic/nsTextFrameThebes.cpp @@ -747,10 +747,32 @@ TextContainsLineBreakerWhiteSpace(const void* aText, PRUint32 aLength, } struct FrameTextTraversal { - nsIFrame* mFrameToDescendInto; - PRPackedBool mDescendIntoFrameSiblings; + // These fields identify which frames should be recursively scanned + // The first normal frame to scan (or null, if no such frame should be scanned) + nsIFrame* mFrameToScan; + // The first overflow frame to scan (or null, if no such frame should be scanned) + nsIFrame* mOverflowFrameToScan; + // Whether to scan the siblings of mFrameToDescendInto/mOverflowFrameToDescendInto + PRPackedBool mScanSiblings; + + // These identify the boundaries of the context required for + // line breaking or textrun construction PRPackedBool mLineBreakerCanCrossFrameBoundary; PRPackedBool mTextRunCanCrossFrameBoundary; + + nsIFrame* NextFrameToScan() { + nsIFrame* f; + if (mFrameToScan) { + f = mFrameToScan; + mFrameToScan = mScanSiblings ? f->GetNextSibling() : nsnull; + } else if (mOverflowFrameToScan) { + f = mOverflowFrameToScan; + mOverflowFrameToScan = mScanSiblings ? f->GetNextSibling() : nsnull; + } else { + f = nsnull; + } + return f; + } }; static FrameTextTraversal @@ -765,28 +787,33 @@ CanTextCrossFrameBoundary(nsIFrame* aFrame, nsIAtom* aType) // placeholders are "invisible", so a text run should be able to span // across one. But don't descend into the out-of-flow. result.mLineBreakerCanCrossFrameBoundary = PR_TRUE; + result.mOverflowFrameToScan = nsnull; if (continuesTextRun) { // ... Except for first-letter floats, which are really in-flow // from the point of view of capitalization etc, so we'd better // descend into them. But we actually need to break the textrun for // first-letter floats since things look bad if, say, we try to make a // ligature across the float boundary. - result.mFrameToDescendInto = + result.mFrameToScan = (static_cast(aFrame))->GetOutOfFlowFrame(); - result.mDescendIntoFrameSiblings = PR_FALSE; + result.mScanSiblings = PR_FALSE; result.mTextRunCanCrossFrameBoundary = PR_FALSE; } else { - result.mFrameToDescendInto = nsnull; + result.mFrameToScan = nsnull; result.mTextRunCanCrossFrameBoundary = PR_TRUE; } } else { if (continuesTextRun) { - result.mFrameToDescendInto = aFrame->GetFirstChild(nsnull); - result.mDescendIntoFrameSiblings = PR_TRUE; + result.mFrameToScan = aFrame->GetFirstChild(nsnull); + result.mOverflowFrameToScan = aFrame->GetFirstChild(nsGkAtoms::overflowList); + NS_WARN_IF_FALSE(!result.mOverflowFrameToScan, + "Scanning overflow inline frames is something we should avoid"); + result.mScanSiblings = PR_TRUE; result.mTextRunCanCrossFrameBoundary = PR_TRUE; result.mLineBreakerCanCrossFrameBoundary = PR_TRUE; } else { - result.mFrameToDescendInto = nsnull; + result.mFrameToScan = nsnull; + result.mOverflowFrameToScan = nsnull; result.mTextRunCanCrossFrameBoundary = PR_FALSE; result.mLineBreakerCanCrossFrameBoundary = PR_FALSE; } @@ -842,13 +869,11 @@ BuildTextRunsScanner::FindBoundaries(nsIFrame* aFrame, FindBoundaryState* aState return FB_FOUND_VALID_TEXTRUN_BOUNDARY; } - for (nsIFrame* f = traversal.mFrameToDescendInto; f; - f = f->GetNextSibling()) { + for (nsIFrame* f = traversal.NextFrameToScan(); f; + f = traversal.NextFrameToScan()) { FindBoundaryResult result = FindBoundaries(f, aState); if (result != FB_CONTINUE) return result; - if (!traversal.mDescendIntoFrameSiblings) - break; } if (!traversal.mTextRunCanCrossFrameBoundary) { @@ -1257,11 +1282,9 @@ void BuildTextRunsScanner::ScanFrame(nsIFrame* aFrame) FlushFrames(PR_FALSE, PR_FALSE); } - for (nsIFrame* f = traversal.mFrameToDescendInto; f; - f = f->GetNextSibling()) { + for (nsIFrame* f = traversal.NextFrameToScan(); f; + f = traversal.NextFrameToScan()) { ScanFrame(f); - if (!traversal.mDescendIntoFrameSiblings) - break; } if (!traversal.mLineBreakerCanCrossFrameBoundary) { @@ -3278,10 +3301,16 @@ nsContinuingTextFrame::Init(nsIContent* aContent, void nsContinuingTextFrame::Destroy() { - ClearTextRun(); - if (mPrevContinuation || mNextContinuation) { - nsSplittableFrame::RemoveFromFlow(this); + // The text associated with this frame will become associated with our + // prev-continuation. If that means the text has changed style, then + // we need to wipe out the text run for the text. + // Note that mPrevContinuation can be null if we're destroying the whole + // frame chain from the start to the end. + if (!mPrevContinuation || + mPrevContinuation->GetStyleContext() != GetStyleContext()) { + ClearTextRun(); } + nsSplittableFrame::RemoveFromFlow(this); // Let the base class destroy the frame nsFrame::Destroy(); } diff --git a/mozilla/layout/reftests/bugs/455826-1-ref.html b/mozilla/layout/reftests/bugs/455826-1-ref.html new file mode 100644 index 00000000000..7bc0743de63 --- /dev/null +++ b/mozilla/layout/reftests/bugs/455826-1-ref.html @@ -0,0 +1,6 @@ + + +aa +aa +aa a + diff --git a/mozilla/layout/reftests/bugs/455826-1.html b/mozilla/layout/reftests/bugs/455826-1.html new file mode 100644 index 00000000000..b9ae24e2bc1 --- /dev/null +++ b/mozilla/layout/reftests/bugs/455826-1.html @@ -0,0 +1,4 @@ + + +aa aa aa a + diff --git a/mozilla/layout/reftests/bugs/reftest.list b/mozilla/layout/reftests/bugs/reftest.list index 47677e2a0b6..72f78c4af88 100644 --- a/mozilla/layout/reftests/bugs/reftest.list +++ b/mozilla/layout/reftests/bugs/reftest.list @@ -836,5 +836,6 @@ fails-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 424074-1-ref2.xul 424074-1-ref3.xul == 440112.html 440112-ref.html == 440149-1.html 440149-1-ref.html == 445004-1.html 445004-1-ref.html +== 455826-1.html 455826-1-ref.html == 459443-1.html 459443-1-ref.html == 471594-1.xhtml 471594-1-ref.html