bug 594865 - fall back to GDI rendering on dwrite font list failure. r=bas a=blocking2.0

This commit is contained in:
Jonathan Kew 2010-11-08 11:02:27 +00:00
parent 766651cddb
commit 5be531ab2e
16 changed files with 93 additions and 45 deletions

View File

@ -270,7 +270,12 @@ gfxAndroidPlatform::GetStandardFamilyName(const nsAString& aFontName, nsAString&
gfxPlatformFontList*
gfxAndroidPlatform::CreatePlatformFontList()
{
return new gfxFT2FontList();
gfxPlatformFontList* list = new gfxFT2FontList();
if (NS_SUCCEEDED(list->InitFontList())) {
return list;
}
gfxPlatformFontList::Shutdown();
return nsnull;
}
PRBool

View File

@ -467,7 +467,7 @@ gfxDWriteFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
return entry;
}
void
nsresult
gfxDWriteFontList::InitFontList()
{
HRESULT hr;
@ -486,6 +486,10 @@ gfxDWriteFontList::InitFontList()
GetSystemFontCollection(getter_AddRefs(systemFonts));
NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
if (FAILED(hr)) {
return NS_ERROR_FAILURE;
}
for (UINT32 i = 0; i < systemFonts->GetFontFamilyCount(); i++) {
nsRefPtr<IDWriteFontFamily> family;
systemFonts->GetFontFamily(i, getter_AddRefs(family));
@ -543,6 +547,8 @@ gfxDWriteFontList::InitFontList()
GetFontSubstitutes();
StartLoader(kDelayBeforeLoadingFonts, kIntervalBetweenLoadingFonts);
return NS_OK;
}
static void

View File

@ -191,6 +191,9 @@ public:
return static_cast<gfxDWriteFontList*>(sPlatformFontList);
}
// initialize font lists
virtual nsresult InitFontList();
virtual gfxFontEntry* GetDefaultFont(const gfxFontStyle* aStyle,
PRBool& aNeedsBold);
@ -210,9 +213,6 @@ public:
private:
friend class gfxDWriteFontFamily;
// initialize font lists
virtual void InitFontList();
nsresult GetFontSubstitutes();
/**

View File

@ -235,13 +235,15 @@ gfxFT2FontList::FindFonts()
#endif // XP_WIN && ANDROID
}
void
nsresult
gfxFT2FontList::InitFontList()
{
// reset font lists
gfxPlatformFontList::InitFontList();
FindFonts();
return NS_OK;
}
struct FullFontNameSearch {

View File

@ -65,7 +65,7 @@ public:
PRUint32 aLength);
protected:
virtual void InitFontList();
virtual nsresult InitFontList();
void AppendFacesFromFontFile(const PRUnichar *aFileName);
void AppendFacesFromFontFile(const char *aFileName);

View File

@ -638,7 +638,7 @@ gfxGDIFontList::GetFontSubstitutes()
return NS_OK;
}
void
nsresult
gfxGDIFontList::InitFontList()
{
gfxFontCache *fc = gfxFontCache::GetCache();
@ -664,8 +664,10 @@ gfxGDIFontList::InitFontList()
GetFontSubstitutes();
StartLoader(kDelayBeforeLoadingFonts, kIntervalBetweenLoadingFonts);
return NS_OK;
}
int CALLBACK
gfxGDIFontList::EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,
NEWTEXTMETRICEXW *lpntme,

View File

@ -334,6 +334,9 @@ public:
return static_cast<gfxGDIFontList*>(sPlatformFontList);
}
// initialize font lists
virtual nsresult InitFontList();
virtual gfxFontEntry* GetDefaultFont(const gfxFontStyle* aStyle, PRBool& aNeedsBold);
virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
@ -352,9 +355,6 @@ private:
void InitializeFontEmbeddingProcs();
// initialize font lists
virtual void InitFontList();
nsresult GetFontSubstitutes();
static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,

View File

@ -113,7 +113,7 @@ private:
gfxMacPlatformFontList();
// initialize font lists
virtual void InitFontList();
virtual nsresult InitFontList();
// special case font faces treated as font families (set via prefs)
void InitSingleFaceList();

View File

@ -608,7 +608,7 @@ gfxMacPlatformFontList::gfxMacPlatformFontList() :
sFontManager = [NSFontManager sharedFontManager];
}
void
nsresult
gfxMacPlatformFontList::InitFontList()
{
nsAutoreleasePool localPool;
@ -617,7 +617,7 @@ gfxMacPlatformFontList::InitFontList()
// need to ignore notifications after adding each font
if (mATSGeneration == currentGeneration)
return;
return NS_OK;
mATSGeneration = currentGeneration;
PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit) updating to generation: %d", mATSGeneration));
@ -672,6 +672,8 @@ gfxMacPlatformFontList::InitFontList()
// start the delayed cmap loader
StartLoader(kDelayBeforeLoadingCmaps, kIntervalBetweenLoadingCmaps);
return NS_OK;
}
void

View File

@ -256,15 +256,6 @@ gfxPlatform::Init()
if (!gPlatform)
return NS_ERROR_OUT_OF_MEMORY;
gPlatform->mScreenReferenceSurface =
gPlatform->CreateOffscreenSurface(gfxIntSize(1,1),
gfxASurface::CONTENT_COLOR_ALPHA);
if (!gPlatform->mScreenReferenceSurface) {
NS_ERROR("Could not initialize mScreenReferenceSurface");
Shutdown();
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv;
#if defined(XP_MACOSX) || defined(XP_WIN) || defined(ANDROID) // temporary, until this is implemented on others
@ -276,6 +267,15 @@ gfxPlatform::Init()
}
#endif
gPlatform->mScreenReferenceSurface =
gPlatform->CreateOffscreenSurface(gfxIntSize(1,1),
gfxASurface::CONTENT_COLOR_ALPHA);
if (!gPlatform->mScreenReferenceSurface) {
NS_ERROR("Could not initialize mScreenReferenceSurface");
Shutdown();
return NS_ERROR_OUT_OF_MEMORY;
}
rv = gfxFontCache::Init();
if (NS_FAILED(rv)) {
NS_ERROR("Could not initialize gfxFontCache");

View File

@ -174,7 +174,9 @@ public:
virtual nsresult UpdateFontList();
/**
* Create the platform font-list object (gfxPlatformFontList concrete subclass)
* Create the platform font-list object (gfxPlatformFontList concrete subclass).
* This function is responsible to create the appropriate subclass of
* gfxPlatformFontList *and* to call its InitFontList() method.
*/
virtual gfxPlatformFontList *CreatePlatformFontList() {
NS_NOTREACHED("oops, this platform doesn't have a gfxPlatformFontList implementation");

View File

@ -138,7 +138,7 @@ gfxPlatformFontList::gfxPlatformFontList(PRBool aNeedFullnamePostscriptNames)
}
}
void
nsresult
gfxPlatformFontList::InitFontList()
{
mFontFamilies.Clear();
@ -156,6 +156,10 @@ gfxPlatformFontList::InitFontList()
mCodepointsWithNoFonts.reset();
mCodepointsWithNoFonts.SetRange(0,0x1f); // C0 controls
mCodepointsWithNoFonts.SetRange(0x7f,0x9f); // C1 controls
sPlatformFontList = this;
return NS_OK;
}
void

View File

@ -67,9 +67,10 @@ public:
NS_TIME_FUNCTION;
NS_ASSERTION(!sPlatformFontList, "What's this doing here?");
sPlatformFontList = gfxPlatform::GetPlatform()->CreatePlatformFontList();
if (!sPlatformFontList) return NS_ERROR_OUT_OF_MEMORY;
sPlatformFontList->InitFontList();
gfxPlatform::GetPlatform()->CreatePlatformFontList();
if (!sPlatformFontList) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
@ -78,6 +79,9 @@ public:
sPlatformFontList = nsnull;
}
// initialize font lists
virtual nsresult InitFontList();
void GetFontList (nsIAtom *aLangGroup,
const nsACString& aGenericFamily,
nsTArray<nsString>& aListOfFonts);
@ -140,9 +144,6 @@ protected:
nsRefPtr<gfxFontFamily>& aFamilyEntry,
void* userArg);
// initialize font lists
virtual void InitFontList();
// separate initialization for reading in name tables, since this is expensive
void InitOtherFamilyNames();

View File

@ -71,7 +71,12 @@ gfxPlatformMac::~gfxPlatformMac()
gfxPlatformFontList*
gfxPlatformMac::CreatePlatformFontList()
{
return new gfxMacPlatformFontList();
gfxPlatformFontList* list = new gfxMacPlatformFontList();
if (NS_SUCCEEDED(list->InitFontList())) {
return list;
}
gfxPlatformFontList::Shutdown();
return nsnull;
}
already_AddRefed<gfxASurface>

View File

@ -201,6 +201,8 @@ gfxWindowsPlatform::gfxWindowsPlatform()
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
mUseClearTypeAlways = UNINITIALIZED_VALUE;
mUsingGDIFonts = PR_FALSE;
/*
* Initialize COM
*/
@ -235,8 +237,7 @@ gfxWindowsPlatform::~gfxWindowsPlatform()
/*
* Uninitialize COM
*/
CoUninitialize();
CoUninitialize();
}
void
@ -301,12 +302,13 @@ gfxWindowsPlatform::UpdateRenderMode()
d2dDisabled = PR_FALSE;
rv = pref->GetBoolPref("gfx.direct2d.force-enabled", &d2dForceEnabled);
if (NS_FAILED(rv))
d2dDisabled = PR_FALSE;
d2dForceEnabled = PR_FALSE;
bool tryD2D = !d2dBlocked || d2dForceEnabled;
// Do not ever try if d2d is explicitly disabled.
if (d2dDisabled) {
// Do not ever try if d2d is explicitly disabled,
// or if we're not using DWrite fonts.
if (d2dDisabled || mUsingGDIFonts) {
tryD2D = false;
}
@ -406,22 +408,38 @@ gfxWindowsPlatform::VerifyD2DDevice(PRBool aAttemptForce)
}
#endif
}
gfxPlatformFontList*
gfxWindowsPlatform::CreatePlatformFontList()
{
mUsingGDIFonts = PR_FALSE;
gfxPlatformFontList *pfl;
#ifdef MOZ_FT2_FONTS
return new gfxFT2FontList();
pfl = new gfxFT2FontList();
#else
#ifdef CAIRO_HAS_DWRITE_FONT
if (!GetDWriteFactory()) {
#endif
return new gfxGDIFontList();
#ifdef CAIRO_HAS_DWRITE_FONT
} else {
return new gfxDWriteFontList();
if (GetDWriteFactory()) {
pfl = new gfxDWriteFontList();
if (NS_SUCCEEDED(pfl->InitFontList())) {
return pfl;
}
// DWrite font initialization failed! Don't know why this would happen,
// but apparently it can - see bug 594865.
// So we're going to fall back to GDI fonts & rendering.
gfxPlatformFontList::Shutdown();
SetRenderMode(RENDER_GDI);
}
#endif
pfl = new gfxGDIFontList();
mUsingGDIFonts = PR_TRUE;
#endif
if (NS_SUCCEEDED(pfl->InitFontList())) {
return pfl;
}
gfxPlatformFontList::Shutdown();
return nsnull;
}
already_AddRefed<gfxASurface>

View File

@ -255,6 +255,7 @@ private:
void Init();
PRBool mUseDirectWrite;
PRBool mUsingGDIFonts;
#ifdef CAIRO_HAS_DWRITE_FONT
nsRefPtr<IDWriteFactory> mDWriteFactory;