Bug 1611467 - unify UnscaledFont::GetFontDescriptor and GetWRFontDescriptor implementations. r=jrmuizel
authorLee Salzman <lsalzman@mozilla.com>
Thu, 26 Mar 2020 16:11:00 +0000
changeset 520598 5f5128e544848156d7a6bc5aa826a60b470dd604
parent 520597 29024ee1f5a79192d0495789e658687d2b7a19fe
child 520599 7b36a0458e5005380fc53ca1f53978009cd609b9
push id37253
push usernerli@mozilla.com
push dateThu, 26 Mar 2020 21:36:52 +0000
treeherdermozilla-central@c644dd16e2cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1611467
milestone76.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 1611467 - unify UnscaledFont::GetFontDescriptor and GetWRFontDescriptor implementations. r=jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D68284
gfx/2d/2D.h
gfx/2d/Factory.cpp
gfx/2d/ScaledFontDWrite.cpp
gfx/2d/ScaledFontFreeType.cpp
gfx/2d/ScaledFontMac.cpp
gfx/2d/UnscaledFontDWrite.h
gfx/2d/UnscaledFontFreeType.cpp
gfx/2d/UnscaledFontFreeType.h
gfx/2d/UnscaledFontMac.h
gfx/layers/wr/WebRenderBridgeChild.cpp
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -897,29 +897,23 @@ class UnscaledFont : public SupportsThre
   virtual ~UnscaledFont();
 
   virtual FontType GetType() const = 0;
 
   static uint32_t DeletionCounter() { return sDeletionCounter; }
 
   typedef void (*FontFileDataOutput)(const uint8_t* aData, uint32_t aLength,
                                      uint32_t aIndex, void* aBaton);
-  typedef void (*WRFontDescriptorOutput)(const uint8_t* aData, uint32_t aLength,
-                                         uint32_t aIndex, void* aBaton);
   typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength,
                                          void* aBaton);
   typedef void (*FontDescriptorOutput)(const uint8_t* aData, uint32_t aLength,
                                        uint32_t aIndex, void* aBaton);
 
   virtual bool GetFontFileData(FontFileDataOutput, void*) { return false; }
 
-  virtual bool GetWRFontDescriptor(WRFontDescriptorOutput, void*) {
-    return false;
-  }
-
   virtual bool GetFontInstanceData(FontInstanceDataOutput, void*) {
     return false;
   }
 
   virtual bool GetFontDescriptor(FontDescriptorOutput, void*) { return false; }
 
   virtual already_AddRefed<ScaledFont> CreateScaledFont(
       Float aGlyphSize, const uint8_t* aInstanceData,
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -21,33 +21,36 @@
 #  include "ScaledFontWin.h"
 #  include "NativeFontResourceGDI.h"
 #  include "UnscaledFontGDI.h"
 #endif
 
 #ifdef XP_DARWIN
 #  include "ScaledFontMac.h"
 #  include "NativeFontResourceMac.h"
+#  include "UnscaledFontMac.h"
 #endif
 
 #ifdef MOZ_WIDGET_GTK
 #  include "ScaledFontFontconfig.h"
 #  include "NativeFontResourceFreeType.h"
 #  include "UnscaledFontFreeType.h"
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 #  include "ScaledFontFreeType.h"
 #  include "NativeFontResourceFreeType.h"
+#  include "UnscaledFontFreeType.h"
 #endif
 
 #ifdef WIN32
 #  include "DrawTargetD2D1.h"
 #  include "ScaledFontDWrite.h"
 #  include "NativeFontResourceDWrite.h"
+#  include "UnscaledFontDWrite.h"
 #  include <d3d10_1.h>
 #  include <stdlib.h>
 #  include "HelpersD2D.h"
 #  include "DXVA2Manager.h"
 #  include "mozilla/layers/TextureD3D11.h"
 #endif
 
 #include "DrawTargetCapture.h"
@@ -590,24 +593,34 @@ already_AddRefed<NativeFontResource> Fac
   }
 }
 
 already_AddRefed<UnscaledFont> Factory::CreateUnscaledFontFromFontDescriptor(
     FontType aType, const uint8_t* aData, uint32_t aDataLength,
     uint32_t aIndex) {
   switch (aType) {
 #ifdef WIN32
+    case FontType::DWRITE:
+      return UnscaledFontDWrite::CreateFromFontDescriptor(aData, aDataLength,
+                                                          aIndex);
     case FontType::GDI:
       return UnscaledFontGDI::CreateFromFontDescriptor(aData, aDataLength,
                                                        aIndex);
-#endif
-#ifdef MOZ_WIDGET_GTK
+#elif defined(XP_DARWIN)
+    case FontType::MAC:
+      return UnscaledFontMac::CreateFromFontDescriptor(aData, aDataLength,
+                                                       aIndex);
+#elif defined(MOZ_WIDGET_GTK)
     case FontType::FONTCONFIG:
       return UnscaledFontFontconfig::CreateFromFontDescriptor(
           aData, aDataLength, aIndex);
+#elif defined(MOZ_WIDGET_ANDROID)
+    case FontType::FREETYPE:
+      return UnscaledFontFreeType::CreateFromFontDescriptor(aData, aDataLength,
+                                                            aIndex);
 #endif
     default:
       gfxWarning() << "Invalid type specified for UnscaledFont font descriptor";
       return nullptr;
   }
 }
 
 #ifdef XP_DARWIN
--- a/gfx/2d/ScaledFontDWrite.cpp
+++ b/gfx/2d/ScaledFontDWrite.cpp
@@ -376,18 +376,18 @@ static bool GetFontFileName(RefPtr<IDWri
   if (attribs == INVALID_FILE_ATTRIBUTES) {
     gfxDebug() << "Invalid file \"" << aFileName.data() << "\" for WR font";
     return false;
   }
   aFileName.pop_back();
   return true;
 }
 
-bool UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
-                                             void* aBaton) {
+bool UnscaledFontDWrite::GetFontDescriptor(FontDescriptorOutput aCb,
+                                           void* aBaton) {
   if (!mFont) {
     return false;
   }
 
   std::vector<WCHAR> fileName;
   if (!GetFontFileName(mFontFace, fileName)) {
     return false;
   }
@@ -705,10 +705,47 @@ cairo_font_face_t* ScaledFontDWrite::Cre
 
 void ScaledFontDWrite::PrepareCairoScaledFont(cairo_scaled_font_t* aFont) {
   if (mRenderingMode == DWRITE_RENDERING_MODE_GDI_CLASSIC) {
     cairo_dwrite_scaled_font_set_force_GDI_classic(aFont, true);
   }
 }
 #endif
 
+already_AddRefed<UnscaledFont> UnscaledFontDWrite::CreateFromFontDescriptor(
+    const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex) {
+  if (aDataLength == 0) {
+    gfxWarning() << "DWrite font descriptor is truncated.";
+    return nullptr;
+  }
+
+  RefPtr<IDWriteFactory> factory = Factory::GetDWriteFactory();
+  if (!factory) {
+    return nullptr;
+  }
+  RefPtr<IDWriteFontFile> fontFile;
+  HRESULT hr = factory->CreateFontFileReference((const WCHAR*)aData, nullptr,
+                                                getter_AddRefs(fontFile));
+  if (FAILED(hr)) {
+    return nullptr;
+  }
+  BOOL isSupported;
+  DWRITE_FONT_FILE_TYPE fileType;
+  DWRITE_FONT_FACE_TYPE faceType;
+  UINT32 numFaces;
+  hr = fontFile->Analyze(&isSupported, &fileType, &faceType, &numFaces);
+  if (FAILED(hr) || !isSupported || aIndex >= numFaces) {
+    return nullptr;
+  }
+  IDWriteFontFile* fontFiles[1] = {fontFile.get()};
+  RefPtr<IDWriteFontFace> fontFace;
+  hr = factory->CreateFontFace(faceType, 1, fontFiles, aIndex,
+                               DWRITE_FONT_SIMULATIONS_NONE,
+                               getter_AddRefs(fontFace));
+  if (FAILED(hr)) {
+    return nullptr;
+  }
+  RefPtr<UnscaledFont> unscaledFont = new UnscaledFontDWrite(fontFace, nullptr);
+  return unscaledFont.forget();
+}
+
 }  // namespace gfx
 }  // namespace mozilla
--- a/gfx/2d/ScaledFontFreeType.cpp
+++ b/gfx/2d/ScaledFontFreeType.cpp
@@ -176,10 +176,22 @@ already_AddRefed<ScaledFont> UnscaledFon
 bool ScaledFontFreeType::HasVariationSettings() {
   // Check if the FT face has been cloned.
   return mFace &&
          mFace->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS &&
          mFace !=
              static_cast<UnscaledFontFreeType*>(mUnscaledFont.get())->GetFace();
 }
 
+already_AddRefed<UnscaledFont> UnscaledFontFreeType::CreateFromFontDescriptor(
+    const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex) {
+  if (aDataLength == 0) {
+    gfxWarning() << "FreeType font descriptor is truncated.";
+    return nullptr;
+  }
+  const char* path = reinterpret_cast<const char*>(aData);
+  RefPtr<UnscaledFont> unscaledFont =
+      new UnscaledFontFreeType(std::string(path, aDataLength), aIndex);
+  return unscaledFont.forget();
+}
+
 }  // namespace gfx
 }  // namespace mozilla
--- a/gfx/2d/ScaledFontMac.cpp
+++ b/gfx/2d/ScaledFontMac.cpp
@@ -369,18 +369,18 @@ bool UnscaledFontMac::GetFontFileData(Fo
          sizeof(fontChecksum));
 
   // we always use an index of 0
   aDataCallback(buf.data, buf.offset, 0, aBaton);
 
   return true;
 }
 
-bool UnscaledFontMac::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
-                                          void* aBaton) {
+bool UnscaledFontMac::GetFontDescriptor(FontDescriptorOutput aCb,
+                                        void* aBaton) {
   if (mIsDataFont) {
     return false;
   }
 
   CFStringRef psname = CGFontCopyPostScriptName(mFont);
   if (!psname) {
     return false;
   }
@@ -649,10 +649,32 @@ already_AddRefed<ScaledFont> UnscaledFon
 #ifdef USE_CAIRO_SCALED_FONT
 cairo_font_face_t* ScaledFontMac::CreateCairoFontFace(
     cairo_font_options_t* aFontOptions) {
   MOZ_ASSERT(mFont);
   return cairo_quartz_font_face_create_for_cgfont(mFont);
 }
 #endif
 
+already_AddRefed<UnscaledFont> UnscaledFontMac::CreateFromFontDescriptor(
+    const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex) {
+  if (aDataLength == 0) {
+    gfxWarning() << "Mac font descriptor is truncated.";
+    return nullptr;
+  }
+  CFStringRef name =
+      CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)aData,
+                              aDataLength, kCFStringEncodingUTF8, false);
+  if (!name) {
+    return nullptr;
+  }
+  CGFontRef font = CGFontCreateWithFontName(name);
+  CFRelease(name);
+  if (!font) {
+    return nullptr;
+  }
+  RefPtr<UnscaledFont> unscaledFont = new UnscaledFontMac(font);
+  CFRelease(font);
+  return unscaledFont.forget();
+}
+
 }  // namespace gfx
 }  // namespace mozilla
--- a/gfx/2d/UnscaledFontDWrite.h
+++ b/gfx/2d/UnscaledFontDWrite.h
@@ -35,17 +35,20 @@ class UnscaledFontDWrite final : public 
       uint32_t aInstanceDataLength, const FontVariation* aVariations,
       uint32_t aNumVariations) override;
 
   already_AddRefed<ScaledFont> CreateScaledFontFromWRFont(
       Float aGlyphSize, const wr::FontInstanceOptions* aOptions,
       const wr::FontInstancePlatformOptions* aPlatformOptions,
       const FontVariation* aVariations, uint32_t aNumVariations) override;
 
-  bool GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton) override;
+  bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
+
+  static already_AddRefed<UnscaledFont> CreateFromFontDescriptor(
+      const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex);
 
  private:
   bool InitBold();
 
   RefPtr<IDWriteFontFace> mFontFace;
   RefPtr<IDWriteFontFace> mFontFaceBold;
   RefPtr<IDWriteFont> mFont;
 };
--- a/gfx/2d/UnscaledFontFreeType.cpp
+++ b/gfx/2d/UnscaledFontFreeType.cpp
@@ -72,27 +72,16 @@ bool UnscaledFontFreeType::GetFontDescri
     return false;
   }
 
   aCb(reinterpret_cast<const uint8_t*>(mFile.data()), mFile.size(), mIndex,
       aBaton);
   return true;
 }
 
-bool UnscaledFontFreeType::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
-                                               void* aBaton) {
-  if (mFile.empty()) {
-    return false;
-  }
-
-  aCb(reinterpret_cast<const uint8_t*>(mFile.data()), mFile.size(), mIndex,
-      aBaton);
-  return true;
-}
-
 RefPtr<SharedFTFace> UnscaledFontFreeType::InitFace() {
   if (mFace) {
     return mFace;
   }
   if (mFile.empty()) {
     return nullptr;
   }
   mFace = Factory::NewSharedFTFace(nullptr, mFile.c_str(), mIndex);
--- a/gfx/2d/UnscaledFontFreeType.h
+++ b/gfx/2d/UnscaledFontFreeType.h
@@ -34,21 +34,22 @@ class UnscaledFontFreeType : public Unsc
   const RefPtr<SharedFTFace>& GetFace() const { return mFace; }
   const std::string& GetFile() const { return mFile; }
   uint32_t GetIndex() const { return mIndex; }
 
   bool GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton) override;
 
   bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
 
-  bool GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton) override;
-
   RefPtr<SharedFTFace> InitFace();
 
 #ifdef MOZ_WIDGET_ANDROID
+  static already_AddRefed<UnscaledFont> CreateFromFontDescriptor(
+      const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex);
+
   already_AddRefed<ScaledFont> CreateScaledFont(
       Float aGlyphSize, const uint8_t* aInstanceData,
       uint32_t aInstanceDataLength, const FontVariation* aVariations,
       uint32_t aNumVariations) override;
 
   already_AddRefed<ScaledFont> CreateScaledFontFromWRFont(
       Float aGlyphSize, const wr::FontInstanceOptions* aOptions,
       const wr::FontInstancePlatformOptions* aPlatformOptions,
--- a/gfx/2d/UnscaledFontMac.h
+++ b/gfx/2d/UnscaledFontMac.h
@@ -45,17 +45,20 @@ class UnscaledFontMac final : public Uns
       Float aGlyphSize, const wr::FontInstanceOptions* aOptions,
       const wr::FontInstancePlatformOptions* aPlatformOptions,
       const FontVariation* aVariations, uint32_t aNumVariations) override;
 
   static CGFontRef CreateCGFontWithVariations(CGFontRef aFont,
                                               uint32_t aVariationCount,
                                               const FontVariation* aVariations);
 
-  bool GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton) override;
+  bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
+
+  static already_AddRefed<UnscaledFont> CreateFromFontDescriptor(
+      const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex);
 
  private:
   CGFontRef mFont;
   bool mIsDataFont;
 };
 
 }  // namespace gfx
 }  // namespace mozilla
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -324,17 +324,17 @@ Maybe<wr::FontKey> WebRenderBridgeChild:
         aResources ? Nothing() : Some(wr::IpcResourceUpdateQueue(this));
 
     FontFileDataSink sink = {&fontKey, this, resources.ptrOr(aResources)};
     // First try to retrieve a descriptor for the font, as this is much cheaper
     // to send over IPC than the full raw font data. If this is not possible,
     // then and only then fall back to getting the raw font file data. If that
     // fails, then the only thing left to do is signal failure by returning a
     // null font key.
-    if (!aUnscaled->GetWRFontDescriptor(WriteFontDescriptor, &sink) &&
+    if (!aUnscaled->GetFontDescriptor(WriteFontDescriptor, &sink) &&
         !aUnscaled->GetFontFileData(WriteFontFileData, &sink)) {
       return Nothing();
     }
 
     if (resources.isSome()) {
       UpdateResources(resources.ref(), aRenderRoot);
     }