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"
19 class gfxFT2FontEntryBase
: public gfxFontEntry
{
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
,
30 enum { kNumCmapCacheSlots
= 256 };
32 struct CmapCacheSlot
{
33 CmapCacheSlot() : mCharCode(0), mGlyphIndex(0) {}
39 mozilla::UniquePtr
<CmapCacheSlot
[]> mCmapCache
MOZ_GUARDED_BY(mLock
);
42 class gfxFT2FontBase
: public gfxFont
{
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
,
73 FT_Face
LockFTFace() const;
74 void UnlockFTFace() const;
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) const;
86 ~gfxFT2FontBase() override
;
88 const Metrics
& GetHorizontalMetrics() const override
{ return mMetrics
; }
89 FT_Vector
GetEmboldenStrength(FT_Face aFace
) const;
91 RefPtr
<mozilla::gfx::SharedFTFace
> mFTFace
;
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
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
) {
127 mWidth
= aBounds
.width
;
128 mHeight
= aBounds
.height
;
134 mozilla::gfx::IntRect
GetBounds() const {
135 return mozilla::gfx::IntRect(mX
, mY
, mWidth
, mHeight
);
145 const GlyphMetrics
& GetCachedGlyphMetrics(
146 uint16_t aGID
, mozilla::gfx::IntRect
* aBounds
= nullptr) const;
148 mutable mozilla::UniquePtr
<nsTHashMap
<nsUint32HashKey
, GlyphMetrics
>>
149 mGlyphMetrics
MOZ_GUARDED_BY(mLock
);
152 #endif /* GFX_FT2FONTBASE_H */