Backed out changeset 1b14354719c0 (bug 1895254) for causing bustages on NavigationTra...
[gecko.git] / gfx / thebes / gfxFT2FontBase.h
blob08a79c2ada7fbfc8fbdd1a115283c413a227b646
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/. */
6 #ifndef GFX_FT2FONTBASE_H
7 #define GFX_FT2FONTBASE_H
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"
17 class gfxFT2FontBase;
19 class gfxFT2FontEntryBase : public gfxFontEntry {
20 public:
21 explicit gfxFT2FontEntryBase(const nsACString& aName) : gfxFontEntry(aName) {}
23 uint32_t GetGlyph(uint32_t aCharCode, gfxFT2FontBase* aFont);
25 static bool FaceHasTable(mozilla::gfx::SharedFTFace*, uint32_t aTableTag);
26 static nsresult CopyFaceTable(mozilla::gfx::SharedFTFace*, uint32_t aTableTag,
27 nsTArray<uint8_t>&);
29 private:
30 enum { kNumCmapCacheSlots = 256 };
32 struct CmapCacheSlot {
33 CmapCacheSlot() : mCharCode(0), mGlyphIndex(0) {}
35 uint32_t mCharCode;
36 uint32_t mGlyphIndex;
39 mozilla::UniquePtr<CmapCacheSlot[]> mCmapCache MOZ_GUARDED_BY(mLock);
42 class gfxFT2FontBase : public gfxFont {
43 public:
44 gfxFT2FontBase(
45 const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
46 RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, gfxFontEntry* aFontEntry,
47 const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
49 uint32_t GetGlyph(uint32_t aCharCode) {
50 auto* entry = static_cast<gfxFT2FontEntryBase*>(mFontEntry.get());
51 return entry->GetGlyph(aCharCode, this);
54 bool ProvidesGetGlyph() const override { return true; }
55 virtual uint32_t GetGlyph(uint32_t unicode,
56 uint32_t variation_selector) override;
58 bool ProvidesGlyphWidths() const override { return true; }
59 int32_t GetGlyphWidth(uint16_t aGID) override {
60 return GetCachedGlyphMetrics(aGID).mAdvance;
63 bool GetGlyphBounds(uint16_t aGID, gfxRect* aBounds, bool aTight) override;
65 FontType GetType() const override { return FONT_TYPE_FT2; }
67 bool ShouldRoundXOffset(cairo_t* aCairo) const override;
69 static void SetupVarCoords(FT_MM_Var* aMMVar,
70 const nsTArray<gfxFontVariation>& aVariations,
71 FT_Face aFTFace);
73 FT_Face LockFTFace() const;
74 void UnlockFTFace() const;
76 private:
77 uint32_t GetCharExtents(uint32_t aChar, gfxFloat* aWidth,
78 gfxRect* aBounds = nullptr);
80 // Get advance (and optionally bounds) of a single glyph from FreeType,
81 // and return true, or return false if we failed.
82 bool GetFTGlyphExtents(uint16_t aGID, int32_t* aWidth,
83 mozilla::gfx::IntRect* aBounds = nullptr);
85 protected:
86 ~gfxFT2FontBase() override;
87 void InitMetrics();
88 const Metrics& GetHorizontalMetrics() const override { return mMetrics; }
89 FT_Vector GetEmboldenStrength(FT_Face aFace) const;
91 RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
93 Metrics mMetrics;
94 int mFTLoadFlags;
95 bool mEmbolden;
96 gfxFloat mFTSize;
98 // For variation/multiple-master fonts, this will be an array of the values
99 // for each axis, as specified by mStyle.variationSettings (or the font's
100 // default for axes not present in variationSettings). Values here are in
101 // freetype's 16.16 fixed-point format, and clamped to the valid min/max
102 // range reported by the face.
103 nsTArray<FT_Fixed> mCoords;
105 // Store cached glyph metrics for reasonably small glyph sizes. The bounds
106 // are stored unscaled to losslessly compress 26.6 fixed point to an int16_t.
107 // Larger glyphs are handled directly via GetFTGlyphExtents.
108 struct GlyphMetrics {
109 // Set the X coord to INT16_MIN to signal the bounds are invalid, or
110 // INT16_MAX to signal that the bounds would overflow an int16_t.
111 enum { INVALID = INT16_MIN, LARGE = INT16_MAX };
113 GlyphMetrics() : mAdvance(0), mX(INVALID), mY(0), mWidth(0), mHeight(0) {}
115 bool HasValidBounds() const { return mX != INVALID; }
116 bool HasCachedBounds() const { return mX != LARGE; }
118 // If the bounds can fit in an int16_t, set them. Otherwise, leave the
119 // bounds invalid to signal that GetFTGlyphExtents should be queried
120 // directly.
121 void SetBounds(const mozilla::gfx::IntRect& aBounds) {
122 if (aBounds.x > INT16_MIN && aBounds.x < INT16_MAX &&
123 aBounds.y > INT16_MIN && aBounds.y < INT16_MAX &&
124 aBounds.width <= UINT16_MAX && aBounds.height <= UINT16_MAX) {
125 mX = aBounds.x;
126 mY = aBounds.y;
127 mWidth = aBounds.width;
128 mHeight = aBounds.height;
129 } else {
130 mX = LARGE;
134 mozilla::gfx::IntRect GetBounds() const {
135 return mozilla::gfx::IntRect(mX, mY, mWidth, mHeight);
138 int32_t mAdvance;
139 int16_t mX;
140 int16_t mY;
141 uint16_t mWidth;
142 uint16_t mHeight;
145 const GlyphMetrics& GetCachedGlyphMetrics(
146 uint16_t aGID, mozilla::gfx::IntRect* aBounds = nullptr);
148 mozilla::UniquePtr<nsTHashMap<nsUint32HashKey, GlyphMetrics>> mGlyphMetrics
149 MOZ_GUARDED_BY(mLock);
152 #endif /* GFX_FT2FONTBASE_H */