Bug 1397458 - part 2 - refactor ScaledFontMac font variation collection for easier reuse r=kats
authorLee Salzman <lsalzman@mozilla.com>
Tue, 19 Sep 2017 23:08:16 -0400
changeset 669099 de9bea55622f6d9e3a9dbf4cc74b02c05f668c4f
parent 669098 3ed606c9faa030c744d14aaaec814fd7e2a5bb2c
child 669100 ff25f43503fed195b6a7425133f80d02e78497f5
push id81210
push userkgupta@mozilla.com
push dateFri, 22 Sep 2017 14:09:59 +0000
reviewerskats
bugs1397458
milestone58.0a1
Bug 1397458 - part 2 - refactor ScaledFontMac font variation collection for easier reuse r=kats MozReview-Commit-ID: C2L8tZe4jEa
gfx/2d/ScaledFontMac.cpp
--- a/gfx/2d/ScaledFontMac.cpp
+++ b/gfx/2d/ScaledFontMac.cpp
@@ -230,34 +230,16 @@ struct writeBuf
             this->offset++;
         }
     }
 
     unsigned char *data;
     int offset;
 };
 
-static void CollectVariationSetting(const void *key, const void *value, void *context)
-{
-  auto keyPtr = static_cast<const CFTypeRef>(key);
-  auto valuePtr = static_cast<const CFTypeRef>(value);
-  auto vpp = static_cast<FontVariation**>(context);
-  if (CFGetTypeID(keyPtr) == CFNumberGetTypeID() &&
-      CFGetTypeID(valuePtr) == CFNumberGetTypeID()) {
-    uint64_t t;
-    double v;
-    if (CFNumberGetValue(static_cast<CFNumberRef>(keyPtr), kCFNumberSInt64Type, &t) &&
-        CFNumberGetValue(static_cast<CFNumberRef>(valuePtr), kCFNumberDoubleType, &v)) {
-      (*vpp)->mTag = t;
-      (*vpp)->mValue = v;
-      (*vpp)++;
-    }
-  }
-}
-
 bool
 UnscaledFontMac::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
 {
     // We'll reconstruct a TTF font from the tables we can get from the CGFont
     CFArrayRef tags = CGFontCopyTableTags(mFont);
     CFIndex count = CFArrayGetCount(tags);
 
     TableRecord *records = new TableRecord[count];
@@ -322,43 +304,62 @@ UnscaledFontMac::GetFontFileData(FontFil
     memcpy(&buf.data[checkSumAdjustmentOffset], &fontChecksum, sizeof(fontChecksum));
 
     // we always use an index of 0
     aDataCallback(buf.data, buf.offset, 0, aBaton);
 
     return true;
 }
 
+static void
+CollectVariationsFromDictionary(const void* aKey, const void* aValue, void* aContext)
+{
+  auto keyPtr = static_cast<const CFTypeRef>(aKey);
+  auto valuePtr = static_cast<const CFTypeRef>(aValue);
+  auto outVariations = static_cast<std::vector<FontVariation>*>(aContext);
+  if (CFGetTypeID(keyPtr) == CFNumberGetTypeID() &&
+      CFGetTypeID(valuePtr) == CFNumberGetTypeID()) {
+    uint64_t t;
+    double v;
+    if (CFNumberGetValue(static_cast<CFNumberRef>(keyPtr), kCFNumberSInt64Type, &t) &&
+        CFNumberGetValue(static_cast<CFNumberRef>(valuePtr), kCFNumberDoubleType, &v)) {
+      outVariations->push_back(FontVariation{uint32_t(t), float(v)});
+    }
+  }
+}
+
+static bool
+GetVariationsForCTFont(CTFontRef aCTFont, std::vector<FontVariation>* aOutVariations)
+{
+  // Avoid calling potentially buggy variation APIs on pre-Sierra macOS
+  // versions (see bug 1331683)
+  if (!nsCocoaFeatures::OnSierraOrLater()) {
+    return true;
+  }
+  if (!aCTFont) {
+    return true;
+  }
+  AutoRelease<CFDictionaryRef> dict(CTFontCopyVariation(aCTFont));
+  CFIndex count = dict ? CFDictionaryGetCount(dict) : 0;
+  if (count > 0) {
+    aOutVariations->reserve(count);
+    CFDictionaryApplyFunction(dict, CollectVariationsFromDictionary, aOutVariations);
+  }
+  return true;
+}
+
 bool
 ScaledFontMac::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
 {
     // Collect any variation settings that were incorporated into the CTFont.
-    uint32_t variationCount = 0;
-    FontVariation* variations = nullptr;
-    // Avoid calling potentially buggy variation APIs on pre-Sierra macOS
-    // versions (see bug 1331683)
-    if (nsCocoaFeatures::OnSierraOrLater()) {
-      if (mCTFont) {
-        CFDictionaryRef dict = CTFontCopyVariation(mCTFont);
-        if (dict) {
-          CFIndex count = CFDictionaryGetCount(dict);
-          if (count > 0) {
-            variations = new FontVariation[count];
-            FontVariation* vPtr = variations;
-            CFDictionaryApplyFunction(dict, CollectVariationSetting, &vPtr);
-            variationCount = vPtr - variations;
-          }
-          CFRelease(dict);
-        }
-      }
+    std::vector<FontVariation> variations;
+    if (!GetVariationsForCTFont(mCTFont, &variations)) {
+      return false;
     }
-
-    aCb(nullptr, 0, variations, variationCount, aBaton);
-    delete[] variations;
-
+    aCb(nullptr, 0, variations.data(), variations.size(), aBaton);
     return true;
 }
 
 static CFDictionaryRef
 CreateVariationDictionaryOrNull(CGFontRef aCGFont, uint32_t aVariationCount,
                                 const FontVariation* aVariations)
 {
   // Avoid calling potentially buggy variation APIs on pre-Sierra macOS