/src/mozilla-central/gfx/thebes/gfxFcPlatformFontList.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
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 GFXFCPLATFORMFONTLIST_H_ |
7 | | #define GFXFCPLATFORMFONTLIST_H_ |
8 | | |
9 | | #include "gfxFont.h" |
10 | | #include "gfxFontEntry.h" |
11 | | #include "gfxFT2FontBase.h" |
12 | | #include "gfxPlatformFontList.h" |
13 | | #include "mozilla/FontPropertyTypes.h" |
14 | | #include "mozilla/mozalloc.h" |
15 | | #include "nsAutoRef.h" |
16 | | #include "nsClassHashtable.h" |
17 | | |
18 | | #include <fontconfig/fontconfig.h> |
19 | | #include "ft2build.h" |
20 | | #include FT_FREETYPE_H |
21 | | #include FT_TRUETYPE_TABLES_H |
22 | | #include FT_MULTIPLE_MASTERS_H |
23 | | #include <cairo.h> |
24 | | #include <cairo-ft.h> |
25 | | |
26 | | #if defined(MOZ_CONTENT_SANDBOX) && defined (XP_LINUX) |
27 | | #include "mozilla/SandboxBroker.h" |
28 | | #endif |
29 | | |
30 | | namespace mozilla { |
31 | | namespace dom { |
32 | | class SystemFontListEntry; |
33 | | }; |
34 | | }; |
35 | | |
36 | | template <> |
37 | | class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern> |
38 | | { |
39 | | public: |
40 | 0 | static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); } |
41 | 0 | static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); } |
42 | | }; |
43 | | |
44 | | template <> |
45 | | class nsAutoRefTraits<FcConfig> : public nsPointerRefTraits<FcConfig> |
46 | | { |
47 | | public: |
48 | 0 | static void Release(FcConfig *ptr) { FcConfigDestroy(ptr); } |
49 | 0 | static void AddRef(FcConfig *ptr) { FcConfigReference(ptr); } |
50 | | }; |
51 | | |
52 | | // Helper classes used for clearning out user font data when cairo font |
53 | | // face is destroyed. Since multiple faces may use the same data, be |
54 | | // careful to assure that the data is only cleared out when all uses |
55 | | // expire. The font entry object contains a refptr to FTUserFontData and |
56 | | // each cairo font created from that font entry contains a |
57 | | // FTUserFontDataRef with a refptr to that same FTUserFontData object. |
58 | | |
59 | | class FTUserFontData { |
60 | | public: |
61 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FTUserFontData) |
62 | | |
63 | | explicit FTUserFontData(FT_Face aFace, const uint8_t* aData) |
64 | | : mFace(aFace), mFontData(aData) |
65 | 0 | { |
66 | 0 | } |
67 | | |
68 | 0 | const uint8_t *FontData() const { return mFontData; } |
69 | | |
70 | | private: |
71 | | ~FTUserFontData() |
72 | 0 | { |
73 | 0 | mozilla::gfx::Factory::ReleaseFTFace(mFace); |
74 | 0 | if (mFontData) { |
75 | 0 | free((void*)mFontData); |
76 | 0 | } |
77 | 0 | } |
78 | | |
79 | | FT_Face mFace; |
80 | | const uint8_t *mFontData; |
81 | | }; |
82 | | |
83 | | // The names for the font entry and font classes should really |
84 | | // the common 'Fc' abbreviation but the gfxPangoFontGroup code already |
85 | | // defines versions of these, so use the verbose name for now. |
86 | | |
87 | | class gfxFontconfigFontEntry : public gfxFontEntry { |
88 | | public: |
89 | | // used for system fonts with explicit patterns |
90 | | explicit gfxFontconfigFontEntry(const nsACString& aFaceName, |
91 | | FcPattern* aFontPattern, |
92 | | bool aIgnoreFcCharmap); |
93 | | |
94 | | // used for data fonts where the fontentry takes ownership |
95 | | // of the font data and the FT_Face |
96 | | explicit gfxFontconfigFontEntry(const nsACString& aFaceName, |
97 | | WeightRange aWeight, |
98 | | StretchRange aStretch, |
99 | | SlantStyleRange aStyle, |
100 | | const uint8_t *aData, |
101 | | uint32_t aLength, |
102 | | FT_Face aFace); |
103 | | |
104 | | // used for @font-face local system fonts with explicit patterns |
105 | | explicit gfxFontconfigFontEntry(const nsACString& aFaceName, |
106 | | FcPattern* aFontPattern, |
107 | | WeightRange aWeight, |
108 | | StretchRange aStretch, |
109 | | SlantStyleRange aStyle); |
110 | | |
111 | | gfxFontEntry* Clone() const override; |
112 | | |
113 | 0 | FcPattern* GetPattern() { return mFontPattern; } |
114 | | |
115 | | nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override; |
116 | | bool TestCharacterMap(uint32_t aCh) override; |
117 | | |
118 | | FT_Face GetFTFace(); |
119 | | |
120 | | FT_MM_Var* GetMMVar() override; |
121 | | |
122 | | bool HasVariations() override; |
123 | | void GetVariationAxes(nsTArray<gfxFontVariationAxis>& aAxes) override; |
124 | | void GetVariationInstances(nsTArray<gfxFontVariationInstance>& aInstances) override; |
125 | | |
126 | | hb_blob_t* GetFontTable(uint32_t aTableTag) override; |
127 | | |
128 | | void ForgetHBFace() override; |
129 | | void ReleaseGrFace(gr_face* aFace) override; |
130 | | |
131 | | double GetAspect(); |
132 | | |
133 | | protected: |
134 | | virtual ~gfxFontconfigFontEntry(); |
135 | | |
136 | | gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle) override; |
137 | | |
138 | | // helper method for creating cairo font from pattern |
139 | | cairo_scaled_font_t* |
140 | | CreateScaledFont(FcPattern* aRenderPattern, |
141 | | gfxFloat aAdjustedSize, |
142 | | const gfxFontStyle *aStyle, |
143 | | FT_Face aFTFace); |
144 | | |
145 | | // override to pull data from FTFace |
146 | | virtual nsresult |
147 | | CopyFontTable(uint32_t aTableTag, |
148 | | nsTArray<uint8_t>& aBuffer) override; |
149 | | |
150 | | // if HB or GR faces are gone, close down the FT_Face |
151 | | void MaybeReleaseFTFace(); |
152 | | |
153 | | // pattern for a single face of a family |
154 | | nsCountedRef<FcPattern> mFontPattern; |
155 | | |
156 | | // user font data, when needed |
157 | | RefPtr<FTUserFontData> mUserFontData; |
158 | | |
159 | | // FTFace - initialized when needed |
160 | | FT_Face mFTFace; |
161 | | bool mFTFaceInitialized; |
162 | | |
163 | | // Whether TestCharacterMap should check the actual cmap rather than asking |
164 | | // fontconfig about character coverage. |
165 | | // We do this for app-bundled (rather than system) fonts, as they may |
166 | | // include color glyphs that fontconfig would overlook, and for fonts |
167 | | // loaded via @font-face. |
168 | | bool mIgnoreFcCharmap; |
169 | | |
170 | | // Whether the face supports variations. For system-installed fonts, we |
171 | | // query fontconfig for this (so they will only work if fontconfig is |
172 | | // recent enough to include support); for downloaded user-fonts we query |
173 | | // the FreeType face. |
174 | | bool mHasVariations; |
175 | | bool mHasVariationsInitialized; |
176 | | |
177 | | double mAspect; |
178 | | |
179 | | // data font |
180 | | const uint8_t* mFontData; |
181 | | uint32_t mLength; |
182 | | |
183 | | class UnscaledFontCache |
184 | | { |
185 | | public: |
186 | | already_AddRefed<mozilla::gfx::UnscaledFontFontconfig> |
187 | | Lookup(const char* aFile, uint32_t aIndex); |
188 | | |
189 | 0 | void Add(const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont) { |
190 | 0 | mUnscaledFonts[kNumEntries-1] = aUnscaledFont; |
191 | 0 | MoveToFront(kNumEntries-1); |
192 | 0 | } |
193 | | |
194 | | private: |
195 | | void MoveToFront(size_t aIndex); |
196 | | |
197 | | static const size_t kNumEntries = 3; |
198 | | mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFontconfig> mUnscaledFonts[kNumEntries]; |
199 | | }; |
200 | | |
201 | | UnscaledFontCache mUnscaledFontCache; |
202 | | |
203 | | // Because of FreeType bug 52955, we keep the FT_MM_Var struct when it is |
204 | | // first loaded, rather than releasing it and re-fetching it as needed. |
205 | | FT_MM_Var* mMMVar = nullptr; |
206 | | bool mMMVarInitialized = false; |
207 | | }; |
208 | | |
209 | | class gfxFontconfigFontFamily : public gfxFontFamily { |
210 | | public: |
211 | | explicit gfxFontconfigFontFamily(const nsACString& aName) : |
212 | | gfxFontFamily(aName), |
213 | | mContainsAppFonts(false), |
214 | | mHasNonScalableFaces(false), |
215 | | mForceScalable(false) |
216 | 0 | { } |
217 | | |
218 | | template<typename Func> |
219 | | void AddFacesToFontList(Func aAddPatternFunc); |
220 | | |
221 | | void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) override; |
222 | | |
223 | | // Families are constructed initially with just references to patterns. |
224 | | // When necessary, these are enumerated within FindStyleVariations. |
225 | | void AddFontPattern(FcPattern* aFontPattern); |
226 | | |
227 | | void SetFamilyContainsAppFonts(bool aContainsAppFonts) |
228 | 0 | { |
229 | 0 | mContainsAppFonts = aContainsAppFonts; |
230 | 0 | } |
231 | | |
232 | | void |
233 | | FindAllFontsForStyle(const gfxFontStyle& aFontStyle, |
234 | | nsTArray<gfxFontEntry*>& aFontEntryList, |
235 | | bool aIgnoreSizeTolerance) override; |
236 | | |
237 | | bool FilterForFontList(nsAtom* aLangGroup, |
238 | 0 | const nsACString& aGeneric) const final { |
239 | 0 | return SupportsLangGroup(aLangGroup); |
240 | 0 | } |
241 | | |
242 | | protected: |
243 | | virtual ~gfxFontconfigFontFamily(); |
244 | | |
245 | | // helper for FilterForFontList |
246 | | bool SupportsLangGroup(nsAtom *aLangGroup) const; |
247 | | |
248 | | nsTArray<nsCountedRef<FcPattern> > mFontPatterns; |
249 | | |
250 | | bool mContainsAppFonts; |
251 | | bool mHasNonScalableFaces; |
252 | | bool mForceScalable; |
253 | | }; |
254 | | |
255 | | class gfxFontconfigFont : public gfxFT2FontBase { |
256 | | public: |
257 | | gfxFontconfigFont(const RefPtr<mozilla::gfx::UnscaledFontFontconfig> &aUnscaledFont, |
258 | | cairo_scaled_font_t *aScaledFont, |
259 | | FcPattern *aPattern, |
260 | | gfxFloat aAdjustedSize, |
261 | | gfxFontEntry *aFontEntry, |
262 | | const gfxFontStyle *aFontStyle); |
263 | | |
264 | 0 | virtual FontType GetType() const override { return FONT_TYPE_FONTCONFIG; } |
265 | 0 | virtual FcPattern *GetPattern() const { return mPattern; } |
266 | | |
267 | | virtual already_AddRefed<mozilla::gfx::ScaledFont> |
268 | | GetScaledFont(DrawTarget *aTarget) override; |
269 | | |
270 | | private: |
271 | | virtual ~gfxFontconfigFont(); |
272 | | |
273 | | nsCountedRef<FcPattern> mPattern; |
274 | | }; |
275 | | |
276 | | class gfxFcPlatformFontList : public gfxPlatformFontList { |
277 | | public: |
278 | | gfxFcPlatformFontList(); |
279 | | |
280 | 0 | static gfxFcPlatformFontList* PlatformFontList() { |
281 | 0 | return static_cast<gfxFcPlatformFontList*>(sPlatformFontList); |
282 | 0 | } |
283 | | |
284 | | // initialize font lists |
285 | | virtual nsresult InitFontListForPlatform() override; |
286 | | |
287 | | void GetFontList(nsAtom *aLangGroup, |
288 | | const nsACString& aGenericFamily, |
289 | | nsTArray<nsString>& aListOfFonts) override; |
290 | | |
291 | | void ReadSystemFontList( |
292 | | InfallibleTArray<mozilla::dom::SystemFontListEntry>* retValue); |
293 | | |
294 | | gfxFontEntry* |
295 | | LookupLocalFont(const nsACString& aFontName, |
296 | | WeightRange aWeightForEntry, |
297 | | StretchRange aStretchForEntry, |
298 | | SlantStyleRange aStyleForEntry) override; |
299 | | |
300 | | gfxFontEntry* |
301 | | MakePlatformFont(const nsACString& aFontName, |
302 | | WeightRange aWeightForEntry, |
303 | | StretchRange aStretchForEntry, |
304 | | SlantStyleRange aStyleForEntry, |
305 | | const uint8_t* aFontData, |
306 | | uint32_t aLength) override; |
307 | | |
308 | | bool FindAndAddFamilies(const nsACString& aFamily, |
309 | | nsTArray<FamilyAndGeneric>* aOutput, |
310 | | FindFamiliesFlags aFlags, |
311 | | gfxFontStyle* aStyle = nullptr, |
312 | | gfxFloat aDevToCssSize = 1.0) override; |
313 | | |
314 | | bool GetStandardFamilyName(const nsCString& aFontName, |
315 | | nsACString& aFamilyName) override; |
316 | | |
317 | 0 | FcConfig* GetLastConfig() const { return mLastConfig; } |
318 | | |
319 | | // override to use fontconfig lookup for generics |
320 | | void AddGenericFonts(mozilla::FontFamilyType aGenericType, |
321 | | nsAtom* aLanguage, |
322 | | nsTArray<FamilyAndGeneric>& aFamilyList) override; |
323 | | |
324 | | void ClearLangGroupPrefFonts() override; |
325 | | |
326 | | // clear out cached generic-lang ==> family-list mappings |
327 | 0 | void ClearGenericMappings() { |
328 | 0 | mGenericMappings.Clear(); |
329 | 0 | } |
330 | | |
331 | | // map lang group ==> lang string |
332 | | // When aForFontEnumerationThread is true, this method will avoid using |
333 | | // LanguageService::LookupLanguage, because it is not safe for off-main- |
334 | | // thread use (except by stylo traversal, which does the necessary locking) |
335 | | void GetSampleLangForGroup(nsAtom* aLanguage, nsACString& aLangStr, |
336 | | bool aForFontEnumerationThread = false); |
337 | | |
338 | | static FT_Library GetFTLibrary(); |
339 | | |
340 | | protected: |
341 | | virtual ~gfxFcPlatformFontList(); |
342 | | |
343 | | #if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX) |
344 | | typedef mozilla::SandboxBroker::Policy SandboxPolicy; |
345 | | #else |
346 | | // Dummy type just so we can still have a SandboxPolicy* parameter. |
347 | | struct SandboxPolicy {}; |
348 | | #endif |
349 | | |
350 | | // Add all the font families found in a font set. |
351 | | // aAppFonts indicates whether this is the system or application fontset. |
352 | | void AddFontSetFamilies(FcFontSet* aFontSet, const SandboxPolicy* aPolicy, |
353 | | bool aAppFonts); |
354 | | |
355 | | // Helper for above, to add a single font pattern. |
356 | | void AddPatternToFontList(FcPattern* aFont, FcChar8*& aLastFamilyName, |
357 | | nsACString& aFamilyName, |
358 | | RefPtr<gfxFontconfigFontFamily>& aFontFamily, |
359 | | bool aAppFonts); |
360 | | |
361 | | // figure out which families fontconfig maps a generic to |
362 | | // (aGeneric assumed already lowercase) |
363 | | PrefFontList* FindGenericFamilies(const nsCString& aGeneric, |
364 | | nsAtom* aLanguage); |
365 | | |
366 | | // are all pref font settings set to use fontconfig generics? |
367 | | bool PrefFontListsUseOnlyGenerics(); |
368 | | |
369 | | static void CheckFontUpdates(nsITimer *aTimer, void *aThis); |
370 | | |
371 | | virtual gfxFontFamily* |
372 | | GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override; |
373 | | |
374 | | gfxFontFamily* CreateFontFamily(const nsACString& aName) const override; |
375 | | |
376 | | // helper method for finding an appropriate lang string |
377 | | bool TryLangForGroup(const nsACString& aOSLang, nsAtom* aLangGroup, |
378 | | nsACString& aLang, bool aForFontEnumerationThread); |
379 | | |
380 | | #ifdef MOZ_BUNDLED_FONTS |
381 | | void ActivateBundledFonts(); |
382 | | nsCString mBundledFontsPath; |
383 | | bool mBundledFontsInitialized; |
384 | | #endif |
385 | | |
386 | | // to avoid enumerating all fonts, maintain a mapping of local font |
387 | | // names to family |
388 | | nsBaseHashtable<nsCStringHashKey, |
389 | | nsCountedRef<FcPattern>, |
390 | | FcPattern*> mLocalNames; |
391 | | |
392 | | // caching generic/lang ==> font family list |
393 | | nsClassHashtable<nsCStringHashKey, |
394 | | PrefFontList> mGenericMappings; |
395 | | |
396 | | // Caching family lookups as found by FindAndAddFamilies after resolving |
397 | | // substitutions. The gfxFontFamily objects cached here are owned by the |
398 | | // gfxFcPlatformFontList via its mFamilies table; note that if the main |
399 | | // font list is rebuilt (e.g. due to a fontconfig configuration change), |
400 | | // these pointers will be invalidated. InitFontList() flushes the cache |
401 | | // in this case. |
402 | | nsDataHashtable<nsCStringHashKey, |
403 | | nsTArray<FamilyAndGeneric>> mFcSubstituteCache; |
404 | | |
405 | | nsCOMPtr<nsITimer> mCheckFontUpdatesTimer; |
406 | | nsCountedRef<FcConfig> mLastConfig; |
407 | | |
408 | | // By default, font prefs under Linux are set to simply lookup |
409 | | // via fontconfig the appropriate font for serif/sans-serif/monospace. |
410 | | // Rather than check each time a font pref is used, check them all at startup |
411 | | // and set a boolean to flag the case that non-default user font prefs exist |
412 | | // Note: langGroup == x-math is handled separately |
413 | | bool mAlwaysUseFontconfigGenerics; |
414 | | |
415 | | static FT_Library sCairoFTLibrary; |
416 | | }; |
417 | | |
418 | | #endif /* GFXPLATFORMFONTLIST_H_ */ |