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"
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 gfxFT2FontEntryBase
: public gfxFontEntry
{
19 explicit gfxFT2FontEntryBase(const nsACString
& aName
) : gfxFontEntry(aName
) {}
21 struct CmapCacheSlot
{
22 CmapCacheSlot() : mCharCode(0), mGlyphIndex(0) {}
28 CmapCacheSlot
* GetCmapCacheSlot(uint32_t aCharCode
);
30 static bool FaceHasTable(mozilla::gfx::SharedFTFace
*, uint32_t aTableTag
);
31 static nsresult
CopyFaceTable(mozilla::gfx::SharedFTFace
*, uint32_t aTableTag
,
35 enum { kNumCmapCacheSlots
= 256 };
37 mozilla::UniquePtr
<CmapCacheSlot
[]> mCmapCache
;
40 class gfxFT2FontBase
: public gfxFont
{
43 const RefPtr
<mozilla::gfx::UnscaledFontFreeType
>& aUnscaledFont
,
44 RefPtr
<mozilla::gfx::SharedFTFace
>&& aFTFace
, gfxFontEntry
* aFontEntry
,
45 const gfxFontStyle
* aFontStyle
, int aLoadFlags
, bool aEmbolden
);
46 virtual ~gfxFT2FontBase();
48 uint32_t GetGlyph(uint32_t aCharCode
);
49 bool ProvidesGetGlyph() const override
{ return true; }
50 virtual uint32_t GetGlyph(uint32_t unicode
,
51 uint32_t variation_selector
) override
;
52 bool ProvidesGlyphWidths() const override
{ return true; }
53 int32_t GetGlyphWidth(uint16_t aGID
) override
;
54 bool GetGlyphBounds(uint16_t aGID
, gfxRect
* aBounds
, bool aTight
) override
;
56 FontType
GetType() const override
{ return FONT_TYPE_FT2
; }
58 bool ShouldRoundXOffset(cairo_t
* aCairo
) const override
;
60 static void SetupVarCoords(FT_MM_Var
* aMMVar
,
61 const nsTArray
<gfxFontVariation
>& aVariations
,
68 uint32_t GetCharExtents(char aChar
, gfxFloat
* aWidth
,
69 gfxRect
* aBounds
= nullptr);
71 // Get advance (and optionally bounds) of a single glyph from FreeType,
72 // and return true, or return false if we failed.
73 bool GetFTGlyphExtents(uint16_t aGID
, int32_t* aWidth
,
74 mozilla::gfx::IntRect
* aBounds
= nullptr);
78 const Metrics
& GetHorizontalMetrics() override
;
79 FT_Vector
GetEmboldenStrength(FT_Face aFace
);
81 RefPtr
<mozilla::gfx::SharedFTFace
> mFTFace
;
88 // For variation/multiple-master fonts, this will be an array of the values
89 // for each axis, as specified by mStyle.variationSettings (or the font's
90 // default for axes not present in variationSettings). Values here are in
91 // freetype's 16.16 fixed-point format, and clamped to the valid min/max
92 // range reported by the face.
93 nsTArray
<FT_Fixed
> mCoords
;
95 // Store cached glyph metrics for reasonably small glyph sizes. The bounds
96 // are stored unscaled to losslessly compress 26.6 fixed point to an int16_t.
97 // Larger glyphs are handled directly via GetFTGlyphExtents.
99 // Set the X coord to INT16_MIN to signal the bounds are invalid, or
100 // INT16_MAX to signal that the bounds would overflow an int16_t.
101 enum { INVALID
= INT16_MIN
, LARGE
= INT16_MAX
};
103 GlyphMetrics() : mAdvance(0), mX(INVALID
), mY(0), mWidth(0), mHeight(0) {}
105 bool HasValidBounds() const { return mX
!= INVALID
; }
106 bool HasCachedBounds() const { return mX
!= LARGE
; }
108 // If the bounds can fit in an int16_t, set them. Otherwise, leave the
109 // bounds invalid to signal that GetFTGlyphExtents should be queried
111 void SetBounds(const mozilla::gfx::IntRect
& aBounds
) {
112 if (aBounds
.x
> INT16_MIN
&& aBounds
.x
< INT16_MAX
&&
113 aBounds
.y
> INT16_MIN
&& aBounds
.y
< INT16_MAX
&&
114 aBounds
.width
<= UINT16_MAX
&& aBounds
.height
<= UINT16_MAX
) {
117 mWidth
= aBounds
.width
;
118 mHeight
= aBounds
.height
;
124 mozilla::gfx::IntRect
GetBounds() const {
125 return mozilla::gfx::IntRect(mX
, mY
, mWidth
, mHeight
);
135 const GlyphMetrics
& GetCachedGlyphMetrics(
136 uint16_t aGID
, mozilla::gfx::IntRect
* aBounds
= nullptr);
138 mozilla::UniquePtr
<nsTHashMap
<nsUint32HashKey
, GlyphMetrics
>> mGlyphMetrics
;
141 // Helper classes used for clearing out user font data when FT font
142 // face is destroyed. Since multiple faces may use the same data, be
143 // careful to assure that the data is only cleared out when all uses
144 // expire. The font entry object contains a refptr to FTUserFontData and
145 // each FT face created from that font entry contains a refptr to that
146 // same FTUserFontData object.
148 class FTUserFontData final
149 : public mozilla::gfx::SharedFTFaceRefCountedData
<FTUserFontData
> {
151 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FTUserFontData
)
153 FTUserFontData(const uint8_t* aData
, uint32_t aLength
)
154 : mFontData(aData
), mLength(aLength
) {}
156 const uint8_t* FontData() const { return mFontData
; }
158 already_AddRefed
<mozilla::gfx::SharedFTFace
> CloneFace(
159 int aFaceIndex
= 0) override
;
164 free((void*)mFontData
);
168 const uint8_t* mFontData
;
172 #endif /* GFX_FT2FONTBASE_H */