no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / gfx / thebes / gfxHarfBuzzShaper.h
blob4e4e89966067b23b5813ed2a24cb8505bc562842
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_HARFBUZZSHAPER_H
7 #define GFX_HARFBUZZSHAPER_H
9 #include "gfxFont.h"
11 #include "harfbuzz/hb.h"
12 #include "nsUnicodeProperties.h"
13 #include "mozilla/gfx/2D.h"
14 #include "mozilla/MruCache.h"
15 #include "mozilla/Mutex.h"
17 class gfxHarfBuzzShaper : public gfxFontShaper {
18 public:
19 explicit gfxHarfBuzzShaper(gfxFont* aFont);
20 virtual ~gfxHarfBuzzShaper();
23 * For HarfBuzz font callback functions, font_data is a ptr to a
24 * FontCallbackData struct
26 struct FontCallbackData {
27 gfxHarfBuzzShaper* mShaper;
30 // Initializes the shaper and returns whether this was successful.
31 bool Initialize();
33 // Returns whether the shaper has been successfully initialized.
34 bool IsInitialized() const { return mHBFont != nullptr; }
36 bool ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
37 uint32_t aOffset, uint32_t aLength, Script aScript,
38 nsAtom* aLanguage, bool aVertical, RoundingFlags aRounding,
39 gfxShapedText* aShapedText) override;
41 // get a given font table in harfbuzz blob form
42 hb_blob_t* GetFontTable(hb_tag_t aTag) const;
44 // map unicode character to glyph ID
45 hb_codepoint_t GetNominalGlyph(hb_codepoint_t unicode) const;
46 unsigned int GetNominalGlyphs(unsigned int count,
47 const hb_codepoint_t* first_unicode,
48 unsigned int unicode_stride,
49 hb_codepoint_t* first_glyph,
50 unsigned int glyph_stride);
51 hb_codepoint_t GetVariationGlyph(hb_codepoint_t unicode,
52 hb_codepoint_t variation_selector) const;
54 // get harfbuzz glyph advance, in font design units
55 hb_position_t GetGlyphHAdvance(hb_codepoint_t glyph) const;
56 void GetGlyphHAdvances(unsigned int count, const hb_codepoint_t* first_glyph,
57 unsigned int glyph_stride,
58 hb_position_t* first_advance,
59 unsigned int advance_stride) const;
61 // Get vertical glyph advance, or -1 if not available; caller should check
62 // for a negative result and provide a fallback or fail, as appropriate.
63 hb_position_t GetGlyphVAdvance(hb_codepoint_t glyph);
65 void GetGlyphVOrigin(hb_codepoint_t aGlyph, hb_position_t* aX,
66 hb_position_t* aY) const;
68 hb_position_t GetHKerning(uint16_t aFirstGlyph, uint16_t aSecondGlyph) const;
70 hb_bool_t GetGlyphExtents(hb_codepoint_t aGlyph,
71 hb_glyph_extents_t* aExtents) const;
73 bool UseVerticalPresentationForms() const {
74 return mUseVerticalPresentationForms;
77 static hb_script_t GetHBScriptUsedForShaping(Script aScript) {
78 // Decide what harfbuzz script code will be used for shaping
79 hb_script_t hbScript;
80 if (aScript <= Script::INHERITED) {
81 // For unresolved "common" or "inherited" runs,
82 // default to Latin for now.
83 hbScript = HB_SCRIPT_LATIN;
84 } else {
85 hbScript = hb_script_t(mozilla::unicode::GetScriptTagForCode(aScript));
87 return hbScript;
90 static hb_codepoint_t GetVerticalPresentationForm(hb_codepoint_t aUnicode);
92 // Create an hb_font corresponding to the given gfxFont instance, with size
93 // and variations set appropriately. If aFontFuncs and aCallbackData are
94 // provided, they may be used as harfbuzz font callbacks for advances, glyph
95 // bounds, etc; if not, the built-in hb_ot font functions will be used.
96 static hb_font_t* CreateHBFont(gfxFont* aFont,
97 hb_font_funcs_t* aFontFuncs = nullptr,
98 FontCallbackData* aCallbackData = nullptr);
100 hb_font_t* GetHBFont() const { return mHBFont; }
101 hb_face_t* GetHBFace() const { return hb_font_get_face(mHBFont); }
103 protected:
104 // This is called with the cache locked, but if mUseFontGetGlyph is true, it
105 // may unlock it temporarily. So in this case, it may invalidate an earlier
106 // cache entry reference.
107 hb_codepoint_t GetGlyphUncached(hb_codepoint_t unicode) const
108 MOZ_REQUIRES(mCacheLock);
110 hb_position_t GetGlyphHAdvanceUncached(hb_codepoint_t gid) const;
112 nsresult SetGlyphsFromRun(gfxShapedText* aShapedText, uint32_t aOffset,
113 uint32_t aLength, const char16_t* aText,
114 bool aVertical, RoundingFlags aRounding);
116 // retrieve glyph positions, applying advance adjustments and attachments
117 // returns results in appUnits
118 nscoord GetGlyphPositions(gfxContext* aContext, nsTArray<nsPoint>& aPositions,
119 uint32_t aAppUnitsPerDevUnit);
121 void InitializeVertical();
122 bool LoadHmtxTable();
124 struct Glyf { // we only need the bounding-box at the beginning
125 // of the glyph record, not the actual outline data
126 mozilla::AutoSwap_PRInt16 numberOfContours;
127 mozilla::AutoSwap_PRInt16 xMin;
128 mozilla::AutoSwap_PRInt16 yMin;
129 mozilla::AutoSwap_PRInt16 xMax;
130 mozilla::AutoSwap_PRInt16 yMax;
133 const Glyf* FindGlyf(hb_codepoint_t aGlyph, bool* aEmptyGlyf) const;
135 // size-specific font object, owned by the gfxHarfBuzzShaper
136 hb_font_t* mHBFont;
138 // harfbuzz buffer for the shaping process
139 hb_buffer_t* mBuffer;
141 mutable mozilla::Mutex mCacheLock = mozilla::Mutex("shaperCacheMutex");
143 struct CmapCacheData {
144 uint32_t mCodepoint;
145 uint32_t mGlyphId;
148 struct CmapCache
149 : public mozilla::MruCache<uint32_t, CmapCacheData, CmapCache, 251> {
150 static mozilla::HashNumber Hash(const uint32_t& aKey) { return aKey; }
151 static bool Match(const uint32_t& aKey, const CmapCacheData& aData) {
152 return aKey == aData.mCodepoint;
156 mutable mozilla::UniquePtr<CmapCache> mCmapCache MOZ_GUARDED_BY(mCacheLock);
158 struct WidthCacheData {
159 hb_codepoint_t mGlyphId;
160 hb_position_t mAdvance;
163 struct WidthCache
164 : public mozilla::MruCache<uint32_t, WidthCacheData, WidthCache, 251> {
165 static mozilla::HashNumber Hash(const hb_codepoint_t& aKey) { return aKey; }
166 static bool Match(const uint32_t& aKey, const WidthCacheData& aData) {
167 return aKey == aData.mGlyphId;
171 mutable mozilla::UniquePtr<WidthCache> mWidthCache MOZ_GUARDED_BY(mCacheLock);
173 FontCallbackData mCallbackData;
175 // Following table references etc are declared "mutable" because the
176 // harfbuzz callback functions take a const ptr to the shaper, but
177 // wish to cache tables here to avoid repeatedly looking them up
178 // in the font.
180 // Old-style TrueType kern table, if we're not doing GPOS kerning
181 mutable hb_blob_t* mKernTable;
183 // Cached copy of the hmtx table.
184 mutable hb_blob_t* mHmtxTable;
186 // For vertical fonts, cached vmtx and VORG table, if present.
187 mutable hb_blob_t* mVmtxTable;
188 mutable hb_blob_t* mVORGTable;
189 // And for vertical TrueType (not CFF) fonts that have vmtx,
190 // we also use loca and glyf to get glyph bounding boxes.
191 mutable hb_blob_t* mLocaTable;
192 mutable hb_blob_t* mGlyfTable;
194 // Cached pointer to cmap subtable to be used for char-to-glyph mapping.
195 // This comes from GetFontTablePtr; if it is non-null, our destructor
196 // must call ReleaseFontTablePtr to avoid permanently caching the table.
197 mutable hb_blob_t* mCmapTable;
198 mutable int32_t mCmapFormat;
199 mutable uint32_t mSubtableOffset;
200 mutable uint32_t mUVSTableOffset;
202 // Cached copy of numLongMetrics field from the hhea table,
203 // for use when looking up glyph metrics; initialized to 0 by the
204 // constructor so we can tell it hasn't been set yet.
205 // This is a signed value so that we can use -1 to indicate
206 // an error (if the hhea table was not available).
207 mutable int32_t mNumLongHMetrics;
208 // Similarly for vhea if it's a vertical font.
209 mutable int32_t mNumLongVMetrics;
211 // Default y-coordinate for glyph vertical origin, used if the font
212 // does not actually have vertical-layout metrics.
213 mutable gfxFloat mDefaultVOrg;
215 // Whether the font implements GetGlyph, or we should read tables
216 // directly
217 bool mUseFontGetGlyph;
219 // Whether the font is an MS Symbol-encoded font, in which case we will
220 // try remapping U+0020..00FF to U+F020..F0FF for characters in the U+00xx
221 // range that are otherwise unsupported.
222 bool mIsSymbolFont;
224 // Whether the font implements GetGlyphWidth, or we should read tables
225 // directly to get ideal widths
226 bool mUseFontGlyphWidths;
228 bool mInitialized;
229 bool mVerticalInitialized;
231 // Whether to use vertical presentation forms for CJK characters
232 // when available (only set if the 'vert' feature is not available).
233 bool mUseVerticalPresentationForms;
235 // these are set from the FindGlyf callback on first use of the glyf data
236 mutable bool mLoadedLocaGlyf;
237 mutable bool mLocaLongOffsets;
240 #endif /* GFX_HARFBUZZSHAPER_H */