Bug 1554193 - Move support for the AAT 'trak' table from platform-specific MacFontEntry/gfxMacFont into the generic gfxFontEntry/gfxFont classes. r=jrmuizel
authorJonathan Kew <jkew@mozilla.com>
Thu, 30 May 2019 10:28:44 +0000
changeset 476203 56d554aac00055173692059fccd9390eb6cdcdb4
parent 476202 daf1de2ade3be21a73c64dd4934bf6b7ec5615ce
child 476204 ccaee449786a7dfaad6cc691afc9a87acb0b3c72
push id36089
push usernbeleuzu@mozilla.com
push dateThu, 30 May 2019 21:48:30 +0000
treeherdermozilla-central@e09471d13659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1554193
milestone69.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 1554193 - Move support for the AAT 'trak' table from platform-specific MacFontEntry/gfxMacFont into the generic gfxFontEntry/gfxFont classes. r=jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D33068
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFontEntry.cpp
gfx/thebes/gfxFontEntry.h
gfx/thebes/gfxMacFont.cpp
gfx/thebes/gfxMacPlatformFontList.h
gfx/thebes/gfxMacPlatformFontList.mm
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2737,46 +2737,60 @@ bool gfxFont::ShapeText(DrawTarget* aDra
   return ShapeText(aDrawTarget, utf16.BeginReading(), aOffset, aLength, aScript,
                    aVertical, aRounding, aShapedText);
 }
 
 bool gfxFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
                         uint32_t aOffset, uint32_t aLength, Script aScript,
                         bool aVertical, RoundingFlags aRounding,
                         gfxShapedText* aShapedText) {
-  bool ok = false;
-
   // XXX Currently, we do all vertical shaping through harfbuzz.
   // Vertical graphite support may be wanted as a future enhancement.
   if (FontCanSupportGraphite() && !aVertical) {
     if (gfxPlatform::GetPlatform()->UseGraphiteShaping()) {
       if (!mGraphiteShaper) {
         mGraphiteShaper = MakeUnique<gfxGraphiteShaper>(this);
         Telemetry::ScalarAdd(Telemetry::ScalarID::BROWSER_USAGE_GRAPHITE, 1);
       }
-      ok = mGraphiteShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
-                                      aScript, aVertical, aRounding,
-                                      aShapedText);
+      if (mGraphiteShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
+                                     aScript, aVertical, aRounding,
+                                     aShapedText)) {
+        PostShapingFixup(aDrawTarget, aText, aOffset, aLength, aVertical,
+                         aShapedText);
+        return true;
+      }
     }
   }
 
-  if (!ok) {
-    if (!mHarfBuzzShaper) {
-      mHarfBuzzShaper = MakeUnique<gfxHarfBuzzShaper>(this);
-    }
-    ok = mHarfBuzzShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
-                                    aScript, aVertical, aRounding, aShapedText);
+  if (!mHarfBuzzShaper) {
+    mHarfBuzzShaper = MakeUnique<gfxHarfBuzzShaper>(this);
   }
-
-  NS_WARNING_ASSERTION(ok, "shaper failed, expect scrambled or missing text");
-
-  PostShapingFixup(aDrawTarget, aText, aOffset, aLength, aVertical,
-                   aShapedText);
-
-  return ok;
+  if (mHarfBuzzShaper->ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
+                                 aVertical, aRounding, aShapedText)) {
+    PostShapingFixup(aDrawTarget, aText, aOffset, aLength, aVertical,
+                     aShapedText);
+    if (GetFontEntry()->HasTrackingTable()) {
+      // Convert font size from device pixels back to CSS px
+      // to use in selecting tracking value
+      float trackSize = GetAdjustedSize() *
+                        aShapedText->GetAppUnitsPerDevUnit() /
+                        AppUnitsPerCSSPixel();
+      float tracking =
+          GetFontEntry()->TrackingForCSSPx(trackSize) * mFUnitsConvFactor;
+      // Applying tracking is a lot like the adjustment we do for
+      // synthetic bold: we want to apply between clusters, not to
+      // non-spacing glyphs within a cluster. So we can reuse that
+      // helper here.
+      aShapedText->AdjustAdvancesForSyntheticBold(tracking, aOffset, aLength);
+    }
+    return true;
+  }
+
+  NS_WARNING_ASSERTION(false, "shaper failed, expect scrambled/missing text");
+  return false;
 }
 
 void gfxFont::PostShapingFixup(DrawTarget* aDrawTarget, const char16_t* aText,
                                uint32_t aOffset, uint32_t aLength,
                                bool aVertical, gfxShapedText* aShapedText) {
   if (IsSyntheticBold()) {
     const Metrics& metrics = GetMetrics(aVertical ? nsFontMetrics::eVertical
                                                   : nsFontMetrics::eHorizontal);
--- a/gfx/thebes/gfxFontEntry.cpp
+++ b/gfx/thebes/gfxFontEntry.cpp
@@ -114,16 +114,21 @@ gfxFontEntry::gfxFontEntry(const nsACStr
   memset(&mNonDefaultSubSpaceFeatures, 0, sizeof(mNonDefaultSubSpaceFeatures));
 }
 
 gfxFontEntry::~gfxFontEntry() {
   // Should not be dropped by stylo
   MOZ_ASSERT(NS_IsMainThread());
   hb_blob_destroy(mCOLR);
   hb_blob_destroy(mCPAL);
+  if (TrakTableInitialized()) {
+    // Only if it was initialized, so that we don't try to call hb_blob_destroy
+    // on the kTrakTableUninitialized flag value!
+    hb_blob_destroy(mTrakTable);
+  }
 
   // For downloaded fonts, we need to tell the user font cache that this
   // entry is being deleted.
   if (mIsDataUserFont) {
     gfxUserFontSet::UserFontCache::ForgetFont(this);
   }
 
   if (mFeatureInputs) {
@@ -911,16 +916,144 @@ void gfxFontEntry::GetFeatureInfo(nsTArr
 bool gfxFontEntry::GetColorLayersInfo(
     uint32_t aGlyphId, const mozilla::gfx::Color& aDefaultColor,
     nsTArray<uint16_t>& aLayerGlyphs,
     nsTArray<mozilla::gfx::Color>& aLayerColors) {
   return gfxFontUtils::GetColorGlyphLayers(
       mCOLR, mCPAL, aGlyphId, aDefaultColor, aLayerGlyphs, aLayerColors);
 }
 
+typedef struct {
+  AutoSwap_PRUint32 version;
+  AutoSwap_PRUint16 format;
+  AutoSwap_PRUint16 horizOffset;
+  AutoSwap_PRUint16 vertOffset;
+  AutoSwap_PRUint16 reserved;
+  //  TrackData horizData;
+  //  TrackData vertData;
+} TrakHeader;
+
+typedef struct {
+  AutoSwap_PRUint16 nTracks;
+  AutoSwap_PRUint16 nSizes;
+  AutoSwap_PRUint32 sizeTableOffset;
+  //  trackTableEntry trackTable[];
+  //  fixed32 sizeTable[];
+} TrackData;
+
+typedef struct {
+  AutoSwap_PRUint32 track;
+  AutoSwap_PRUint16 nameIndex;
+  AutoSwap_PRUint16 offset;
+} TrackTableEntry;
+
+bool gfxFontEntry::HasTrackingTable() {
+  if (!TrakTableInitialized()) {
+    mTrakTable = GetFontTable(TRUETYPE_TAG('t', 'r', 'a', 'k'));
+    if (mTrakTable) {
+      if (!ParseTrakTable()) {
+        hb_blob_destroy(mTrakTable);
+        mTrakTable = nullptr;
+      }
+    }
+  }
+  return mTrakTable != nullptr;
+}
+
+bool gfxFontEntry::ParseTrakTable() {
+  // Check table validity and set up the subtable pointers we need;
+  // if 'trak' table is invalid, or doesn't contain a 'normal' track,
+  // return false to tell the caller not to try using it.
+  unsigned int len;
+  const char* data = hb_blob_get_data(mTrakTable, &len);
+  if (len < sizeof(TrakHeader)) {
+    return false;
+  }
+  auto trak = reinterpret_cast<const TrakHeader*>(data);
+  uint16_t horizOffset = trak->horizOffset;
+  if (trak->version != 0x00010000 || uint16_t(trak->format) != 0 ||
+      horizOffset == 0 || uint16_t(trak->reserved) != 0) {
+    return false;
+  }
+  // Find the horizontal trackData, and check it doesn't overrun the buffer.
+  if (horizOffset > len - sizeof(TrackData)) {
+    return false;
+  }
+  auto trackData = reinterpret_cast<const TrackData*>(data + horizOffset);
+  uint16_t nTracks = trackData->nTracks;
+  mNumTrakSizes = trackData->nSizes;
+  if (nTracks == 0 || mNumTrakSizes < 2) {
+    return false;
+  }
+  uint32_t sizeTableOffset = trackData->sizeTableOffset;
+  // Find the trackTable, and check it doesn't overrun the buffer.
+  if (horizOffset >
+      len - (sizeof(TrackData) + nTracks * sizeof(TrackTableEntry))) {
+    return false;
+  }
+  auto trackTable = reinterpret_cast<const TrackTableEntry*>(
+      data + horizOffset + sizeof(TrackData));
+  // Look for 'normal' tracking, bail out if no such track is present.
+  unsigned trackIndex;
+  for (trackIndex = 0; trackIndex < nTracks; ++trackIndex) {
+    if (trackTable[trackIndex].track == 0x00000000) {
+      break;
+    }
+  }
+  if (trackIndex == nTracks) {
+    return false;
+  }
+  // Find list of tracking values, and check they won't overrun.
+  uint16_t offset = trackTable[trackIndex].offset;
+  if (offset > len - mNumTrakSizes * sizeof(uint16_t)) {
+    return false;
+  }
+  mTrakValues = reinterpret_cast<const AutoSwap_PRInt16*>(data + offset);
+  // Find the size subtable, and check it doesn't overrun the buffer.
+  mTrakSizeTable =
+      reinterpret_cast<const AutoSwap_PRInt32*>(data + sizeTableOffset);
+  if (mTrakSizeTable + mNumTrakSizes >
+      reinterpret_cast<const AutoSwap_PRInt32*>(data + len)) {
+    return false;
+  }
+  return true;
+}
+
+float gfxFontEntry::TrackingForCSSPx(float aSize) const {
+  MOZ_ASSERT(TrakTableInitialized() && mTrakTable && mTrakValues &&
+             mTrakSizeTable);
+
+  // Find index of first sizeTable entry that is >= the requested size.
+  int32_t fixedSize = int32_t(aSize * 65536.0);  // float -> 16.16 fixed-point
+  unsigned sizeIndex;
+  for (sizeIndex = 0; sizeIndex < mNumTrakSizes; ++sizeIndex) {
+    if (mTrakSizeTable[sizeIndex] >= fixedSize) {
+      break;
+    }
+  }
+  // Return the tracking value for the requested size, or an interpolated
+  // value if the exact size isn't found.
+  if (sizeIndex == mNumTrakSizes) {
+    // Request is larger than last entry in the table, so just use that.
+    // (We don't attempt to extrapolate more extreme tracking values than
+    // the largest or smallest present in the table.)
+    return int16_t(mTrakValues[mNumTrakSizes - 1]);
+  }
+  if (sizeIndex == 0 || mTrakSizeTable[sizeIndex] == fixedSize) {
+    // Found an exact match, or size was smaller than the first entry.
+    return int16_t(mTrakValues[sizeIndex]);
+  }
+  // Requested size falls between two entries: interpolate value.
+  double s0 = mTrakSizeTable[sizeIndex - 1] / 65536.0;  // 16.16 -> float
+  double s1 = mTrakSizeTable[sizeIndex] / 65536.0;
+  double t = (aSize - s0) / (s1 - s0);
+  return (1.0 - t) * int16_t(mTrakValues[sizeIndex - 1]) +
+         t * int16_t(mTrakValues[sizeIndex]);
+}
+
 void gfxFontEntry::SetupVariationRanges() {
   if (!gfxPlatform::GetPlatform()->HasVariationFontSupport() ||
       !StaticPrefs::layout_css_font_variations_enabled() || !HasVariations() ||
       IsUserFont()) {
     return;
   }
   AutoTArray<gfxFontVariationAxis, 4> axes;
   GetVariationAxes(axes);
--- a/gfx/thebes/gfxFontEntry.h
+++ b/gfx/thebes/gfxFontEntry.h
@@ -402,16 +402,25 @@ class gfxFontEntry {
                              const gfxFontStyle& aStyle);
 
   // Get the font's list of features (if any) for DevTools support.
   void GetFeatureInfo(nsTArray<gfxFontFeatureInfo>& aFeatureInfo);
 
   // This is only called on platforms where we use FreeType.
   virtual FT_MM_Var* GetMMVar() { return nullptr; }
 
+  // Return true if the font has a 'trak' table (and we can successfully
+  // interpret it), otherwise false. This will load and cache the table
+  // the first time it is called.
+  bool HasTrackingTable();
+
+  // Return the tracking (in font units) to be applied for the given size.
+  // (This is a floating-point number because of possible interpolation.)
+  float TrackingForCSSPx(float aSize) const;
+
   nsCString mName;
   nsCString mFamilyName;
 
   RefPtr<gfxCharacterMap> mCharacterMap;
 
   mozilla::fontlist::Face* mShmemFace = nullptr;
   const SharedBitSet* mShmemCharacterMap = nullptr;
 
@@ -522,16 +531,21 @@ class gfxFontEntry {
   virtual nsresult CopyFontTable(uint32_t aTableTag,
                                  nsTArray<uint8_t>& aBuffer) {
     MOZ_ASSERT_UNREACHABLE(
         "forgot to override either GetFontTable or "
         "CopyFontTable?");
     return NS_ERROR_FAILURE;
   }
 
+  // Helper for HasTrackingTable; check/parse the table and cache pointers
+  // to the subtables we need. Returns false on failure, in which case the
+  // table is unusable.
+  bool ParseTrakTable();
+
   // lookup the cmap in cached font data
   virtual already_AddRefed<gfxCharacterMap> GetCMAPFromFontInfo(
       FontInfoData* aFontInfoData, uint32_t& aUVSOffset);
 
   // helper for HasCharacter(), which is what client code should call
   virtual bool TestCharacterMap(uint32_t aCh);
 
   // Try to set mShmemCharacterMap, based on the char map in mShmemFace;
@@ -561,16 +575,27 @@ class gfxFontEntry {
   // each shaper is responsible to call ReleaseGrFace on its entry when
   // finished with it, so that we know when it can be deleted.
   gr_face* mGrFace = nullptr;
 
   // hashtable to map raw table data ptr back to its owning blob, for use by
   // graphite table-release callback
   nsDataHashtable<nsPtrHashKey<const void>, void*>* mGrTableMap = nullptr;
 
+  // For AAT font, a strong reference to the 'trak' table (if present).
+  hb_blob_t* const kTrakTableUninitialized = (hb_blob_t* const)(intptr_t(-1));
+  hb_blob_t* mTrakTable = kTrakTableUninitialized;
+  bool TrakTableInitialized() const {
+    return mTrakTable != kTrakTableUninitialized;
+  }
+
+  // Cached pointers to tables within 'trak', initialized by ParseTrakTable.
+  const mozilla::AutoSwap_PRInt16* mTrakValues;
+  const mozilla::AutoSwap_PRInt32* mTrakSizeTable;
+
   // number of current users of this entry's mGrFace
   nsrefcnt mGrFaceRefCnt = 0;
 
   static const void* GrGetTable(const void* aAppFaceHandle, unsigned int aName,
                                 size_t* aLen);
   static void GrReleaseTable(const void* aAppFaceHandle,
                              const void* aTableBuffer);
 
@@ -579,16 +604,18 @@ class gfxFontEntry {
   // handed over to platform APIs, so that it would become difficult (and
   // platform-specific) to measure it directly at report-gathering time.
   uint32_t mComputedSizeOfUserFont = 0;
 
   // Font's unitsPerEm from the 'head' table, if available (will be set to
   // kInvalidUPEM for non-sfnt font formats)
   uint16_t mUnitsPerEm = 0;
 
+  uint16_t mNumTrakSizes;
+
  private:
   /**
    * Font table hashtable, to support GetFontTable for harfbuzz.
    *
    * The harfbuzz shaper (and potentially other clients) needs access to raw
    * font table data. This needs to be cached so that it can be used
    * repeatedly (each time we construct a text run; in some cases, for
    * each character/glyph within the run) without re-fetching large tables
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -190,54 +190,49 @@ bool gfxMacFont::ShapeText(DrawTarget* a
                            uint32_t aOffset, uint32_t aLength, Script aScript,
                            bool aVertical, RoundingFlags aRounding,
                            gfxShapedText* aShapedText) {
   if (!mIsValid) {
     NS_WARNING("invalid font! expect incorrect text rendering");
     return false;
   }
 
-  bool ok = false;
-
   // Currently, we don't support vertical shaping via CoreText,
   // so we ignore RequiresAATLayout if vertical is requested.
   auto macFontEntry = static_cast<MacOSFontEntry*>(GetFontEntry());
   if (macFontEntry->RequiresAATLayout() && !aVertical &&
       StaticPrefs::CoreTextEnabled()) {
     if (!mCoreTextShaper) {
       mCoreTextShaper = MakeUnique<gfxCoreTextShaper>(this);
     }
-    ok = mCoreTextShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
-                                    aScript, aVertical, aRounding, aShapedText);
-    if (ok) {
+    if (mCoreTextShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
+                                   aScript, aVertical, aRounding,
+                                   aShapedText)) {
       PostShapingFixup(aDrawTarget, aText, aOffset, aLength, aVertical,
                        aShapedText);
+      if (GetFontEntry()->HasTrackingTable()) {
+        // Convert font size from device pixels back to CSS px
+        // to use in selecting tracking value
+        float trackSize = GetAdjustedSize() *
+                          aShapedText->GetAppUnitsPerDevUnit() /
+                          AppUnitsPerCSSPixel();
+        float tracking =
+            GetFontEntry()->TrackingForCSSPx(trackSize) * mFUnitsConvFactor;
+        // Applying tracking is a lot like the adjustment we do for
+        // synthetic bold: we want to apply between clusters, not to
+        // non-spacing glyphs within a cluster. So we can reuse that
+        // helper here.
+        aShapedText->AdjustAdvancesForSyntheticBold(tracking, aOffset, aLength);
+      }
+      return true;
     }
   }
 
-  if (!ok) {
-    ok = gfxFont::ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
+  return gfxFont::ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
                             aVertical, aRounding, aShapedText);
-  }
-
-  if (ok && macFontEntry->HasTrackingTable()) {
-    // Convert font size from device pixels back to CSS px
-    // to use in selecting tracking value
-    float trackSize = GetAdjustedSize() * aShapedText->GetAppUnitsPerDevUnit() /
-                      AppUnitsPerCSSPixel();
-    float tracking =
-        macFontEntry->TrackingForCSSPx(trackSize) * mFUnitsConvFactor;
-    // Applying tracking is a lot like the adjustment we do for
-    // synthetic bold: we want to apply between clusters, not to
-    // non-spacing glyphs within a cluster. So we can reuse that
-    // helper here.
-    aShapedText->AdjustAdvancesForSyntheticBold(tracking, aOffset, aLength);
-  }
-
-  return ok;
 }
 
 bool gfxMacFont::SetupCairoFont(DrawTarget* aDrawTarget) {
   if (cairo_scaled_font_status(mScaledFont) != CAIRO_STATUS_SUCCESS) {
     // Don't cairo_set_scaled_font as that would propagate the error to
     // the cairo_t, precluding any further drawing.
     return false;
   }
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -34,20 +34,17 @@ class MacOSFontEntry : public gfxFontEnt
   MacOSFontEntry(const nsACString& aPostscriptName, WeightRange aWeight,
                  bool aIsStandardFace = false, double aSizeHint = 0.0);
 
   // for use with data fonts
   MacOSFontEntry(const nsACString& aPostscriptName, CGFontRef aFontRef,
                  WeightRange aWeight, StretchRange aStretch,
                  SlantStyleRange aStyle, bool aIsDataUserFont, bool aIsLocal);
 
-  virtual ~MacOSFontEntry() {
-    hb_blob_destroy(mTrakTable);
-    ::CGFontRelease(mFontRef);
-  }
+  virtual ~MacOSFontEntry() { ::CGFontRelease(mFontRef); }
 
   gfxFontEntry* Clone() const override;
 
   CGFontRef GetFontRef();
 
   // override gfxFontEntry table access function to bypass table cache,
   // use CGFontRef API to get direct access to system font data
   hb_blob_t* GetFontTable(uint32_t aTag) override;
@@ -62,77 +59,54 @@ class MacOSFontEntry : public gfxFontEnt
   bool HasVariations() override;
   void GetVariationAxes(
       nsTArray<gfxFontVariationAxis>& aVariationAxes) override;
   void GetVariationInstances(
       nsTArray<gfxFontVariationInstance>& aInstances) override;
 
   bool IsCFF();
 
-  // Return true if the font has a 'trak' table (and we can successfully
-  // interpret it), otherwise false. This will load and cache the table
-  // the first time it is called.
-  bool HasTrackingTable();
-
   bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag) override;
 
-  // Return the tracking (in font units) to be applied for the given size.
-  // (This is a floating-point number because of possible interpolation.)
-  float TrackingForCSSPx(float aPointSize) const;
-
  protected:
   gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override;
 
   bool HasFontTable(uint32_t aTableTag) override;
 
-  // Helper for HasTrackingTable; check/parse the table and cache pointers
-  // to the subtables we need. Returns false on failure, in which case the
-  // table is unusable.
-  bool ParseTrakTable();
-
   static void DestroyBlobFunc(void* aUserData);
 
   CGFontRef
       mFontRef;  // owning reference to the CGFont, released on destruction
 
   double mSizeHint;
 
   bool mFontRefInitialized;
   bool mRequiresAAT;
   bool mIsCFF;
   bool mIsCFFInitialized;
   bool mHasVariations;
   bool mHasVariationsInitialized;
   bool mHasAATSmallCaps;
   bool mHasAATSmallCapsInitialized;
-  bool mCheckedForTracking;
 
   // To work around Core Text's mishandling of the default value for 'opsz',
   // we need to record whether the font has an a optical size axis, what its
   // range and default values are, and a usable close-to-default alternative.
   // (See bug 1457417 for details.)
   // These fields are used by gfxMacFont, but stored in the font entry so
   // that only a single font instance needs to inspect the available
   // variations.
   bool mCheckedForOpszAxis;
   bool mHasOpszAxis;
   gfxFontVariationAxis mOpszAxis;
   float mAdjustedDefaultOpsz;
 
   nsTHashtable<nsUint32HashKey> mAvailableTables;
 
   mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontMac> mUnscaledFont;
-
-  // For AAT font being shaped by Core Text, a strong reference to the 'trak'
-  // table (if present).
-  hb_blob_t* mTrakTable;
-  // Cached pointers to tables within 'trak', initialized by ParseTrakTable.
-  const mozilla::AutoSwap_PRInt16* mTrakValues;
-  const mozilla::AutoSwap_PRInt32* mTrakSizeTable;
-  uint16_t mNumTrakSizes;
 };
 
 class gfxMacPlatformFontList : public gfxPlatformFontList {
  public:
   static gfxMacPlatformFontList* PlatformFontList() {
     return static_cast<gfxMacPlatformFontList*>(sPlatformFontList);
   }
 
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -355,22 +355,17 @@ MacOSFontEntry::MacOSFontEntry(const nsA
       mFontRefInitialized(false),
       mRequiresAAT(false),
       mIsCFF(false),
       mIsCFFInitialized(false),
       mHasVariations(false),
       mHasVariationsInitialized(false),
       mHasAATSmallCaps(false),
       mHasAATSmallCapsInitialized(false),
-      mCheckedForTracking(false),
-      mCheckedForOpszAxis(false),
-      mTrakTable(nullptr),
-      mTrakValues(nullptr),
-      mTrakSizeTable(nullptr),
-      mNumTrakSizes(0) {
+      mCheckedForOpszAxis(false) {
   mWeightRange = aWeight;
 }
 
 MacOSFontEntry::MacOSFontEntry(const nsACString& aPostscriptName, CGFontRef aFontRef,
                                WeightRange aWeight, StretchRange aStretch, SlantStyleRange aStyle,
                                bool aIsDataUserFont, bool aIsLocalUserFont)
     : gfxFontEntry(aPostscriptName, false),
       mFontRef(NULL),
@@ -378,22 +373,17 @@ MacOSFontEntry::MacOSFontEntry(const nsA
       mFontRefInitialized(false),
       mRequiresAAT(false),
       mIsCFF(false),
       mIsCFFInitialized(false),
       mHasVariations(false),
       mHasVariationsInitialized(false),
       mHasAATSmallCaps(false),
       mHasAATSmallCapsInitialized(false),
-      mCheckedForTracking(false),
-      mCheckedForOpszAxis(false),
-      mTrakTable(nullptr),
-      mTrakValues(nullptr),
-      mTrakSizeTable(nullptr),
-      mNumTrakSizes(0) {
+      mCheckedForOpszAxis(false) {
   mFontRef = aFontRef;
   mFontRefInitialized = true;
   ::CFRetain(mFontRef);
 
   mWeightRange = aWeight;
   mStretchRange = aStretch;
   mFixedPitch = false;  // xxx - do we need this for downloaded fonts?
   mStyleRange = aStyle;
@@ -513,140 +503,16 @@ bool MacOSFontEntry::HasFontTable(uint32
       mAvailableTables.PutEntry(tag);
     }
     ::CFRelease(tags);
   }
 
   return mAvailableTables.GetEntry(aTableTag);
 }
 
-typedef struct {
-  AutoSwap_PRUint32 version;
-  AutoSwap_PRUint16 format;
-  AutoSwap_PRUint16 horizOffset;
-  AutoSwap_PRUint16 vertOffset;
-  AutoSwap_PRUint16 reserved;
-  //  TrackData horizData;
-  //  TrackData vertData;
-} TrakHeader;
-
-typedef struct {
-  AutoSwap_PRUint16 nTracks;
-  AutoSwap_PRUint16 nSizes;
-  AutoSwap_PRUint32 sizeTableOffset;
-  //  trackTableEntry trackTable[];
-  //  fixed32 sizeTable[];
-} TrackData;
-
-typedef struct {
-  AutoSwap_PRUint32 track;
-  AutoSwap_PRUint16 nameIndex;
-  AutoSwap_PRUint16 offset;
-} TrackTableEntry;
-
-bool MacOSFontEntry::HasTrackingTable() {
-  if (!mCheckedForTracking) {
-    mCheckedForTracking = true;
-    mTrakTable = GetFontTable(TRUETYPE_TAG('t', 'r', 'a', 'k'));
-    if (mTrakTable) {
-      if (!ParseTrakTable()) {
-        hb_blob_destroy(mTrakTable);
-        mTrakTable = nullptr;
-      }
-    }
-  }
-  return mTrakTable != nullptr;
-}
-
-bool MacOSFontEntry::ParseTrakTable() {
-  // Check table validity and set up the subtable pointers we need;
-  // if 'trak' table is invalid, or doesn't contain a 'normal' track,
-  // return false to tell the caller not to try using it.
-  unsigned int len;
-  const char* data = hb_blob_get_data(mTrakTable, &len);
-  if (len < sizeof(TrakHeader)) {
-    return false;
-  }
-  auto trak = reinterpret_cast<const TrakHeader*>(data);
-  uint16_t horizOffset = trak->horizOffset;
-  if (trak->version != 0x00010000 || uint16_t(trak->format) != 0 || horizOffset == 0 ||
-      uint16_t(trak->reserved) != 0) {
-    return false;
-  }
-  // Find the horizontal trackData, and check it doesn't overrun the buffer.
-  if (horizOffset > len - sizeof(TrackData)) {
-    return false;
-  }
-  auto trackData = reinterpret_cast<const TrackData*>(data + horizOffset);
-  uint16_t nTracks = trackData->nTracks;
-  mNumTrakSizes = trackData->nSizes;
-  if (nTracks == 0 || mNumTrakSizes < 2) {
-    return false;
-  }
-  uint32_t sizeTableOffset = trackData->sizeTableOffset;
-  // Find the trackTable, and check it doesn't overrun the buffer.
-  if (horizOffset > len - (sizeof(TrackData) + nTracks * sizeof(TrackTableEntry))) {
-    return false;
-  }
-  auto trackTable =
-      reinterpret_cast<const TrackTableEntry*>(data + horizOffset + sizeof(TrackData));
-  // Look for 'normal' tracking, bail out if no such track is present.
-  unsigned trackIndex;
-  for (trackIndex = 0; trackIndex < nTracks; ++trackIndex) {
-    if (trackTable[trackIndex].track == 0x00000000) {
-      break;
-    }
-  }
-  if (trackIndex == nTracks) {
-    return false;
-  }
-  // Find list of tracking values, and check they won't overrun.
-  uint16_t offset = trackTable[trackIndex].offset;
-  if (offset > len - mNumTrakSizes * sizeof(uint16_t)) {
-    return false;
-  }
-  mTrakValues = reinterpret_cast<const AutoSwap_PRInt16*>(data + offset);
-  // Find the size subtable, and check it doesn't overrun the buffer.
-  mTrakSizeTable = reinterpret_cast<const AutoSwap_PRInt32*>(data + sizeTableOffset);
-  if (mTrakSizeTable + mNumTrakSizes > reinterpret_cast<const AutoSwap_PRInt32*>(data + len)) {
-    return false;
-  }
-  return true;
-}
-
-float MacOSFontEntry::TrackingForCSSPx(float aSize) const {
-  MOZ_ASSERT(mTrakTable && mTrakValues && mTrakSizeTable);
-
-  // Find index of first sizeTable entry that is >= the requested size.
-  Fixed fixedSize = X2Fix(aSize);
-  unsigned sizeIndex;
-  for (sizeIndex = 0; sizeIndex < mNumTrakSizes; ++sizeIndex) {
-    if (mTrakSizeTable[sizeIndex] >= fixedSize) {
-      break;
-    }
-  }
-  // Return the tracking value for the requested size, or an interpolated
-  // value if the exact size isn't found.
-  if (sizeIndex == mNumTrakSizes) {
-    // Request is larger than last entry in the table, so just use that.
-    // (We don't attempt to extrapolate more extreme tracking values than
-    // the largest or smallest present in the table.)
-    return int16_t(mTrakValues[mNumTrakSizes - 1]);
-  }
-  if (sizeIndex == 0 || mTrakSizeTable[sizeIndex] == fixedSize) {
-    // Found an exact match, or size was smaller than the first entry.
-    return int16_t(mTrakValues[sizeIndex]);
-  }
-  // Requested size falls between two entries: interpolate value.
-  double s0 = Fix2X(mTrakSizeTable[sizeIndex - 1]);
-  double s1 = Fix2X(mTrakSizeTable[sizeIndex]);
-  double t = (aSize - s0) / (s1 - s0);
-  return (1.0 - t) * int16_t(mTrakValues[sizeIndex - 1]) + t * int16_t(mTrakValues[sizeIndex]);
-}
-
 static bool CheckForAATSmallCaps(CFArrayRef aFeatures) {
   // Walk the array of feature descriptors from the font, and see whether
   // a small-caps feature setting is available.
   // Just bail out (returning false) if at any point we fail to find the
   // expected dictionary keys, etc; if the font has bad data, we don't even
   // try to search the rest of it.
   auto numFeatures = CFArrayGetCount(aFeatures);
   for (auto f = 0; f < numFeatures; ++f) {