Bug 1495400 - don't draw non-scalable FT faces as paths. r=jnicol
authorLee Salzman <lsalzman@mozilla.com>
Fri, 22 Mar 2019 17:52:48 +0000
changeset 465753 d96ed1741bded4ad4902a3bfc1bc59a43ee5df91
parent 465752 25a055417a5ca6244bffd485e2ad058164969066
child 465754 8cefa694f81188548a52bce32825ecfbd7e3c3c6
push id35746
push usershindli@mozilla.com
push dateSat, 23 Mar 2019 09:46:24 +0000
treeherdermozilla-central@02b7484f316b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjnicol
bugs1495400
milestone68.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 1495400 - don't draw non-scalable FT faces as paths. r=jnicol Differential Revision: https://phabricator.services.mozilla.com/D24416
gfx/2d/ScaledFontFreeType.cpp
gfx/skia/skia/include/ports/SkTypeface_cairo.h
gfx/skia/skia/src/ports/SkFontHost_cairo.cpp
--- a/gfx/2d/ScaledFontFreeType.cpp
+++ b/gfx/2d/ScaledFontFreeType.cpp
@@ -28,17 +28,17 @@ ScaledFontFreeType::ScaledFontFreeType(
     cairo_scaled_font_t* aScaledFont, FT_Face aFace,
     const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize)
     : ScaledFontBase(aUnscaledFont, aSize), mFace(aFace) {
   SetCairoScaledFont(aScaledFont);
 }
 
 #ifdef USE_SKIA
 SkTypeface* ScaledFontFreeType::CreateSkTypeface() {
-  return SkCreateTypefaceFromCairoFTFont(mScaledFont);
+  return SkCreateTypefaceFromCairoFTFont(mScaledFont, mFace);
 }
 #endif
 
 bool ScaledFontFreeType::GetFontInstanceData(FontInstanceDataOutput aCb,
                                              void* aBaton) {
   std::vector<FontVariation> variations;
   if (HasVariationSettings()) {
     UnscaledFontFreeType::GetVariationSettingsFromFace(&variations, mFace);
--- a/gfx/skia/skia/include/ports/SkTypeface_cairo.h
+++ b/gfx/skia/skia/include/ports/SkTypeface_cairo.h
@@ -3,16 +3,16 @@
 
 #include <cairo.h>
 #include <cairo-ft.h>
 
 #include "SkTypeface.h"
 
 SK_API extern void SkInitCairoFT(bool fontHintingEnabled);
 
-SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont);
+SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont, FT_Face face = nullptr);
 
 #ifdef CAIRO_HAS_FC_FONT
-SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* scaledFont, FcPattern* pattern);
+SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* scaledFont, FcPattern* pattern, FT_Face face = nullptr);
 #endif
 
 #endif
 
--- a/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp
+++ b/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp
@@ -247,70 +247,92 @@ public:
         return 0;
     }
 
     virtual size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override
     {
         return 0;
     }
 
-    SkCairoFTTypeface(cairo_font_face_t* fontFace, FcPattern* pattern)
+    SkCairoFTTypeface(cairo_font_face_t* fontFace, FcPattern* pattern, FT_Face face)
         : SkTypeface(SkFontStyle::Normal())
         , fFontFace(fontFace)
         , fPattern(pattern)
+        , fFTFace(face)
     {
         cairo_font_face_reference(fFontFace);
 #ifdef CAIRO_HAS_FC_FONT
         if (fPattern) {
             FcPatternReference(fPattern);
         }
 #endif
     }
 
     cairo_font_face_t* GetCairoFontFace() const { return fFontFace; }
 
+    virtual bool hasColorGlyphs() const override
+    {
+        // Check if the font has scalable outlines, either using the FT_Face directly
+        // or the Fontconfig pattern, whichever is available. If not, then avoid trying
+        // to render it as a path.
+        if (fFTFace) {
+            return !FT_IS_SCALABLE(fFTFace);
+        }
+#ifdef CAIRO_HAS_FC_FONT
+        if (fPattern) {
+            FcBool outline;
+            if (FcPatternGetBool(fPattern, FC_OUTLINE, 0, &outline) != FcResultMatch ||
+                !outline) {
+                return true;
+            }
+        }
+#endif
+        return false;
+    }
+
    private:
     ~SkCairoFTTypeface()
     {
         cairo_font_face_destroy(fFontFace);
 #ifdef CAIRO_HAS_FC_FONT
         if (fPattern) {
             FcPatternDestroy(fPattern);
         }
 #endif
     }
 
     cairo_font_face_t* fFontFace;
     FcPattern* fPattern;
+    FT_Face    fFTFace;
 };
 
 static bool FindByCairoFontFace(SkTypeface* typeface, void* context) {
   return static_cast<SkCairoFTTypeface*>(typeface)->GetCairoFontFace() ==
          static_cast<cairo_font_face_t*>(context);
 }
 
-SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* scaledFont, FcPattern* pattern)
+SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* scaledFont, FcPattern* pattern, FT_Face face)
 {
     cairo_font_face_t* fontFace = cairo_scaled_font_get_font_face(scaledFont);
     SkASSERT(cairo_font_face_status(fontFace) == CAIRO_STATUS_SUCCESS);
     SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT);
 
     SkTypeface* typeface =
         SkTypefaceCache::FindByProcAndRef(FindByCairoFontFace, fontFace);
     if (!typeface) {
-      typeface = new SkCairoFTTypeface(fontFace, pattern);
+      typeface = new SkCairoFTTypeface(fontFace, pattern, face);
       SkTypefaceCache::Add(typeface);
     }
 
     return typeface;
 }
 
-SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont)
+SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont, FT_Face face)
 {
-    return SkCreateTypefaceFromCairoFTFontWithFontconfig(scaledFont, nullptr);
+    return SkCreateTypefaceFromCairoFTFontWithFontconfig(scaledFont, nullptr, face);
 }
 
 SkScalerContext_CairoFT::SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects, const SkDescriptor* desc,
                                                  cairo_font_face_t* fontFace, FcPattern* pattern)
     : SkScalerContext_FreeType_Base(std::move(typeface), effects, desc)
     , fLcdFilter(FT_LCD_FILTER_NONE)
 {
     SkMatrix matrix;