From 1dd5b9dab2fc37dc2a3bd3be3c9c3ef8ff0df17b Mon Sep 17 00:00:00 2001 From: "henry.jia%sun.com" Date: Mon, 24 Feb 2003 10:26:20 +0000 Subject: [PATCH] Bug 35296: SetCaretEnabled() takes too long Patch by Leon.Zhang@sun.com, r/sr=sfraser --- layout/base/nsCaret.cpp | 18 ++++++++++++++---- layout/base/nsCaret.h | 13 ++++++++----- layout/base/src/nsCaret.cpp | 18 ++++++++++++++---- layout/base/src/nsCaret.h | 13 ++++++++----- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 70c2d7b35abf..fd6fef1053c2 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -92,6 +92,7 @@ nsCaret::nsCaret() , mDrawn(PR_FALSE) , mReadOnly(PR_FALSE) , mShowDuringSelection(PR_FALSE) +, mCachedOffsetValid(PR_FALSE) , mLastCaretFrame(nsnull) , mLastCaretView(nsnull) , mLastContentOffset(0) @@ -392,6 +393,7 @@ NS_IMETHODIMP nsCaret::ClearFrameRefs(nsIFrame* aFrame) mLastCaretFrame = nsnull; // frames are not refcounted. mLastCaretView = nsnull; mLastContentOffset = 0; + mCachedOffsetValid = PR_FALSE; } mDrawn = PR_FALSE; // assume that the view has been cleared, and ensure @@ -755,6 +757,9 @@ PRBool nsCaret::SetupDrawingFrameAndOffset() frameState |= NS_FRAME_EXTERNAL_REFERENCE; theFrame->SetFrameState(frameState); + if (theFrame != mLastCaretFrame || theFrameOffset != mLastContentOffset) + mCachedOffsetValid = PR_FALSE; + mLastCaretFrame = theFrame; mLastContentOffset = theFrameOffset; return PR_TRUE; @@ -1025,11 +1030,16 @@ void nsCaret::DrawCaret() if (!mDrawn) { - nsPoint framePos(0, 0); nsRect caretRect = frameRect; - - mLastCaretFrame->GetPointFromOffset(presContext, mRendContext, mLastContentOffset, &framePos); - caretRect += framePos; + + // if mCachedOffsetValid, apply cached FrameOffset, else compute it again + if (!mCachedOffsetValid) + { + mLastCaretFrame->GetPointFromOffset(presContext, mRendContext, mLastContentOffset, &mCachedFrameOffset); + mCachedOffsetValid = PR_TRUE; + } + + caretRect += mCachedFrameOffset; //printf("Content offset %ld, frame offset %ld\n", focusOffset, framePos.x); if(mCaretTwipsWidth < 0) diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 895dbc000d69..dac34035e104 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -60,11 +60,11 @@ class nsCaret : public nsICaret, NS_IMETHOD GetCaretDOMSelection(nsISelection **outDOMSel); NS_IMETHOD SetCaretDOMSelection(nsISelection *inDOMSel); NS_IMETHOD GetCaretVisible(PRBool *outMakeVisible); - NS_IMETHOD SetCaretVisible(PRBool intMakeVisible); - NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly); - NS_IMETHOD GetCaretCoordinates(EViewCoordinates aRelativeToType, nsISelection *inDOMSel, nsRect* outCoordinates, PRBool* outIsCollapsed, nsIView **outView); - NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame); - NS_IMETHOD EraseCaret(); + NS_IMETHOD SetCaretVisible(PRBool intMakeVisible); + NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly); + NS_IMETHOD GetCaretCoordinates(EViewCoordinates aRelativeToType, nsISelection *inDOMSel, nsRect* outCoordinates, PRBool* outIsCollapsed, nsIView **outView); + NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame); + NS_IMETHOD EraseCaret(); NS_IMETHOD SetCaretWidth(nscoord aPixels); NS_IMETHOD SetVisibilityDuringSelection(PRBool aVisibility); @@ -105,6 +105,9 @@ protected: PRPackedBool mDrawn; // this should be mutable PRPackedBool mReadOnly; // it the caret in readonly state (draws differently) PRPackedBool mShowDuringSelection; // show when text is selected + + PRPackedBool mCachedOffsetValid; //whether the cached frame offset is valid + nsPoint mCachedFrameOffset; //cached frame offset nsRect mCaretRect; // the last caret rect nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in. diff --git a/layout/base/src/nsCaret.cpp b/layout/base/src/nsCaret.cpp index 70c2d7b35abf..fd6fef1053c2 100644 --- a/layout/base/src/nsCaret.cpp +++ b/layout/base/src/nsCaret.cpp @@ -92,6 +92,7 @@ nsCaret::nsCaret() , mDrawn(PR_FALSE) , mReadOnly(PR_FALSE) , mShowDuringSelection(PR_FALSE) +, mCachedOffsetValid(PR_FALSE) , mLastCaretFrame(nsnull) , mLastCaretView(nsnull) , mLastContentOffset(0) @@ -392,6 +393,7 @@ NS_IMETHODIMP nsCaret::ClearFrameRefs(nsIFrame* aFrame) mLastCaretFrame = nsnull; // frames are not refcounted. mLastCaretView = nsnull; mLastContentOffset = 0; + mCachedOffsetValid = PR_FALSE; } mDrawn = PR_FALSE; // assume that the view has been cleared, and ensure @@ -755,6 +757,9 @@ PRBool nsCaret::SetupDrawingFrameAndOffset() frameState |= NS_FRAME_EXTERNAL_REFERENCE; theFrame->SetFrameState(frameState); + if (theFrame != mLastCaretFrame || theFrameOffset != mLastContentOffset) + mCachedOffsetValid = PR_FALSE; + mLastCaretFrame = theFrame; mLastContentOffset = theFrameOffset; return PR_TRUE; @@ -1025,11 +1030,16 @@ void nsCaret::DrawCaret() if (!mDrawn) { - nsPoint framePos(0, 0); nsRect caretRect = frameRect; - - mLastCaretFrame->GetPointFromOffset(presContext, mRendContext, mLastContentOffset, &framePos); - caretRect += framePos; + + // if mCachedOffsetValid, apply cached FrameOffset, else compute it again + if (!mCachedOffsetValid) + { + mLastCaretFrame->GetPointFromOffset(presContext, mRendContext, mLastContentOffset, &mCachedFrameOffset); + mCachedOffsetValid = PR_TRUE; + } + + caretRect += mCachedFrameOffset; //printf("Content offset %ld, frame offset %ld\n", focusOffset, framePos.x); if(mCaretTwipsWidth < 0) diff --git a/layout/base/src/nsCaret.h b/layout/base/src/nsCaret.h index 895dbc000d69..dac34035e104 100644 --- a/layout/base/src/nsCaret.h +++ b/layout/base/src/nsCaret.h @@ -60,11 +60,11 @@ class nsCaret : public nsICaret, NS_IMETHOD GetCaretDOMSelection(nsISelection **outDOMSel); NS_IMETHOD SetCaretDOMSelection(nsISelection *inDOMSel); NS_IMETHOD GetCaretVisible(PRBool *outMakeVisible); - NS_IMETHOD SetCaretVisible(PRBool intMakeVisible); - NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly); - NS_IMETHOD GetCaretCoordinates(EViewCoordinates aRelativeToType, nsISelection *inDOMSel, nsRect* outCoordinates, PRBool* outIsCollapsed, nsIView **outView); - NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame); - NS_IMETHOD EraseCaret(); + NS_IMETHOD SetCaretVisible(PRBool intMakeVisible); + NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly); + NS_IMETHOD GetCaretCoordinates(EViewCoordinates aRelativeToType, nsISelection *inDOMSel, nsRect* outCoordinates, PRBool* outIsCollapsed, nsIView **outView); + NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame); + NS_IMETHOD EraseCaret(); NS_IMETHOD SetCaretWidth(nscoord aPixels); NS_IMETHOD SetVisibilityDuringSelection(PRBool aVisibility); @@ -105,6 +105,9 @@ protected: PRPackedBool mDrawn; // this should be mutable PRPackedBool mReadOnly; // it the caret in readonly state (draws differently) PRPackedBool mShowDuringSelection; // show when text is selected + + PRPackedBool mCachedOffsetValid; //whether the cached frame offset is valid + nsPoint mCachedFrameOffset; //cached frame offset nsRect mCaretRect; // the last caret rect nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.