Bug 1492908 [wpt PR 13122] - Update wpt metadata, a=testonly
[gecko.git] / gfx / thebes / gfxFcPlatformFontList.h
blob2feac5b49a7d8c7db91019b086e1fe0f5672d884
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/. */
6 #ifndef GFXFCPLATFORMFONTLIST_H_
7 #define GFXFCPLATFORMFONTLIST_H_
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"
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>
26 #if defined(MOZ_CONTENT_SANDBOX) && defined (XP_LINUX)
27 #include "mozilla/SandboxBroker.h"
28 #endif
30 namespace mozilla {
31 namespace dom {
32 class SystemFontListEntry;
36 template <>
37 class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern>
39 public:
40 static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); }
41 static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); }
44 template <>
45 class nsAutoRefTraits<FcConfig> : public nsPointerRefTraits<FcConfig>
47 public:
48 static void Release(FcConfig *ptr) { FcConfigDestroy(ptr); }
49 static void AddRef(FcConfig *ptr) { FcConfigReference(ptr); }
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.
59 class FTUserFontData {
60 public:
61 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FTUserFontData)
63 explicit FTUserFontData(FT_Face aFace, const uint8_t* aData)
64 : mFace(aFace), mFontData(aData)
68 const uint8_t *FontData() const { return mFontData; }
70 private:
71 ~FTUserFontData()
73 mozilla::gfx::Factory::ReleaseFTFace(mFace);
74 if (mFontData) {
75 free((void*)mFontData);
79 FT_Face mFace;
80 const uint8_t *mFontData;
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.
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);
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);
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);
111 gfxFontEntry* Clone() const override;
113 FcPattern* GetPattern() { return mFontPattern; }
115 nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override;
116 bool TestCharacterMap(uint32_t aCh) override;
118 FT_Face GetFTFace();
120 FT_MM_Var* GetMMVar() override;
122 bool HasVariations() override;
123 void GetVariationAxes(nsTArray<gfxFontVariationAxis>& aAxes) override;
124 void GetVariationInstances(nsTArray<gfxFontVariationInstance>& aInstances) override;
126 hb_blob_t* GetFontTable(uint32_t aTableTag) override;
128 void ForgetHBFace() override;
129 void ReleaseGrFace(gr_face* aFace) override;
131 double GetAspect();
133 protected:
134 virtual ~gfxFontconfigFontEntry();
136 gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle) override;
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);
145 // override to pull data from FTFace
146 virtual nsresult
147 CopyFontTable(uint32_t aTableTag,
148 nsTArray<uint8_t>& aBuffer) override;
150 // if HB or GR faces are gone, close down the FT_Face
151 void MaybeReleaseFTFace();
153 // pattern for a single face of a family
154 nsCountedRef<FcPattern> mFontPattern;
156 // user font data, when needed
157 RefPtr<FTUserFontData> mUserFontData;
159 // FTFace - initialized when needed
160 FT_Face mFTFace;
161 bool mFTFaceInitialized;
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;
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;
177 double mAspect;
179 // data font
180 const uint8_t* mFontData;
181 uint32_t mLength;
183 class UnscaledFontCache
185 public:
186 already_AddRefed<mozilla::gfx::UnscaledFontFontconfig>
187 Lookup(const char* aFile, uint32_t aIndex);
189 void Add(const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont) {
190 mUnscaledFonts[kNumEntries-1] = aUnscaledFont;
191 MoveToFront(kNumEntries-1);
194 private:
195 void MoveToFront(size_t aIndex);
197 static const size_t kNumEntries = 3;
198 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFontconfig> mUnscaledFonts[kNumEntries];
201 UnscaledFontCache mUnscaledFontCache;
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;
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)
218 template<typename Func>
219 void AddFacesToFontList(Func aAddPatternFunc);
221 void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) override;
223 // Families are constructed initially with just references to patterns.
224 // When necessary, these are enumerated within FindStyleVariations.
225 void AddFontPattern(FcPattern* aFontPattern);
227 void SetFamilyContainsAppFonts(bool aContainsAppFonts)
229 mContainsAppFonts = aContainsAppFonts;
232 void
233 FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
234 nsTArray<gfxFontEntry*>& aFontEntryList,
235 bool aIgnoreSizeTolerance) override;
237 bool FilterForFontList(nsAtom* aLangGroup,
238 const nsACString& aGeneric) const final {
239 return SupportsLangGroup(aLangGroup);
242 protected:
243 virtual ~gfxFontconfigFontFamily();
245 // helper for FilterForFontList
246 bool SupportsLangGroup(nsAtom *aLangGroup) const;
248 nsTArray<nsCountedRef<FcPattern> > mFontPatterns;
250 bool mContainsAppFonts;
251 bool mHasNonScalableFaces;
252 bool mForceScalable;
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);
264 virtual FontType GetType() const override { return FONT_TYPE_FONTCONFIG; }
265 virtual FcPattern *GetPattern() const { return mPattern; }
267 virtual already_AddRefed<mozilla::gfx::ScaledFont>
268 GetScaledFont(DrawTarget *aTarget) override;
270 private:
271 virtual ~gfxFontconfigFont();
273 nsCountedRef<FcPattern> mPattern;
276 class gfxFcPlatformFontList : public gfxPlatformFontList {
277 public:
278 gfxFcPlatformFontList();
280 static gfxFcPlatformFontList* PlatformFontList() {
281 return static_cast<gfxFcPlatformFontList*>(sPlatformFontList);
284 // initialize font lists
285 virtual nsresult InitFontListForPlatform() override;
287 void GetFontList(nsAtom *aLangGroup,
288 const nsACString& aGenericFamily,
289 nsTArray<nsString>& aListOfFonts) override;
291 void ReadSystemFontList(
292 InfallibleTArray<mozilla::dom::SystemFontListEntry>* retValue);
294 gfxFontEntry*
295 LookupLocalFont(const nsACString& aFontName,
296 WeightRange aWeightForEntry,
297 StretchRange aStretchForEntry,
298 SlantStyleRange aStyleForEntry) override;
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;
308 bool FindAndAddFamilies(const nsACString& aFamily,
309 nsTArray<FamilyAndGeneric>* aOutput,
310 FindFamiliesFlags aFlags,
311 gfxFontStyle* aStyle = nullptr,
312 gfxFloat aDevToCssSize = 1.0) override;
314 bool GetStandardFamilyName(const nsCString& aFontName,
315 nsACString& aFamilyName) override;
317 FcConfig* GetLastConfig() const { return mLastConfig; }
319 // override to use fontconfig lookup for generics
320 void AddGenericFonts(mozilla::FontFamilyType aGenericType,
321 nsAtom* aLanguage,
322 nsTArray<FamilyAndGeneric>& aFamilyList) override;
324 void ClearLangGroupPrefFonts() override;
326 // clear out cached generic-lang ==> family-list mappings
327 void ClearGenericMappings() {
328 mGenericMappings.Clear();
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);
338 static FT_Library GetFTLibrary();
340 protected:
341 virtual ~gfxFcPlatformFontList();
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
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);
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);
361 // figure out which families fontconfig maps a generic to
362 // (aGeneric assumed already lowercase)
363 PrefFontList* FindGenericFamilies(const nsCString& aGeneric,
364 nsAtom* aLanguage);
366 // are all pref font settings set to use fontconfig generics?
367 bool PrefFontListsUseOnlyGenerics();
369 static void CheckFontUpdates(nsITimer *aTimer, void *aThis);
371 virtual gfxFontFamily*
372 GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
374 gfxFontFamily* CreateFontFamily(const nsACString& aName) const override;
376 // helper method for finding an appropriate lang string
377 bool TryLangForGroup(const nsACString& aOSLang, nsAtom* aLangGroup,
378 nsACString& aLang, bool aForFontEnumerationThread);
380 #ifdef MOZ_BUNDLED_FONTS
381 void ActivateBundledFonts();
382 nsCString mBundledFontsPath;
383 bool mBundledFontsInitialized;
384 #endif
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;
392 // caching generic/lang ==> font family list
393 nsClassHashtable<nsCStringHashKey,
394 PrefFontList> mGenericMappings;
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;
405 nsCOMPtr<nsITimer> mCheckFontUpdatesTimer;
406 nsCountedRef<FcConfig> mLastConfig;
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;
415 static FT_Library sCairoFTLibrary;
418 #endif /* GFXPLATFORMFONTLIST_H_ */