From 8c4eb4e25f79a498da9d960a7be08e916aca18c0 Mon Sep 17 00:00:00 2001 From: "reed@reedloden.com" Date: Thu, 8 Nov 2007 22:55:32 -0800 Subject: [PATCH] Bug 398101 - Be more diligent about invalidating textruns for lines [p=roc r+sr=dbaron a=blocking1.9+] --- layout/generic/nsBlockFrame.cpp | 24 +++++++++++++----------- layout/generic/nsBlockFrame.h | 4 +++- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 336eaf4f4823..f95cef1fb7dc 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1432,6 +1432,7 @@ nsBlockFrame::MarkLineDirty(line_iterator aLine) { // Mark aLine dirty aLine->MarkDirty(); + aLine->SetInvalidateTextRuns(PR_TRUE); #ifdef DEBUG if (gNoisyReflow) { IndentBy(stdout, gNoiseIndent); @@ -1447,6 +1448,7 @@ nsBlockFrame::MarkLineDirty(line_iterator aLine) aLine->IsInline() && aLine.prev()->IsInline()) { aLine.prev()->MarkDirty(); + aLine.prev()->SetInvalidateTextRuns(PR_TRUE); #ifdef DEBUG if (gNoisyReflow) { IndentBy(stdout, gNoiseIndent); @@ -4857,13 +4859,13 @@ nsBlockFrame::AddFrames(nsIFrame* aFrameList, } mLines.after_insert(prevSibLine, line); prevSibLine->SetChildCount(prevSibLine->GetChildCount() - rem); - prevSibLine->MarkDirty(); - } - // Force the lines next to where we're inserting content to regenerate - // their textruns - prevSibLine->SetInvalidateTextRuns(PR_TRUE); - if (prevSibLine.next() != end_lines()) { - prevSibLine.next()->SetInvalidateTextRuns(PR_TRUE); + // Mark prevSibLine dirty and as needing textrun invalidation, since + // we may be breaking up text in the line. Its previous line may also + // need to be invalidated because it may be able to pull some text up. + MarkLineDirty(prevSibLine); + // The new line will also need its textruns recomputed because of the + // frame changes. + line->SetInvalidateTextRuns(PR_TRUE); } // Now (partially) join the sibling lists together @@ -4911,7 +4913,10 @@ nsBlockFrame::AddFrames(nsIFrame* aFrameList, } else { prevSibLine->SetChildCount(prevSibLine->GetChildCount() + 1); - prevSibLine->MarkDirty(); + // We're adding inline content to prevSibLine, so we need to mark it + // dirty, ensure its textruns are recomputed, and possibly do the same + // to its previous line since that line may be able to pull content up. + MarkLineDirty(prevSibLine); } aPrevSibling = newFrame; @@ -6208,9 +6213,6 @@ nsBlockFrame::ChildIsDirty(nsIFrame* aChild) // child is being dirtied. line_iterator fline = FindLineFor(aChild); if (fline != end_lines()) { - // An inline descendant might have been added or removed, so we should - // reconstruct textruns. - fline->SetInvalidateTextRuns(PR_TRUE); MarkLineDirty(fline); } } diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 373edcc739fd..15bb2263acaf 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -460,7 +460,9 @@ protected: /** * Mark |aLine| dirty, and, if necessary because of possible - * pull-up, mark the previous line dirty as well. + * pull-up, mark the previous line dirty as well. Also invalidates textruns + * on those lines because the text in the lines might have changed due to + * addition/removal of frames. */ nsresult MarkLineDirty(line_iterator aLine);