diff --git a/gfx/thebes/gfxFT2FontBase.cpp b/gfx/thebes/gfxFT2FontBase.cpp index 05af57e0ff67..bcdd1d60a3e3 100644 --- a/gfx/thebes/gfxFT2FontBase.cpp +++ b/gfx/thebes/gfxFT2FontBase.cpp @@ -138,14 +138,6 @@ static void SnapLineToPixels(gfxFloat& aOffset, gfxFloat& aSize) { aSize = snappedSize; } -static inline gfxRect ScaleGlyphBounds(const IntRect& aBounds, - gfxFloat aScale) { - return gfxRect(FLOAT_FROM_26_6(aBounds.x) * aScale, - FLOAT_FROM_26_6(aBounds.y) * aScale, - FLOAT_FROM_26_6(aBounds.width) * aScale, - FLOAT_FROM_26_6(aBounds.height) * aScale); -} - /** * Get extents for a simple character representable by a single glyph. * The return value is the glyph id of that glyph or zero if no such glyph @@ -156,14 +148,10 @@ uint32_t gfxFT2FontBase::GetCharExtents(char aChar, gfxFloat* aWidth, gfxRect* aBounds) { FT_UInt gid = GetGlyph(aChar); int32_t width; - IntRect bounds; - if (gid && GetFTGlyphExtents(gid, &width, &bounds)) { + if (gid && GetFTGlyphExtents(gid, &width, aBounds)) { if (aWidth) { *aWidth = FLOAT_FROM_16_16(width); } - if (aBounds) { - *aBounds = ScaleGlyphBounds(bounds, GetAdjustedSize() / mFTSize); - } return gid; } else { return 0; @@ -501,7 +489,7 @@ uint32_t gfxFT2FontBase::GetGlyph(uint32_t unicode, } FT_Vector gfxFT2FontBase::GetEmboldenStrength(FT_Face aFace) { - FT_Vector strength = {0, 0}; + FT_Vector strength = { 0, 0 }; if (!mEmbolden) { return strength; } @@ -520,7 +508,7 @@ FT_Vector gfxFT2FontBase::GetEmboldenStrength(FT_Face aFace) { } bool gfxFT2FontBase::GetFTGlyphExtents(uint16_t aGID, int32_t* aAdvance, - IntRect* aBounds) { + gfxRect* aBounds) { gfxFT2LockedFace face(this); MOZ_ASSERT(face.get()); if (!face.get()) { @@ -529,7 +517,8 @@ bool gfxFT2FontBase::GetFTGlyphExtents(uint16_t aGID, int32_t* aAdvance, return false; } - if (Factory::LoadFTGlyph(face.get(), aGID, mFTLoadFlags) != FT_Err_Ok) { + FT_Error ftError = Factory::LoadFTGlyph(face.get(), aGID, mFTLoadFlags); + if (ftError != FT_Err_Ok) { // FT_Face was somehow broken/invalid? Don't try to access glyph slot. // This probably shouldn't happen, but does: see bug 1440938. NS_WARNING("failed to load glyph!"); @@ -583,56 +572,36 @@ bool gfxFT2FontBase::GetFTGlyphExtents(uint16_t aGID, int32_t* aAdvance, x2 = (x2 + 63) & -64; y2 = (y2 + 63) & -64; } - *aBounds = IntRect(x, y, x2 - x, y2 - y); + *aBounds = gfxRect(FLOAT_FROM_26_6(x) * extentsScale, + FLOAT_FROM_26_6(y) * extentsScale, + FLOAT_FROM_26_6(x2 - x) * extentsScale, + FLOAT_FROM_26_6(y2 - y) * extentsScale); } return true; } -/** - * Get the cached glyph metrics for the glyph id if available. Otherwise, query - * FreeType for the glyph extents and initialize the glyph metrics. - */ -const gfxFT2FontBase::GlyphMetrics& gfxFT2FontBase::GetCachedGlyphMetrics( - uint16_t aGID) { - if (!mGlyphMetrics) { - mGlyphMetrics = - mozilla::MakeUnique>( - 128); - } - - if (const GlyphMetrics* metrics = mGlyphMetrics->GetValue(aGID)) { - return *metrics; - } - - GlyphMetrics& metrics = mGlyphMetrics->GetOrInsert(aGID); - IntRect bounds; - if (GetFTGlyphExtents(aGID, &metrics.mAdvance, &bounds)) { - metrics.SetBounds(bounds); - } - return metrics; -} - int32_t gfxFT2FontBase::GetGlyphWidth(uint16_t aGID) { - return GetCachedGlyphMetrics(aGID).mAdvance; + if (!mGlyphWidths) { + mGlyphWidths = + mozilla::MakeUnique>(128); + } + + int32_t width; + if (mGlyphWidths->Get(aGID, &width)) { + return width; + } + + if (!GetFTGlyphExtents(aGID, &width)) { + width = 0; + } + mGlyphWidths->Put(aGID, width); + + return width; } bool gfxFT2FontBase::GetGlyphBounds(uint16_t aGID, gfxRect* aBounds, bool aTight) { - const GlyphMetrics& metrics = GetCachedGlyphMetrics(aGID); - if (!metrics.HasValidBounds()) { - return false; - } - // Check if there are cached bounds and use those if available. Otherwise, - // fall back to directly querying the glyph extents. - IntRect bounds; - if (metrics.HasCachedBounds()) { - bounds = metrics.GetBounds(); - } else if (!GetFTGlyphExtents(aGID, nullptr, &bounds)) { - return false; - } - // The bounds are stored unscaled, so must be scaled to the adjusted size. - *aBounds = ScaleGlyphBounds(bounds, GetAdjustedSize() / mFTSize); - return true; + return GetFTGlyphExtents(aGID, nullptr, aBounds); } // For variation fonts, figure out the variation coordinates to be applied diff --git a/gfx/thebes/gfxFT2FontBase.h b/gfx/thebes/gfxFT2FontBase.h index 82d70eb863a6..63aac5dfc63f 100644 --- a/gfx/thebes/gfxFT2FontBase.h +++ b/gfx/thebes/gfxFT2FontBase.h @@ -48,7 +48,7 @@ class gfxFT2FontBase : public gfxFont { // Get advance (and optionally bounds) of a single glyph from FreeType, // and return true, or return false if we failed. bool GetFTGlyphExtents(uint16_t aGID, int32_t* aWidth, - mozilla::gfx::IntRect* aBounds = nullptr); + gfxRect* aBounds = nullptr); protected: void InitMetrics(); @@ -70,50 +70,7 @@ class gfxFT2FontBase : public gfxFont { // range reported by the face. nsTArray mCoords; - // Store cached glyph metrics for reasonably small glyph sizes. The bounds - // are stored unscaled to losslessly compress 26.6 fixed point to an int16_t. - // Larger glyphs are handled directly via GetFTGlyphExtents. - struct GlyphMetrics { - // Set the X coord to INT16_MIN to signal the bounds are invalid, or - // INT16_MAX to signal that the bounds would overflow an int16_t. - enum { INVALID = INT16_MIN, OVERFLOW = INT16_MAX }; - - GlyphMetrics() : mAdvance(0), mX(INVALID), mY(0), mWidth(0), mHeight(0) {} - - bool HasValidBounds() const { return mX != INVALID; } - bool HasCachedBounds() const { return mX != OVERFLOW; } - - // If the bounds can fit in an int16_t, set them. Otherwise, leave the - // bounds invalid to signal that GetFTGlyphExtents should be queried - // directly. - void SetBounds(const mozilla::gfx::IntRect& aBounds) { - if (aBounds.x > INT16_MIN && aBounds.x < INT16_MAX && - aBounds.y > INT16_MIN && aBounds.y < INT16_MAX && - aBounds.width <= UINT16_MAX && aBounds.height <= UINT16_MAX) { - mX = aBounds.x; - mY = aBounds.y; - mWidth = aBounds.width; - mHeight = aBounds.height; - } else { - mX = OVERFLOW; - } - } - - mozilla::gfx::IntRect GetBounds() const { - return mozilla::gfx::IntRect(mX, mY, mWidth, mHeight); - } - - int32_t mAdvance; - int16_t mX; - int16_t mY; - uint16_t mWidth; - uint16_t mHeight; - }; - - const GlyphMetrics& GetCachedGlyphMetrics(uint16_t aGID); - - mozilla::UniquePtr> - mGlyphMetrics; + mozilla::UniquePtr> mGlyphWidths; }; // Helper classes used for clearing out user font data when FT font