diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index eb273ef3cd35..4e59c63f0e52 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -1046,89 +1046,100 @@ gfxFontEntry* gfxDWriteFontList::CreateFontEntry( bool foundExpectedFamily = false; const nsCString& familyName = aFamily->DisplayName().AsString(SharedFontList()); - if (aFamily->Index() < collection->GetFontFamilyCount()) { - HRESULT hr = - collection->GetFontFamily(aFamily->Index(), getter_AddRefs(family)); - // Check that the family name is what we expected; if not, fall back to - // search by name. It's sad we have to do this, but it is possible for - // Windows to have given different versions of the system font collection - // to the parent and child processes. - if (SUCCEEDED(hr) && family) { - RefPtr names; - hr = family->GetFamilyNames(getter_AddRefs(names)); - if (SUCCEEDED(hr) && names) { - nsAutoCString name; - if (GetEnglishOrFirstName(name, names)) { - foundExpectedFamily = name.Equals(familyName); + + // The DirectWrite calls here might throw exceptions, e.g. in case of disk + // errors when trying to read the font file. + MOZ_SEH_TRY { + if (aFamily->Index() < collection->GetFontFamilyCount()) { + HRESULT hr = + collection->GetFontFamily(aFamily->Index(), getter_AddRefs(family)); + // Check that the family name is what we expected; if not, fall back to + // search by name. It's sad we have to do this, but it is possible for + // Windows to have given different versions of the system font collection + // to the parent and child processes. + if (SUCCEEDED(hr) && family) { + RefPtr names; + hr = family->GetFamilyNames(getter_AddRefs(names)); + if (SUCCEEDED(hr) && names) { + nsAutoCString name; + if (GetEnglishOrFirstName(name, names)) { + foundExpectedFamily = name.Equals(familyName); + } } } } - } - if (!foundExpectedFamily) { - // Try to get family by name instead of index (to deal with the case of - // collection mismatch). - UINT32 index; - BOOL exists; - NS_ConvertUTF8toUTF16 name16(familyName); - HRESULT hr = collection->FindFamilyName( - reinterpret_cast(name16.BeginReading()), &index, &exists); - if (FAILED(hr) || !exists || index == UINT_MAX || - FAILED(collection->GetFontFamily(index, getter_AddRefs(family))) || - !family) { + if (!foundExpectedFamily) { + // Try to get family by name instead of index (to deal with the case of + // collection mismatch). + UINT32 index; + BOOL exists; + NS_ConvertUTF8toUTF16 name16(familyName); + HRESULT hr = collection->FindFamilyName( + reinterpret_cast(name16.BeginReading()), &index, + &exists); + if (FAILED(hr) || !exists || index == UINT_MAX || + FAILED(collection->GetFontFamily(index, getter_AddRefs(family))) || + !family) { + return nullptr; + } + } + + // Retrieve the required face by index within the family. + RefPtr font; + if (FAILED(family->GetFont(aFace->mIndex, getter_AddRefs(font))) || !font) { return nullptr; } - } - // Retrieve the required face by index within the family. - RefPtr font; - if (FAILED(family->GetFont(aFace->mIndex, getter_AddRefs(font))) || !font) { - return nullptr; - } - - // Retrieve the psName from the font, so we can check we've found the - // expected face. - nsAutoCString psName; - if (FAILED(GetDirectWriteFaceName(font, PSNAME_ID, psName))) { - RefPtr dwFontFace; - if (SUCCEEDED(font->CreateFontFace(getter_AddRefs(dwFontFace)))) { - GetPostScriptNameFromNameTable(dwFontFace, psName); + // Retrieve the psName from the font, so we can check we've found the + // expected face. + nsAutoCString psName; + if (FAILED(GetDirectWriteFaceName(font, PSNAME_ID, psName))) { + RefPtr dwFontFace; + if (SUCCEEDED(font->CreateFontFace(getter_AddRefs(dwFontFace)))) { + GetPostScriptNameFromNameTable(dwFontFace, psName); + } } - } - // If it doesn't match, DirectWrite must have shuffled the order of faces - // returned for the family; search by name as a fallback. - nsCString faceName = aFace->mDescriptor.AsString(SharedFontList()); - if (psName != faceName) { - gfxWarning() << "Face name mismatch for index " << aFace->mIndex - << " in family " << familyName.get() << ": expected " - << faceName.get() << ", found " << psName.get(); - for (uint32_t i = 0; i < family->GetFontCount(); ++i) { - if (i == aFace->mIndex) { - continue; // this was the face we already tried - } - if (FAILED(family->GetFont(i, getter_AddRefs(font))) || !font) { - return nullptr; // this font family is broken! - } - if (FAILED(GetDirectWriteFaceName(font, PSNAME_ID, psName))) { - RefPtr dwFontFace; - if (SUCCEEDED(font->CreateFontFace(getter_AddRefs(dwFontFace)))) { - GetPostScriptNameFromNameTable(dwFontFace, psName); + // If it doesn't match, DirectWrite must have shuffled the order of faces + // returned for the family; search by name as a fallback. + nsCString faceName = aFace->mDescriptor.AsString(SharedFontList()); + if (psName != faceName) { + gfxWarning() << "Face name mismatch for index " << aFace->mIndex + << " in family " << familyName.get() << ": expected " + << faceName.get() << ", found " << psName.get(); + for (uint32_t i = 0; i < family->GetFontCount(); ++i) { + if (i == aFace->mIndex) { + continue; // this was the face we already tried + } + if (FAILED(family->GetFont(i, getter_AddRefs(font))) || !font) { + return nullptr; // this font family is broken! + } + if (FAILED(GetDirectWriteFaceName(font, PSNAME_ID, psName))) { + RefPtr dwFontFace; + if (SUCCEEDED(font->CreateFontFace(getter_AddRefs(dwFontFace)))) { + GetPostScriptNameFromNameTable(dwFontFace, psName); + } + } + if (psName == faceName) { + break; } } - if (psName == faceName) { - break; - } } - } - if (psName != faceName) { - return nullptr; - } + if (psName != faceName) { + return nullptr; + } - auto fe = new gfxDWriteFontEntry(faceName, font, !aFamily->IsBundled()); - fe->InitializeFrom(aFace, aFamily); - fe->mForceGDIClassic = aFamily->IsForceClassic(); - fe->mMayUseGDIAccess = aFamily->IsSimple(); - return fe; + auto fe = new gfxDWriteFontEntry(faceName, font, !aFamily->IsBundled()); + fe->InitializeFrom(aFace, aFamily); + fe->mForceGDIClassic = aFamily->IsForceClassic(); + fe->mMayUseGDIAccess = aFamily->IsSimple(); + return fe; + } + MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + gfxCriticalNote << "Exception occurred while creating font entry for " + << familyName.get(); + } + return nullptr; } FontVisibility gfxDWriteFontList::GetVisibilityForFamily(