From bd43ebe418fe849a10cdebd260bd150c3fc31c50 Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Fri, 20 May 2016 09:16:29 -0700 Subject: [PATCH] Bug 1249600. Fallback to arial fonts or draw nothing if typeface is unavailable. r=bas --- gfx/2d/DrawTargetSkia.cpp | 6 +++- gfx/2d/ScaledFontDWrite.cpp | 56 +++++++++++++++++++++++++++++++------ gfx/2d/ScaledFontDWrite.h | 3 +- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 5dc6f0c95c05..ff8d52db5d7f 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -1018,9 +1018,13 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont, #endif ScaledFontBase* skiaFont = static_cast(aFont); + SkTypeface* typeface = skiaFont->GetSkTypeface(); + if (!typeface) { + return; + } AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern); - paint.mPaint.setTypeface(skiaFont->GetSkTypeface()); + paint.mPaint.setTypeface(typeface); paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize)); paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); diff --git a/gfx/2d/ScaledFontDWrite.cpp b/gfx/2d/ScaledFontDWrite.cpp index 4b95f864f126..0d5398703cb4 100644 --- a/gfx/2d/ScaledFontDWrite.cpp +++ b/gfx/2d/ScaledFontDWrite.cpp @@ -115,31 +115,65 @@ ScaledFontDWrite::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget #ifdef USE_SKIA +bool +ScaledFontDWrite::DefaultToArialFont(IDWriteFontCollection* aSystemFonts) +{ + // If we can't find the same font face as we're given, fallback to arial + static const WCHAR fontFamilyName[] = L"Arial"; + + UINT32 fontIndex; + BOOL exists; + HRESULT hr = aSystemFonts->FindFamilyName(fontFamilyName, &fontIndex, &exists); + if (FAILED(hr)) { + gfxCriticalNote << "Failed to get backup arial font font from system fonts. Code: " << hexa(hr); + return false; + } + + hr = aSystemFonts->GetFontFamily(fontIndex, getter_AddRefs(mFontFamily)); + if (FAILED(hr)) { + gfxCriticalNote << "Failed to get font family for arial. Code: " << hexa(hr); + return false; + } + + hr = mFontFamily->GetFirstMatchingFont(DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + getter_AddRefs(mFont)); + if (FAILED(hr)) { + gfxCriticalNote << "Failed to get a matching font for arial. Code: " << hexa(hr); + return false; + } + + return true; +} + // This can happen if we have mixed backends which create DWrite // fonts in a mixed environment. e.g. a cairo content backend // but Skia canvas backend. -void +bool ScaledFontDWrite::GetFontDataFromSystemFonts(IDWriteFactory* aFactory) { MOZ_ASSERT(mFontFace); RefPtr systemFonts; HRESULT hr = aFactory->GetSystemFontCollection(getter_AddRefs(systemFonts)); if (FAILED(hr)) { - gfxWarning() << "Failed to get system font collection from file data. Code: " << hexa(hr); - return; + gfxCriticalNote << "Failed to get system font collection from file data. Code: " << hexa(hr); + return false; } hr = systemFonts->GetFontFromFontFace(mFontFace, getter_AddRefs(mFont)); if (FAILED(hr)) { - gfxWarning() << "Failed to get system font from font face. Code: " << hexa(hr); - return; + gfxCriticalNote << "Failed to get system font from font face. Code: " << hexa(hr); + return DefaultToArialFont(systemFonts); } hr = mFont->GetFontFamily(getter_AddRefs(mFontFamily)); if (FAILED(hr)) { - gfxWarning() << "Failed to get font family from font face. Code: " << hexa(hr); - return; + gfxCriticalNote << "Failed to get font family from font face. Code: " << hexa(hr); + return DefaultToArialFont(systemFonts); } + + return true; } SkTypeface* @@ -147,8 +181,14 @@ ScaledFontDWrite::GetSkTypeface() { if (!mTypeface) { IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory(); + if (!factory) { + return nullptr; + } + if (!mFont || !mFontFamily) { - GetFontDataFromSystemFonts(factory); + if (!GetFontDataFromSystemFonts(factory)) { + return nullptr; + } } mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mFont, mFontFamily); diff --git a/gfx/2d/ScaledFontDWrite.h b/gfx/2d/ScaledFontDWrite.h index 9a4d16264e13..4aa45a8c8fe1 100644 --- a/gfx/2d/ScaledFontDWrite.h +++ b/gfx/2d/ScaledFontDWrite.h @@ -46,7 +46,8 @@ public: #ifdef USE_SKIA virtual SkTypeface* GetSkTypeface(); - void GetFontDataFromSystemFonts(IDWriteFactory* aFactory); + bool GetFontDataFromSystemFonts(IDWriteFactory* aFactory); + bool DefaultToArialFont(IDWriteFontCollection* aSystemFonts); #endif // The font and font family are only used with Skia