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_
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>
20 #include FT_FREETYPE_H
21 #include FT_TRUETYPE_TABLES_H
22 #include FT_MULTIPLE_MASTERS_H
26 #if defined(MOZ_CONTENT_SANDBOX) && defined (XP_LINUX)
27 #include "mozilla/SandboxBroker.h"
32 class SystemFontListEntry
;
37 class nsAutoRefTraits
<FcPattern
> : public nsPointerRefTraits
<FcPattern
>
40 static void Release(FcPattern
*ptr
) { FcPatternDestroy(ptr
); }
41 static void AddRef(FcPattern
*ptr
) { FcPatternReference(ptr
); }
45 class nsAutoRefTraits
<FcConfig
> : public nsPointerRefTraits
<FcConfig
>
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
{
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
; }
73 mozilla::gfx::Factory::ReleaseFTFace(mFace
);
75 free((void*)mFontData
);
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
{
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
,
98 StretchRange aStretch
,
99 SlantStyleRange aStyle
,
100 const uint8_t *aData
,
104 // used for @font-face local system fonts with explicit patterns
105 explicit gfxFontconfigFontEntry(const nsACString
& aFaceName
,
106 FcPattern
* aFontPattern
,
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
;
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
;
134 virtual ~gfxFontconfigFontEntry();
136 gfxFont
*CreateFontInstance(const gfxFontStyle
*aFontStyle
) override
;
138 // helper method for creating cairo font from pattern
140 CreateScaledFont(FcPattern
* aRenderPattern
,
141 gfxFloat aAdjustedSize
,
142 const gfxFontStyle
*aStyle
,
145 // override to pull data from FTFace
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
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.
175 bool mHasVariationsInitialized
;
180 const uint8_t* mFontData
;
183 class UnscaledFontCache
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);
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
{
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
;
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
);
243 virtual ~gfxFontconfigFontFamily();
245 // helper for FilterForFontList
246 bool SupportsLangGroup(nsAtom
*aLangGroup
) const;
248 nsTArray
<nsCountedRef
<FcPattern
> > mFontPatterns
;
250 bool mContainsAppFonts
;
251 bool mHasNonScalableFaces
;
255 class gfxFontconfigFont
: public gfxFT2FontBase
{
257 gfxFontconfigFont(const RefPtr
<mozilla::gfx::UnscaledFontFontconfig
> &aUnscaledFont
,
258 cairo_scaled_font_t
*aScaledFont
,
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
;
271 virtual ~gfxFontconfigFont();
273 nsCountedRef
<FcPattern
> mPattern
;
276 class gfxFcPlatformFontList
: public gfxPlatformFontList
{
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
);
295 LookupLocalFont(const nsACString
& aFontName
,
296 WeightRange aWeightForEntry
,
297 StretchRange aStretchForEntry
,
298 SlantStyleRange aStyleForEntry
) override
;
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
,
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();
341 virtual ~gfxFcPlatformFontList();
343 #if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX)
344 typedef mozilla::SandboxBroker::Policy SandboxPolicy
;
346 // Dummy type just so we can still have a SandboxPolicy* parameter.
347 struct SandboxPolicy
{};
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
,
355 // Helper for above, to add a single font pattern.
356 void AddPatternToFontList(FcPattern
* aFont
, FcChar8
*& aLastFamilyName
,
357 nsACString
& aFamilyName
,
358 RefPtr
<gfxFontconfigFontFamily
>& aFontFamily
,
361 // figure out which families fontconfig maps a generic to
362 // (aGeneric assumed already lowercase)
363 PrefFontList
* FindGenericFamilies(const nsCString
& aGeneric
,
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
;
386 // to avoid enumerating all fonts, maintain a mapping of local font
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
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_ */