Bug 1287552 - part 4 - add ScaledFontFontconfig to remember generating FcPattern. r?jrmuizel draft
authorLee Salzman <lsalzman@mozilla.com>
Wed, 20 Jul 2016 15:07:11 -0400
changeset 390168 bb3a7806c48ca0f4529e8d010de743e11030def6
parent 390167 7e0dfa9f663a098ef2670c3d363a9b51c856aa96
child 525944 b32bb9af778f288f576fb6717990e963ff9ab990
push id23612
push userbmo:lsalzman@mozilla.com
push dateWed, 20 Jul 2016 19:07:40 +0000
reviewersjrmuizel
bugs1287552
milestone50.0a1
Bug 1287552 - part 4 - add ScaledFontFontconfig to remember generating FcPattern. r?jrmuizel MozReview-Commit-ID: AbWjvL5IWCN
gfx/2d/2D.h
gfx/2d/DrawTargetSkia.cpp
gfx/2d/Factory.cpp
gfx/2d/ScaledFontCairo.cpp
gfx/2d/ScaledFontCairo.h
gfx/2d/ScaledFontFontconfig.cpp
gfx/2d/ScaledFontFontconfig.h
gfx/2d/Types.h
gfx/2d/moz.build
gfx/thebes/gfxFT2Fonts.cpp
gfx/thebes/gfxFT2Fonts.h
gfx/thebes/gfxFcPlatformFontList.cpp
gfx/thebes/gfxFcPlatformFontList.h
gfx/thebes/gfxFont.h
gfx/thebes/gfxFontconfigFonts.cpp
gfx/thebes/gfxFontconfigUtils.cpp
gfx/thebes/gfxFontconfigUtils.h
gfx/thebes/gfxPlatformGtk.cpp
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -31,16 +31,19 @@
 #endif
 
 struct _cairo_surface;
 typedef _cairo_surface cairo_surface_t;
 
 struct _cairo_scaled_font;
 typedef _cairo_scaled_font cairo_scaled_font_t;
 
+struct _FcPattern;
+typedef _FcPattern FcPattern;
+
 struct ID3D11Texture2D;
 struct ID3D11Device;
 struct ID2D1Device;
 struct IDWriteRenderingParams;
 struct IDWriteFont;
 struct IDWriteFontFamily;
 struct IDWriteFontFace;
 
@@ -1291,16 +1294,21 @@ public:
     CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
 
   static already_AddRefed<DrawTarget>
     CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
 
   static already_AddRefed<ScaledFont>
     CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
 
+#ifdef MOZ_WIDGET_GTK
+  static already_AddRefed<ScaledFont>
+    CreateScaledFontForFontconfigFont(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern, Float aSize);
+#endif
+
   /**
    * This creates a NativeFontResource from TrueType data.
    *
    * @param aData Pointer to the data
    * @param aSize Size of the TrueType data
    * @param aType Type of NativeFontResource that should be created.
    * @return a NativeFontResource of nullptr if failed.
    */
@@ -1382,20 +1390,16 @@ public:
   static already_AddRefed<DrawTarget>
     CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
                                       const IntSize &aSize,
                                       SurfaceFormat aFormat);
 #endif
 
   static void PurgeAllCaches();
 
-#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
-  static already_AddRefed<GlyphRenderingOptions>
-    CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting, AntialiasMode aAntialiasMode = AntialiasMode::DEFAULT);
-#endif
   static already_AddRefed<DrawTarget>
     CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB);
 
   /*
    * This creates a new tiled DrawTarget. When a tiled drawtarget is used the
    * drawing is distributed over number of tiles which may each hold an
    * individual offset. The tiles in the set must each have the same backend
    * and format.
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -608,16 +608,17 @@ DrawTargetSkia::ShouldLCDRenderText(Font
     return false;
   }
 
   if (aAntialiasMode == AntialiasMode::DEFAULT) {
     switch (aFontType) {
       case FontType::MAC:
       case FontType::GDI:
       case FontType::DWRITE:
+      case FontType::FONTCONFIG:
         return true;
       default:
         // TODO: Figure out what to do for the other platforms.
         return false;
     }
   }
   return (aAntialiasMode == AntialiasMode::SUBPIXEL);
 }
@@ -998,20 +999,25 @@ ShouldUseCGToFillGlyphs(const GlyphRende
 
 void
 DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
                            const GlyphBuffer &aBuffer,
                            const Pattern &aPattern,
                            const DrawOptions &aOptions,
                            const GlyphRenderingOptions *aRenderingOptions)
 {
-  if (aFont->GetType() != FontType::MAC &&
-      aFont->GetType() != FontType::SKIA &&
-      aFont->GetType() != FontType::GDI &&
-      aFont->GetType() != FontType::DWRITE) {
+  switch (aFont->GetType()) {
+  case FontType::SKIA:
+  case FontType::CAIRO:
+  case FontType::FONTCONFIG:
+  case FontType::MAC:
+  case FontType::GDI:
+  case FontType::DWRITE:
+    break;
+  default:
     return;
   }
 
   MarkChanged();
 
 #ifdef MOZ_WIDGET_COCOA
   if (ShouldUseCGToFillGlyphs(aRenderingOptions, aPattern)) {
     if (FillGlyphsWithCG(aFont, aBuffer, aPattern, aOptions, aRenderingOptions)) {
@@ -1029,64 +1035,60 @@ DrawTargetSkia::FillGlyphs(ScaledFont *a
   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
   paint.mPaint.setTypeface(typeface);
   paint.mPaint.setTextSize(SkFloatToScalar(skiaFont->mSize));
   paint.mPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
 
   bool shouldLCDRenderText = ShouldLCDRenderText(aFont->GetType(), aOptions.mAntialiasMode);
   paint.mPaint.setLCDRenderText(shouldLCDRenderText);
 
-  if (aRenderingOptions && aRenderingOptions->GetType() == FontType::CAIRO) {
-    const GlyphRenderingOptionsCairo* cairoOptions =
-      static_cast<const GlyphRenderingOptionsCairo*>(aRenderingOptions);
-
-    paint.mPaint.setHinting(GfxHintingToSkiaHinting(cairoOptions->GetHinting()));
+  bool useSubpixelText = true;
 
-    if (cairoOptions->GetAutoHinting()) {
-      paint.mPaint.setAutohinted(true);
-    }
-
-    if (cairoOptions->GetAntialiasMode() == AntialiasMode::NONE) {
-      paint.mPaint.setAntiAlias(false);
-    }
-  } else {
+  switch (aFont->GetType()) {
+  case FontType::SKIA:
+  case FontType::CAIRO:
+  case FontType::FONTCONFIG:
     // SkFontHost_cairo does not support subpixel text positioning,
     // so only enable it for other font hosts.
-    paint.mPaint.setSubpixelText(true);
-
-    if (aFont->GetType() == FontType::MAC &&
-       aOptions.mAntialiasMode == AntialiasMode::GRAY) {
+    useSubpixelText = false;
+    break;
+  case FontType::MAC:
+    if (aOptions.mAntialiasMode == AntialiasMode::GRAY) {
       // Normally, Skia enables LCD FontSmoothing which creates thicker fonts
       // and also enables subpixel AA. CoreGraphics without font smoothing
       // explicitly creates thinner fonts and grayscale AA.
       // CoreGraphics doesn't support a configuration that produces thicker
       // fonts with grayscale AA as LCD Font Smoothing enables or disables both.
       // However, Skia supports it by enabling font smoothing (producing subpixel AA)
       // and converts it to grayscale AA. Since Skia doesn't support subpixel AA on
       // transparent backgrounds, we still want font smoothing for the thicker fonts,
       // even if it is grayscale AA.
       //
       // With explicit Grayscale AA (from -moz-osx-font-smoothing:grayscale),
       // we want to have grayscale AA with no smoothing at all. This means
       // disabling the LCD font smoothing behaviour.
       // To accomplish this we have to explicitly disable hinting,
       // and disable LCDRenderText.
       paint.mPaint.setHinting(SkPaint::kNo_Hinting);
-    } else {
-      paint.mPaint.setHinting(SkPaint::kNormal_Hinting);
     }
+    break;
+  case FontType::GDI:
+    if (!shouldLCDRenderText) {
+      // If we have non LCD GDI text, Cairo currently always uses cleartype fonts and
+      // converts them to grayscale. Force Skia to do the same, otherwise we use
+      // GDI fonts with the ANTIALIASED_QUALITY which is generally bolder than
+      // Cleartype fonts.
+      paint.mPaint.setFlags(paint.mPaint.getFlags() | SkPaint::kGenA8FromLCD_Flag);
+    }
+    break;
+  default:
+    break;
   }
 
-  if (!shouldLCDRenderText && aFont->GetType() == FontType::GDI) {
-    // If we have non LCD GDI text, Cairo currently always uses cleartype fonts and
-    // converts them to grayscale. Force Skia to do the same, otherwise we use
-    // GDI fonts with the ANTIALIASED_QUALITY which is generally bolder than
-    // Cleartype fonts.
-    paint.mPaint.setFlags(paint.mPaint.getFlags() | SkPaint::kGenA8FromLCD_Flag);
-  }
+  paint.mPaint.setSubpixelText(useSubpixelText);
 
   std::vector<uint16_t> indices;
   std::vector<SkPoint> offsets;
   indices.resize(aBuffer.mNumGlyphs);
   offsets.resize(aBuffer.mNumGlyphs);
 
   for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
     indices[i] = aBuffer.mGlyphs[i].mIndex;
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -24,16 +24,19 @@
 #include "ScaledFontWin.h"
 #include "NativeFontResourceGDI.h"
 #endif
 
 #ifdef XP_DARWIN
 #include "ScaledFontMac.h"
 #endif
 
+#ifdef MOZ_WIDGET_GTK
+#include "ScaledFontFontconfig.h"
+#endif
 
 #ifdef XP_DARWIN
 #include "DrawTargetCG.h"
 #endif
 
 #ifdef WIN32
 #include "DrawTargetD2D1.h"
 #include "ScaledFontDWrite.h"
@@ -570,16 +573,24 @@ Factory::CreateScaledFontWithCairo(const
   RefPtr<ScaledFont> font = CreateScaledFontForNativeFont(aNativeFont, aSize);
   static_cast<ScaledFontBase*>(font.get())->SetCairoScaledFont(aScaledFont);
   return font.forget();
 #else
   return nullptr;
 #endif
 }
 
+#ifdef MOZ_WIDGET_GTK
+already_AddRefed<ScaledFont>
+Factory::CreateScaledFontForFontconfigFont(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern, Float aSize)
+{
+  return MakeAndAddRef<ScaledFontFontconfig>(aScaledFont, aPattern, aSize);
+}
+#endif
+
 already_AddRefed<DrawTarget>
 Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB)
 {
   MOZ_ASSERT(targetA && targetB);
 
   RefPtr<DrawTarget> newTarget =
     new DrawTargetDual(targetA, targetB);
 
@@ -719,30 +730,16 @@ Factory::CreateDrawTargetSkiaWithGrConte
 
 #endif // USE_SKIA_GPU
 
 void
 Factory::PurgeAllCaches()
 {
 }
 
-#ifdef USE_SKIA_FREETYPE
-already_AddRefed<GlyphRenderingOptions>
-Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting, AntialiasMode aAntialiasMode)
-{
-  RefPtr<GlyphRenderingOptionsCairo> options =
-    new GlyphRenderingOptionsCairo();
-
-  options->SetHinting(aHinting);
-  options->SetAutoHinting(aAutoHinting);
-  options->SetAntialiasMode(aAntialiasMode);
-  return options.forget();
-}
-#endif
-
 already_AddRefed<DrawTarget>
 Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat)
 {
   RefPtr<DrawTarget> retVal;
 
 #ifdef USE_CAIRO
   RefPtr<DrawTargetCairo> newTarget = new DrawTargetCairo();
 
--- a/gfx/2d/ScaledFontCairo.cpp
+++ b/gfx/2d/ScaledFontCairo.cpp
@@ -1,33 +1,20 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ScaledFontCairo.h"
 #include "Logging.h"
 
-#ifdef MOZ_ENABLE_FREETYPE
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include "cairo-ft.h"
-#endif
-
 #if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
-#include "skia/include/core/SkTypeface.h"
 #include "skia/include/ports/SkTypeface_cairo.h"
 #endif
 
-#include <string>
-
-typedef struct FT_FaceRec_* FT_Face;
-
-using namespace std;
-
 namespace mozilla {
 namespace gfx {
 
 // On Linux and Android our "platform" font is a cairo_scaled_font_t and we use
 // an SkFontHost implementation that allows Skia to render using this.
 // This is mainly because FT_Face is not good for sharing between libraries, which
 // is a requirement when we consider runtime switchable backends and so on
 ScaledFontCairo::ScaledFontCairo(cairo_scaled_font_t* aScaledFont, Float aSize)
@@ -35,31 +22,17 @@ ScaledFontCairo::ScaledFontCairo(cairo_s
 { 
   SetCairoScaledFont(aScaledFont);
 }
 
 #if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
 SkTypeface* ScaledFontCairo::GetSkTypeface()
 {
   if (!mTypeface) {
-    cairo_font_face_t* fontFace = cairo_scaled_font_get_font_face(mScaledFont);
-    MOZ_ASSERT(cairo_font_face_status(fontFace) == CAIRO_STATUS_SUCCESS);
-
-    FT_Face face = cairo_ft_scaled_font_lock_face(mScaledFont);
-
-    SkFontStyle style(face->style_flags & FT_STYLE_FLAG_BOLD ?
-                        SkFontStyle::kBold_Weight : SkFontStyle::kNormal_Weight,
-                      SkFontStyle::kNormal_Width,
-                      face->style_flags & FT_STYLE_FLAG_ITALIC ?
-                        SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant);
-
-    bool isFixedWidth = face->face_flags & FT_FACE_FLAG_FIXED_WIDTH;
-    cairo_ft_scaled_font_unlock_face(mScaledFont);
-
-    mTypeface = SkCreateTypefaceFromCairoFont(fontFace, style, isFixedWidth);
+    mTypeface = SkCreateTypefaceFromCairoFTFont(mScaledFont);
   }
 
   return mTypeface;
 }
 #endif
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/ScaledFontCairo.h
+++ b/gfx/2d/ScaledFontCairo.h
@@ -20,41 +20,12 @@ public:
 
   ScaledFontCairo(cairo_scaled_font_t* aScaledFont, Float aSize);
 
 #if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
   virtual SkTypeface* GetSkTypeface();
 #endif
 };
 
-// We need to be able to tell Skia whether or not to use
-// hinting when rendering text, so that the glyphs it renders
-// are the same as what layout is expecting. At the moment, only
-// Skia uses this class when rendering with FreeType, as gfxFT2Font
-// is the only gfxFont that honours gfxPlatform::FontHintingEnabled().
-class GlyphRenderingOptionsCairo : public GlyphRenderingOptions
-{
-public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsCairo)
-  GlyphRenderingOptionsCairo()
-    : mHinting(FontHinting::NORMAL)
-    , mAutoHinting(false)
-    , mAntialiasMode(AntialiasMode::DEFAULT)
-  {
-  }
-
-  void SetHinting(FontHinting aHinting) { mHinting = aHinting; }
-  void SetAutoHinting(bool aAutoHinting) { mAutoHinting = aAutoHinting; }
-  FontHinting GetHinting() const { return mHinting; }
-  bool GetAutoHinting() const { return mAutoHinting; }
-  void SetAntialiasMode(AntialiasMode aAntialiasMode) { mAntialiasMode = aAntialiasMode; }
-  virtual AntialiasMode GetAntialiasMode() const { return mAntialiasMode; }
-  virtual FontType GetType() const { return FontType::CAIRO; }
-private:
-  FontHinting mHinting;
-  bool mAutoHinting;
-  AntialiasMode mAntialiasMode;
-};
-
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_SCALEDFONTCAIRO_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontFontconfig.cpp
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ScaledFontFontconfig.h"
+#include "Logging.h"
+
+#ifdef USE_SKIA
+#include "skia/include/ports/SkTypeface_cairo.h"
+#endif
+
+namespace mozilla {
+namespace gfx {
+
+// On Linux and Android our "platform" font is a cairo_scaled_font_t and we use
+// an SkFontHost implementation that allows Skia to render using this.
+// This is mainly because FT_Face is not good for sharing between libraries, which
+// is a requirement when we consider runtime switchable backends and so on
+ScaledFontFontconfig::ScaledFontFontconfig(cairo_scaled_font_t* aScaledFont,
+                                           FcPattern* aPattern,
+                                           Float aSize)
+  : ScaledFontBase(aSize),
+    mPattern(aPattern)
+{
+  SetCairoScaledFont(aScaledFont);
+  FcPatternReference(aPattern);
+}
+
+ScaledFontFontconfig::~ScaledFontFontconfig()
+{
+  FcPatternDestroy(mPattern);
+}
+
+#ifdef USE_SKIA
+SkTypeface* ScaledFontFontconfig::GetSkTypeface()
+{
+  if (!mTypeface) {
+    mTypeface = SkCreateTypefaceFromCairoFTFontWithFontconfig(mScaledFont, mPattern);
+  }
+
+  return mTypeface;
+}
+#endif
+
+} // namespace gfx
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontFontconfig.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_GFX_SCALEDFONTFONTCONFIG_H_
+#define MOZILLA_GFX_SCALEDFONTFONTCONFIG_H_
+
+#include "ScaledFontBase.h"
+
+#include <fontconfig/fontconfig.h>
+#include <cairo.h>
+
+namespace mozilla {
+namespace gfx {
+
+class ScaledFontFontconfig : public ScaledFontBase
+{
+public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontFontconfig)
+  ScaledFontFontconfig(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern, Float aSize);
+  ~ScaledFontFontconfig();
+
+  virtual FontType GetType() const { return FontType::FONTCONFIG; }
+
+#ifdef USE_SKIA
+  virtual SkTypeface* GetSkTypeface();
+#endif
+
+private:
+  FcPattern* mPattern;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_SCALEDFONTFONTCONFIG_H_ */
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -141,17 +141,18 @@ enum class BackendType : int8_t {
 };
 
 enum class FontType : int8_t {
   DWRITE,
   GDI,
   MAC,
   SKIA,
   CAIRO,
-  COREGRAPHICS
+  COREGRAPHICS,
+  FONTCONFIG
 };
 
 enum class NativeSurfaceType : int8_t {
   D3D10_TEXTURE,
   CAIRO_CONTEXT,
   CGCONTEXT,
   CGCONTEXT_ACCELERATED,
   OPENGL_TEXTURE
--- a/gfx/2d/moz.build
+++ b/gfx/2d/moz.build
@@ -83,16 +83,21 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wi
     ]
     DEFINES['WIN32'] = True
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'windows':
     SOURCES += [
         'JobScheduler_posix.cpp',
     ]
 
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):
+    SOURCES += [
+        'ScaledFontFontconfig.cpp',
+    ]
+
 if CONFIG['MOZ_ENABLE_SKIA']:
     UNIFIED_SOURCES += [
         'convolver.cpp',
     ]
     SOURCES += [
         'DrawTargetSkia.cpp',
         'image_operations.cpp', # Uses _USE_MATH_DEFINES
         'PathSkia.cpp',
--- a/gfx/thebes/gfxFT2Fonts.cpp
+++ b/gfx/thebes/gfxFT2Fonts.cpp
@@ -220,25 +220,8 @@ gfxFT2Font::AddSizeOfExcludingThis(mozil
 void
 gfxFT2Font::AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                                    FontCacheSizes* aSizes) const
 {
     aSizes->mFontInstances += aMallocSizeOf(this);
     AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
 }
 
-#ifdef USE_SKIA
-already_AddRefed<mozilla::gfx::GlyphRenderingOptions>
-gfxFT2Font::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams)
-{
-  mozilla::gfx::FontHinting hinting;
-
-  if (gfxPlatform::GetPlatform()->FontHintingEnabled()) {
-    hinting = mozilla::gfx::FontHinting::NORMAL;
-  } else {
-    hinting = mozilla::gfx::FontHinting::NONE;
-  }
-
-  // We don't want to force the use of the autohinter over the font's built in hints
-  return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false);
-}
-#endif
-
--- a/gfx/thebes/gfxFT2Fonts.h
+++ b/gfx/thebes/gfxFT2Fonts.h
@@ -54,21 +54,16 @@ public: // new functions
         return &entry->mData;
     }
 
     virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                                         FontCacheSizes* aSizes) const override;
     virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                                         FontCacheSizes* aSizes) const override;
 
-#ifdef USE_SKIA
-    virtual already_AddRefed<mozilla::gfx::GlyphRenderingOptions>
-        GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) override;
-#endif
-
 protected:
     virtual bool ShapeText(DrawTarget      *aDrawTarget,
                            const char16_t *aText,
                            uint32_t         aOffset,
                            uint32_t         aLength,
                            Script           aScript,
                            bool             aVertical,
                            gfxShapedText   *aShapedText) override;
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -756,26 +756,20 @@ gfxFontconfigFontEntry::CreateFontInstan
 {
     nsAutoRef<FcPattern> pattern(FcPatternCreate());
     FcPatternAddDouble(pattern, FC_PIXEL_SIZE, aFontStyle->size);
 
     PreparePattern(pattern, aFontStyle->printerFont);
     nsAutoRef<FcPattern> renderPattern
         (FcFontRenderPrepare(nullptr, pattern, mFontPattern));
 
-    FcBool autohint;
-    if (FcPatternGetBool(renderPattern, FC_AUTOHINT, 0, &autohint) != FcResultMatch) {
-      autohint = FcFalse;
-    }
-
     cairo_scaled_font_t* scaledFont =
         CreateScaledFont(renderPattern, aFontStyle, aNeedsBold);
     gfxFont* newFont =
-        new gfxFontconfigFont(scaledFont, this, aFontStyle, aNeedsBold,
-                              bool(autohint));
+        new gfxFontconfigFont(scaledFont, renderPattern, this, aFontStyle, aNeedsBold);
     cairo_scaled_font_destroy(scaledFont);
 
     return newFont;
 }
 
 nsresult
 gfxFontconfigFontEntry::CopyFontTable(uint32_t aTableTag,
                                       nsTArray<uint8_t>& aBuffer)
@@ -877,53 +871,28 @@ gfxFontconfigFontFamily::AddFontPattern(
     NS_ASSERTION(!mHasStyles,
                  "font patterns must not be added to already enumerated families");
 
     nsCountedRef<FcPattern> pattern(aFontPattern);
     mFontPatterns.AppendElement(pattern);
 }
 
 gfxFontconfigFont::gfxFontconfigFont(cairo_scaled_font_t *aScaledFont,
+                                     FcPattern *aPattern,
                                      gfxFontEntry *aFontEntry,
                                      const gfxFontStyle *aFontStyle,
-                                     bool aNeedsBold,
-                                     bool aAutoHinting) :
-    gfxFT2FontBase(aScaledFont, aFontEntry, aFontStyle),
-    mAutoHinting(aAutoHinting)
+                                     bool aNeedsBold) :
+    gfxFontconfigFontBase(aScaledFont, aPattern, aFontEntry, aFontStyle)
 {
 }
 
 gfxFontconfigFont::~gfxFontconfigFont()
 {
 }
 
-#ifdef USE_SKIA
-already_AddRefed<mozilla::gfx::GlyphRenderingOptions>
-gfxFontconfigFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams)
-{
-  cairo_scaled_font_t *scaled_font = CairoScaledFont();
-  cairo_font_options_t *options = cairo_font_options_create();
-  cairo_scaled_font_get_font_options(scaled_font, options);
-  cairo_hint_style_t hint_style = cairo_font_options_get_hint_style(options);
-  cairo_antialias_t antialias = cairo_font_options_get_antialias(options);
-  cairo_font_options_destroy(options);
-
-  mozilla::gfx::FontHinting hinting =
-    mozilla::gfx::CairoHintingToGfxHinting(hint_style);
-
-  mozilla::gfx::AntialiasMode aaMode =
-    mozilla::gfx::CairoAntialiasToGfxAntialias(antialias);
-
-  bool autohint = GetAutoHinting();
-
-  // The fontconfig AA mode must be passed along because it may override the hinting style.
-  return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, autohint, aaMode);
-}
-#endif
-
 gfxFcPlatformFontList::gfxFcPlatformFontList()
     : mLocalNames(64)
     , mGenericMappings(32)
     , mFcSubstituteCache(64)
     , mLastConfig(nullptr)
     , mAlwaysUseFontconfigGenerics(true)
 {
     // if the rescan interval is set, start the timer
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -190,36 +190,26 @@ public:
 protected:
     virtual ~gfxFontconfigFontFamily() { }
 
     nsTArray<nsCountedRef<FcPattern> > mFontPatterns;
 
     bool      mContainsAppFonts;
 };
 
-class gfxFontconfigFont : public gfxFT2FontBase {
+class gfxFontconfigFont : public gfxFontconfigFontBase {
 public:
     gfxFontconfigFont(cairo_scaled_font_t *aScaledFont,
+                      FcPattern *aPattern,
                       gfxFontEntry *aFontEntry,
                       const gfxFontStyle *aFontStyle,
-                      bool aNeedsBold,
-                      bool aAutoHinting = false);
-
-    bool GetAutoHinting() const { return mAutoHinting; }
-
-#ifdef USE_SKIA
-    virtual already_AddRefed<mozilla::gfx::GlyphRenderingOptions>
-    GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) override;
-#endif
+                      bool aNeedsBold);
 
 protected:
     virtual ~gfxFontconfigFont();
-
-private:
-    bool mAutoHinting;
 };
 
 class nsILanguageAtomService;
 
 class gfxFcPlatformFontList : public gfxPlatformFontList {
 public:
     gfxFcPlatformFontList();
 
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -1788,17 +1788,18 @@ public:
                                         FontCacheSizes* aSizes) const;
 
     typedef enum {
         FONT_TYPE_DWRITE,
         FONT_TYPE_GDI,
         FONT_TYPE_FT2,
         FONT_TYPE_MAC,
         FONT_TYPE_OS2,
-        FONT_TYPE_CAIRO
+        FONT_TYPE_CAIRO,
+        FONT_TYPE_FONTCONFIG
     } FontType;
 
     virtual FontType GetType() const = 0;
 
     virtual already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(DrawTarget* aTarget)
     { return gfxPlatform::GetPlatform()->GetScaledFontForFont(aTarget, this); }
 
     bool KerningDisabled() {
--- a/gfx/thebes/gfxFontconfigFonts.cpp
+++ b/gfx/thebes/gfxFontconfigFonts.cpp
@@ -657,39 +657,36 @@ gfxDownloadedFcFontEntry::GetFontTable(u
 
 /*
  * gfxFcFont
  *
  * This is a gfxFont implementation using a CAIRO_FONT_TYPE_FT
  * cairo_scaled_font created from an FcPattern.
  */
 
-class gfxFcFont : public gfxFT2FontBase {
+class gfxFcFont : public gfxFontconfigFontBase {
 public:
     virtual ~gfxFcFont();
     static already_AddRefed<gfxFcFont>
     GetOrMakeFont(FcPattern *aRequestedPattern, FcPattern *aFontPattern,
                   const gfxFontStyle *aFontStyle);
 
-#ifdef USE_SKIA
-    virtual already_AddRefed<mozilla::gfx::GlyphRenderingOptions>
-        GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) override;
-#endif
-
     // return a cloned font resized and offset to simulate sub/superscript glyphs
     virtual already_AddRefed<gfxFont>
     GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel) override;
 
 protected:
     virtual already_AddRefed<gfxFont> MakeScaledFont(gfxFontStyle *aFontStyle,
                                                      gfxFloat aFontScale);
     virtual already_AddRefed<gfxFont> GetSmallCapsFont() override;
 
 private:
-    gfxFcFont(cairo_scaled_font_t *aCairoFont, gfxFcFontEntry *aFontEntry,
+    gfxFcFont(cairo_scaled_font_t *aCairoFont,
+              FcPattern *aPattern,
+              gfxFcFontEntry *aFontEntry,
               const gfxFontStyle *aFontStyle);
 
     // key for locating a gfxFcFont corresponding to a cairo_scaled_font
     static cairo_user_data_key_t sGfxFontKey;
 };
 
 /**
  * gfxFcFontSet:
@@ -1658,19 +1655,20 @@ gfxPangoFontGroup::FindFontForChar(uint3
 
 /**
  ** gfxFcFont
  **/
 
 cairo_user_data_key_t gfxFcFont::sGfxFontKey;
 
 gfxFcFont::gfxFcFont(cairo_scaled_font_t *aCairoFont,
+                     FcPattern *aPattern,
                      gfxFcFontEntry *aFontEntry,
                      const gfxFontStyle *aFontStyle)
-    : gfxFT2FontBase(aCairoFont, aFontEntry, aFontStyle)
+    : gfxFontconfigFontBase(aCairoFont, aPattern, aFontEntry, aFontStyle)
 {
     cairo_scaled_font_set_user_data(mScaledFont, &sGfxFontKey, this, nullptr);
 }
 
 gfxFcFont::~gfxFcFont()
 {
     cairo_scaled_font_set_user_data(mScaledFont,
                                     &sGfxFontKey,
@@ -1705,17 +1703,17 @@ gfxFcFont::MakeScaledFont(gfxFontStyle *
     cairo_font_options_t *options = cairo_font_options_create();
     cairo_scaled_font_get_font_options(mScaledFont, options);
 
     cairo_scaled_font_t *newFont =
         cairo_scaled_font_create(cairo_scaled_font_get_font_face(mScaledFont),
                                  &fontMatrix, &ctm, options);
     cairo_font_options_destroy(options);
 
-    font = new gfxFcFont(newFont, fe, aFontStyle);
+    font = new gfxFcFont(newFont, GetPattern(), fe, aFontStyle);
     gfxFontCache::GetCache()->AddNew(font);
     cairo_scaled_font_destroy(newFont);
 
     return font.forget();
 }
 
 already_AddRefed<gfxFont>
 gfxFcFont::GetSmallCapsFont()
@@ -1955,17 +1953,17 @@ gfxFcFont::GetOrMakeFont(FcPattern *aReq
         // Note that a file/index pair (or FT_Face) and the gfxFontStyle are
         // not necessarily enough to provide a key that will describe a unique
         // font.  cairoFont contains information from renderPattern, which is a
         // fully resolved pattern from FcFontRenderPrepare.
         // FcFontRenderPrepare takes the requested pattern and the face
         // pattern as input and can modify elements of the resulting pattern
         // that affect rendering but are not included in the gfxFontStyle.
         cairo_scaled_font_t *cairoFont = CreateScaledFont(renderPattern, face);
-        font = new gfxFcFont(cairoFont, fe, &style);
+        font = new gfxFcFont(cairoFont, renderPattern, fe, &style);
         gfxFontCache::GetCache()->AddNew(font);
         cairo_scaled_font_destroy(cairoFont);
     }
 
     cairo_font_face_destroy(face);
 
     RefPtr<gfxFcFont> retval(static_cast<gfxFcFont*>(font.get()));
     return retval.forget();
@@ -2256,30 +2254,8 @@ ApplyGdkScreenFontOptions(FcPattern *aPa
     const cairo_font_options_t *options =
         gdk_screen_get_font_options(gdk_screen_get_default());
 
     cairo_ft_font_options_substitute(options, aPattern);
 }
 
 #endif // MOZ_WIDGET_GTK
 
-#ifdef USE_SKIA
-already_AddRefed<mozilla::gfx::GlyphRenderingOptions>
-gfxFcFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams)
-{
-  cairo_scaled_font_t *scaled_font = CairoScaledFont();
-  cairo_font_options_t *options = cairo_font_options_create();
-  cairo_scaled_font_get_font_options(scaled_font, options);
-  cairo_hint_style_t hint_style = cairo_font_options_get_hint_style(options);     
-  cairo_antialias_t antialias = cairo_font_options_get_antialias(options);
-  cairo_font_options_destroy(options);
-
-  mozilla::gfx::FontHinting hinting =
-    mozilla::gfx::CairoHintingToGfxHinting(hint_style);
-
-  mozilla::gfx::AntialiasMode aaMode =
-    mozilla::gfx::CairoAntialiasToGfxAntialias(antialias);
-
-  // We don't want to force the use of the autohinter over the font's built in hints
-  // The fontconfig AA mode must be passed along because it may override the hinting style.
-  return mozilla::gfx::Factory::CreateCairoGlyphRenderingOptions(hinting, false, aaMode);
-}
-#endif
--- a/gfx/thebes/gfxFontconfigUtils.cpp
+++ b/gfx/thebes/gfxFontconfigUtils.cpp
@@ -1082,9 +1082,18 @@ gfxFontconfigUtils::ActivateBundledFonts
             return;
         }
     }
     if (!mBundledFontsPath.IsEmpty()) {
         FcConfigAppFontAddDir(nullptr, (const FcChar8*)mBundledFontsPath.get());
     }
 }
 
+gfxFontconfigFontBase::gfxFontconfigFontBase(cairo_scaled_font_t *aScaledFont,
+                                             FcPattern *aPattern,
+                                             gfxFontEntry *aFontEntry,
+                                             const gfxFontStyle *aFontStyle)
+    : gfxFT2FontBase(aScaledFont, aFontEntry, aFontStyle)
+    , mPattern(aPattern)
+{
+}
+
 #endif
--- a/gfx/thebes/gfxFontconfigUtils.h
+++ b/gfx/thebes/gfxFontconfigUtils.h
@@ -8,16 +8,17 @@
 
 #include "gfxPlatform.h"
 
 #include "mozilla/MathAlgorithms.h"
 #include "nsAutoRef.h"
 #include "nsTArray.h"
 #include "nsTHashtable.h"
 #include "nsISupportsImpl.h"
+#include "gfxFT2FontBase.h"
 
 #include <fontconfig/fontconfig.h>
 
 
 template <>
 class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern>
 {
 public:
@@ -307,9 +308,23 @@ protected:
 #ifdef MOZ_BUNDLED_FONTS
     void      ActivateBundledFonts();
 
     nsCString mBundledFontsPath;
     bool      mBundledFontsInitialized;
 #endif
 };
 
+class gfxFontconfigFontBase : public gfxFT2FontBase {
+public:
+    gfxFontconfigFontBase(cairo_scaled_font_t *aScaledFont,
+                          FcPattern *aPattern,
+                          gfxFontEntry *aFontEntry,
+                          const gfxFontStyle *aFontStyle);
+
+    virtual FontType GetType() const override { return FONT_TYPE_FONTCONFIG; }
+    virtual FcPattern *GetPattern() const { return mPattern; }
+
+private:
+    nsCountedRef<FcPattern> mPattern;
+};
+
 #endif /* GFX_FONTCONFIG_UTILS_H */
--- a/gfx/thebes/gfxPlatformGtk.cpp
+++ b/gfx/thebes/gfxPlatformGtk.cpp
@@ -620,17 +620,30 @@ gfxPlatformGtk::GetGdkDrawable(cairo_sur
 
     return nullptr;
 }
 #endif
 
 already_AddRefed<ScaledFont>
 gfxPlatformGtk::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
 {
-    return GetScaledFontForFontWithCairoSkia(aTarget, aFont);
+    switch (aTarget->GetBackendType()) {
+    case BackendType::CAIRO:
+    case BackendType::SKIA:
+        if (aFont->GetType() == gfxFont::FONT_TYPE_FONTCONFIG) {
+            gfxFontconfigFontBase* fcFont = static_cast<gfxFontconfigFontBase*>(aFont);
+            return Factory::CreateScaledFontForFontconfigFont(
+                    fcFont->GetCairoScaledFont(),
+                    fcFont->GetPattern(),
+                    fcFont->GetAdjustedSize());
+        }
+        MOZ_FALLTHROUGH;
+    default:
+        return GetScaledFontForFontWithCairoSkia(aTarget, aFont);
+    }
 }
 
 #ifdef GL_PROVIDER_GLX
 
 class GLXVsyncSource final : public VsyncSource
 {
 public:
   GLXVsyncSource()