Bug 1249600. Fallback to arial fonts or draw nothing if typeface is unavailable. r=bas

This commit is contained in:
Mason Chang 2016-05-20 09:16:29 -07:00
parent afc862c3e9
commit bd43ebe418
3 changed files with 55 additions and 10 deletions

View File

@ -1018,9 +1018,13 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
#endif #endif
ScaledFontBase* skiaFont = static_cast<ScaledFontBase*>(aFont); ScaledFontBase* skiaFont = static_cast<ScaledFontBase*>(aFont);
SkTypeface* typeface = skiaFont->GetSkTypeface();
if (!typeface) {
return;
}
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern); AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
paint.mPaint.setTypeface(skiaFont->GetSkTypeface()); paint.mPaint.setTypeface(typeface);
paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize)); paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize));
paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

View File

@ -115,31 +115,65 @@ ScaledFontDWrite::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget
#ifdef USE_SKIA #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 // This can happen if we have mixed backends which create DWrite
// fonts in a mixed environment. e.g. a cairo content backend // fonts in a mixed environment. e.g. a cairo content backend
// but Skia canvas backend. // but Skia canvas backend.
void bool
ScaledFontDWrite::GetFontDataFromSystemFonts(IDWriteFactory* aFactory) ScaledFontDWrite::GetFontDataFromSystemFonts(IDWriteFactory* aFactory)
{ {
MOZ_ASSERT(mFontFace); MOZ_ASSERT(mFontFace);
RefPtr<IDWriteFontCollection> systemFonts; RefPtr<IDWriteFontCollection> systemFonts;
HRESULT hr = aFactory->GetSystemFontCollection(getter_AddRefs(systemFonts)); HRESULT hr = aFactory->GetSystemFontCollection(getter_AddRefs(systemFonts));
if (FAILED(hr)) { if (FAILED(hr)) {
gfxWarning() << "Failed to get system font collection from file data. Code: " << hexa(hr); gfxCriticalNote << "Failed to get system font collection from file data. Code: " << hexa(hr);
return; return false;
} }
hr = systemFonts->GetFontFromFontFace(mFontFace, getter_AddRefs(mFont)); hr = systemFonts->GetFontFromFontFace(mFontFace, getter_AddRefs(mFont));
if (FAILED(hr)) { if (FAILED(hr)) {
gfxWarning() << "Failed to get system font from font face. Code: " << hexa(hr); gfxCriticalNote << "Failed to get system font from font face. Code: " << hexa(hr);
return; return DefaultToArialFont(systemFonts);
} }
hr = mFont->GetFontFamily(getter_AddRefs(mFontFamily)); hr = mFont->GetFontFamily(getter_AddRefs(mFontFamily));
if (FAILED(hr)) { if (FAILED(hr)) {
gfxWarning() << "Failed to get font family from font face. Code: " << hexa(hr); gfxCriticalNote << "Failed to get font family from font face. Code: " << hexa(hr);
return; return DefaultToArialFont(systemFonts);
} }
return true;
} }
SkTypeface* SkTypeface*
@ -147,8 +181,14 @@ ScaledFontDWrite::GetSkTypeface()
{ {
if (!mTypeface) { if (!mTypeface) {
IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory(); IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory();
if (!factory) {
return nullptr;
}
if (!mFont || !mFontFamily) { if (!mFont || !mFontFamily) {
GetFontDataFromSystemFonts(factory); if (!GetFontDataFromSystemFonts(factory)) {
return nullptr;
}
} }
mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mFont, mFontFamily); mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mFont, mFontFamily);

View File

@ -46,7 +46,8 @@ public:
#ifdef USE_SKIA #ifdef USE_SKIA
virtual SkTypeface* GetSkTypeface(); virtual SkTypeface* GetSkTypeface();
void GetFontDataFromSystemFonts(IDWriteFactory* aFactory); bool GetFontDataFromSystemFonts(IDWriteFactory* aFactory);
bool DefaultToArialFont(IDWriteFontCollection* aSystemFonts);
#endif #endif
// The font and font family are only used with Skia // The font and font family are only used with Skia