Bug 1228022 - part 1 - Support replay of Mac print stream, adds NativeFontResourceMac, ScaledFontMac::GetCairoFontFace; r=jfkthame draft
authorHaik Aftandilian <haftandilian@mozilla.com>
Thu, 15 Sep 2016 14:13:57 -0700
changeset 414207 ae3a137be2567a4d4d0fadbfa0ecbd405e28316e
parent 412830 2e35fd4a4932abe6ea89311f914233dbf251b6de
child 414208 f63f5be979fd938c2673d16efcae59705c3da66a
push id29617
push userhaftandilian@mozilla.com
push dateThu, 15 Sep 2016 21:14:57 +0000
reviewersjfkthame
bugs1228022
milestone51.0a1
Bug 1228022 - part 1 - Support replay of Mac print stream, adds NativeFontResourceMac, ScaledFontMac::GetCairoFontFace; r=jfkthame Adds the necessary plumbing to allow Mac font creation and referencing during replay of a remote print stream. MozReview-Commit-ID: 18jpeImPwCI
gfx/2d/Factory.cpp
gfx/2d/NativeFontResourceMac.cpp
gfx/2d/NativeFontResourceMac.h
gfx/2d/RecordedEvent.cpp
gfx/2d/ScaledFontMac.cpp
gfx/2d/ScaledFontMac.h
gfx/2d/moz.build
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -22,16 +22,17 @@
 
 #if defined(WIN32)
 #include "ScaledFontWin.h"
 #include "NativeFontResourceGDI.h"
 #endif
 
 #ifdef XP_DARWIN
 #include "ScaledFontMac.h"
+#include "NativeFontResourceMac.h"
 #endif
 
 #ifdef MOZ_WIDGET_GTK
 #include "ScaledFontFontconfig.h"
 #endif
 
 #ifdef XP_DARWIN
 #include "DrawTargetCG.h"
@@ -543,16 +544,18 @@ Factory::CreateNativeFontResource(uint8_
 #ifdef WIN32
       if (GetDirect3D11Device()) {
         return NativeFontResourceDWrite::Create(aData, aSize,
                                                 /* aNeedsCairo = */ true);
       } else {
         return NativeFontResourceGDI::Create(aData, aSize,
                                              /* aNeedsCairo = */ true);
       }
+#elif XP_DARWIN
+      return NativeFontResourceMac::Create(aData, aSize);
 #else
       gfxWarning() << "Unable to create cairo scaled font from truetype data";
       return nullptr;
 #endif
     }
   default:
     gfxWarning() << "Unable to create requested font resource from truetype data";
     return nullptr;
new file mode 100644
--- /dev/null
+++ b/gfx/2d/NativeFontResourceMac.cpp
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "NativeFontResourceMac.h"
+#include "Types.h"
+
+#include "mozilla/RefPtr.h"
+
+#ifdef MOZ_WIDGET_UIKIT
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+namespace mozilla {
+namespace gfx {
+
+/* static */
+already_AddRefed<NativeFontResourceMac>
+NativeFontResourceMac::Create(uint8_t *aFontData, uint32_t aDataLength)
+{
+  // copy font data
+  CFDataRef data = CFDataCreate(kCFAllocatorDefault, aFontData, aDataLength);
+  if (!data) {
+    return nullptr;
+  }
+
+  // create a provider
+  CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);
+
+  // release our reference to the CFData, provider keeps it alive
+  CFRelease(data);
+
+  // create the font object
+  CGFontRef fontRef = CGFontCreateWithDataProvider(provider);
+
+  // release our reference, font will keep it alive as long as needed
+  CGDataProviderRelease(provider);
+
+  if (!fontRef) {
+    return nullptr;
+  }
+
+  // passes ownership of fontRef to the NativeFontResourceMac instance
+  RefPtr<NativeFontResourceMac> fontResource =
+    new NativeFontResourceMac(fontRef);
+
+  return fontResource.forget();
+}
+
+already_AddRefed<ScaledFont>
+NativeFontResourceMac::CreateScaledFont(uint32_t aIndex, uint32_t aGlyphSize)
+{
+  RefPtr<ScaledFontBase> scaledFont = new ScaledFontMac(mFontRef, aGlyphSize);
+
+  if (!scaledFont->PopulateCairoScaledFont()) {
+    gfxWarning() << "Unable to create cairo scaled Mac font.";
+    return nullptr;
+  }
+
+  return scaledFont.forget();
+}
+
+} // gfx
+} // mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/2d/NativeFontResourceMac.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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_NativeFontResourceMac_h
+#define mozilla_gfx_NativeFontResourceMac_h
+
+#include "2D.h"
+#include "mozilla/AlreadyAddRefed.h"
+#include "ScaledFontMac.h"
+
+namespace mozilla {
+namespace gfx {
+
+class NativeFontResourceMac final : public NativeFontResource
+{
+public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResourceMac)
+
+  static already_AddRefed<NativeFontResourceMac>
+    Create(uint8_t *aFontData, uint32_t aDataLength);
+
+  already_AddRefed<ScaledFont>
+    CreateScaledFont(uint32_t aIndex, uint32_t aGlyphSize);
+
+  ~NativeFontResourceMac()
+  {
+    CFRelease(mFontRef);
+  }
+
+private:
+  explicit NativeFontResourceMac(CGFontRef aFontRef) : mFontRef(aFontRef) {}
+
+  CGFontRef mFontRef;
+};
+
+} // gfx
+} // mozilla
+
+#endif // mozilla_gfx_NativeFontResourceMac_h
--- a/gfx/2d/RecordedEvent.cpp
+++ b/gfx/2d/RecordedEvent.cpp
@@ -1514,16 +1514,20 @@ RecordedFontData::~RecordedFontData()
 }
 
 bool
 RecordedFontData::PlayEvent(Translator *aTranslator) const
 {
   RefPtr<NativeFontResource> fontResource =
     Factory::CreateNativeFontResource(mData, mFontDetails.size,
                                       aTranslator->GetDesiredFontType());
+  if (!fontResource) {
+    return false;
+  }
+
   aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource);
   return true;
 }
 
 void
 RecordedFontData::RecordToStream(std::ostream &aStream) const
 {
   MOZ_ASSERT(mGetFontFileDataSucceeded);
--- a/gfx/2d/ScaledFontMac.cpp
+++ b/gfx/2d/ScaledFontMac.cpp
@@ -19,16 +19,19 @@
 
 #ifdef MOZ_WIDGET_COCOA
 // prototype for private API
 extern "C" {
 CGPathRef CGFontGetGlyphPath(CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph);
 };
 #endif
 
+#ifdef USE_CAIRO_SCALED_FONT
+#include "cairo-quartz.h"
+#endif
 
 namespace mozilla {
 namespace gfx {
 
 ScaledFontMac::CTFontDrawGlyphsFuncT* ScaledFontMac::CTFontDrawGlyphsPtr = nullptr;
 bool ScaledFontMac::sSymbolLookupDone = false;
 
 ScaledFontMac::ScaledFontMac(CGFontRef aFont, Float aSize)
@@ -279,10 +282,19 @@ ScaledFontMac::GetFontFileData(FontFileD
 
     // we always use an index of 0
     aDataCallback(buf.data, buf.offset, 0, mSize, aBaton);
 
     return true;
 
 }
 
+#ifdef USE_CAIRO_SCALED_FONT
+cairo_font_face_t*
+ScaledFontMac::GetCairoFontFace()
+{
+  MOZ_ASSERT(mFont);
+  return cairo_quartz_font_face_create_for_cgfont(mFont);
+}
+#endif
+
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/ScaledFontMac.h
+++ b/gfx/2d/ScaledFontMac.h
@@ -30,16 +30,20 @@ public:
   virtual FontType GetType() const { return FontType::MAC; }
 #ifdef USE_SKIA
   virtual SkTypeface* GetSkTypeface();
 #endif
   virtual already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
   virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint);
   virtual bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton);
 
+#ifdef USE_CAIRO_SCALED_FONT
+  cairo_font_face_t* GetCairoFontFace();
+#endif
+
 private:
   friend class DrawTargetCG;
   friend class DrawTargetSkia;
   CGFontRef mFont;
   CTFontRef mCTFont; // only created if CTFontDrawGlyphs is available, otherwise null
 
   typedef void (CTFontDrawGlyphsFuncT)(CTFontRef,
                                        const CGGlyph[], const CGPoint[],
--- a/gfx/2d/moz.build
+++ b/gfx/2d/moz.build
@@ -59,16 +59,17 @@ EXPORTS.mozilla.gfx += [
 EXPORTS.mozilla.gfx += ['ssse3-scaler.h']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):
     EXPORTS.mozilla.gfx += [
         'MacIOSurface.h',
     ]
     UNIFIED_SOURCES += [
         'DrawTargetCG.cpp',
+        'NativeFontResourceMac.cpp',
         'PathCG.cpp',
         'ScaledFontMac.cpp',
         'SourceSurfaceCG.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     SOURCES += [
         'DrawTargetD2D1.cpp',
         'ExtendInputEffectD2D1.cpp',