Verified Commit 4846c1da authored by Jonathan Kew's avatar Jonathan Kew Committed by ma1
Browse files

Bug 1890204 - Ensure font entry's unitsPerEm and font extents are initialized...

Bug 1890204 - Ensure font entry's unitsPerEm and font extents are initialized when gfxFont is created. r=gfx-reviewers,lsalzman

This means that by the time we potentially call GetFontExtents() when drawing,
the extents fields are guaranteed to have been been initialized, and there's no
risk of the (read-only) access here racing with setting them in UnitsPerEm().

Differential Revision: https://phabricator.services.mozilla.com/D206920
parent 62619558
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -952,6 +952,10 @@ gfxFont::gfxFont(const RefPtr<UnscaledFont>& aUnscaledFont,
  }

  mKerningSet = HasFeatureSet(HB_TAG('k', 'e', 'r', 'n'), mKerningEnabled);

  // Ensure the gfxFontEntry's unitsPerEm and extents fields are initialized,
  // so that GetFontExtents can use them without risk of races.
  Unused << mFontEntry->UnitsPerEm();
}

gfxFont::~gfxFont() {
+16 −6
Original line number Diff line number Diff line
@@ -262,14 +262,22 @@ already_AddRefed<gfxFont> gfxFontEntry::FindOrMakeFont(
}

uint16_t gfxFontEntry::UnitsPerEm() {
  if (!mUnitsPerEm) {
  {
    AutoReadLock lock(mLock);
    if (mUnitsPerEm) {
      return mUnitsPerEm;
    }
  }

  AutoTable headTable(this, TRUETYPE_TAG('h', 'e', 'a', 'd'));
  AutoWriteLock lock(mLock);

  if (!mUnitsPerEm) {
    if (headTable) {
      uint32_t len;
      const HeadTable* head =
          reinterpret_cast<const HeadTable*>(hb_blob_get_data(headTable, &len));
      if (len >= sizeof(HeadTable)) {
        mUnitsPerEm = head->unitsPerEm;
        if (int16_t(head->xMax) > int16_t(head->xMin) &&
            int16_t(head->yMax) > int16_t(head->yMin)) {
          mXMin = head->xMin;
@@ -277,6 +285,7 @@ uint16_t gfxFontEntry::UnitsPerEm() {
          mXMax = head->xMax;
          mYMax = head->yMax;
        }
        mUnitsPerEm = head->unitsPerEm;
      }
    }

@@ -286,11 +295,12 @@ uint16_t gfxFontEntry::UnitsPerEm() {
      mUnitsPerEm = kInvalidUPEM;
    }
  }

  return mUnitsPerEm;
}

bool gfxFontEntry::HasSVGGlyph(uint32_t aGlyphId) {
  NS_ASSERTION(mSVGInitialized,
  MOZ_ASSERT(mSVGInitialized,
             "SVG data has not yet been loaded. TryGetSVGData() first.");
  return GetSVGGlyphs()->HasSVGGlyph(aGlyphId);
}
@@ -309,7 +319,7 @@ bool gfxFontEntry::GetSVGGlyphExtents(DrawTarget* aDrawTarget,

void gfxFontEntry::RenderSVGGlyph(gfxContext* aContext, uint32_t aGlyphId,
                                  SVGContextPaint* aContextPaint) {
  NS_ASSERTION(mSVGInitialized,
  MOZ_ASSERT(mSVGInitialized,
             "SVG data has not yet been loaded. TryGetSVGData() first.");
  GetSVGGlyphs()->RenderGlyph(aContext, aGlyphId, aContextPaint);
}
+3 −0
Original line number Diff line number Diff line
@@ -538,6 +538,9 @@ class gfxFontEntry {

  mozilla::gfx::Rect GetFontExtents(float aFUnitScaleFactor) const {
    // Flip the y-axis here to match the orientation of Gecko's coordinates.
    // We don't need to take a lock here because the min/max fields are inert
    // after initialization, and we make sure to initialize them at gfxFont-
    // creation time.
    return mozilla::gfx::Rect(float(mXMin) * aFUnitScaleFactor,
                              float(-mYMax) * aFUnitScaleFactor,
                              float(mXMax - mXMin) * aFUnitScaleFactor,