From 77bea95a75ecd05eceb1fc4f698cd8bbc71ef335 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Tue, 10 Aug 2004 19:09:49 +0000 Subject: [PATCH] Cache the IsEmpty() state in the framestate so we don't have to do quite as much style-getting and QIing. Bug 254378, r+sr=roc git-svn-id: svn://10.0.0.236/trunk@160616 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsTextFrame.cpp | 37 ++++++++++++++++++-- mozilla/layout/html/base/src/nsTextFrame.cpp | 37 ++++++++++++++++++-- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index dc924a05a33..6bac036f664 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -467,6 +467,8 @@ public: NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end)const; virtual void AdjustOffsetsForBidi(PRInt32 start, PRInt32 end); + + NS_IMETHOD DidSetStyleContext(nsPresContext* aPresContext); NS_IMETHOD GetPointFromOffset(nsPresContext* inPresContext, nsIRenderingContext* inRendContext, @@ -1274,6 +1276,12 @@ DrawSelectionIterator::IsBeforeOrAfter() #define TEXT_BLINK_ON 0x80000000 +#define TEXT_IS_EMPTY 0x00100000 + +#define TEXT_ISNOT_EMPTY 0x00200000 + +#define TEXT_ISEMPTY_FLAGS 0x00300000 + //---------------------------------------------------------------------- nsresult @@ -1389,6 +1397,7 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext, if (aAppend) { markAllDirty = PR_FALSE; nsTextFrame* frame = (nsTextFrame*)GetLastInFlow(); + frame->mState &= ~TEXT_ISEMPTY_FLAGS; frame->mState |= NS_FRAME_IS_DIRTY; targetTextFrame = frame; } @@ -1397,6 +1406,7 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext, // Mark this frame and all the next-in-flow frames as dirty nsTextFrame* textFrame = this; while (textFrame) { + textFrame->mState &= ~TEXT_ISEMPTY_FLAGS; textFrame->mState |= NS_FRAME_IS_DIRTY; #ifdef IBMBIDI void* nextBidiFrame; @@ -5826,8 +5836,20 @@ nsTextFrame::GetType() const /* virtual */ PRBool nsTextFrame::IsEmpty() { - // XXXldb Should this check compatibility mode as well??? + NS_ASSERTION(!(mState & TEXT_IS_EMPTY) || !(mState & TEXT_ISNOT_EMPTY), + "Invalid state"); + + if (mState & TEXT_ISNOT_EMPTY) { + return PR_FALSE; + } + + if (mState & TEXT_IS_EMPTY) { + return PR_TRUE; + } + + // XXXldb Should this check compatibility mode as well??? if (GetStyleText()->WhiteSpaceIsSignificant()) { + mState |= TEXT_ISNOT_EMPTY; return PR_FALSE; } @@ -5836,7 +5858,18 @@ nsTextFrame::IsEmpty() NS_NOTREACHED("text frame has no text content"); return PR_TRUE; } - return textContent->IsOnlyWhitespace(); + + PRBool isEmpty = textContent->IsOnlyWhitespace(); + mState |= (isEmpty ? TEXT_IS_EMPTY : TEXT_ISNOT_EMPTY); + return isEmpty; +} + +NS_IMETHODIMP +nsTextFrame::DidSetStyleContext(nsPresContext* aPresContext) { + // Clear out our cached IsEmpty() state, since that depends on style + mState &= ~TEXT_ISEMPTY_FLAGS; + + return nsFrame::DidSetStyleContext(aPresContext); } #ifdef DEBUG diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index dc924a05a33..6bac036f664 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -467,6 +467,8 @@ public: NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end)const; virtual void AdjustOffsetsForBidi(PRInt32 start, PRInt32 end); + + NS_IMETHOD DidSetStyleContext(nsPresContext* aPresContext); NS_IMETHOD GetPointFromOffset(nsPresContext* inPresContext, nsIRenderingContext* inRendContext, @@ -1274,6 +1276,12 @@ DrawSelectionIterator::IsBeforeOrAfter() #define TEXT_BLINK_ON 0x80000000 +#define TEXT_IS_EMPTY 0x00100000 + +#define TEXT_ISNOT_EMPTY 0x00200000 + +#define TEXT_ISEMPTY_FLAGS 0x00300000 + //---------------------------------------------------------------------- nsresult @@ -1389,6 +1397,7 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext, if (aAppend) { markAllDirty = PR_FALSE; nsTextFrame* frame = (nsTextFrame*)GetLastInFlow(); + frame->mState &= ~TEXT_ISEMPTY_FLAGS; frame->mState |= NS_FRAME_IS_DIRTY; targetTextFrame = frame; } @@ -1397,6 +1406,7 @@ nsTextFrame::CharacterDataChanged(nsPresContext* aPresContext, // Mark this frame and all the next-in-flow frames as dirty nsTextFrame* textFrame = this; while (textFrame) { + textFrame->mState &= ~TEXT_ISEMPTY_FLAGS; textFrame->mState |= NS_FRAME_IS_DIRTY; #ifdef IBMBIDI void* nextBidiFrame; @@ -5826,8 +5836,20 @@ nsTextFrame::GetType() const /* virtual */ PRBool nsTextFrame::IsEmpty() { - // XXXldb Should this check compatibility mode as well??? + NS_ASSERTION(!(mState & TEXT_IS_EMPTY) || !(mState & TEXT_ISNOT_EMPTY), + "Invalid state"); + + if (mState & TEXT_ISNOT_EMPTY) { + return PR_FALSE; + } + + if (mState & TEXT_IS_EMPTY) { + return PR_TRUE; + } + + // XXXldb Should this check compatibility mode as well??? if (GetStyleText()->WhiteSpaceIsSignificant()) { + mState |= TEXT_ISNOT_EMPTY; return PR_FALSE; } @@ -5836,7 +5858,18 @@ nsTextFrame::IsEmpty() NS_NOTREACHED("text frame has no text content"); return PR_TRUE; } - return textContent->IsOnlyWhitespace(); + + PRBool isEmpty = textContent->IsOnlyWhitespace(); + mState |= (isEmpty ? TEXT_IS_EMPTY : TEXT_ISNOT_EMPTY); + return isEmpty; +} + +NS_IMETHODIMP +nsTextFrame::DidSetStyleContext(nsPresContext* aPresContext) { + // Clear out our cached IsEmpty() state, since that depends on style + mState &= ~TEXT_ISEMPTY_FLAGS; + + return nsFrame::DidSetStyleContext(aPresContext); } #ifdef DEBUG