Bug 1799258 - Fix constexpr issue on base toolchain builds. r=gfx-reviewers,lsalzman
[gecko.git] / gfx / thebes / gfxFcPlatformFontList.h
blob3becf45e444984a71fcbaf601664c5c7578d0804
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 GFXFCPLATFORMFONTLIST_H_
7 #define GFXFCPLATFORMFONTLIST_H_
9 #include "gfxFT2FontBase.h"
10 #include "gfxPlatformFontList.h"
11 #include "mozilla/FontPropertyTypes.h"
12 #include "mozilla/mozalloc.h"
13 #include "mozilla/RefPtr.h"
14 #include "mozilla/UniquePtr.h"
15 #include "nsClassHashtable.h"
16 #include "nsTHashMap.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
24 #if defined(MOZ_SANDBOX) && defined(XP_LINUX)
25 # include "mozilla/SandboxBroker.h"
26 #endif
28 namespace mozilla {
29 namespace dom {
30 class SystemFontListEntry;
31 class SystemFontList;
32 class SystemFontOptions;
33 }; // namespace dom
35 template <>
36 class RefPtrTraits<FcPattern> {
37 public:
38 static void Release(FcPattern* ptr) { FcPatternDestroy(ptr); }
39 static void AddRef(FcPattern* ptr) { FcPatternReference(ptr); }
42 template <>
43 class RefPtrTraits<FcConfig> {
44 public:
45 static void Release(FcConfig* ptr) { FcConfigDestroy(ptr); }
46 static void AddRef(FcConfig* ptr) { FcConfigReference(ptr); }
49 template <>
50 class DefaultDelete<FcFontSet> {
51 public:
52 void operator()(FcFontSet* aPtr) { FcFontSetDestroy(aPtr); }
55 template <>
56 class DefaultDelete<FcObjectSet> {
57 public:
58 void operator()(FcObjectSet* aPtr) { FcObjectSetDestroy(aPtr); }
61 }; // namespace mozilla
63 // The names for the font entry and font classes should really
64 // the common 'Fc' abbreviation but the gfxPangoFontGroup code already
65 // defines versions of these, so use the verbose name for now.
67 class gfxFontconfigFontEntry final : public gfxFT2FontEntryBase {
68 friend class gfxFcPlatformFontList;
69 using FTUserFontData = mozilla::gfx::FTUserFontData;
71 public:
72 // used for system fonts with explicit patterns
73 explicit gfxFontconfigFontEntry(const nsACString& aFaceName,
74 FcPattern* aFontPattern,
75 bool aIgnoreFcCharmap);
77 // used for data fonts where the fontentry takes ownership
78 // of the font data and the FT_Face
79 explicit gfxFontconfigFontEntry(const nsACString& aFaceName,
80 WeightRange aWeight, StretchRange aStretch,
81 SlantStyleRange aStyle,
82 RefPtr<mozilla::gfx::SharedFTFace>&& aFace);
84 // used for @font-face local system fonts with explicit patterns
85 explicit gfxFontconfigFontEntry(const nsACString& aFaceName,
86 FcPattern* aFontPattern, WeightRange aWeight,
87 StretchRange aStretch,
88 SlantStyleRange aStyle);
90 gfxFontEntry* Clone() const override;
92 FcPattern* GetPattern() { return mFontPattern; }
94 nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
95 bool TestCharacterMap(uint32_t aCh) override;
97 const RefPtr<mozilla::gfx::SharedFTFace>& GetFTFace();
98 FTUserFontData* GetUserFontData();
100 FT_MM_Var* GetMMVar() override;
102 bool HasVariations() override;
103 void GetVariationAxes(nsTArray<gfxFontVariationAxis>& aAxes) override;
104 void GetVariationInstances(
105 nsTArray<gfxFontVariationInstance>& aInstances) override;
107 bool HasFontTable(uint32_t aTableTag) override;
108 nsresult CopyFontTable(uint32_t aTableTag, nsTArray<uint8_t>&) override;
109 hb_blob_t* GetFontTable(uint32_t aTableTag) override;
111 double GetAspect(uint8_t aSizeAdjustBasis);
113 protected:
114 virtual ~gfxFontconfigFontEntry();
116 gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override;
118 void GetUserFontFeatures(FcPattern* aPattern);
120 // pattern for a single face of a family
121 RefPtr<FcPattern> mFontPattern;
123 // FTFace - initialized when needed
124 RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
125 bool mFTFaceInitialized;
127 // Whether TestCharacterMap should check the actual cmap rather than asking
128 // fontconfig about character coverage.
129 // We do this for app-bundled (rather than system) fonts, as they may
130 // include color glyphs that fontconfig would overlook, and for fonts
131 // loaded via @font-face.
132 bool mIgnoreFcCharmap;
134 // Whether the face supports variations. For system-installed fonts, we
135 // query fontconfig for this (so they will only work if fontconfig is
136 // recent enough to include support); for downloaded user-fonts we query
137 // the FreeType face.
138 bool mHasVariations;
139 bool mHasVariationsInitialized;
141 class UnscaledFontCache {
142 public:
143 already_AddRefed<mozilla::gfx::UnscaledFontFontconfig> Lookup(
144 const std::string& aFile, uint32_t aIndex);
146 void Add(
147 const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont) {
148 mUnscaledFonts[kNumEntries - 1] = aUnscaledFont;
149 MoveToFront(kNumEntries - 1);
152 private:
153 void MoveToFront(size_t aIndex);
155 static const size_t kNumEntries = 3;
156 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFontconfig>
157 mUnscaledFonts[kNumEntries];
160 UnscaledFontCache mUnscaledFontCache;
162 // Because of FreeType bug 52955, we keep the FT_MM_Var struct when it is
163 // first loaded, rather than releasing it and re-fetching it as needed.
164 FT_MM_Var* mMMVar = nullptr;
165 bool mMMVarInitialized = false;
168 class gfxFontconfigFontFamily final : public gfxFontFamily {
169 public:
170 gfxFontconfigFontFamily(const nsACString& aName, FontVisibility aVisibility)
171 : gfxFontFamily(aName, aVisibility),
172 mContainsAppFonts(false),
173 mHasNonScalableFaces(false),
174 mForceScalable(false) {}
176 template <typename Func>
177 void AddFacesToFontList(Func aAddPatternFunc);
179 void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr)
180 MOZ_REQUIRES(mLock) override;
182 // Families are constructed initially with just references to patterns.
183 // When necessary, these are enumerated within FindStyleVariations.
184 void AddFontPattern(FcPattern* aFontPattern, bool aSingleName);
186 void SetFamilyContainsAppFonts(bool aContainsAppFonts) {
187 mContainsAppFonts = aContainsAppFonts;
190 void FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
191 nsTArray<gfxFontEntry*>& aFontEntryList,
192 bool aIgnoreSizeTolerance) override;
194 bool FilterForFontList(nsAtom* aLangGroup,
195 const nsACString& aGeneric) const final {
196 return SupportsLangGroup(aLangGroup);
199 protected:
200 virtual ~gfxFontconfigFontFamily();
202 // helper for FilterForFontList
203 bool SupportsLangGroup(nsAtom* aLangGroup) const;
205 nsTArray<RefPtr<FcPattern>> mFontPatterns;
207 // Number of faces that have a single name. Faces that have multiple names are
208 // sorted last.
209 uint32_t mUniqueNameFaceCount = 0;
210 bool mContainsAppFonts : 1;
211 bool mHasNonScalableFaces : 1;
212 bool mForceScalable : 1;
215 class gfxFontconfigFont final : public gfxFT2FontBase {
216 public:
217 gfxFontconfigFont(
218 const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont,
219 RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, FcPattern* aPattern,
220 gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry,
221 const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
223 FontType GetType() const override { return FONT_TYPE_FONTCONFIG; }
224 FcPattern* GetPattern() const { return mPattern; }
226 already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
227 const TextRunDrawParams& aRunParams) override;
229 bool ShouldHintMetrics() const override;
231 private:
232 ~gfxFontconfigFont() override;
234 RefPtr<FcPattern> mPattern;
237 class gfxFcPlatformFontList final : public gfxPlatformFontList {
238 using FontPatternListEntry = mozilla::dom::SystemFontListEntry;
240 public:
241 gfxFcPlatformFontList();
243 static gfxFcPlatformFontList* PlatformFontList() {
244 return static_cast<gfxFcPlatformFontList*>(
245 gfxPlatformFontList::PlatformFontList());
248 // initialize font lists
249 nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) override;
250 void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock) override;
252 void GetFontList(nsAtom* aLangGroup, const nsACString& aGenericFamily,
253 nsTArray<nsString>& aListOfFonts) override;
255 void ReadSystemFontList(mozilla::dom::SystemFontList*);
257 gfxFontEntry* CreateFontEntry(
258 mozilla::fontlist::Face* aFace,
259 const mozilla::fontlist::Family* aFamily) override;
261 gfxFontEntry* LookupLocalFont(nsPresContext* aPresContext,
262 const nsACString& aFontName,
263 WeightRange aWeightForEntry,
264 StretchRange aStretchForEntry,
265 SlantStyleRange aStyleForEntry) override;
267 gfxFontEntry* MakePlatformFont(const nsACString& aFontName,
268 WeightRange aWeightForEntry,
269 StretchRange aStretchForEntry,
270 SlantStyleRange aStyleForEntry,
271 const uint8_t* aFontData,
272 uint32_t aLength) override;
274 bool FindAndAddFamiliesLocked(
275 nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
276 const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
277 FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
278 nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0)
279 MOZ_REQUIRES(mLock) override;
281 bool GetStandardFamilyName(const nsCString& aFontName,
282 nsACString& aFamilyName) override;
284 FcConfig* GetLastConfig() const { return mLastConfig; }
286 // override to use fontconfig lookup for generics
287 void AddGenericFonts(nsPresContext* aPresContext,
288 mozilla::StyleGenericFontFamily, nsAtom* aLanguage,
289 nsTArray<FamilyAndGeneric>& aFamilyList) override;
291 void ClearLangGroupPrefFontsLocked() MOZ_REQUIRES(mLock) override;
293 // clear out cached generic-lang ==> family-list mappings
294 void ClearGenericMappings() {
295 AutoLock lock(mLock);
296 ClearGenericMappingsLocked();
298 void ClearGenericMappingsLocked() MOZ_REQUIRES(mLock) {
299 mGenericMappings.Clear();
302 // map lang group ==> lang string
303 // When aForFontEnumerationThread is true, this method will avoid using
304 // LanguageService::LookupLanguage, because it is not safe for off-main-
305 // thread use (except by stylo traversal, which does the necessary locking)
306 void GetSampleLangForGroup(nsAtom* aLanguage, nsACString& aLangStr,
307 bool aForFontEnumerationThread = false);
309 protected:
310 virtual ~gfxFcPlatformFontList();
312 #if defined(MOZ_SANDBOX) && defined(XP_LINUX)
313 typedef mozilla::SandboxBroker::Policy SandboxPolicy;
314 #else
315 // Dummy type just so we can still have a SandboxPolicy* parameter.
316 struct SandboxPolicy {};
317 #endif
319 // Add all the font families found in a font set.
320 // aAppFonts indicates whether this is the system or application fontset.
321 void AddFontSetFamilies(FcFontSet* aFontSet, const SandboxPolicy* aPolicy,
322 bool aAppFonts) MOZ_REQUIRES(mLock);
324 // Helper for above, to add a single font pattern.
325 void AddPatternToFontList(FcPattern* aFont, FcChar8*& aLastFamilyName,
326 nsACString& aFamilyName,
327 RefPtr<gfxFontconfigFontFamily>& aFontFamily,
328 bool aAppFonts) MOZ_REQUIRES(mLock);
330 // figure out which families fontconfig maps a generic to
331 // (aGeneric assumed already lowercase)
332 PrefFontList* FindGenericFamilies(nsPresContext* aPresContext,
333 const nsCString& aGeneric,
334 nsAtom* aLanguage) MOZ_REQUIRES(mLock);
336 // are all pref font settings set to use fontconfig generics?
337 bool PrefFontListsUseOnlyGenerics() MOZ_REQUIRES(mLock);
339 static void CheckFontUpdates(nsITimer* aTimer, void* aThis);
341 FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
342 const gfxFontStyle* aStyle,
343 nsAtom* aLanguage = nullptr)
344 MOZ_REQUIRES(mLock) override;
346 enum class DistroID : int8_t {
347 Unknown = 0,
348 Ubuntu = 1,
349 Fedora = 2,
350 // To be extended with any distros that ship a useful base set of fonts
351 // that we want to explicitly support.
353 DistroID GetDistroID() const; // -> DistroID::Unknown if we can't tell
355 FontVisibility GetVisibilityForFamily(const nsACString& aName) const;
357 gfxFontFamily* CreateFontFamily(const nsACString& aName,
358 FontVisibility aVisibility) const override;
360 // helper method for finding an appropriate lang string
361 bool TryLangForGroup(const nsACString& aOSLang, nsAtom* aLangGroup,
362 nsACString& aLang, bool aForFontEnumerationThread);
364 #ifdef MOZ_BUNDLED_FONTS
365 void ActivateBundledFonts();
366 nsCString mBundledFontsPath;
367 bool mBundledFontsInitialized;
368 #endif
370 // to avoid enumerating all fonts, maintain a mapping of local font
371 // names to family
372 nsTHashMap<nsCString, RefPtr<FcPattern>> mLocalNames;
374 // caching generic/lang ==> font family list
375 nsClassHashtable<nsCStringHashKey, PrefFontList> mGenericMappings;
377 // Caching family lookups as found by FindAndAddFamilies after resolving
378 // substitutions. The gfxFontFamily objects cached here are owned by the
379 // gfxFcPlatformFontList via its mFamilies table; note that if the main
380 // font list is rebuilt (e.g. due to a fontconfig configuration change),
381 // these pointers will be invalidated. InitFontList() flushes the cache
382 // in this case.
383 nsTHashMap<nsCStringHashKey, nsTArray<FamilyAndGeneric>> mFcSubstituteCache;
385 nsCOMPtr<nsITimer> mCheckFontUpdatesTimer;
386 RefPtr<FcConfig> mLastConfig;
388 // The current system font options in effect.
389 #ifdef MOZ_WIDGET_GTK
390 // NOTE(emilio): This is a *system cairo* cairo_font_options_t object. As
391 // such, it can't be used outside of the few functions defined here.
392 cairo_font_options_t* mSystemFontOptions = nullptr;
393 int32_t mFreetypeLcdSetting = -1; // -1 for not set
395 void ClearSystemFontOptions();
397 // Returns whether options actually changed.
398 // TODO(emilio): We could call this when gsettings change or such, but
399 // historically we haven't reacted to these settings changes, so keeping it
400 // simple for now.
401 bool UpdateSystemFontOptions();
403 void UpdateSystemFontOptionsFromIpc(const mozilla::dom::SystemFontOptions&);
404 void SystemFontOptionsToIpc(mozilla::dom::SystemFontOptions&);
406 public:
407 void SubstituteSystemFontOptions(FcPattern*);
409 private:
410 #endif
412 // Cache for most recently used language code in FindAndAddFamiliesLocked,
413 // and the result of checking whether to use lang-specific lookups.
414 RefPtr<nsAtom> mPrevLanguage;
415 nsCString mSampleLang;
416 bool mUseCustomLookups = false;
418 // By default, font prefs under Linux are set to simply lookup
419 // via fontconfig the appropriate font for serif/sans-serif/monospace.
420 // Rather than check each time a font pref is used, check them all at startup
421 // and set a boolean to flag the case that non-default user font prefs exist
422 // Note: langGroup == x-math is handled separately
423 bool mAlwaysUseFontconfigGenerics;
425 static FT_Library sFTLibrary;
428 #endif /* GFXPLATFORMFONTLIST_H_ */