Bug 1395061 - patch 1 - Refactor gfxFontEntry::SupportsLangGroup and MatchesGenericFamily into gfxFontFamily. r=jfkthame

This commit is contained in:
Myk Melez 2017-09-11 19:22:15 +01:00
Родитель 122408f0ff
Коммит aa59a13010
6 изменённых файлов: 151 добавлений и 128 удалений

Просмотреть файл

@ -325,39 +325,6 @@ gfxFontconfigFontEntry::~gfxFontconfigFontEntry()
{ {
} }
static bool
PatternHasLang(const FcPattern *aPattern, const FcChar8 *aLang)
{
FcLangSet *langset;
if (FcPatternGetLangSet(aPattern, FC_LANG, 0, &langset) != FcResultMatch) {
return false;
}
if (FcLangSetHasLang(langset, aLang) != FcLangDifferentLang) {
return true;
}
return false;
}
bool
gfxFontconfigFontEntry::SupportsLangGroup(nsIAtom *aLangGroup) const
{
if (!aLangGroup || aLangGroup == nsGkAtoms::Unicode) {
return true;
}
nsAutoCString fcLang;
gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
pfl->GetSampleLangForGroup(aLangGroup, fcLang);
if (fcLang.IsEmpty()) {
return true;
}
// is lang included in the underlying pattern?
return PatternHasLang(mFontPattern, ToFcChar8Ptr(fcLang.get()));
}
nsresult nsresult
gfxFontconfigFontEntry::ReadCMAP(FontInfoData *aFontInfoData) gfxFontconfigFontEntry::ReadCMAP(FontInfoData *aFontInfoData)
{ {
@ -1189,6 +1156,54 @@ gfxFontconfigFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
} }
} }
static bool
PatternHasLang(const FcPattern *aPattern, const FcChar8 *aLang)
{
FcLangSet *langset;
if (FcPatternGetLangSet(aPattern, FC_LANG, 0, &langset) != FcResultMatch) {
return false;
}
if (FcLangSetHasLang(langset, aLang) != FcLangDifferentLang) {
return true;
}
return false;
}
bool
gfxFontconfigFontFamily::SupportsLangGroup(nsIAtom *aLangGroup) const
{
if (!aLangGroup || aLangGroup == nsGkAtoms::Unicode) {
return true;
}
nsAutoCString fcLang;
gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
pfl->GetSampleLangForGroup(aLangGroup, fcLang);
if (fcLang.IsEmpty()) {
return true;
}
// Before FindStyleVariations has been called, mFontPatterns will contain
// the font patterns. Afterward, it'll be empty, but mAvailableFonts
// will contain the font entries, each of which holds a reference to its
// pattern. We only check the first pattern in each list, because support
// for langs is considered to be consistent across all faces in a family.
FcPattern* fontPattern;
if (mFontPatterns.Length()) {
fontPattern = mFontPatterns[0];
} else if (mAvailableFonts.Length()) {
fontPattern = static_cast<gfxFontconfigFontEntry*>
(mAvailableFonts[0].get())->GetPattern();
} else {
return true;
}
// is lang included in the underlying pattern?
return PatternHasLang(fontPattern, ToFcChar8Ptr(fcLang.get()));
}
/* virtual */ /* virtual */
gfxFontconfigFontFamily::~gfxFontconfigFontFamily() gfxFontconfigFontFamily::~gfxFontconfigFontFamily()
{ {

Просмотреть файл

@ -99,8 +99,6 @@ public:
FcPattern* GetPattern() { return mFontPattern; } FcPattern* GetPattern() { return mFontPattern; }
bool SupportsLangGroup(nsIAtom *aLangGroup) const override;
nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override; nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override;
bool TestCharacterMap(uint32_t aCh) override; bool TestCharacterMap(uint32_t aCh) override;
@ -201,6 +199,8 @@ public:
bool& aNeedsSyntheticBold, bool& aNeedsSyntheticBold,
bool aIgnoreSizeTolerance) override; bool aIgnoreSizeTolerance) override;
bool SupportsLangGroup(nsIAtom *aLangGroup) const override;
protected: protected:
virtual ~gfxFontconfigFontFamily(); virtual ~gfxFontconfigFontFamily();

Просмотреть файл

@ -207,13 +207,6 @@ public:
nsTArray<uint16_t>& layerGlyphs, nsTArray<uint16_t>& layerGlyphs,
nsTArray<mozilla::gfx::Color>& layerColors); nsTArray<mozilla::gfx::Color>& layerColors);
virtual bool MatchesGenericFamily(const nsACString& aGeneric) const {
return true;
}
virtual bool SupportsLangGroup(nsIAtom *aLangGroup) const {
return true;
}
// Access to raw font table data (needed for Harfbuzz): // Access to raw font table data (needed for Harfbuzz):
// returns a pointer to data owned by the fontEntry or the OS, // returns a pointer to data owned by the fontEntry or the OS,
// which will remain valid until the blob is destroyed. // which will remain valid until the blob is destroyed.
@ -764,6 +757,14 @@ public:
mSkipDefaultFeatureSpaceCheck = aSkipCheck; mSkipDefaultFeatureSpaceCheck = aSkipCheck;
} }
virtual bool MatchesGenericFamily(const nsACString& aGeneric) const {
return true;
}
virtual bool SupportsLangGroup(nsIAtom *aLangGroup) const {
return true;
}
protected: protected:
// Protected destructor, to discourage deletion outside of Release(): // Protected destructor, to discourage deletion outside of Release():
virtual ~gfxFontFamily(); virtual ~gfxFontFamily();

Просмотреть файл

@ -120,11 +120,10 @@ GDIFontEntry::GDIFontEntry(const nsAString& aFaceName,
gfxUserFontData *aUserFontData, gfxUserFontData *aUserFontData,
bool aFamilyHasItalicFace) bool aFamilyHasItalicFace)
: gfxFontEntry(aFaceName), : gfxFontEntry(aFaceName),
mWindowsFamily(0), mWindowsPitch(0),
mFontType(aFontType), mFontType(aFontType),
mForceGDI(false), mForceGDI(false),
mFamilyHasItalicFace(aFamilyHasItalicFace), mFamilyHasItalicFace(aFamilyHasItalicFace),
mCharset(), mUnicodeRanges() mUnicodeRanges()
{ {
mUserFontData.reset(aUserFontData); mUserFontData.reset(aUserFontData);
mStyle = aStyle; mStyle = aStyle;
@ -486,7 +485,9 @@ GDIFontFamily::FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe,
if (fe->mWeight == logFont.lfWeight && if (fe->mWeight == logFont.lfWeight &&
fe->IsItalic() == (logFont.lfItalic == 0xFF)) { fe->IsItalic() == (logFont.lfItalic == 0xFF)) {
// update the charset bit here since this could be different // update the charset bit here since this could be different
fe->mCharset.set(metrics.tmCharSet); // XXX Can we still do this now that we store mCharset
// on the font family rather than the font entry?
ff->mCharset.set(metrics.tmCharSet);
return 1; return 1;
} }
} }
@ -505,12 +506,6 @@ GDIFontFamily::FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe,
ff->AddFontEntry(fe); ff->AddFontEntry(fe);
// mark the charset bit
fe->mCharset.set(metrics.tmCharSet);
fe->mWindowsFamily = logFont.lfPitchAndFamily & 0xF0;
fe->mWindowsPitch = logFont.lfPitchAndFamily & 0x0F;
if (nmetrics->ntmFontSig.fsUsb[0] != 0x00000000 && if (nmetrics->ntmFontSig.fsUsb[0] != 0x00000000 &&
nmetrics->ntmFontSig.fsUsb[1] != 0x00000000 && nmetrics->ntmFontSig.fsUsb[1] != 0x00000000 &&
nmetrics->ntmFontSig.fsUsb[2] != 0x00000000 && nmetrics->ntmFontSig.fsUsb[2] != 0x00000000 &&
@ -713,6 +708,7 @@ gfxGDIFontList::EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,
DWORD fontType, DWORD fontType,
LPARAM lParam) LPARAM lParam)
{ {
const NEWTEXTMETRICW& metrics = lpntme->ntmTm;
const LOGFONTW& lf = lpelfe->elfLogFont; const LOGFONTW& lf = lpelfe->elfLogFont;
if (lf.lfFaceName[0] == '@') { if (lf.lfFaceName[0] == '@') {
@ -726,7 +722,7 @@ gfxGDIFontList::EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,
if (!fontList->mFontFamilies.GetWeak(name)) { if (!fontList->mFontFamilies.GetWeak(name)) {
nsDependentString faceName(lf.lfFaceName); nsDependentString faceName(lf.lfFaceName);
RefPtr<gfxFontFamily> family = new GDIFontFamily(faceName); RefPtr<GDIFontFamily> family = new GDIFontFamily(faceName);
fontList->mFontFamilies.Put(name, family); fontList->mFontFamilies.Put(name, family);
// if locale is such that CJK font names are the default coming from // if locale is such that CJK font names are the default coming from
@ -739,6 +735,12 @@ gfxGDIFontList::EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,
if (fontList->mBadUnderlineFamilyNames.Contains(name)) if (fontList->mBadUnderlineFamilyNames.Contains(name))
family->SetBadUnderlineFamily(); family->SetBadUnderlineFamily();
family->mWindowsFamily = lf.lfPitchAndFamily & 0xF0;
family->mWindowsPitch = lf.lfPitchAndFamily & 0x0F;
// mark the charset bit
family->mCharset.set(metrics.tmCharSet);
} }
return 1; return 1;

Просмотреть файл

@ -147,6 +147,83 @@ public:
mFontType == GFX_FONT_TYPE_TT_OPENTYPE); mFontType == GFX_FONT_TYPE_TT_OPENTYPE);
} }
virtual bool SupportsRange(uint8_t range) {
return mUnicodeRanges.test(range);
}
virtual bool SkipDuringSystemFallback() {
return !HasCmapTable(); // explicitly skip non-SFNT fonts
}
virtual bool TestCharacterMap(uint32_t aCh);
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const;
gfxFontEntry* Clone() const override;
// create a font entry for a font with a given name
static GDIFontEntry* CreateFontEntry(const nsAString& aName,
gfxWindowsFontType aFontType,
uint8_t aStyle,
uint16_t aWeight, int16_t aStretch,
gfxUserFontData* aUserFontData,
bool aFamilyHasItalicFace);
// create a font entry for a font referenced by its fullname
static GDIFontEntry* LoadLocalFont(const nsAString& aFontName,
uint16_t aWeight,
int16_t aStretch,
uint8_t aStyle);
gfxWindowsFontType mFontType;
bool mForceGDI : 1;
// For src:local user-fonts, we keep track of whether the platform family
// contains an italic face, because in this case we can't safely ask GDI
// to create synthetic italics (oblique) via the LOGFONT.
// (For other types of font, this is just set to false.)
bool mFamilyHasItalicFace : 1;
gfxSparseBitSet mUnicodeRanges;
protected:
friend class gfxGDIFont;
GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType,
uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
gfxUserFontData *aUserFontData, bool aFamilyHasItalicFace);
void InitLogFont(const nsAString& aName, gfxWindowsFontType aFontType);
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold);
virtual nsresult CopyFontTable(uint32_t aTableTag,
nsTArray<uint8_t>& aBuffer) override;
already_AddRefed<mozilla::gfx::UnscaledFontGDI> LookupUnscaledFont(HFONT aFont);
LOGFONTW mLogFont;
mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
};
// a single font family, referencing one or more faces
class GDIFontFamily : public gfxFontFamily
{
public:
explicit GDIFontFamily(const nsAString& aName) :
gfxFontFamily(aName),
mWindowsFamily(0),
mWindowsPitch(0),
mCharset()
{}
virtual void FindStyleVariations(FontInfoData *aFontInfoData = nullptr);
uint8_t mWindowsFamily;
uint8_t mWindowsPitch;
virtual bool MatchesGenericFamily(const nsACString& aGeneric) const { virtual bool MatchesGenericFamily(const nsACString& aGeneric) const {
if (aGeneric.IsEmpty()) { if (aGeneric.IsEmpty()) {
return true; return true;
@ -183,6 +260,8 @@ public:
return false; return false;
} }
gfxSparseBitSet mCharset;
virtual bool SupportsLangGroup(nsIAtom* aLangGroup) const override { virtual bool SupportsLangGroup(nsIAtom* aLangGroup) const override {
if (!aLangGroup || aLangGroup == nsGkAtoms::Unicode) { if (!aLangGroup || aLangGroup == nsGkAtoms::Unicode) {
return true; return true;
@ -220,80 +299,6 @@ public:
return false; return false;
} }
virtual bool SupportsRange(uint8_t range) {
return mUnicodeRanges.test(range);
}
virtual bool SkipDuringSystemFallback() {
return !HasCmapTable(); // explicitly skip non-SFNT fonts
}
virtual bool TestCharacterMap(uint32_t aCh);
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const;
gfxFontEntry* Clone() const override;
// create a font entry for a font with a given name
static GDIFontEntry* CreateFontEntry(const nsAString& aName,
gfxWindowsFontType aFontType,
uint8_t aStyle,
uint16_t aWeight, int16_t aStretch,
gfxUserFontData* aUserFontData,
bool aFamilyHasItalicFace);
// create a font entry for a font referenced by its fullname
static GDIFontEntry* LoadLocalFont(const nsAString& aFontName,
uint16_t aWeight,
int16_t aStretch,
uint8_t aStyle);
uint8_t mWindowsFamily;
uint8_t mWindowsPitch;
gfxWindowsFontType mFontType;
bool mForceGDI : 1;
// For src:local user-fonts, we keep track of whether the platform family
// contains an italic face, because in this case we can't safely ask GDI
// to create synthetic italics (oblique) via the LOGFONT.
// (For other types of font, this is just set to false.)
bool mFamilyHasItalicFace : 1;
gfxSparseBitSet mCharset;
gfxSparseBitSet mUnicodeRanges;
protected:
friend class gfxGDIFont;
GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType,
uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
gfxUserFontData *aUserFontData, bool aFamilyHasItalicFace);
void InitLogFont(const nsAString& aName, gfxWindowsFontType aFontType);
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold);
virtual nsresult CopyFontTable(uint32_t aTableTag,
nsTArray<uint8_t>& aBuffer) override;
already_AddRefed<mozilla::gfx::UnscaledFontGDI> LookupUnscaledFont(HFONT aFont);
LOGFONTW mLogFont;
mozilla::WeakPtr<mozilla::gfx::UnscaledFont> mUnscaledFont;
};
// a single font family, referencing one or more faces
class GDIFontFamily : public gfxFontFamily
{
public:
explicit GDIFontFamily(const nsAString& aName) :
gfxFontFamily(aName) {}
virtual void FindStyleVariations(FontInfoData *aFontInfoData = nullptr);
private: private:
static int CALLBACK FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe, static int CALLBACK FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe,
const NEWTEXTMETRICEXW *nmetrics, const NEWTEXTMETRICEXW *nmetrics,

Просмотреть файл

@ -500,8 +500,8 @@ gfxPlatformFontList::GetFontList(nsIAtom *aLangGroup,
continue; continue;
} }
if (fontEntry->SupportsLangGroup(aLangGroup) && if (family->SupportsLangGroup(aLangGroup) &&
fontEntry->MatchesGenericFamily(aGenericFamily)) { family->MatchesGenericFamily(aGenericFamily)) {
nsAutoString localizedFamilyName; nsAutoString localizedFamilyName;
family->LocalizedName(localizedFamilyName); family->LocalizedName(localizedFamilyName);
aListOfFonts.AppendElement(localizedFamilyName); aListOfFonts.AppendElement(localizedFamilyName);