Bug 1454598 - part 2.1 - For system-installed fonts, query FC_VARIABLE to determine if a face has variations rather than instantiating a FT_Face. r=lsalzman
authorJonathan Kew <jkew@mozilla.com>
Wed, 25 Apr 2018 07:18:23 +0100
changeset 415630 53b86f2f71a8bc7f09b650bc93669f25cef27dc2
parent 415629 de118016272b5783c543a57e65d79cdbd87dd035
child 415631 3c05b11ca2b837819a60c4a05ac85822f56c608e
push id33901
push userapavel@mozilla.com
push dateThu, 26 Apr 2018 06:05:37 +0000
treeherdermozilla-central@b62ad926cf2a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1454598
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1454598 - part 2.1 - For system-installed fonts, query FC_VARIABLE to determine if a face has variations rather than instantiating a FT_Face. r=lsalzman
gfx/thebes/gfxFcPlatformFontList.cpp
gfx/thebes/gfxFcPlatformFontList.h
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -53,16 +53,19 @@ using namespace mozilla::gfx;
 using namespace mozilla::unicode;
 
 using mozilla::dom::SystemFontListEntry;
 using mozilla::dom::FontPatternListEntry;
 
 #ifndef FC_POSTSCRIPT_NAME
 #define FC_POSTSCRIPT_NAME  "postscriptname"      /* String */
 #endif
+#ifndef FC_VARIABLE
+#define FC_VARIABLE         "variable"            /* Bool */
+#endif
 
 #define PRINTING_FC_PROPERTY "gfx.printing"
 
 #define LOG_FONTLIST(args) MOZ_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
                                LogLevel::Debug, args)
 #define LOG_FONTLIST_ENABLED() MOZ_LOG_TEST( \
                                    gfxPlatform::GetLog(eGfxLog_fontlist), \
                                    LogLevel::Debug)
@@ -228,16 +231,17 @@ MapFcWidth(int aFcWidth)
 }
 
 gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
                                                FcPattern* aFontPattern,
                                                bool aIgnoreFcCharmap)
         : gfxFontEntry(aFaceName), mFontPattern(aFontPattern),
           mFTFace(nullptr), mFTFaceInitialized(false),
           mIgnoreFcCharmap(aIgnoreFcCharmap),
+          mHasVariationsInitialized(false),
           mAspect(0.0), mFontData(nullptr), mLength(0)
 {
     // italic
     int slant;
     if (FcPatternGetInteger(aFontPattern, FC_SLANT, 0, &slant) != FcResultMatch) {
         slant = FC_SLANT_ROMAN;
     }
     if (slant == FC_SLANT_OBLIQUE) {
@@ -316,16 +320,17 @@ gfxFontconfigFontEntry::gfxFontconfigFon
                                                FontStretch aStretch,
                                                FontSlantStyle aStyle,
                                                const uint8_t *aData,
                                                uint32_t aLength,
                                                FT_Face aFace)
     : gfxFontEntry(aFaceName),
       mFTFace(aFace), mFTFaceInitialized(true),
       mIgnoreFcCharmap(true),
+      mHasVariationsInitialized(false),
       mAspect(0.0), mFontData(aData), mLength(aLength)
 {
     mWeight = aWeight;
     mStyle = aStyle;
     mStretch = aStretch;
     mIsDataUserFont = true;
 
     mFontPattern = CreatePatternForFace(mFTFace);
@@ -335,16 +340,17 @@ gfxFontconfigFontEntry::gfxFontconfigFon
 
 gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
                                                FcPattern* aFontPattern,
                                                FontWeight aWeight,
                                                FontStretch aStretch,
                                                FontSlantStyle aStyle)
         : gfxFontEntry(aFaceName), mFontPattern(aFontPattern),
           mFTFace(nullptr), mFTFaceInitialized(false),
+          mHasVariationsInitialized(false),
           mAspect(0.0), mFontData(nullptr), mLength(0)
 {
     mWeight = aWeight;
     mStyle = aStyle;
     mStretch = aStretch;
     mIsLocalUserFont = true;
 
     // The proper setting of mIgnoreFcCharmap is tricky for fonts loaded
@@ -1059,21 +1065,38 @@ gfxFontconfigFontEntry::GetFTFace()
         mFTFace = CreateFaceForPattern(mFontPattern);
     }
     return mFTFace;
 }
 
 bool
 gfxFontconfigFontEntry::HasVariations()
 {
-    FT_Face face = GetFTFace();
-    if (face) {
-        return face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
+    if (mHasVariationsInitialized) {
+        return mHasVariations;
     }
-    return false;
+    mHasVariationsInitialized = true;
+    mHasVariations = false;
+
+    // For installed fonts, query the fontconfig pattern rather than paying
+    // the cost of loading a FT_Face that we otherwise might never need.
+    if (!IsUserFont() || IsLocalUserFont()) {
+        FcBool variable;
+        if ((FcPatternGetBool(mFontPattern, FC_VARIABLE, 0,
+                              &variable) == FcResultMatch) && variable) {
+            mHasVariations = true;
+        }
+    } else {
+        FT_Face face = GetFTFace();
+        if (face) {
+            mHasVariations = face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
+        }
+    }
+
+    return mHasVariations;
 }
 
 FT_MM_Var*
 gfxFontconfigFontEntry::GetMMVar()
 {
     if (mMMVarInitialized) {
         return mMMVar;
     }
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -163,16 +163,23 @@ protected:
 
     // 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;
 
+    // Whether the face supports variations. For system-installed fonts, we
+    // query fontconfig for this (so they will only work if fontconfig is
+    // recent enough to include support); for downloaded user-fonts we query
+    // the FreeType face.
+    bool      mHasVariations;
+    bool      mHasVariationsInitialized;
+
     double    mAspect;
 
     // data font
     const uint8_t* mFontData;
     uint32_t       mLength;
 
     class UnscaledFontCache
     {