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 469147 bac00121657710355c2cb012e6959fcd487299b1
parent 469146 5af215d265b649a69975cc94886dd281c91f5908
child 469148 bc910e36a7d75512b3bfc0a73110166145b095e9
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [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
     {