зеркало из https://github.com/mozilla/gecko-dev.git
Bug 460037 - Fix crasher in font loader when closing windows. r+sr=roc
This commit is contained in:
Родитель
9025de0ae1
Коммит
1a7886ee8c
|
@ -144,24 +144,10 @@ class gfxProxyFontEntry;
|
|||
class THEBES_API gfxUserFontSet {
|
||||
|
||||
public:
|
||||
class LoaderContext;
|
||||
typedef nsresult (*LoaderCallback) (gfxFontEntry *aFontToLoad,
|
||||
const gfxFontFaceSrc *aFontFaceSrc,
|
||||
LoaderContext *aContextData);
|
||||
|
||||
class LoaderContext {
|
||||
public:
|
||||
LoaderContext(LoaderCallback aLoader)
|
||||
: mUserFontSet(nsnull), mLoaderProc(aLoader) { }
|
||||
virtual ~LoaderContext() { }
|
||||
|
||||
gfxUserFontSet* mUserFontSet;
|
||||
LoaderCallback mLoaderProc;
|
||||
};
|
||||
|
||||
THEBES_INLINE_DECL_REFCOUNTING(gfxUserFontSet)
|
||||
|
||||
gfxUserFontSet(LoaderContext *aContext);
|
||||
gfxUserFontSet();
|
||||
virtual ~gfxUserFontSet();
|
||||
|
||||
enum {
|
||||
|
@ -201,7 +187,13 @@ public:
|
|||
|
||||
// lookup a font entry for a given style, returns null if not loaded
|
||||
gfxFontEntry *FindFontEntry(const nsAString& aName,
|
||||
const gfxFontStyle& aFontStyle, PRBool& aNeedsBold);
|
||||
const gfxFontStyle& aFontStyle,
|
||||
PRBool& aNeedsBold);
|
||||
|
||||
// initialize the process that loads external font data, which upon
|
||||
// completion will call OnLoadComplete method
|
||||
virtual nsresult StartLoad(gfxFontEntry *aFontToLoad,
|
||||
const gfxFontFaceSrc *aFontFaceSrc) = 0;
|
||||
|
||||
// when download has been completed, pass back data here
|
||||
// aDownloadStatus == NS_OK ==> download succeeded, error otherwise
|
||||
|
@ -232,9 +224,6 @@ protected:
|
|||
nsRefPtrHashtable<nsStringHashKey, gfxMixedFontFamily> mFontFamilies;
|
||||
|
||||
PRUint64 mGeneration;
|
||||
|
||||
// owned by user font set obj, deleted within destructor
|
||||
nsAutoPtr<LoaderContext> mLoaderContext;
|
||||
};
|
||||
|
||||
// acts a placeholder until the real font is downloaded
|
||||
|
|
|
@ -109,13 +109,9 @@ gfxMixedFontFamily::FindWeightsForStyle(gfxFontEntry* aFontsForWeights[],
|
|||
}
|
||||
|
||||
|
||||
gfxUserFontSet::gfxUserFontSet(LoaderContext *aContext)
|
||||
: mLoaderContext(aContext)
|
||||
gfxUserFontSet::gfxUserFontSet()
|
||||
{
|
||||
NS_ASSERTION(mLoaderContext, "font set loader context not initialized");
|
||||
mFontFamilies.Init(5);
|
||||
mLoaderContext->mUserFontSet = this;
|
||||
|
||||
IncrementGeneration();
|
||||
}
|
||||
|
||||
|
@ -280,10 +276,6 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
|
|||
|
||||
NS_ASSERTION(aProxyEntry->mSrcIndex < numSrc, "already at the end of the src list for user font");
|
||||
|
||||
NS_ASSERTION(mLoaderContext, "user font loader context not initialized");
|
||||
if (!mLoaderContext)
|
||||
return STATUS_ERROR;
|
||||
|
||||
if (aProxyEntry->mIsLoading) {
|
||||
aProxyEntry->mSrcIndex++;
|
||||
} else {
|
||||
|
@ -319,8 +311,7 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
|
|||
else {
|
||||
if (gfxPlatform::GetPlatform()->IsFontFormatSupported(currSrc.mURI,
|
||||
currSrc.mFormatFlags)) {
|
||||
nsresult rv = mLoaderContext->mLoaderProc(aProxyEntry, &currSrc,
|
||||
mLoaderContext);
|
||||
nsresult rv = StartLoad(aProxyEntry, &currSrc);
|
||||
PRBool loadOK = NS_SUCCEEDED(rv);
|
||||
|
||||
if (loadOK) {
|
||||
|
|
|
@ -1787,16 +1787,9 @@ nsPresContext::FlushUserFontSet()
|
|||
NS_IF_RELEASE(mUserFontSet);
|
||||
|
||||
if (rules.Length() > 0) {
|
||||
nsFontFaceLoaderContext *loaderCtx =
|
||||
new nsFontFaceLoaderContext(this);
|
||||
if (!loaderCtx)
|
||||
gfxUserFontSet *fs = new nsUserFontSet(this);
|
||||
if (!fs)
|
||||
return;
|
||||
gfxUserFontSet *fs = new gfxUserFontSet(loaderCtx);
|
||||
// user font set owns loader context
|
||||
if (!fs) {
|
||||
delete loaderCtx;
|
||||
return;
|
||||
}
|
||||
mUserFontSet = fs;
|
||||
NS_ADDREF(mUserFontSet);
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ static PRLogModuleInfo *gFontDownloaderLog = PR_NewLogModule("fontdownloader");
|
|||
|
||||
|
||||
nsFontFaceLoader::nsFontFaceLoader(gfxFontEntry *aFontToLoad, nsIURI *aFontURI,
|
||||
gfxUserFontSet::LoaderContext *aContext)
|
||||
: mFontEntry(aFontToLoad), mFontURI(aFontURI), mLoaderContext(aContext)
|
||||
nsIPresShell *aShell)
|
||||
: mFontEntry(aFontToLoad), mFontURI(aFontURI), mShell(aShell)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -115,19 +115,26 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
|||
|
||||
PRBool fontUpdate;
|
||||
|
||||
// first, check to make sure we're not torn down
|
||||
if (mShell->IsDestroying()) {
|
||||
return aStatus;
|
||||
}
|
||||
|
||||
nsPresContext *ctx = mShell->GetPresContext();
|
||||
if (!ctx) {
|
||||
return aStatus;
|
||||
}
|
||||
|
||||
// whether an error occurred or not, notify the user font set of the completion
|
||||
fontUpdate = mLoaderContext->mUserFontSet->OnLoadComplete(mFontEntry, aLoader,
|
||||
aString, aStringLen,
|
||||
aStatus);
|
||||
fontUpdate = ctx->GetUserFontSet()->OnLoadComplete(mFontEntry, aLoader,
|
||||
aString, aStringLen,
|
||||
aStatus);
|
||||
|
||||
// when new font loaded, need to reflow
|
||||
if (fontUpdate) {
|
||||
nsFontFaceLoaderContext *loaderCtx
|
||||
= static_cast<nsFontFaceLoaderContext*> (mLoaderContext);
|
||||
|
||||
// Update layout for the presence of the new font. Since this is
|
||||
// asynchronous, reflows will coalesce.
|
||||
loaderCtx->mPresContext->UserFontSetUpdated();
|
||||
ctx->UserFontSetUpdated();
|
||||
LOG(("fontdownloader (%p) reflow\n", this));
|
||||
}
|
||||
|
||||
|
@ -135,17 +142,53 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad,
|
||||
const gfxFontFaceSrc *aFontFaceSrc,
|
||||
gfxUserFontSet::LoaderContext *aContext)
|
||||
nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
|
||||
nsIURI* aTargetURI,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!aSourcePrincipal)
|
||||
return NS_OK;
|
||||
|
||||
// check content policy
|
||||
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
|
||||
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT,
|
||||
aTargetURI,
|
||||
aSourcePrincipal,
|
||||
aContext,
|
||||
EmptyCString(), // mime type
|
||||
nsnull,
|
||||
&shouldLoad,
|
||||
nsContentUtils::GetContentPolicy(),
|
||||
nsContentUtils::GetSecurityManager());
|
||||
|
||||
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsUserFontSet::nsUserFontSet(nsPresContext *aContext)
|
||||
: mPresContext(aContext)
|
||||
{
|
||||
NS_ASSERTION(mPresContext, "null context passed to nsUserFontSet");
|
||||
}
|
||||
|
||||
nsUserFontSet::~nsUserFontSet()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUserFontSet::StartLoad(gfxFontEntry *aFontToLoad,
|
||||
const gfxFontFaceSrc *aFontFaceSrc)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// check same-site origin
|
||||
nsFontFaceLoaderContext *loaderCtx
|
||||
= static_cast<nsFontFaceLoaderContext*> (aContext);
|
||||
|
||||
nsIPresShell *ps = loaderCtx->mPresContext->PresShell();
|
||||
nsIPresShell *ps = mPresContext->PresShell();
|
||||
if (!ps)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -166,7 +209,8 @@ nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad,
|
|||
principal = do_QueryInterface(aFontFaceSrc->mOriginPrincipal);
|
||||
}
|
||||
|
||||
rv = CheckLoadAllowed(principal, aFontFaceSrc->mURI, ps->GetDocument());
|
||||
rv = nsFontFaceLoader::CheckLoadAllowed(principal, aFontFaceSrc->mURI,
|
||||
ps->GetDocument());
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef PR_LOGGING
|
||||
if (LOG_ENABLED()) {
|
||||
|
@ -184,7 +228,7 @@ nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad,
|
|||
|
||||
nsRefPtr<nsFontFaceLoader> fontLoader = new nsFontFaceLoader(aFontToLoad,
|
||||
aFontFaceSrc->mURI,
|
||||
aContext);
|
||||
ps);
|
||||
if (!fontLoader)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -238,34 +282,3 @@ nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad,
|
|||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
|
||||
nsIURI* aTargetURI,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!aSourcePrincipal)
|
||||
return NS_OK;
|
||||
|
||||
// check content policy
|
||||
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
|
||||
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT,
|
||||
aTargetURI,
|
||||
aSourcePrincipal,
|
||||
aContext,
|
||||
EmptyCString(), // mime type
|
||||
nsnull,
|
||||
&shouldLoad,
|
||||
nsContentUtils::GetContentPolicy(),
|
||||
nsContentUtils::GetSecurityManager());
|
||||
|
||||
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,12 +42,15 @@
|
|||
#ifndef nsFontFaceLoader_h_
|
||||
#define nsFontFaceLoader_h_
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "nsIURI.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
|
||||
class nsIRequest;
|
||||
class nsISupports;
|
||||
class nsIPresShell;
|
||||
class nsPresContext;
|
||||
class nsIPrincipal;
|
||||
|
||||
|
@ -56,7 +59,7 @@ class nsFontFaceLoader : public nsIStreamLoaderObserver
|
|||
public:
|
||||
|
||||
nsFontFaceLoader(gfxFontEntry *aFontToLoad, nsIURI *aFontURI,
|
||||
gfxUserFontSet::LoaderContext *aContext);
|
||||
nsIPresShell *aShell);
|
||||
virtual ~nsFontFaceLoader();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -65,33 +68,31 @@ public:
|
|||
// initiate the load
|
||||
nsresult Init();
|
||||
|
||||
// returns whether create succeeded or not
|
||||
static nsresult CreateHandler(gfxFontEntry *aFontToLoad,
|
||||
const gfxFontFaceSrc *aFontFaceSrc,
|
||||
gfxUserFontSet::LoaderContext *aContext);
|
||||
|
||||
private:
|
||||
|
||||
static nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
|
||||
nsIURI* aTargetURI,
|
||||
nsISupports* aContext);
|
||||
|
||||
nsRefPtr<gfxFontEntry> mFontEntry;
|
||||
nsCOMPtr<nsIURI> mFontURI;
|
||||
gfxUserFontSet::LoaderContext* mLoaderContext;
|
||||
private:
|
||||
|
||||
nsRefPtr<gfxFontEntry> mFontEntry;
|
||||
nsCOMPtr<nsIURI> mFontURI;
|
||||
nsCOMPtr<nsIPresShell> mShell;
|
||||
};
|
||||
|
||||
class nsFontFaceLoaderContext : public gfxUserFontSet::LoaderContext {
|
||||
// nsUserFontSet - defines the loading mechanism for downloadable fonts
|
||||
|
||||
class nsUserFontSet : public gfxUserFontSet
|
||||
{
|
||||
public:
|
||||
nsFontFaceLoaderContext(nsPresContext* aContext)
|
||||
: gfxUserFontSet::LoaderContext(nsFontFaceLoader::CreateHandler),
|
||||
mPresContext(aContext)
|
||||
{
|
||||
nsUserFontSet(nsPresContext *aContext);
|
||||
~nsUserFontSet();
|
||||
|
||||
}
|
||||
|
||||
nsPresContext* mPresContext;
|
||||
// starts loading process, creating and initializing a nsFontFaceLoader obj
|
||||
// returns whether load process successfully started or not
|
||||
nsresult StartLoad(gfxFontEntry *aFontToLoad,
|
||||
const gfxFontFaceSrc *aFontFaceSrc);
|
||||
protected:
|
||||
nsPresContext *mPresContext; // weak reference
|
||||
};
|
||||
|
||||
|
||||
#endif /* !defined(nsFontFaceLoader_h_) */
|
||||
|
|
Загрузка…
Ссылка в новой задаче