Coverage Report

Created: 2018-09-25 14:53

/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_ */