Bug 1914102 - Use OffscreenCanvas in TabBase.capture instead of creating a canvas...
[gecko.git] / gfx / thebes / gfxFcPlatformFontList.h
blobebf57fbcaa8a39228e25263834ffbaabc6cd2e76
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 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. Once mFTFaceInitialized is true,
124 // the face can be accessed without locking.
125 // Note that mFTFace owns a reference to the SharedFTFace, but is not
126 // a RefPtr because we need it to be an atomic.
127 mozilla::Atomic<mozilla::gfx::SharedFTFace*> mFTFace;
128 mozilla::Atomic<bool> mFTFaceInitialized;
130 // Whether TestCharacterMap should check the actual cmap rather than asking
131 // fontconfig about character coverage.
132 // We do this for app-bundled (rather than system) fonts, as they may
133 // include color glyphs that fontconfig would overlook, and for fonts
134 // loaded via @font-face.
135 bool mIgnoreFcCharmap;
137 // Whether the face supports variations. For system-installed fonts, we
138 // query fontconfig for this (so they will only work if fontconfig is
139 // recent enough to include support); for downloaded user-fonts we query
140 // the FreeType face.
141 enum class HasVariationsState : int8_t {
142 Uninitialized = -1,
143 No = 0,
144 Yes = 1,
146 std::atomic<HasVariationsState> mHasVariations =
147 HasVariationsState::Uninitialized;
149 class UnscaledFontCache {
150 public:
151 already_AddRefed<mozilla::gfx::UnscaledFontFontconfig> Lookup(
152 const std::string& aFile, uint32_t aIndex);
154 void Add(
155 const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont) {
156 mUnscaledFonts[kNumEntries - 1] = aUnscaledFont;
157 MoveToFront(kNumEntries - 1);
160 private:
161 void MoveToFront(size_t aIndex);
163 static const size_t kNumEntries = 3;
164 mozilla::ThreadSafeWeakPtr<mozilla::gfx::UnscaledFontFontconfig>
165 mUnscaledFonts[kNumEntries];
168 UnscaledFontCache mUnscaledFontCache;
170 // Because of FreeType bug 52955, we keep the FT_MM_Var struct when it is
171 // first loaded, rather than releasing it and re-fetching it as needed.
172 FT_MM_Var* mMMVar = nullptr;
173 bool mMMVarInitialized = false;
176 class gfxFontconfigFontFamily final : public gfxFontFamily {
177 public:
178 gfxFontconfigFontFamily(const nsACString& aName, FontVisibility aVisibility)
179 : gfxFontFamily(aName, aVisibility),
180 mContainsAppFonts(false),
181 mHasNonScalableFaces(false),
182 mForceScalable(false) {}
184 template <typename Func>
185 void AddFacesToFontList(Func aAddPatternFunc);
187 void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr)
188 MOZ_REQUIRES(mLock) override;
190 // Families are constructed initially with just references to patterns.
191 // When necessary, these are enumerated within FindStyleVariations.
192 void AddFontPattern(FcPattern* aFontPattern, bool aSingleName);
194 void SetFamilyContainsAppFonts(bool aContainsAppFonts) {
195 mContainsAppFonts = aContainsAppFonts;
198 void FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
199 nsTArray<gfxFontEntry*>& aFontEntryList,
200 bool aIgnoreSizeTolerance) override;
202 bool FilterForFontList(nsAtom* aLangGroup,
203 const nsACString& aGeneric) const final {
204 return SupportsLangGroup(aLangGroup);
207 protected:
208 virtual ~gfxFontconfigFontFamily();
210 // helper for FilterForFontList
211 bool SupportsLangGroup(nsAtom* aLangGroup) const;
213 nsTArray<RefPtr<FcPattern>> mFontPatterns;
215 // Number of faces that have a single name. Faces that have multiple names are
216 // sorted last.
217 uint32_t mUniqueNameFaceCount = 0;
218 bool mContainsAppFonts : 1;
219 bool mHasNonScalableFaces : 1;
220 bool mForceScalable : 1;
223 class gfxFontconfigFont final : public gfxFT2FontBase {
224 public:
225 gfxFontconfigFont(
226 const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont,
227 RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, FcPattern* aPattern,
228 gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry,
229 const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
231 FontType GetType() const override { return FONT_TYPE_FONTCONFIG; }
232 FcPattern* GetPattern() const { return mPattern; }
234 already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
235 const TextRunDrawParams& aRunParams) override;
237 bool ShouldHintMetrics() const override;
239 private:
240 ~gfxFontconfigFont() override;
242 RefPtr<FcPattern> mPattern;
245 class gfxFcPlatformFontList final : public gfxPlatformFontList {
246 using FontPatternListEntry = mozilla::dom::SystemFontListEntry;
248 public:
249 gfxFcPlatformFontList();
251 static gfxFcPlatformFontList* PlatformFontList() {
252 return static_cast<gfxFcPlatformFontList*>(
253 gfxPlatformFontList::PlatformFontList());
256 // initialize font lists
257 nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) override;
258 void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock) override;
260 void GetFontList(nsAtom* aLangGroup, const nsACString& aGenericFamily,
261 nsTArray<nsString>& aListOfFonts) override;
263 void ReadSystemFontList(mozilla::dom::SystemFontList*);
265 gfxFontEntry* CreateFontEntry(
266 mozilla::fontlist::Face* aFace,
267 const mozilla::fontlist::Family* aFamily) override;
269 gfxFontEntry* LookupLocalFont(nsPresContext* aPresContext,
270 const nsACString& aFontName,
271 WeightRange aWeightForEntry,
272 StretchRange aStretchForEntry,
273 SlantStyleRange aStyleForEntry) override;
275 gfxFontEntry* MakePlatformFont(const nsACString& aFontName,
276 WeightRange aWeightForEntry,
277 StretchRange aStretchForEntry,
278 SlantStyleRange aStyleForEntry,
279 const uint8_t* aFontData,
280 uint32_t aLength) override;
282 bool FindAndAddFamiliesLocked(
283 nsPresContext* aPresContext, mozilla::StyleGenericFontFamily aGeneric,
284 const nsACString& aFamily, nsTArray<FamilyAndGeneric>* aOutput,
285 FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr,
286 nsAtom* aLanguage = nullptr, gfxFloat aDevToCssSize = 1.0)
287 MOZ_REQUIRES(mLock) override;
289 bool GetStandardFamilyName(const nsCString& aFontName,
290 nsACString& aFamilyName) override;
292 FcConfig* GetLastConfig() const { return mLastConfig; }
294 // override to use fontconfig lookup for generics
295 void AddGenericFonts(nsPresContext* aPresContext,
296 mozilla::StyleGenericFontFamily, nsAtom* aLanguage,
297 nsTArray<FamilyAndGeneric>& aFamilyList) override;
299 void ClearLangGroupPrefFontsLocked() MOZ_REQUIRES(mLock) override;
301 // clear out cached generic-lang ==> family-list mappings
302 void ClearGenericMappings() {
303 AutoLock lock(mLock);
304 ClearGenericMappingsLocked();
306 void ClearGenericMappingsLocked() MOZ_REQUIRES(mLock) {
307 mGenericMappings.Clear();
310 // map lang group ==> lang string
311 // When aForFontEnumerationThread is true, this method will avoid using
312 // LanguageService::LookupLanguage, because it is not safe for off-main-
313 // thread use (except by stylo traversal, which does the necessary locking)
314 void GetSampleLangForGroup(nsAtom* aLanguage, nsACString& aLangStr,
315 bool aForFontEnumerationThread = false);
317 protected:
318 virtual ~gfxFcPlatformFontList();
320 nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists()
321 override;
323 #if defined(MOZ_SANDBOX) && defined(XP_LINUX)
324 typedef mozilla::SandboxBroker::Policy SandboxPolicy;
325 #else
326 // Dummy type just so we can still have a SandboxPolicy* parameter.
327 struct SandboxPolicy {};
328 #endif
330 // Add all the font families found in a font set.
331 // aAppFonts indicates whether this is the system or application fontset.
332 void AddFontSetFamilies(FcFontSet* aFontSet, const SandboxPolicy* aPolicy,
333 bool aAppFonts) MOZ_REQUIRES(mLock);
335 // Helper for above, to add a single font pattern.
336 void AddPatternToFontList(FcPattern* aFont, FcChar8*& aLastFamilyName,
337 nsACString& aFamilyName,
338 RefPtr<gfxFontconfigFontFamily>& aFontFamily,
339 bool aAppFonts) MOZ_REQUIRES(mLock);
341 // figure out which families fontconfig maps a generic to
342 // (aGeneric assumed already lowercase)
343 PrefFontList* FindGenericFamilies(nsPresContext* aPresContext,
344 const nsCString& aGeneric,
345 nsAtom* aLanguage) MOZ_REQUIRES(mLock);
347 // are all pref font settings set to use fontconfig generics?
348 bool PrefFontListsUseOnlyGenerics() MOZ_REQUIRES(mLock);
350 static void CheckFontUpdates(nsITimer* aTimer, void* aThis);
352 FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext,
353 const gfxFontStyle* aStyle,
354 nsAtom* aLanguage = nullptr)
355 MOZ_REQUIRES(mLock) override;
357 FontVisibility GetVisibilityForFamily(const nsACString& aName) const;
359 gfxFontFamily* CreateFontFamily(const nsACString& aName,
360 FontVisibility aVisibility) const override;
362 // helper method for finding an appropriate lang string
363 bool TryLangForGroup(const nsACString& aOSLang, nsAtom* aLangGroup,
364 nsACString& aLang, bool aForFontEnumerationThread);
366 #ifdef MOZ_BUNDLED_FONTS
367 void ActivateBundledFonts();
368 nsCString mBundledFontsPath;
369 bool mBundledFontsInitialized;
370 #endif
372 // to avoid enumerating all fonts, maintain a mapping of local font
373 // names to family
374 nsTHashMap<nsCString, RefPtr<FcPattern>> mLocalNames;
376 // caching generic/lang ==> font family list
377 nsClassHashtable<nsCStringHashKey, PrefFontList> mGenericMappings;
379 // Caching family lookups as found by FindAndAddFamilies after resolving
380 // substitutions. The gfxFontFamily objects cached here are owned by the
381 // gfxFcPlatformFontList via its mFamilies table; note that if the main
382 // font list is rebuilt (e.g. due to a fontconfig configuration change),
383 // these pointers will be invalidated. InitFontList() flushes the cache
384 // in this case.
385 nsTHashMap<nsCStringHashKey, nsTArray<FamilyAndGeneric>> mFcSubstituteCache;
387 nsCOMPtr<nsITimer> mCheckFontUpdatesTimer;
388 RefPtr<FcConfig> mLastConfig;
390 // The current system font options in effect.
391 #ifdef MOZ_WIDGET_GTK
392 // NOTE(emilio): This is a *system cairo* cairo_font_options_t object. As
393 // such, it can't be used outside of the few functions defined here.
394 cairo_font_options_t* mSystemFontOptions = nullptr;
395 int32_t mFreetypeLcdSetting = -1; // -1 for not set
397 void ClearSystemFontOptions();
399 // Returns whether options actually changed.
400 // TODO(emilio): We could call this when gsettings change or such, but
401 // historically we haven't reacted to these settings changes, so keeping it
402 // simple for now.
403 bool UpdateSystemFontOptions();
405 void UpdateSystemFontOptionsFromIpc(const mozilla::dom::SystemFontOptions&);
406 void SystemFontOptionsToIpc(mozilla::dom::SystemFontOptions&);
408 public:
409 void SubstituteSystemFontOptions(FcPattern*);
411 private:
412 #endif
414 // Cache for most recently used language code in FindAndAddFamiliesLocked,
415 // and the result of checking whether to use lang-specific lookups.
416 RefPtr<nsAtom> mPrevLanguage;
417 nsCString mSampleLang;
418 bool mUseCustomLookups = false;
420 // By default, font prefs under Linux are set to simply lookup
421 // via fontconfig the appropriate font for serif/sans-serif/monospace.
422 // Rather than check each time a font pref is used, check them all at startup
423 // and set a boolean to flag the case that non-default user font prefs exist
424 // Note: langGroup == x-math is handled separately
425 bool mAlwaysUseFontconfigGenerics;
427 static FT_Library sFTLibrary;
430 #endif /* GFXPLATFORMFONTLIST_H_ */