Bug 1360862 - allow bitmap fonts to force scaling and bypass tolerance check in gfxFcPlatformFontList. r=jfkthame
authorLee Salzman <lsalzman@mozilla.com>
Fri, 05 May 2017 15:46:10 -0400
changeset 356787 dd650c37854b8944953d9b4bbf9ece2f23bdf410
parent 356786 24ecce36f4012f42ae0d672d0207e7589f16620d
child 356788 041899558dd5c8c1ff7abe7fd393bda48c3f323a
push id89965
push userlsalzman@mozilla.com
push dateFri, 05 May 2017 19:47:43 +0000
treeherdermozilla-inbound@dd650c37854b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1360862
milestone55.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 1360862 - allow bitmap fonts to force scaling and bypass tolerance check in gfxFcPlatformFontList. r=jfkthame MozReview-Commit-ID: Ly5ori9HKqc
gfx/thebes/gfxFcPlatformFontList.cpp
gfx/thebes/gfxFcPlatformFontList.h
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -845,16 +845,25 @@ ChooseFontSize(gfxFontconfigFontEntry* a
                               FC_PIXEL_SIZE, v, &size) == FcResultMatch) {
         ++v;
         double dist = fabs(size - requestedSize);
         if (bestDist < 0.0 || dist < bestDist) {
             bestDist = dist;
             bestSize = size;
         }
     }
+    // If the font has bitmaps but wants to be scaled, then let it scale.
+    if (bestSize >= 0.0) {
+        FcBool scalable;
+        if (FcPatternGetBool(aEntry->GetPattern(),
+                             FC_SCALABLE, 0, &scalable) == FcResultMatch &&
+            scalable) {
+            return requestedSize;
+        }
+    }
     return bestSize;
 }
 
 gfxFont*
 gfxFontconfigFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle,
                                            bool aNeedsBold)
 {
     nsAutoRef<FcPattern> pattern(FcPatternCreate());
@@ -1007,45 +1016,53 @@ gfxFontconfigFontFamily::AddFontPattern(
 {
     NS_ASSERTION(!mHasStyles,
                  "font patterns must not be added to already enumerated families");
 
     FcBool outline;
     if (FcPatternGetBool(aFontPattern, FC_OUTLINE, 0, &outline) != FcResultMatch ||
         !outline) {
         mHasNonScalableFaces = true;
+
+        FcBool scalable;
+        if (FcPatternGetBool(aFontPattern, FC_SCALABLE, 0, &scalable) == FcResultMatch &&
+            scalable) {
+            mForceScalable = true;
+        }
     }
 
     nsCountedRef<FcPattern> pattern(aFontPattern);
     mFontPatterns.AppendElement(pattern);
 }
 
 static const double kRejectDistance = 10000.0;
 
 // Calculate a distance score representing the size disparity between the
 // requested style's size and the font entry's size.
 static double
-SizeDistance(gfxFontconfigFontEntry* aEntry, const gfxFontStyle& aStyle)
+SizeDistance(gfxFontconfigFontEntry* aEntry,
+             const gfxFontStyle& aStyle,
+             bool aForceScalable)
 {
     double requestedSize = SizeForStyle(aEntry, aStyle);
     double bestDist = -1.0;
     double size;
     int v = 0;
     while (FcPatternGetDouble(aEntry->GetPattern(),
                               FC_PIXEL_SIZE, v, &size) == FcResultMatch) {
         ++v;
         double dist = fabs(size - requestedSize);
         if (bestDist < 0.0 || dist < bestDist) {
             bestDist = dist;
         }
     }
     if (bestDist < 0.0) {
         // No size means scalable
         return -1.0;
-    } else if (5.0 * bestDist < requestedSize) {
+    } else if (aForceScalable || 5.0 * bestDist < requestedSize) {
         // fontconfig prefers a matching family or lang to pixelsize of bitmap
         // fonts. CSS suggests a tolerance of 20% on pixelsize.
         return bestDist;
     } else {
         // Reject any non-scalable fonts that are not within tolerance.
         return kRejectDistance;
     }
 }
@@ -1069,17 +1086,17 @@ gfxFontconfigFontFamily::FindAllFontsFor
     // available size is rejected for being outside tolernace, then the
     // entire group will be skipped.
     size_t skipped = 0;
     gfxFontconfigFontEntry* bestEntry = nullptr;
     double bestDist = -1.0;
     for (size_t i = 0; i < aFontEntryList.Length(); i++) {
         gfxFontconfigFontEntry* entry =
             static_cast<gfxFontconfigFontEntry*>(aFontEntryList[i]);
-        double dist = SizeDistance(entry, aFontStyle);
+        double dist = SizeDistance(entry, aFontStyle, mForceScalable);
         // If the entry is scalable or has a style that does not match
         // the group of unscalable fonts, then start a new group.
         if (dist < 0.0 ||
             !bestEntry ||
             bestEntry->Stretch() != entry->Stretch() ||
             bestEntry->Weight() != entry->Weight() ||
             bestEntry->mStyle != entry->mStyle) {
             // If the best entry in this group is still outside the tolerance,
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -190,17 +190,18 @@ protected:
     UnscaledFontCache mUnscaledFontCache;
 };
 
 class gfxFontconfigFontFamily : public gfxFontFamily {
 public:
     explicit gfxFontconfigFontFamily(const nsAString& aName) :
         gfxFontFamily(aName),
         mContainsAppFonts(false),
-        mHasNonScalableFaces(false)
+        mHasNonScalableFaces(false),
+        mForceScalable(false)
     { }
 
     void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) override;
 
     // Families are constructed initially with just references to patterns.
     // When necessary, these are enumerated within FindStyleVariations.
     void AddFontPattern(FcPattern* aFontPattern);
 
@@ -216,16 +217,17 @@ public:
 
 protected:
     virtual ~gfxFontconfigFontFamily();
 
     nsTArray<nsCountedRef<FcPattern> > mFontPatterns;
 
     bool      mContainsAppFonts;
     bool      mHasNonScalableFaces;
+    bool      mForceScalable;
 };
 
 class gfxFontconfigFont : public gfxFontconfigFontBase {
 public:
     gfxFontconfigFont(const RefPtr<mozilla::gfx::UnscaledFontFontconfig> &aUnscaledFont,
                       cairo_scaled_font_t *aScaledFont,
                       FcPattern *aPattern,
                       gfxFloat aAdjustedSize,