diff --git a/gfx/thebes/gfxFontconfigUtils.cpp b/gfx/thebes/gfxFontconfigUtils.cpp index 84aaf7527cd..43ace0eea33 100644 --- a/gfx/thebes/gfxFontconfigUtils.cpp +++ b/gfx/thebes/gfxFontconfigUtils.cpp @@ -16,6 +16,9 @@ #include "nsILanguageAtomService.h" #include "nsTArray.h" #include "mozilla/Preferences.h" +#include "nsDirectoryServiceUtils.h" +#include "nsDirectoryServiceDefs.h" +#include "nsAppDirectoryServiceDefs.h" #include "nsIAtom.h" #include "nsCRT.h" @@ -314,6 +317,9 @@ gfxFontconfigUtils::gfxFontconfigUtils() , mFontsByFullname(50) , mLangSupportTable(50) , mLastConfig(nullptr) +#ifdef MOZ_BUNDLED_FONTS + , mBundledFontsInitialized(false) +#endif { UpdateFontListInternal(); } @@ -579,8 +585,17 @@ gfxFontconfigUtils::UpdateFontListInternal(bool aForce) if (currentConfig == mLastConfig) return NS_OK; - // This FcFontSet is owned by fontconfig - FcFontSet *fontSet = FcConfigGetFonts(currentConfig, FcSetSystem); +#ifdef MOZ_BUNDLED_FONTS + ActivateBundledFonts(); +#endif + + // These FcFontSets are owned by fontconfig + FcFontSet *fontSets[] = { + FcConfigGetFonts(currentConfig, FcSetSystem) +#ifdef MOZ_BUNDLED_FONTS + , FcConfigGetFonts(currentConfig, FcSetApplication) +#endif + }; mFontsByFamily.Clear(); mFontsByFullname.Clear(); @@ -588,29 +603,35 @@ gfxFontconfigUtils::UpdateFontListInternal(bool aForce) mAliasForMultiFonts.Clear(); // Record the existing font families - for (int f = 0; f < fontSet->nfont; ++f) { - FcPattern *font = fontSet->fonts[f]; + for (unsigned fs = 0; fs < ArrayLength(fontSets); ++fs) { + FcFontSet *fontSet = fontSets[fs]; + if (!fontSet) { // the application set might not exist + continue; + } + for (int f = 0; f < fontSet->nfont; ++f) { + FcPattern *font = fontSet->fonts[f]; - FcChar8 *family; - for (int v = 0; - FcPatternGetString(font, FC_FAMILY, v, &family) == FcResultMatch; - ++v) { - FontsByFcStrEntry *entry = mFontsByFamily.PutEntry(family); - if (entry) { - bool added = entry->AddFont(font); + FcChar8 *family; + for (int v = 0; + FcPatternGetString(font, FC_FAMILY, v, &family) == FcResultMatch; + ++v) { + FontsByFcStrEntry *entry = mFontsByFamily.PutEntry(family); + if (entry) { + bool added = entry->AddFont(font); - if (!entry->mKey) { - // The reference to the font pattern keeps the pointer to - // string for the key valid. If adding the font failed - // then the entry must be removed. - if (added) { - entry->mKey = family; - } else { - mFontsByFamily.RawRemoveEntry(entry); - } - } - } - } + if (!entry->mKey) { + // The reference to the font pattern keeps the pointer to + // string for the key valid. If adding the font failed + // then the entry must be removed. + if (added) { + entry->mKey = family; + } else { + mFontsByFamily.RawRemoveEntry(entry); + } + } + } + } + } } // XXX we don't support all alias names. @@ -851,51 +872,62 @@ gfxFontconfigUtils::FontsByFullnameEntry::KeyEquals(KeyTypePointer aKey) const void gfxFontconfigUtils::AddFullnameEntries() { - // This FcFontSet is owned by fontconfig - FcFontSet *fontSet = FcConfigGetFonts(nullptr, FcSetSystem); + // These FcFontSets are owned by fontconfig + FcFontSet *fontSets[] = { + FcConfigGetFonts(nullptr, FcSetSystem) +#ifdef MOZ_BUNDLED_FONTS + , FcConfigGetFonts(nullptr, FcSetApplication) +#endif + }; - // Record the existing font families - for (int f = 0; f < fontSet->nfont; ++f) { - FcPattern *font = fontSet->fonts[f]; + for (unsigned fs = 0; fs < ArrayLength(fontSets); ++fs) { + FcFontSet *fontSet = fontSets[fs]; + if (!fontSet) { + continue; + } + // Record the existing font families + for (int f = 0; f < fontSet->nfont; ++f) { + FcPattern *font = fontSet->fonts[f]; - int v = 0; - FcChar8 *fullname; - while (FcPatternGetString(font, - FC_FULLNAME, v, &fullname) == FcResultMatch) { - FontsByFullnameEntry *entry = mFontsByFullname.PutEntry(fullname); - if (entry) { - // entry always has space for one font, so the first AddFont - // will always succeed, and so the entry will always have a - // font from which to obtain the key. - bool added = entry->AddFont(font); - // The key may be nullptr either if this is the first font, or - // if the first font does not have a fullname property, and so - // the key is obtained from the font. Set the key in both - // cases. The check that AddFont succeeded is required for - // the second case. - if (!entry->mKey && added) { - entry->mKey = fullname; - } - } + int v = 0; + FcChar8 *fullname; + while (FcPatternGetString(font, + FC_FULLNAME, v, &fullname) == FcResultMatch) { + FontsByFullnameEntry *entry = mFontsByFullname.PutEntry(fullname); + if (entry) { + // entry always has space for one font, so the first AddFont + // will always succeed, and so the entry will always have a + // font from which to obtain the key. + bool added = entry->AddFont(font); + // The key may be nullptr either if this is the first font, or + // if the first font does not have a fullname property, and so + // the key is obtained from the font. Set the key in both + // cases. The check that AddFont succeeded is required for + // the second case. + if (!entry->mKey && added) { + entry->mKey = fullname; + } + } - ++v; - } + ++v; + } - // Fontconfig does not provide a fullname property for all fonts. - if (v == 0) { - nsAutoCString name; - if (!GetFullnameFromFamilyAndStyle(font, &name)) - continue; + // Fontconfig does not provide a fullname property for all fonts. + if (v == 0) { + nsAutoCString name; + if (!GetFullnameFromFamilyAndStyle(font, &name)) + continue; - FontsByFullnameEntry *entry = - mFontsByFullname.PutEntry(ToFcChar8(name)); - if (entry) { - entry->AddFont(font); - // Either entry->mKey has been set for a previous font or it - // remains nullptr to indicate that the key is obtained from - // the first font. - } - } + FontsByFullnameEntry *entry = + mFontsByFullname.PutEntry(ToFcChar8(name)); + if (entry) { + entry->AddFont(font); + // Either entry->mKey has been set for a previous font or it + // remains nullptr to indicate that the key is obtained from + // the first font. + } + } + } } } @@ -1009,33 +1041,44 @@ gfxFontconfigUtils::GetLangSupportEntry(const FcChar8 *aLang, bool aWithFonts) return entry; } - // This FcFontSet is owned by fontconfig - FcFontSet *fontSet = FcConfigGetFonts(nullptr, FcSetSystem); + // These FcFontSets are owned by fontconfig + FcFontSet *fontSets[] = { + FcConfigGetFonts(nullptr, FcSetSystem) +#ifdef MOZ_BUNDLED_FONTS + , FcConfigGetFonts(nullptr, FcSetApplication) +#endif + }; nsAutoTArray fonts; - for (int f = 0; f < fontSet->nfont; ++f) { - FcPattern *font = fontSet->fonts[f]; + for (unsigned fs = 0; fs < ArrayLength(fontSets); ++fs) { + FcFontSet *fontSet = fontSets[fs]; + if (!fontSet) { + continue; + } + for (int f = 0; f < fontSet->nfont; ++f) { + FcPattern *font = fontSet->fonts[f]; - FcLangResult support = GetLangSupport(font, aLang); + FcLangResult support = GetLangSupport(font, aLang); - if (support < best) { // lower is better - best = support; - if (aWithFonts) { - fonts.Clear(); - } else if (best == FcLangEqual) { - break; - } - } + if (support < best) { // lower is better + best = support; + if (aWithFonts) { + fonts.Clear(); + } else if (best == FcLangEqual) { + break; + } + } - // The font list in the LangSupportEntry is expected to be used only - // when no default fonts support the language. There would be a large - // number of fonts in entries for languages using Latin script but - // these do not need to be created because default fonts already - // support these languages. - if (aWithFonts && support != FcLangDifferentLang && support == best) { - fonts.AppendElement(font); - } + // The font list in the LangSupportEntry is expected to be used only + // when no default fonts support the language. There would be a large + // number of fonts in entries for languages using Latin script but + // these do not need to be created because default fonts already + // support these languages. + if (aWithFonts && support != FcLangDifferentLang && support == best) { + fonts.AppendElement(font); + } + } } entry->mSupport = best; @@ -1078,3 +1121,33 @@ gfxFontconfigUtils::GetFontsForLang(const FcChar8 *aLang) return entry->mFonts; } + +#ifdef MOZ_BUNDLED_FONTS + +void +gfxFontconfigUtils::ActivateBundledFonts() +{ + if (!mBundledFontsInitialized) { + mBundledFontsInitialized = true; + nsCOMPtr localDir; + nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(localDir)); + if (NS_FAILED(rv)) { + return; + } + if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("fonts")))) { + return; + } + bool isDir; + if (NS_FAILED(localDir->IsDirectory(&isDir)) || !isDir) { + return; + } + if (NS_FAILED(localDir->GetNativePath(mBundledFontsPath))) { + return; + } + } + if (!mBundledFontsPath.IsEmpty()) { + FcConfigAppFontAddDir(nullptr, (const FcChar8*)mBundledFontsPath.get()); + } +} + +#endif diff --git a/gfx/thebes/gfxFontconfigUtils.h b/gfx/thebes/gfxFontconfigUtils.h index 7db8f905055..a2e4890e0c8 100644 --- a/gfx/thebes/gfxFontconfigUtils.h +++ b/gfx/thebes/gfxFontconfigUtils.h @@ -309,6 +309,13 @@ protected: nsTArray mAliasForMultiFonts; FcConfig *mLastConfig; + +#ifdef MOZ_BUNDLED_FONTS + void ActivateBundledFonts(); + + nsCString mBundledFontsPath; + bool mBundledFontsInitialized; +#endif }; #endif /* GFX_FONTCONFIG_UTILS_H */