Commit e77a8d77 authored by Jonathan Kew's avatar Jonathan Kew
Browse files

Bug 1856035 - Merge implementations of CreateCTFontFromCGFontWithVariations...

Bug 1856035 - Merge implementations of CreateCTFontFromCGFontWithVariations from gfxMacFont.cpp and 2d/ScaledFontMac.cpp (no change in behavior). r=gfx-reviewers,lsalzman, a=dmeehan

Differential Revision: https://phabricator.services.mozilla.com/D191123
parent 29b503c4
Loading
Loading
Loading
Loading
+18 −41
Original line number Diff line number Diff line
@@ -46,12 +46,15 @@ class AutoRelease final {
    }
  }

  void operator=(T aObject) {
  AutoRelease<T>& operator=(const T& aObject) {
    if (aObject != mObject) {
      if (mObject) {
        CFRelease(mObject);
      }
      mObject = aObject;
    }
    return *this;
  }

  operator T() { return mObject; }

@@ -67,50 +70,24 @@ class AutoRelease final {

// Helper to create a CTFont from a CGFont, copying any variations that were
// set on the original CGFont.
static CTFontRef CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont,
                                                      CGFloat aSize,
                                                      bool aInstalledFont) {
  // Avoid calling potentially buggy variation APIs on pre-Sierra macOS
  // versions (see bug 1331683).
  //
  // And on HighSierra, CTFontCreateWithGraphicsFont properly carries over
  // variation settings from the CGFont to CTFont, so we don't need to do
  // the extra work here -- and this seems to avoid Core Text crashiness
  // seen in bug 1454094.
  //
  // However, for installed fonts it seems we DO need to copy the variations
  // explicitly even on 10.13, otherwise fonts fail to render (as in bug
  // 1455494) when non-default values are used. Fortunately, the crash
  // mentioned above occurs with data fonts, not (AFAICT) with system-
  // installed fonts.
  //
  // So we only need to do this "the hard way" on Sierra, and for installed
  // fonts on HighSierra+; otherwise, just let the standard CTFont function
  // do its thing.
  //
  // NOTE in case this ever needs further adjustment: there is similar logic
  // in four places in the tree (sadly):
  //    CreateCTFontFromCGFontWithVariations in gfxMacFont.cpp
  //    CreateCTFontFromCGFontWithVariations in ScaledFontMac.cpp
  //    CreateCTFontFromCGFontWithVariations in cairo-quartz-font.c
  //    ctfont_create_exact_copy in SkFontHost_mac.cpp
CTFontRef CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont, CGFloat aSize,
                                               bool aInstalledFont,
                                               CTFontDescriptorRef aFontDesc) {
  CTFontRef ctFont;
  if (nsCocoaFeatures::OnSierraExactly() ||
      (aInstalledFont && nsCocoaFeatures::OnHighSierraOrLater())) {
    CFDictionaryRef vars = CGFontCopyVariations(aCGFont);
  if (aInstalledFont) {
    AutoRelease<CFDictionaryRef> vars(CGFontCopyVariations(aCGFont));
    if (vars) {
      CFDictionaryRef varAttr = CFDictionaryCreate(
      AutoRelease<CFDictionaryRef> varAttr(CFDictionaryCreate(
          nullptr, (const void**)&kCTFontVariationAttribute,
          (const void**)&vars, 1, &kCFTypeDictionaryKeyCallBacks,
          &kCFTypeDictionaryValueCallBacks);
      CFRelease(vars);
          &kCFTypeDictionaryValueCallBacks));

      CTFontDescriptorRef varDesc =
          CTFontDescriptorCreateWithAttributes(varAttr);
      CFRelease(varAttr);
      AutoRelease<CTFontDescriptorRef> varDesc(
          aFontDesc
              ? ::CTFontDescriptorCreateCopyWithAttributes(aFontDesc, varAttr)
              : ::CTFontDescriptorCreateWithAttributes(varAttr));

      ctFont = CTFontCreateWithGraphicsFont(aCGFont, aSize, nullptr, varDesc);
      CFRelease(varDesc);
    } else {
      ctFont = CTFontCreateWithGraphicsFont(aCGFont, aSize, nullptr, nullptr);
    }
+24 −24
Original line number Diff line number Diff line
@@ -21,19 +21,25 @@
namespace mozilla {
namespace gfx {

// Utility to create a CTFont from a CGFont, copying any variations that were
// set on the original CGFont, and applying additional attributes from aDesc
// (which may be NULL).
// Exposed here because it is also used by gfxMacFont and gfxCoreTextShaper.
CTFontRef CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont, CGFloat aSize,
                                               bool aInstalledFont,
                                               CTFontDescriptorRef aFontDesc = nullptr);

class UnscaledFontMac;

class ScaledFontMac : public ScaledFontBase {
 public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontMac, override)
  ScaledFontMac(
      CGFontRef aFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
  ScaledFontMac(CGFontRef aFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
                bool aOwnsFont = false,
                const DeviceColor& aFontSmoothingBackgroundColor = DeviceColor(),
                bool aUseFontSmoothing = true, bool aApplySyntheticBold = false,
                bool aHasColorGlyphs = false);
  ScaledFontMac(
      CTFontRef aFont, const RefPtr<UnscaledFont>& aUnscaledFont,
  ScaledFontMac(CTFontRef aFont, const RefPtr<UnscaledFont>& aUnscaledFont,
                const DeviceColor& aFontSmoothingBackgroundColor = DeviceColor(),
                bool aUseFontSmoothing = true, bool aApplySyntheticBold = false,
                bool aHasColorGlyphs = false);
@@ -47,8 +53,7 @@ class ScaledFontMac : public ScaledFontBase {

  bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;

  bool GetWRFontInstanceOptions(
      Maybe<wr::FontInstanceOptions>* aOutOptions,
  bool GetWRFontInstanceOptions(Maybe<wr::FontInstanceOptions>* aOutOptions,
                                Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
                                std::vector<FontVariation>* aOutVariations) override;

@@ -58,20 +63,16 @@ class ScaledFontMac : public ScaledFontBase {

  bool UseSubpixelPosition() const override { return true; }

  DeviceColor FontSmoothingBackgroundColor() {
    return mFontSmoothingBackgroundColor;
  }
  DeviceColor FontSmoothingBackgroundColor() { return mFontSmoothingBackgroundColor; }

  cairo_font_face_t* CreateCairoFontFace(
      cairo_font_options_t* aFontOptions) override;
  cairo_font_face_t* CreateCairoFontFace(cairo_font_options_t* aFontOptions) override;

 private:
  friend class DrawTargetSkia;
  friend class UnscaledFontMac;

  CGFontRef mFont;
  CTFontRef
      mCTFont;  // only created if CTFontDrawGlyphs is available, otherwise null
  CTFontRef mCTFont;  // only created if CTFontDrawGlyphs is available, otherwise null

  DeviceColor mFontSmoothingBackgroundColor;
  bool mUseFontSmoothing;
@@ -80,8 +81,7 @@ class ScaledFontMac : public ScaledFontBase {

  struct InstanceData {
    explicit InstanceData(ScaledFontMac* aScaledFont)
        : mFontSmoothingBackgroundColor(
              aScaledFont->mFontSmoothingBackgroundColor),
        : mFontSmoothingBackgroundColor(aScaledFont->mFontSmoothingBackgroundColor),
          mUseFontSmoothing(aScaledFont->mUseFontSmoothing),
          mApplySyntheticBold(aScaledFont->mApplySyntheticBold),
          mHasColorGlyphs(aScaledFont->mHasColorGlyphs) {}
+2 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ EXPORTS.mozilla.gfx += ["ssse3-scaler.h"]
if CONFIG["MOZ_WIDGET_TOOLKIT"] in ("cocoa", "uikit"):
    EXPORTS.mozilla.gfx += [
        "MacIOSurface.h",
        "ScaledFontBase.h",
        "ScaledFontMac.h",
        "UnscaledFontMac.h",
    ]
    UNIFIED_SOURCES += [
+4 −2
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include "gfxFontUtils.h"
#include "gfxTextRun.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/ScaledFontMac.h"
#include "mozilla/UniquePtrExtensions.h"

#include <algorithm>
@@ -16,6 +17,7 @@
#include <dlfcn.h>

using namespace mozilla;
using namespace mozilla::gfx;

// standard font descriptors that we construct the first time they're needed
CTFontDescriptorRef gfxCoreTextShaper::sFeaturesDescriptor[kMaxFontInstances];
@@ -634,8 +636,8 @@ CTFontRef gfxCoreTextShaper::CreateCTFontWithFeatures(
  const gfxFontEntry* fe = mFont->GetFontEntry();
  bool isInstalledFont = !fe->IsUserFont() || fe->IsLocalUserFont();
  CGFontRef cgFont = static_cast<gfxMacFont*>(mFont)->GetCGFontRef();
  return gfxMacFont::CreateCTFontFromCGFontWithVariations(
      cgFont, aSize, isInstalledFont, aDescriptor);
  return CreateCTFontFromCGFontWithVariations(cgFont, aSize, isInstalledFont,
                                              aDescriptor);
}

void gfxCoreTextShaper::Shutdown()  // [static]
+1 −56
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/Sprintf.h"
#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/gfx/ScaledFontMac.h"

#include "gfxCoreTextShaper.h"
#include <algorithm>
@@ -435,62 +436,6 @@ gfxFloat gfxMacFont::GetCharWidth(CFDataRef aCmap, char16_t aUniChar,
  return 0;
}

/* static */
CTFontRef gfxMacFont::CreateCTFontFromCGFontWithVariations(
    CGFontRef aCGFont, CGFloat aSize, bool aInstalledFont,
    CTFontDescriptorRef aFontDesc) {
  // Avoid calling potentially buggy variation APIs on pre-Sierra macOS
  // versions (see bug 1331683).
  //
  // And on HighSierra, CTFontCreateWithGraphicsFont properly carries over
  // variation settings from the CGFont to CTFont, so we don't need to do
  // the extra work here -- and this seems to avoid Core Text crashiness
  // seen in bug 1454094.
  //
  // However, for installed fonts it seems we DO need to copy the variations
  // explicitly even on 10.13, otherwise fonts fail to render (as in bug
  // 1455494) when non-default values are used. Fortunately, the crash
  // mentioned above occurs with data fonts, not (AFAICT) with system-
  // installed fonts.
  //
  // So we only need to do this "the hard way" on Sierra, and on HighSierra
  // for system-installed fonts; in other cases just let the standard CTFont
  // function do its thing.
  //
  // NOTE in case this ever needs further adjustment: there is similar logic
  // in four places in the tree (sadly):
  //    CreateCTFontFromCGFontWithVariations in gfxMacFont.cpp
  //    CreateCTFontFromCGFontWithVariations in ScaledFontMac.cpp
  //    CreateCTFontFromCGFontWithVariations in cairo-quartz-font.c
  //    ctfont_create_exact_copy in SkFontHost_mac.cpp

  CTFontRef ctFont;
  if (nsCocoaFeatures::OnSierraExactly() ||
      (aInstalledFont && nsCocoaFeatures::OnHighSierraOrLater())) {
    AutoCFRelease<CFDictionaryRef> variations = ::CGFontCopyVariations(aCGFont);
    if (variations) {
      AutoCFRelease<CFDictionaryRef> varAttr = ::CFDictionaryCreate(
          nullptr, (const void**)&kCTFontVariationAttribute,
          (const void**)&variations, 1, &kCFTypeDictionaryKeyCallBacks,
          &kCFTypeDictionaryValueCallBacks);

      AutoCFRelease<CTFontDescriptorRef> varDesc =
          aFontDesc
              ? ::CTFontDescriptorCreateCopyWithAttributes(aFontDesc, varAttr)
              : ::CTFontDescriptorCreateWithAttributes(varAttr);

      ctFont = ::CTFontCreateWithGraphicsFont(aCGFont, aSize, nullptr, varDesc);
    } else {
      ctFont =
          ::CTFontCreateWithGraphicsFont(aCGFont, aSize, nullptr, aFontDesc);
    }
  } else {
    ctFont = ::CTFontCreateWithGraphicsFont(aCGFont, aSize, nullptr, aFontDesc);
  }

  return ctFont;
}

int32_t gfxMacFont::GetGlyphWidth(uint16_t aGID) {
  if (mVariationFont) {
    // Avoid a potential Core Text crash (bug 1450209) by using
Loading