зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1276594 - Don't rely on the fontconfig charmap for user fonts or app-bundled fonts; check the cmap directly instead. r=karlt
This commit is contained in:
Родитель
a963e59e11
Коммит
96bb44cd34
|
@ -185,9 +185,11 @@ MapFcWidth(int aFcWidth)
|
|||
}
|
||||
|
||||
gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
|
||||
FcPattern* aFontPattern)
|
||||
FcPattern* aFontPattern,
|
||||
bool aIgnoreFcCharmap)
|
||||
: gfxFontEntry(aFaceName), mFontPattern(aFontPattern),
|
||||
mFTFace(nullptr), mFTFaceInitialized(false),
|
||||
mIgnoreFcCharmap(aIgnoreFcCharmap),
|
||||
mAspect(0.0), mFontData(nullptr)
|
||||
{
|
||||
// italic
|
||||
|
@ -224,6 +226,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
|
|||
FT_Face aFace)
|
||||
: gfxFontEntry(aFaceName),
|
||||
mFTFace(aFace), mFTFaceInitialized(true),
|
||||
mIgnoreFcCharmap(true),
|
||||
mAspect(0.0), mFontData(aData)
|
||||
{
|
||||
mWeight = aWeight;
|
||||
|
@ -269,6 +272,19 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
|
|||
mStyle = aStyle;
|
||||
mStretch = aStretch;
|
||||
mIsLocalUserFont = true;
|
||||
|
||||
// The proper setting of mIgnoreFcCharmap is tricky for fonts loaded
|
||||
// via src:local()...
|
||||
// If the local font happens to come from the application fontset,
|
||||
// we want to set it to true so that color/svg fonts will work even
|
||||
// if the default glyphs are blank; but if the local font is a non-
|
||||
// sfnt face (e.g. legacy type 1) then we need to set it to false
|
||||
// because our cmap-reading code will fail and we depend on FT+Fc to
|
||||
// determine the coverage.
|
||||
// We set the flag here, but may flip it the first time TestCharacterMap
|
||||
// is called, at which point we'll look to see whether a 'cmap' is
|
||||
// actually present in the font.
|
||||
mIgnoreFcCharmap = true;
|
||||
}
|
||||
|
||||
gfxFontconfigFontEntry::~gfxFontconfigFontEntry()
|
||||
|
@ -377,11 +393,23 @@ HasChar(FcPattern *aFont, FcChar32 aCh)
|
|||
bool
|
||||
gfxFontconfigFontEntry::TestCharacterMap(uint32_t aCh)
|
||||
{
|
||||
// for system fonts, use the charmap in the pattern
|
||||
if (!mIsDataUserFont) {
|
||||
return HasChar(mFontPattern, aCh);
|
||||
// For user fonts, or for fonts bundled with the app (which might include
|
||||
// color/svg glyphs where the default glyphs may be blank, and thus confuse
|
||||
// fontconfig/freetype's char map checking), we instead check the cmap
|
||||
// directly for character coverage.
|
||||
if (mIgnoreFcCharmap) {
|
||||
// If it does not actually have a cmap, switch our strategy to use
|
||||
// fontconfig's charmap after all (except for data fonts, which must
|
||||
// always have a cmap to have passed OTS validation).
|
||||
if (!mIsDataUserFont && !HasFontTable(TRUETYPE_TAG('c','m','a','p'))) {
|
||||
mIgnoreFcCharmap = false;
|
||||
// ...and continue with HasChar() below.
|
||||
} else {
|
||||
return gfxFontEntry::TestCharacterMap(aCh);
|
||||
}
|
||||
}
|
||||
return gfxFontEntry::TestCharacterMap(aCh);
|
||||
// otherwise (for system fonts), use the charmap in the pattern
|
||||
return HasChar(mFontPattern, aCh);
|
||||
}
|
||||
|
||||
hb_blob_t*
|
||||
|
@ -810,7 +838,7 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData)
|
|||
const nsAutoString& faceName = !psname.IsEmpty() ? psname : fullname;
|
||||
|
||||
gfxFontconfigFontEntry *fontEntry =
|
||||
new gfxFontconfigFontEntry(faceName, face);
|
||||
new gfxFontconfigFontEntry(faceName, face, mContainsAppFonts);
|
||||
AddFontEntry(fontEntry);
|
||||
|
||||
if (fontEntry->IsUpright() &&
|
||||
|
@ -927,7 +955,7 @@ gfxFcPlatformFontList::~gfxFcPlatformFontList()
|
|||
}
|
||||
|
||||
void
|
||||
gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet)
|
||||
gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet, bool aAppFonts)
|
||||
{
|
||||
// This iterates over the fonts in a font set and adds in gfxFontFamily
|
||||
// objects for each family. The patterns for individual fonts are not
|
||||
|
@ -942,7 +970,7 @@ gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet)
|
|||
}
|
||||
|
||||
FcChar8* lastFamilyName = (FcChar8*)"";
|
||||
gfxFontFamily* fontFamily = nullptr;
|
||||
gfxFontconfigFontFamily* fontFamily = nullptr;
|
||||
nsAutoString familyName;
|
||||
for (int f = 0; f < aFontSet->nfont; f++) {
|
||||
FcPattern* font = aFontSet->fonts[f];
|
||||
|
@ -972,11 +1000,18 @@ gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet)
|
|||
nsAutoString keyName(familyName);
|
||||
ToLowerCase(keyName);
|
||||
|
||||
fontFamily = mFontFamilies.GetWeak(keyName);
|
||||
fontFamily = static_cast<gfxFontconfigFontFamily*>
|
||||
(mFontFamilies.GetWeak(keyName));
|
||||
if (!fontFamily) {
|
||||
fontFamily = new gfxFontconfigFontFamily(familyName);
|
||||
mFontFamilies.Put(keyName, fontFamily);
|
||||
}
|
||||
// Record if the family contains fonts from the app font set
|
||||
// (in which case we won't rely on fontconfig's charmap, due to
|
||||
// bug 1276594).
|
||||
if (aAppFonts) {
|
||||
fontFamily->SetFamilyContainsAppFonts(true);
|
||||
}
|
||||
|
||||
// Add pointers to other localized family names. Most fonts
|
||||
// only have a single name, so the first call to GetString
|
||||
|
@ -994,9 +1029,7 @@ gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet)
|
|||
}
|
||||
|
||||
NS_ASSERTION(fontFamily, "font must belong to a font family");
|
||||
gfxFontconfigFontFamily* fcFamily =
|
||||
static_cast<gfxFontconfigFontFamily*>(fontFamily);
|
||||
fcFamily->AddFontPattern(font);
|
||||
fontFamily->AddFontPattern(font);
|
||||
|
||||
// map the psname, fullname ==> font family for local font lookups
|
||||
nsAutoString psname, fullname;
|
||||
|
@ -1025,13 +1058,13 @@ gfxFcPlatformFontList::InitFontList()
|
|||
|
||||
// iterate over available fonts
|
||||
FcFontSet* systemFonts = FcConfigGetFonts(nullptr, FcSetSystem);
|
||||
AddFontSetFamilies(systemFonts);
|
||||
AddFontSetFamilies(systemFonts, /* aAppFonts = */ false);
|
||||
mAlwaysUseFontconfigGenerics = PrefFontListsUseOnlyGenerics();
|
||||
|
||||
#ifdef MOZ_BUNDLED_FONTS
|
||||
ActivateBundledFonts();
|
||||
FcFontSet* appFonts = FcConfigGetFonts(nullptr, FcSetApplication);
|
||||
AddFontSetFamilies(appFonts);
|
||||
AddFontSetFamilies(appFonts, /* aAppFonts = */ true);
|
||||
#endif
|
||||
|
||||
mOtherFamilyNamesInitialized = true;
|
||||
|
@ -1162,8 +1195,7 @@ gfxFcPlatformFontList::LookupLocalFont(const nsAString& aFontName,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return new gfxFontconfigFontEntry(aFontName,
|
||||
fontPattern,
|
||||
return new gfxFontconfigFontEntry(aFontName, fontPattern,
|
||||
aWeight, aStretch, aStyle);
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,8 @@ class gfxFontconfigFontEntry : public gfxFontEntry {
|
|||
public:
|
||||
// used for system fonts with explicit patterns
|
||||
explicit gfxFontconfigFontEntry(const nsAString& aFaceName,
|
||||
FcPattern* aFontPattern);
|
||||
FcPattern* aFontPattern,
|
||||
bool aIgnoreFcCharmap);
|
||||
|
||||
// used for data fonts where the fontentry takes ownership
|
||||
// of the font data and the FT_Face
|
||||
|
@ -154,6 +155,14 @@ protected:
|
|||
// FTFace - initialized when needed
|
||||
FT_Face mFTFace;
|
||||
bool mFTFaceInitialized;
|
||||
|
||||
// Whether TestCharacterMap should check the actual cmap rather than asking
|
||||
// fontconfig about character coverage.
|
||||
// We do this for app-bundled (rather than system) fonts, as they may
|
||||
// include color glyphs that fontconfig would overlook, and for fonts
|
||||
// loaded via @font-face.
|
||||
bool mIgnoreFcCharmap;
|
||||
|
||||
double mAspect;
|
||||
|
||||
// data font
|
||||
|
@ -163,7 +172,9 @@ protected:
|
|||
class gfxFontconfigFontFamily : public gfxFontFamily {
|
||||
public:
|
||||
explicit gfxFontconfigFontFamily(const nsAString& aName) :
|
||||
gfxFontFamily(aName) { }
|
||||
gfxFontFamily(aName),
|
||||
mContainsAppFonts(false)
|
||||
{ }
|
||||
|
||||
void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) override;
|
||||
|
||||
|
@ -171,10 +182,17 @@ public:
|
|||
// When necessary, these are enumerated within FindStyleVariations.
|
||||
void AddFontPattern(FcPattern* aFontPattern);
|
||||
|
||||
void SetFamilyContainsAppFonts(bool aContainsAppFonts)
|
||||
{
|
||||
mContainsAppFonts = aContainsAppFonts;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~gfxFontconfigFontFamily() { }
|
||||
|
||||
nsTArray<nsCountedRef<FcPattern> > mFontPatterns;
|
||||
|
||||
bool mContainsAppFonts;
|
||||
};
|
||||
|
||||
class gfxFontconfigFont : public gfxFT2FontBase {
|
||||
|
@ -258,8 +276,9 @@ public:
|
|||
protected:
|
||||
virtual ~gfxFcPlatformFontList();
|
||||
|
||||
// add all the font families found in a font set
|
||||
void AddFontSetFamilies(FcFontSet* aFontSet);
|
||||
// Add all the font families found in a font set.
|
||||
// aAppFonts indicates whether this is the system or application fontset.
|
||||
void AddFontSetFamilies(FcFontSet* aFontSet, bool aAppFonts);
|
||||
|
||||
// figure out which families fontconfig maps a generic to
|
||||
// (aGeneric assumed already lowercase)
|
||||
|
|
Загрузка…
Ссылка в новой задаче