gfxFT2FontBase.h (5450B)
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef GFX_FT2FONTBASE_H 7 #define GFX_FT2FONTBASE_H 8 9 #include "gfxContext.h" 10 #include "gfxFont.h" 11 #include "gfxFontEntry.h" 12 #include "mozilla/gfx/2D.h" 13 #include "mozilla/gfx/UnscaledFontFreeType.h" 14 #include "nsTHashMap.h" 15 #include "nsHashKeys.h" 16 17 class gfxFT2FontBase; 18 19 namespace mozilla { 20 namespace gfx { 21 class FTUserFontData; 22 } 23 } // namespace mozilla 24 25 class gfxFT2FontEntryBase : public gfxFontEntry { 26 public: 27 explicit gfxFT2FontEntryBase(const nsACString& aName) : gfxFontEntry(aName) {} 28 29 uint32_t GetGlyph(uint32_t aCharCode, gfxFT2FontBase* aFont); 30 31 static bool FaceHasTable(mozilla::gfx::SharedFTFace*, uint32_t aTableTag); 32 static nsresult CopyFaceTable(mozilla::gfx::SharedFTFace*, uint32_t aTableTag, 33 nsTArray<uint8_t>&); 34 35 virtual mozilla::gfx::FTUserFontData* GetUserFontData() = 0; 36 37 size_t ComputedSizeOfExcludingThis( 38 mozilla::MallocSizeOf aMallocSizeOf) override; 39 40 private: 41 enum { kNumCmapCacheSlots = 256 }; 42 43 struct CmapCacheSlot { 44 CmapCacheSlot() : mCharCode(0), mGlyphIndex(0) {} 45 46 uint32_t mCharCode; 47 uint32_t mGlyphIndex; 48 }; 49 50 mozilla::UniquePtr<CmapCacheSlot[]> mCmapCache MOZ_GUARDED_BY(mLock); 51 }; 52 53 class gfxFT2FontBase : public gfxFont { 54 public: 55 gfxFT2FontBase( 56 const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont, 57 RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, gfxFontEntry* aFontEntry, 58 const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden); 59 60 uint32_t GetGlyph(uint32_t aCharCode) { 61 auto* entry = static_cast<gfxFT2FontEntryBase*>(mFontEntry.get()); 62 return entry->GetGlyph(aCharCode, this); 63 } 64 65 bool ProvidesGetGlyph() const override { return true; } 66 virtual uint32_t GetGlyph(uint32_t unicode, 67 uint32_t variation_selector) override; 68 69 bool ProvidesGlyphWidths() const override { return true; } 70 int32_t GetGlyphWidth(uint16_t aGID) override { 71 return GetCachedGlyphMetrics(aGID).mAdvance; 72 } 73 74 bool GetGlyphBounds(uint16_t aGID, gfxRect* aBounds, bool aTight) override; 75 76 FontType GetType() const override { return FONT_TYPE_FT2; } 77 78 bool ShouldRoundXOffset(cairo_t* aCairo) const override; 79 80 static void SetupVarCoords(FT_MM_Var* aMMVar, 81 const nsTArray<gfxFontVariation>& aVariations, 82 FT_Face aFTFace); 83 84 FT_Face LockFTFace() const; 85 void UnlockFTFace() const; 86 87 private: 88 uint32_t GetCharExtents(uint32_t aChar, gfxFloat* aWidth, 89 gfxRect* aBounds = nullptr); 90 91 // Get advance (and optionally bounds) of a single glyph from FreeType, 92 // and return true, or return false if we failed. 93 bool GetFTGlyphExtents(uint16_t aGID, int32_t* aWidth, 94 mozilla::gfx::IntRect* aBounds = nullptr); 95 96 protected: 97 ~gfxFT2FontBase() override; 98 void InitMetrics(); 99 const Metrics& GetHorizontalMetrics() const override { return mMetrics; } 100 FT_Vector GetEmboldenStrength(FT_Face aFace) const; 101 102 RefPtr<mozilla::gfx::SharedFTFace> mFTFace; 103 104 Metrics mMetrics; 105 int mFTLoadFlags; 106 bool mEmbolden; 107 gfxFloat mFTSize; 108 109 // For variation/multiple-master fonts, this will be an array of the values 110 // for each axis, as specified by mStyle.variationSettings (or the font's 111 // default for axes not present in variationSettings). Values here are in 112 // freetype's 16.16 fixed-point format, and clamped to the valid min/max 113 // range reported by the face. 114 nsTArray<FT_Fixed> mCoords; 115 116 // Store cached glyph metrics for reasonably small glyph sizes. The bounds 117 // are stored unscaled to losslessly compress 26.6 fixed point to an int16_t. 118 // Larger glyphs are handled directly via GetFTGlyphExtents. 119 struct GlyphMetrics { 120 // Set the X coord to INT16_MIN to signal the bounds are invalid, or 121 // INT16_MAX to signal that the bounds would overflow an int16_t. 122 enum { INVALID = INT16_MIN, LARGE = INT16_MAX }; 123 124 GlyphMetrics() : mAdvance(0), mX(INVALID), mY(0), mWidth(0), mHeight(0) {} 125 126 bool HasValidBounds() const { return mX != INVALID; } 127 bool HasCachedBounds() const { return mX != LARGE; } 128 129 // If the bounds can fit in an int16_t, set them. Otherwise, leave the 130 // bounds invalid to signal that GetFTGlyphExtents should be queried 131 // directly. 132 void SetBounds(const mozilla::gfx::IntRect& aBounds) { 133 if (aBounds.x > INT16_MIN && aBounds.x < INT16_MAX && 134 aBounds.y > INT16_MIN && aBounds.y < INT16_MAX && 135 aBounds.width <= UINT16_MAX && aBounds.height <= UINT16_MAX) { 136 mX = aBounds.x; 137 mY = aBounds.y; 138 mWidth = aBounds.width; 139 mHeight = aBounds.height; 140 } else { 141 mX = LARGE; 142 } 143 } 144 145 mozilla::gfx::IntRect GetBounds() const { 146 return mozilla::gfx::IntRect(mX, mY, mWidth, mHeight); 147 } 148 149 int32_t mAdvance; 150 int16_t mX; 151 int16_t mY; 152 uint16_t mWidth; 153 uint16_t mHeight; 154 }; 155 156 const GlyphMetrics& GetCachedGlyphMetrics( 157 uint16_t aGID, mozilla::gfx::IntRect* aBounds = nullptr); 158 159 mozilla::UniquePtr<nsTHashMap<nsUint32HashKey, GlyphMetrics>> mGlyphMetrics 160 MOZ_GUARDED_BY(mLock); 161 }; 162 163 #endif /* GFX_FT2FONTBASE_H */