Bug 1732629 - [gfx/2d] Get non-localized variation axis names from CoreGraphics in ScaledFontMac, so that we set up the CGFont correctly with variation values. r=jrmuizel
authorJonathan Kew <jkew@mozilla.com>
Wed, 27 Oct 2021 14:15:12 +0000 (2021-10-27)
changeset 597046 0ad5486182ffdf455a0c0285b87780e7c39e5244
parent 597045 71089265de178cef408d0b861f6252fe6d9ace35
child 597047 b5086513fe50f9598db2391f8cb021425033fadd
push id38919
push userarchaeopteryx@coole-files.de
push dateWed, 27 Oct 2021 15:06:08 +0000 (2021-10-27)
treeherdermozilla-central@b5086513fe50 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1732629
milestone95.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 1732629 - [gfx/2d] Get non-localized variation axis names from CoreGraphics in ScaledFontMac, so that we set up the CGFont correctly with variation values. r=jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D129576
gfx/2d/ScaledFontMac.cpp
gfx/2d/UnscaledFontMac.h
gfx/thebes/gfxMacFont.cpp
--- a/gfx/2d/ScaledFontMac.cpp
+++ b/gfx/2d/ScaledFontMac.cpp
@@ -89,17 +89,16 @@ static CTFontRef CreateCTFontFromCGFontW
   // 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())) {
     CFDictionaryRef vars = CGFontCopyVariations(aCGFont);
     if (vars) {
       CFDictionaryRef varAttr = CFDictionaryCreate(
           nullptr, (const void**)&kCTFontVariationAttribute,
           (const void**)&vars, 1, &kCFTypeDictionaryKeyCallBacks,
@@ -471,58 +470,72 @@ ScaledFontMac::InstanceData::InstanceDat
       mFontSmoothingBackgroundColor =
           DeviceColor::FromU8(aOptions->bg_color.r, aOptions->bg_color.g,
                               aOptions->bg_color.b, aOptions->bg_color.a);
     }
   }
 }
 
 static CFDictionaryRef CreateVariationDictionaryOrNull(
-    CGFontRef aCGFont, CFArrayRef& aAxesCache, uint32_t aVariationCount,
-    const FontVariation* aVariations) {
-  if (!aAxesCache) {
+    CGFontRef aCGFont, CFArrayRef& aCGAxesCache, CFArrayRef& aCTAxesCache,
+    uint32_t aVariationCount, const FontVariation* aVariations) {
+  if (!aCGAxesCache) {
+    aCGAxesCache = CGFontCopyVariationAxes(aCGFont);
+    if (!aCGAxesCache) {
+      return nullptr;
+    }
+  }
+  if (!aCTAxesCache) {
     AutoRelease<CTFontRef> ctFont(
         CTFontCreateWithGraphicsFont(aCGFont, 0, nullptr, nullptr));
-    aAxesCache = CTFontCopyVariationAxes(ctFont);
-    if (!aAxesCache) {
+    aCTAxesCache = CTFontCopyVariationAxes(ctFont);
+    if (!aCTAxesCache) {
       return nullptr;
     }
   }
 
-  CFIndex axisCount = CFArrayGetCount(aAxesCache);
+  CFIndex axisCount = CFArrayGetCount(aCTAxesCache);
+  if (CFArrayGetCount(aCGAxesCache) != axisCount) {
+    return nullptr;
+  }
+
   AutoRelease<CFMutableDictionaryRef> dict(CFDictionaryCreateMutable(
       kCFAllocatorDefault, axisCount, &kCFTypeDictionaryKeyCallBacks,
       &kCFTypeDictionaryValueCallBacks));
 
   // Number of variation settings passed in the aVariations parameter.
   // This will typically be a very low value, so we just linear-search them.
   bool allDefaultValues = true;
 
   for (CFIndex i = 0; i < axisCount; ++i) {
     // We sanity-check the axis info found in the CTFont, and bail out
     // (returning null) if it doesn't have the expected types.
-    CFTypeRef axisInfo = CFArrayGetValueAtIndex(aAxesCache, i);
+    CFTypeRef axisInfo = CFArrayGetValueAtIndex(aCTAxesCache, i);
     if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
       return nullptr;
     }
     CFDictionaryRef axis = static_cast<CFDictionaryRef>(axisInfo);
 
     CFTypeRef axisTag =
         CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey);
     if (!axisTag || CFGetTypeID(axisTag) != CFNumberGetTypeID()) {
       return nullptr;
     }
     int64_t tagLong;
     if (!CFNumberGetValue(static_cast<CFNumberRef>(axisTag),
                           kCFNumberSInt64Type, &tagLong)) {
       return nullptr;
     }
 
-    CFTypeRef axisName =
-        CFDictionaryGetValue(axis, kCTFontVariationAxisNameKey);
+    axisInfo = CFArrayGetValueAtIndex(aCGAxesCache, i);
+    if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
+      return nullptr;
+    }
+    CFTypeRef axisName = CFDictionaryGetValue(
+        static_cast<CFDictionaryRef>(axisInfo), kCGFontVariationAxisName);
     if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
       return nullptr;
     }
 
     // Clamp axis values to the supported range.
     CFTypeRef min =
         CFDictionaryGetValue(axis, kCTFontVariationAxisMinimumValueKey);
     CFTypeRef max =
@@ -651,25 +664,25 @@ static CFDictionaryRef CreateVariationTa
     return nullptr;
   }
 
   return dict.forget();
 }
 
 /* static */
 CGFontRef UnscaledFontMac::CreateCGFontWithVariations(
-    CGFontRef aFont, CFArrayRef& aAxesCache, uint32_t aVariationCount,
-    const FontVariation* aVariations) {
+    CGFontRef aFont, CFArrayRef& aCGAxesCache, CFArrayRef& aCTAxesCache,
+    uint32_t aVariationCount, const FontVariation* aVariations) {
   if (!aVariationCount) {
     return nullptr;
   }
   MOZ_ASSERT(aVariations);
 
   AutoRelease<CFDictionaryRef> varDict(CreateVariationDictionaryOrNull(
-      aFont, aAxesCache, aVariationCount, aVariations));
+      aFont, aCGAxesCache, aCTAxesCache, aVariationCount, aVariations));
   if (!varDict) {
     return nullptr;
   }
 
   return CGFontCreateCopyWithVariations(aFont, varDict);
 }
 
 already_AddRefed<ScaledFont> UnscaledFontMac::CreateScaledFont(
@@ -679,17 +692,16 @@ already_AddRefed<ScaledFont> UnscaledFon
 
 {
   if (aInstanceDataLength < sizeof(ScaledFontMac::InstanceData)) {
     gfxWarning() << "Mac scaled font instance data is truncated.";
     return nullptr;
   }
   const ScaledFontMac::InstanceData& instanceData =
       *reinterpret_cast<const ScaledFontMac::InstanceData*>(aInstanceData);
-
   RefPtr<ScaledFontMac> scaledFont;
   if (mFontDesc) {
     AutoRelease<CTFontRef> font(
         CTFontCreateWithFontDescriptor(mFontDesc, aGlyphSize, nullptr));
     if (aNumVariations > 0) {
       AutoRelease<CFDictionaryRef> varDict(CreateVariationTagDictionaryOrNull(
           font, aNumVariations, aVariations));
       CFDictionaryRef varAttr = CFDictionaryCreate(
@@ -705,17 +717,17 @@ already_AddRefed<ScaledFont> UnscaledFon
     }
     scaledFont = new ScaledFontMac(
         font, this, instanceData.mFontSmoothingBackgroundColor,
         instanceData.mUseFontSmoothing, instanceData.mApplySyntheticBold);
   } else {
     CGFontRef fontRef = mFont;
     if (aNumVariations > 0) {
       CGFontRef varFont = CreateCGFontWithVariations(
-          mFont, mAxesCache, aNumVariations, aVariations);
+          mFont, mCGAxesCache, mCTAxesCache, aNumVariations, aVariations);
       if (varFont) {
         fontRef = varFont;
       }
     }
 
     scaledFont = new ScaledFontMac(fontRef, this, aGlyphSize, fontRef != mFont,
                                    instanceData.mFontSmoothingBackgroundColor,
                                    instanceData.mUseFontSmoothing,
--- a/gfx/2d/UnscaledFontMac.h
+++ b/gfx/2d/UnscaledFontMac.h
@@ -29,18 +29,21 @@ class UnscaledFontMac final : public Uns
   explicit UnscaledFontMac(CTFontDescriptorRef aFontDesc, CGFontRef aFont,
                            bool aIsDataFont = false)
       : mFontDesc(aFontDesc), mFont(aFont), mIsDataFont(aIsDataFont) {
     CFRetain(mFontDesc);
     CFRetain(mFont);
   }
 
   virtual ~UnscaledFontMac() {
-    if (mAxesCache) {
-      CFRelease(mAxesCache);
+    if (mCTAxesCache) {
+      CFRelease(mCTAxesCache);
+    }
+    if (mCGAxesCache) {
+      CFRelease(mCGAxesCache);
     }
     if (mFontDesc) {
       CFRelease(mFontDesc);
     }
     if (mFont) {
       CFRelease(mFont);
     }
   }
@@ -59,30 +62,33 @@ class UnscaledFontMac final : public Uns
       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;
 
   static CGFontRef CreateCGFontWithVariations(CGFontRef aFont,
-                                              CFArrayRef& aAxesCache,
+                                              CFArrayRef& aCGAxesCache,
+                                              CFArrayRef& aCTAxesCache,
                                               uint32_t aVariationCount,
                                               const FontVariation* aVariations);
 
   bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
 
-  CFArrayRef& AxesCache() { return mAxesCache; }
+  CFArrayRef& CGAxesCache() { return mCGAxesCache; }
+  CFArrayRef& CTAxesCache() { return mCTAxesCache; }
 
   static already_AddRefed<UnscaledFont> CreateFromFontDescriptor(
       const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex);
 
  private:
   CTFontDescriptorRef mFontDesc = nullptr;
   CGFontRef mFont = nullptr;
-  CFArrayRef mAxesCache = nullptr;  // Cached array of variation axis details
+  CFArrayRef mCGAxesCache = nullptr;  // Cached arrays of variation axis details
+  CFArrayRef mCTAxesCache = nullptr;
   bool mIsDataFont;
 };
 
 }  // namespace gfx
 }  // namespace mozilla
 
 #endif /* MOZILLA_GFX_UNSCALEDFONTMAC_H_ */
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -99,17 +99,18 @@ gfxMacFont::gfxMacFont(const RefPtr<Unsc
         value = fmin(fmax(value, axis.mMinValue), axis.mMaxValue);
         if (std::abs(value - axis.mDefaultValue) < kOpszFudgeAmount) {
           value = aFontEntry->mAdjustedDefaultOpsz;
         }
       }
     }
 
     mCGFont = UnscaledFontMac::CreateCGFontWithVariations(
-        baseFont, aUnscaledFont->AxesCache(), vars.Length(), vars.Elements());
+        baseFont, aUnscaledFont->CGAxesCache(), aUnscaledFont->CTAxesCache(),
+        vars.Length(), vars.Elements());
     if (!mCGFont) {
       ::CFRetain(baseFont);
       mCGFont = baseFont;
     }
   } else {
     mCGFont = aUnscaledFont->GetFont();
     if (!mCGFont) {
       mIsValid = false;