mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 998844 - part 4 - support bundled fonts on desktop Linux. r=jdaggett
This commit is contained in:
parent
995d8e9e8c
commit
715446ecd5
@ -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<FcPattern*,100> 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<nsIFile> 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
|
||||
|
@ -309,6 +309,13 @@ protected:
|
||||
nsTArray<nsCString> mAliasForMultiFonts;
|
||||
|
||||
FcConfig *mLastConfig;
|
||||
|
||||
#ifdef MOZ_BUNDLED_FONTS
|
||||
void ActivateBundledFonts();
|
||||
|
||||
nsCString mBundledFontsPath;
|
||||
bool mBundledFontsInitialized;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* GFX_FONTCONFIG_UTILS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user