зеркало из https://github.com/mozilla/gecko-dev.git
Bug 651017, part 3: Make nsThebesDeviceContext not an nsIObserver. Also remove some more obsolete junk from nsThebesDeviceContext itself.
--HG-- extra : rebase_source : 38fdc667532509e272726bf8098c6f728e94e8ad
This commit is contained in:
Родитель
cf9f8f9844
Коммит
67295a5d8d
|
@ -44,6 +44,8 @@
|
|||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsCRT.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
|
@ -92,56 +94,70 @@ static nsSystemFontsAndroid *gSystemFonts = nsnull;
|
|||
#error Need to declare gSystemFonts!
|
||||
#endif
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* gThebesGFXLog = nsnull;
|
||||
#endif
|
||||
using mozilla::services::GetObserverService;
|
||||
|
||||
class nsFontCache
|
||||
class nsFontCache : public nsIObserver
|
||||
{
|
||||
public:
|
||||
nsFontCache();
|
||||
~nsFontCache();
|
||||
nsFontCache() { MOZ_COUNT_CTOR(nsFontCache); }
|
||||
~nsFontCache() { MOZ_COUNT_DTOR(nsFontCache); }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
void Init(nsIDeviceContext* aContext);
|
||||
void Destroy();
|
||||
|
||||
nsresult Init(nsIDeviceContext* aContext);
|
||||
nsresult GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
|
||||
gfxUserFontSet* aUserFontSet,
|
||||
nsFontMetrics*& aMetrics);
|
||||
|
||||
nsresult FontMetricsDeleted(const nsFontMetrics* aFontMetrics);
|
||||
nsresult Compact();
|
||||
nsresult Flush();
|
||||
void FontMetricsDeleted(const nsFontMetrics* aFontMetrics);
|
||||
void Compact();
|
||||
void Flush();
|
||||
|
||||
protected:
|
||||
nsIDeviceContext* mContext; // owner
|
||||
nsTArray<nsFontMetrics*> mFontMetrics;
|
||||
nsIDeviceContext *mContext; // we do not addref this since
|
||||
// ownership is implied. MMP.
|
||||
};
|
||||
|
||||
nsFontCache::nsFontCache()
|
||||
NS_IMPL_ISUPPORTS1(nsFontCache, nsIObserver)
|
||||
|
||||
// The Init and Destroy methods are necessary because it's not
|
||||
// safe to call AddObserver from a constructor or RemoveObserver
|
||||
// from a destructor. That should be fixed.
|
||||
void
|
||||
nsFontCache::Init(nsIDeviceContext* aContext)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsFontCache);
|
||||
mContext = nsnull;
|
||||
mContext = aContext;
|
||||
// register as a memory-pressure observer to free font resources
|
||||
// in low-memory situations.
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
if (obs)
|
||||
obs->AddObserver(this, "memory-pressure", PR_FALSE);
|
||||
}
|
||||
|
||||
nsFontCache::~nsFontCache()
|
||||
void
|
||||
nsFontCache::Destroy()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsFontCache);
|
||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
||||
if (obs)
|
||||
obs->RemoveObserver(this, "memory-pressure");
|
||||
Flush();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFontCache::Init(nsIDeviceContext* aContext)
|
||||
NS_IMETHODIMP
|
||||
nsFontCache::Observe(nsISupports*, const char* aTopic, const PRUnichar*)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aContext, "null ptr");
|
||||
// Note: we don't hold a reference to the device context, because it
|
||||
// holds a reference to us and we don't want circular references
|
||||
mContext = aContext;
|
||||
if (!nsCRT::strcmp(aTopic, "memory-pressure"))
|
||||
Compact();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
|
||||
gfxUserFontSet* aUserFontSet, nsFontMetrics*& aMetrics)
|
||||
gfxUserFontSet* aUserFontSet,
|
||||
nsFontMetrics*& aMetrics)
|
||||
{
|
||||
// First check our cache
|
||||
// start from the end, which is where we put the most-recent-used element
|
||||
|
@ -205,17 +221,19 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(NS_SUCCEEDED(rv), "font metrics should not be null - bug 136248");
|
||||
NS_POSTCONDITION(NS_SUCCEEDED(rv),
|
||||
"font metrics should not be null - bug 136248");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsFontCache::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
|
||||
void
|
||||
nsFontCache::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
|
||||
{
|
||||
mFontMetrics.RemoveElement(aFontMetrics);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFontCache::Compact()
|
||||
void
|
||||
nsFontCache::Compact()
|
||||
{
|
||||
// Need to loop backward because the running element can be removed on
|
||||
// the way
|
||||
|
@ -227,15 +245,15 @@ nsresult nsFontCache::Compact()
|
|||
NS_RELEASE(fm); // this will reset fm to nsnull
|
||||
// if the font is really gone, it would have called back in
|
||||
// FontMetricsDeleted() and would have removed itself
|
||||
if (mFontMetrics.IndexOf(oldfm) != mFontMetrics.NoIndex) {
|
||||
if (mFontMetrics.IndexOf(oldfm) != mFontMetrics.NoIndex) {
|
||||
// nope, the font is still there, so let's hold onto it too
|
||||
NS_ADDREF(oldfm);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFontCache::Flush()
|
||||
void
|
||||
nsFontCache::Flush()
|
||||
{
|
||||
for (PRInt32 i = mFontMetrics.Length()-1; i >= 0; --i) {
|
||||
nsFontMetrics* fm = mFontMetrics[i];
|
||||
|
@ -245,23 +263,13 @@ nsresult nsFontCache::Flush()
|
|||
fm->Destroy();
|
||||
NS_RELEASE(fm);
|
||||
}
|
||||
|
||||
mFontMetrics.Clear();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS3(nsThebesDeviceContext, nsIDeviceContext, nsIObserver, nsISupportsWeakReference)
|
||||
NS_IMPL_ISUPPORTS1(nsThebesDeviceContext, nsIDeviceContext)
|
||||
|
||||
nsThebesDeviceContext::nsThebesDeviceContext()
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (!gThebesGFXLog)
|
||||
gThebesGFXLog = PR_NewLogModule("thebesGfx");
|
||||
#endif
|
||||
|
||||
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("#### Creating DeviceContext %p\n", this));
|
||||
|
||||
mAppUnitsPerDevPixel = nscoord(-1);
|
||||
mAppUnitsPerPhysicalInch = nscoord(-1);
|
||||
mAppUnitsPerDevNotScaledPixel = nscoord(-1);
|
||||
|
@ -274,41 +282,26 @@ nsThebesDeviceContext::nsThebesDeviceContext()
|
|||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mPrintingScale = 1.0f;
|
||||
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
SCRIPT_DIGITSUBSTITUTE sds;
|
||||
ScriptRecordDigitSubstitution(LOCALE_USER_DEFAULT, &sds);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Note: we use a bare pointer for mFontCache so that nsFontCache
|
||||
// can be an incomplete type in nsThebesDeviceContext.h.
|
||||
// Therefore we have to do all the refcounting by hand.
|
||||
nsThebesDeviceContext::~nsThebesDeviceContext()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs)
|
||||
obs->RemoveObserver(this, "memory-pressure");
|
||||
|
||||
if (nsnull != mFontCache) {
|
||||
delete mFontCache;
|
||||
mFontCache = nsnull;
|
||||
if (mFontCache) {
|
||||
mFontCache->Destroy();
|
||||
NS_RELEASE(mFontCache);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aSomeData)
|
||||
{
|
||||
if (mFontCache && !nsCRT::strcmp(aTopic, "memory-pressure")) {
|
||||
mFontCache->Compact();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsThebesDeviceContext::CreateFontCache()
|
||||
{
|
||||
mFontCache = new nsFontCache();
|
||||
if (!mFontCache) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return mFontCache->Init(this);
|
||||
NS_ADDREF(mFontCache);
|
||||
mFontCache->Init(this);
|
||||
GetLocaleLanguage();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsThebesDeviceContext::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
|
||||
|
@ -337,15 +330,8 @@ nsThebesDeviceContext::GetLocaleLanguage(void)
|
|||
NS_IMETHODIMP nsThebesDeviceContext::GetMetricsFor(const nsFont& aFont,
|
||||
nsIAtom* aLanguage, gfxUserFontSet* aUserFontSet, nsFontMetrics*& aMetrics)
|
||||
{
|
||||
if (nsnull == mFontCache) {
|
||||
nsresult rv = CreateFontCache();
|
||||
if (NS_FAILED(rv)) {
|
||||
aMetrics = nsnull;
|
||||
return rv;
|
||||
}
|
||||
// XXX temporary fix for performance problem -- erik
|
||||
GetLocaleLanguage();
|
||||
}
|
||||
if (!mFontCache)
|
||||
CreateFontCache();
|
||||
|
||||
// XXX figure out why aLanguage is NULL sometimes
|
||||
// -> see nsPageFrame.cpp:511
|
||||
|
@ -360,15 +346,9 @@ NS_IMETHODIMP nsThebesDeviceContext::GetMetricsFor(const nsFont& aFont,
|
|||
gfxUserFontSet* aUserFontSet,
|
||||
nsFontMetrics*& aMetrics)
|
||||
{
|
||||
if (nsnull == mFontCache) {
|
||||
nsresult rv = CreateFontCache();
|
||||
if (NS_FAILED(rv)) {
|
||||
aMetrics = nsnull;
|
||||
return rv;
|
||||
}
|
||||
// XXX temporary fix for performance problem -- erik
|
||||
GetLocaleLanguage();
|
||||
}
|
||||
if (!mFontCache)
|
||||
CreateFontCache();
|
||||
|
||||
return mFontCache->GetMetricsFor(aFont, mLocaleLanguage, aUserFontSet,
|
||||
aMetrics);
|
||||
}
|
||||
|
@ -409,7 +389,7 @@ nsThebesDeviceContext::GetLocalFontName(const nsString& aFaceName,
|
|||
|
||||
NS_IMETHODIMP nsThebesDeviceContext::FlushFontCache(void)
|
||||
{
|
||||
if (nsnull != mFontCache)
|
||||
if (mFontCache)
|
||||
mFontCache->Flush();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -536,12 +516,6 @@ nsThebesDeviceContext::Init(nsIWidget *aWidget)
|
|||
if (mScreenManager)
|
||||
return NS_OK;
|
||||
|
||||
// register as a memory-pressure observer to free font resources
|
||||
// in low-memory situations.
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs)
|
||||
obs->AddObserver(this, "memory-pressure", PR_TRUE);
|
||||
|
||||
mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -45,17 +45,8 @@
|
|||
#include "nsIDeviceContextSpec.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
extern PRLogModuleInfo* gThebesGFXLog;
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "gfxWindowsSurface.h"
|
||||
#elif defined(XP_OS2)
|
||||
|
@ -64,9 +55,7 @@ extern PRLogModuleInfo* gThebesGFXLog;
|
|||
|
||||
class nsFontCache;
|
||||
|
||||
class nsThebesDeviceContext : public nsIDeviceContext,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
class nsThebesDeviceContext : public nsIDeviceContext
|
||||
{
|
||||
public:
|
||||
nsThebesDeviceContext();
|
||||
|
@ -75,7 +64,6 @@ public:
|
|||
static void Shutdown();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
NS_IMETHOD Init(nsIWidget *aWidget);
|
||||
NS_IMETHOD InitForPrinting(nsIDeviceContextSpec *aDevSpec);
|
||||
|
|
Загрузка…
Ссылка в новой задаче