Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/thebes/gfxUserFontSet.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 GFX_USER_FONT_SET_H
7
#define GFX_USER_FONT_SET_H
8
9
#include "gfxFont.h"
10
#include "gfxFontFamilyList.h"
11
#include "gfxFontSrcPrincipal.h"
12
#include "gfxFontSrcURI.h"
13
#include "nsRefPtrHashtable.h"
14
#include "nsCOMPtr.h"
15
#include "nsIURI.h"
16
#include "nsIPrincipal.h"
17
#include "nsIScriptError.h"
18
#include "nsURIHashKey.h"
19
#include "mozilla/FontPropertyTypes.h"
20
#include "mozilla/net/ReferrerPolicy.h"
21
#include "gfxFontConstants.h"
22
23
namespace mozilla {
24
class PostTraversalTask;
25
} // namespace mozilla
26
class nsFontFaceLoader;
27
28
//#define DEBUG_USERFONT_CACHE
29
30
class gfxFontFaceBufferSource
31
{
32
  NS_INLINE_DECL_REFCOUNTING(gfxFontFaceBufferSource)
33
public:
34
  virtual void TakeBuffer(uint8_t*& aBuffer, uint32_t& aLength) = 0;
35
36
protected:
37
  virtual ~gfxFontFaceBufferSource() {}
38
};
39
40
// parsed CSS @font-face rule information
41
// lifetime: from when @font-face rule processed until font is loaded
42
struct gfxFontFaceSrc {
43
44
    enum SourceType {
45
        eSourceType_Local,
46
        eSourceType_URL,
47
        eSourceType_Buffer
48
    };
49
50
    SourceType             mSourceType;
51
52
    // if url, whether to use the origin principal or not
53
    bool                   mUseOriginPrincipal;
54
55
    // format hint flags, union of all possible formats
56
    // (e.g. TrueType, EOT, SVG, etc.)
57
    // see FLAG_FORMAT_* enum values below
58
    uint32_t               mFormatFlags;
59
60
    nsCString              mLocalName;     // full font name if local
61
    RefPtr<gfxFontSrcURI>  mURI;           // uri if url
62
    nsCOMPtr<nsIURI>       mReferrer;      // referrer url if url
63
    mozilla::net::ReferrerPolicy mReferrerPolicy;
64
    RefPtr<gfxFontSrcPrincipal> mOriginPrincipal; // principal if url
65
66
    RefPtr<gfxFontFaceBufferSource> mBuffer;
67
68
    // The principal that should be used for the load. Should only be used for
69
    // URL sources.
70
    gfxFontSrcPrincipal* LoadPrincipal(const gfxUserFontSet&) const;
71
};
72
73
inline bool
74
operator==(const gfxFontFaceSrc& a, const gfxFontFaceSrc& b)
75
0
{
76
0
    // The mReferrer and mOriginPrincipal comparisons aren't safe OMT.
77
0
    MOZ_ASSERT(NS_IsMainThread());
78
0
79
0
    if (a.mSourceType != b.mSourceType) {
80
0
        return false;
81
0
    }
82
0
    switch (a.mSourceType) {
83
0
        case gfxFontFaceSrc::eSourceType_Local:
84
0
            return a.mLocalName == b.mLocalName;
85
0
        case gfxFontFaceSrc::eSourceType_URL: {
86
0
            bool equals;
87
0
            return a.mUseOriginPrincipal == b.mUseOriginPrincipal &&
88
0
                   a.mFormatFlags == b.mFormatFlags &&
89
0
                   (a.mURI == b.mURI || a.mURI->Equals(b.mURI)) &&
90
0
                   NS_SUCCEEDED(a.mReferrer->Equals(b.mReferrer, &equals)) &&
91
0
                     equals &&
92
0
                   a.mReferrerPolicy == b.mReferrerPolicy &&
93
0
                   a.mOriginPrincipal->Equals(b.mOriginPrincipal);
94
0
        }
95
0
        case gfxFontFaceSrc::eSourceType_Buffer:
96
0
            return a.mBuffer == b.mBuffer;
97
0
    }
98
0
    NS_WARNING("unexpected mSourceType");
99
0
    return false;
100
0
}
101
102
// Subclassed to store platform-specific code cleaned out when font entry is
103
// deleted.
104
// Lifetime: from when platform font is created until it is deactivated.
105
// If the platform does not need to add any platform-specific code/data here,
106
// then the gfxUserFontSet will allocate a base gfxUserFontData and attach
107
// to the entry to track the basic user font info fields here.
108
class gfxUserFontData {
109
public:
110
    gfxUserFontData()
111
        : mSrcIndex(0), mFormat(0), mMetaOrigLen(0),
112
          mCompression(kUnknownCompression),
113
          mPrivate(false), mIsBuffer(false)
114
0
    { }
115
0
    virtual ~gfxUserFontData() { }
116
117
    size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
118
119
    nsTArray<uint8_t> mMetadata;  // woff metadata block (compressed), if any
120
    RefPtr<gfxFontSrcURI>  mURI;       // URI of the source, if it was url()
121
    RefPtr<gfxFontSrcPrincipal> mPrincipal; // principal for the download, if url()
122
    nsCString         mLocalName; // font name used for the source, if local()
123
    nsCString         mRealName;  // original fullname from the font resource
124
    uint32_t          mSrcIndex;  // index in the rule's source list
125
    uint32_t          mFormat;    // format hint for the source used, if any
126
    uint32_t          mMetaOrigLen; // length needed to decompress metadata
127
    uint8_t           mCompression; // compression type
128
    bool              mPrivate;   // whether font belongs to a private window
129
    bool              mIsBuffer;  // whether the font source was a buffer
130
131
    enum {
132
        kUnknownCompression = 0,
133
        kZlibCompression = 1,
134
        kBrotliCompression = 2
135
    };
136
};
137
138
// initially contains a set of userfont font entry objects, replaced with
139
// platform/user fonts as downloaded
140
141
class gfxUserFontFamily : public gfxFontFamily {
142
public:
143
    friend class gfxUserFontSet;
144
145
    explicit gfxUserFontFamily(const nsACString& aName)
146
0
        : gfxFontFamily(aName) { }
147
148
    virtual ~gfxUserFontFamily();
149
150
    // add the given font entry to the end of the family's list
151
0
    void AddFontEntry(gfxFontEntry* aFontEntry) {
152
0
        // keep ref while removing existing entry
153
0
        RefPtr<gfxFontEntry> fe = aFontEntry;
154
0
        // remove existing entry, if already present
155
0
        mAvailableFonts.RemoveElement(aFontEntry);
156
0
        // insert at the beginning so that the last-defined font is the first
157
0
        // one in the fontlist used for matching, as per CSS Fonts spec
158
0
        mAvailableFonts.InsertElementAt(0, aFontEntry);
159
0
160
0
        if (aFontEntry->mFamilyName.IsEmpty()) {
161
0
            aFontEntry->mFamilyName = Name();
162
0
        } else {
163
#ifdef DEBUG
164
            nsCString thisName = Name();
165
            nsCString entryName = aFontEntry->mFamilyName;
166
            ToLowerCase(thisName);
167
            ToLowerCase(entryName);
168
            MOZ_ASSERT(thisName.Equals(entryName));
169
#endif
170
        }
171
0
        ResetCharacterMap();
172
0
    }
173
174
    // Remove all font entries from the family
175
    void DetachFontEntries() {
176
        mAvailableFonts.Clear();
177
    }
178
};
179
180
class gfxUserFontEntry;
181
class gfxOTSContext;
182
183
class gfxUserFontSet {
184
    friend class gfxUserFontEntry;
185
    friend class gfxOTSContext;
186
187
public:
188
    typedef mozilla::FontStretch FontStretch;
189
    typedef mozilla::StretchRange StretchRange;
190
    typedef mozilla::FontSlantStyle FontSlantStyle;
191
    typedef mozilla::SlantStyleRange SlantStyleRange;
192
    typedef mozilla::FontWeight FontWeight;
193
    typedef mozilla::WeightRange WeightRange;
194
    typedef gfxFontEntry::RangeFlags RangeFlags;
195
196
    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxUserFontSet)
197
198
    gfxUserFontSet();
199
200
    enum {
201
        // no flags ==> no hint set
202
        // unknown ==> unknown format hint set
203
        FLAG_FORMAT_UNKNOWN        = 1,
204
        FLAG_FORMAT_OPENTYPE       = 1 << 1,
205
        FLAG_FORMAT_TRUETYPE       = 1 << 2,
206
        FLAG_FORMAT_TRUETYPE_AAT   = 1 << 3,
207
        FLAG_FORMAT_EOT            = 1 << 4,
208
        FLAG_FORMAT_SVG            = 1 << 5,
209
        FLAG_FORMAT_WOFF           = 1 << 6,
210
        FLAG_FORMAT_WOFF2          = 1 << 7,
211
212
        FLAG_FORMAT_OPENTYPE_VARIATIONS = 1 << 8,
213
        FLAG_FORMAT_TRUETYPE_VARIATIONS = 1 << 9,
214
        FLAG_FORMAT_WOFF_VARIATIONS     = 1 << 10,
215
        FLAG_FORMAT_WOFF2_VARIATIONS    = 1 << 11,
216
217
        // the common formats that we support everywhere
218
        FLAG_FORMATS_COMMON        = FLAG_FORMAT_OPENTYPE |
219
                                     FLAG_FORMAT_TRUETYPE |
220
                                     FLAG_FORMAT_WOFF     |
221
                                     FLAG_FORMAT_WOFF2    |
222
                                     FLAG_FORMAT_OPENTYPE_VARIATIONS |
223
                                     FLAG_FORMAT_TRUETYPE_VARIATIONS |
224
                                     FLAG_FORMAT_WOFF_VARIATIONS     |
225
                                     FLAG_FORMAT_WOFF2_VARIATIONS,
226
227
        // mask of all unused bits, update when adding new formats
228
        FLAG_FORMAT_NOT_USED       = ~((1 << 12)-1)
229
    };
230
231
232
    // creates a font face without adding it to a particular family
233
    // weight - [100, 900] (multiples of 100)
234
    // stretch = [FontStretch::UltraCondensed(), FontStretch::UltraExpanded()]
235
    // italic style = constants in gfxFontConstants.h, e.g. NS_FONT_STYLE_NORMAL
236
    // language override = result of calling nsLayoutUtils::ParseFontLanguageOverride
237
    // TODO: support for unicode ranges not yet implemented
238
    virtual already_AddRefed<gfxUserFontEntry> CreateUserFontEntry(
239
                              const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
240
                              WeightRange aWeight,
241
                              StretchRange aStretch,
242
                              SlantStyleRange aStyle,
243
                              const nsTArray<gfxFontFeature>& aFeatureSettings,
244
                              const nsTArray<gfxFontVariation>& aVariationSettings,
245
                              uint32_t aLanguageOverride,
246
                              gfxCharacterMap* aUnicodeRanges,
247
                              uint8_t aFontDisplay,
248
                              RangeFlags aRangeFlags) = 0;
249
250
    // creates a font face for the specified family, or returns an existing
251
    // matching entry on the family if there is one
252
    already_AddRefed<gfxUserFontEntry> FindOrCreateUserFontEntry(
253
                               const nsACString& aFamilyName,
254
                               const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
255
                               WeightRange aWeight,
256
                               StretchRange aStretch,
257
                               SlantStyleRange aStyle,
258
                               const nsTArray<gfxFontFeature>& aFeatureSettings,
259
                               const nsTArray<gfxFontVariation>& aVariationSettings,
260
                               uint32_t aLanguageOverride,
261
                               gfxCharacterMap* aUnicodeRanges,
262
                               uint8_t aFontDisplay,
263
                               RangeFlags aRangeFlags);
264
265
    // add in a font face for which we have the gfxUserFontEntry already
266
    void AddUserFontEntry(const nsCString& aFamilyName,
267
                          gfxUserFontEntry* aUserFontEntry);
268
269
    // Whether there is a face with this family name
270
    bool HasFamily(const nsACString& aFamilyName) const
271
0
    {
272
0
        return LookupFamily(aFamilyName) != nullptr;
273
0
    }
274
275
    // Look up and return the gfxUserFontFamily in mFontFamilies with
276
    // the given name
277
    gfxUserFontFamily* LookupFamily(const nsACString& aName) const;
278
279
    // Look up names in a fontlist and return true if any are in the set
280
    bool ContainsUserFontSetFonts(const mozilla::FontFamilyList& aFontList) const;
281
282
    virtual gfxFontSrcPrincipal* GetStandardFontLoadPrincipal() const = 0;
283
284
    // check whether content policies allow the given URI to load.
285
    virtual bool IsFontLoadAllowed(const gfxFontFaceSrc&) = 0;
286
287
    // Dispatches all of the specified runnables to the font face set's
288
    // document's event queue.
289
    virtual void DispatchFontLoadViolations(
290
        nsTArray<nsCOMPtr<nsIRunnable>>& aViolations) = 0;
291
292
    // initialize the process that loads external font data, which upon
293
    // completion will call FontDataDownloadComplete method
294
    virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
295
                               const gfxFontFaceSrc* aFontFaceSrc) = 0;
296
297
    // generation - each time a face is loaded, generation is
298
    // incremented so that the change can be recognized
299
0
    uint64_t GetGeneration() { return mGeneration; }
300
301
    // increment the generation on font load
302
    void IncrementGeneration(bool aIsRebuild = false);
303
304
    // Generation is bumped on font loads but that doesn't affect name-style
305
    // mappings. Rebuilds do however affect name-style mappings so need to
306
    // lookup fontlists again when that happens.
307
0
    uint64_t GetRebuildGeneration() { return mRebuildGeneration; }
308
309
    // rebuild if local rules have been used
310
    void RebuildLocalRules();
311
312
    class UserFontCache {
313
    public:
314
        // Record a loaded user-font in the cache. This requires that the
315
        // font-entry's userFontData has been set up already, as it relies
316
        // on the URI and Principal recorded there.
317
        static void CacheFont(gfxFontEntry* aFontEntry);
318
319
        // The given gfxFontEntry is being destroyed, so remove any record that
320
        // refers to it.
321
        static void ForgetFont(gfxFontEntry* aFontEntry);
322
323
        // Return the gfxFontEntry corresponding to a given URI and principal,
324
        // and the features of the given userfont entry, or nullptr if none is available.
325
        // The aPrivate flag is set for requests coming from private windows,
326
        // so we can avoid leaking fonts cached in private windows mode out to
327
        // normal windows.
328
        static gfxFontEntry* GetFont(const gfxFontFaceSrc&, const gfxUserFontEntry&);
329
330
        // Clear everything so that we don't leak URIs and Principals.
331
        static void Shutdown();
332
333
        // Memory-reporting support.
334
        class MemoryReporter final : public nsIMemoryReporter
335
        {
336
        private:
337
0
            ~MemoryReporter() { }
338
339
        public:
340
            NS_DECL_ISUPPORTS
341
            NS_DECL_NSIMEMORYREPORTER
342
        };
343
344
#ifdef DEBUG_USERFONT_CACHE
345
        // dump contents
346
        static void Dump();
347
#endif
348
349
    private:
350
        // Helper that we use to observe the empty-cache notification
351
        // from nsICacheService.
352
        class Flusher : public nsIObserver
353
        {
354
0
            virtual ~Flusher() {}
355
        public:
356
            NS_DECL_ISUPPORTS
357
            NS_DECL_NSIOBSERVER
358
0
            Flusher() {}
359
        };
360
361
        // Key used to look up entries in the user-font cache.
362
        // Note that key comparison does *not* use the mFontEntry field
363
        // as a whole; it only compares specific fields within the entry
364
        // (weight/width/style/features) that could affect font selection
365
        // or rendering, and that must match between a font-set's userfont
366
        // entry and the corresponding "real" font entry.
367
        struct Key {
368
            RefPtr<gfxFontSrcURI>   mURI;
369
            RefPtr<gfxFontSrcPrincipal> mPrincipal; // use nullptr with data: URLs
370
            // The font entry MUST notify the cache when it is destroyed
371
            // (by calling ForgetFont()).
372
            gfxFontEntry* MOZ_NON_OWNING_REF mFontEntry;
373
            bool                    mPrivate;
374
375
            Key(gfxFontSrcURI* aURI, gfxFontSrcPrincipal* aPrincipal,
376
                gfxFontEntry* aFontEntry, bool aPrivate)
377
                : mURI(aURI),
378
                  mPrincipal(aPrincipal),
379
                  mFontEntry(aFontEntry),
380
                  mPrivate(aPrivate)
381
0
            { }
382
        };
383
384
        class Entry : public PLDHashEntryHdr {
385
        public:
386
            typedef const Key& KeyType;
387
            typedef const Key* KeyTypePointer;
388
389
            explicit Entry(KeyTypePointer aKey)
390
                : mURI(aKey->mURI),
391
                  mPrincipal(aKey->mPrincipal),
392
                  mFontEntry(aKey->mFontEntry),
393
                  mPrivate(aKey->mPrivate)
394
0
            { }
395
396
            Entry(Entry&& aOther)
397
                : PLDHashEntryHdr(std::move(aOther))
398
                , mURI(std::move(aOther.mURI))
399
                , mPrincipal(std::move(aOther.mPrincipal))
400
                , mFontEntry(std::move(aOther.mFontEntry))
401
                , mPrivate(std::move(aOther.mPrivate))
402
0
            { }
403
404
0
            ~Entry() { }
405
406
            bool KeyEquals(const KeyTypePointer aKey) const;
407
408
0
            static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
409
410
0
            static PLDHashNumber HashKey(const KeyTypePointer aKey) {
411
0
                PLDHashNumber principalHash =
412
0
                    aKey->mPrincipal ? aKey->mPrincipal->Hash() : 0;
413
0
                return mozilla::HashGeneric(principalHash + int(aKey->mPrivate),
414
0
                                            aKey->mURI->Hash(),
415
0
                                            HashFeatures(aKey->mFontEntry->mFeatureSettings),
416
0
                                            HashVariations(aKey->mFontEntry->mVariationSettings),
417
0
                                            mozilla::HashString(aKey->mFontEntry->mFamilyName),
418
0
                                            aKey->mFontEntry->Weight().AsScalar(),
419
0
                                            aKey->mFontEntry->SlantStyle().AsScalar(),
420
0
                                            aKey->mFontEntry->Stretch().AsScalar(),
421
0
                                            aKey->mFontEntry->mLanguageOverride);
422
0
            }
423
424
            enum { ALLOW_MEMMOVE = false };
425
426
0
            gfxFontSrcURI* GetURI() const { return mURI; }
427
0
            gfxFontSrcPrincipal* GetPrincipal() const { return mPrincipal; }
428
0
            gfxFontEntry* GetFontEntry() const { return mFontEntry; }
429
0
            bool IsPrivate() const { return mPrivate; }
430
431
            void ReportMemory(nsIHandleReportCallback* aHandleReport,
432
                              nsISupports* aData, bool aAnonymize);
433
434
#ifdef DEBUG_USERFONT_CACHE
435
            void Dump();
436
#endif
437
438
        private:
439
            static uint32_t
440
0
            HashFeatures(const nsTArray<gfxFontFeature>& aFeatures) {
441
0
                return mozilla::HashBytes(aFeatures.Elements(),
442
0
                                          aFeatures.Length() * sizeof(gfxFontFeature));
443
0
            }
444
445
            static uint32_t
446
0
            HashVariations(const nsTArray<gfxFontVariation>& aVariations) {
447
0
                return mozilla::HashBytes(aVariations.Elements(),
448
0
                                          aVariations.Length() * sizeof(gfxFontVariation));
449
0
            }
450
451
            RefPtr<gfxFontSrcURI>  mURI;
452
            RefPtr<gfxFontSrcPrincipal> mPrincipal; // or nullptr for data: URLs
453
454
            // The "real" font entry corresponding to this downloaded font.
455
            // The font entry MUST notify the cache when it is destroyed
456
            // (by calling ForgetFont()).
457
            gfxFontEntry* MOZ_NON_OWNING_REF mFontEntry;
458
459
            // Whether this font was loaded from a private window.
460
            bool                   mPrivate;
461
        };
462
463
        static nsTHashtable<Entry>* sUserFonts;
464
    };
465
466
0
    void SetLocalRulesUsed() {
467
0
        mLocalRulesUsed = true;
468
0
    }
469
470
    static mozilla::LogModule* GetUserFontsLog();
471
472
    // record statistics about font completion
473
    virtual void RecordFontLoadDone(uint32_t aFontSize,
474
0
                                    mozilla::TimeStamp aDoneTime) {}
475
476
    void GetLoadStatistics(uint32_t& aLoadCount, uint64_t& aLoadSize) const {
477
        aLoadCount = mDownloadCount;
478
        aLoadSize = mDownloadSize;
479
    }
480
481
protected:
482
    // Protected destructor, to discourage deletion outside of Release():
483
    virtual ~gfxUserFontSet();
484
485
    // Return whether the font set is associated with a private-browsing tab.
486
    virtual bool GetPrivateBrowsing() = 0;
487
488
    // Return whether the font set is associated with a document that was
489
    // shift-reloaded, for example, and thus should bypass the font cache.
490
    virtual bool BypassCache() = 0;
491
492
    // parse data for a data URL
493
    virtual nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
494
                                      const gfxFontFaceSrc* aFontFaceSrc,
495
                                      uint8_t* &aBuffer,
496
                                      uint32_t &aBufferLength) = 0;
497
498
    // report a problem of some kind (implemented in nsUserFontSet)
499
    virtual nsresult LogMessage(gfxUserFontEntry* aUserFontEntry,
500
                                const char* aMessage,
501
                                uint32_t aFlags = nsIScriptError::errorFlag,
502
                                nsresult aStatus = NS_OK) = 0;
503
504
    // helper method for performing the actual userfont set rebuild
505
    virtual void DoRebuildUserFontSet() = 0;
506
507
    // helper method for FindOrCreateUserFontEntry
508
    gfxUserFontEntry* FindExistingUserFontEntry(
509
                                   gfxUserFontFamily* aFamily,
510
                                   const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
511
                                   WeightRange aWeight,
512
                                   StretchRange aStretch,
513
                                   SlantStyleRange aStyle,
514
                                   const nsTArray<gfxFontFeature>& aFeatureSettings,
515
                                   const nsTArray<gfxFontVariation>& aVariationSettings,
516
                                   uint32_t aLanguageOverride,
517
                                   gfxCharacterMap* aUnicodeRanges,
518
                                   uint8_t aFontDisplay,
519
                                   RangeFlags aRangeFlags);
520
521
    // creates a new gfxUserFontFamily in mFontFamilies, or returns an existing
522
    // family if there is one
523
    gfxUserFontFamily* GetFamily(const nsACString& aFamilyName);
524
525
    // font families defined by @font-face rules
526
    nsRefPtrHashtable<nsCStringHashKey, gfxUserFontFamily> mFontFamilies;
527
528
    uint64_t        mGeneration;        // bumped on any font load change
529
    uint64_t        mRebuildGeneration; // only bumped on rebuilds
530
531
    // true when local names have been looked up, false otherwise
532
    bool mLocalRulesUsed;
533
534
    // true when rules using local names need to be redone
535
    bool mRebuildLocalRules;
536
537
    // performance stats
538
    uint32_t mDownloadCount;
539
    uint64_t mDownloadSize;
540
};
541
542
// acts a placeholder until the real font is downloaded
543
544
class gfxUserFontEntry : public gfxFontEntry {
545
    friend class mozilla::PostTraversalTask;
546
    friend class gfxUserFontSet;
547
    friend class nsUserFontSet;
548
    friend class nsFontFaceLoader;
549
    friend class gfxOTSContext;
550
551
public:
552
    enum UserFontLoadState {
553
        STATUS_NOT_LOADED = 0,
554
        STATUS_LOAD_PENDING,
555
        STATUS_LOADING,
556
        STATUS_LOADED,
557
        STATUS_FAILED
558
    };
559
560
    gfxUserFontEntry(gfxUserFontSet* aFontSet,
561
                     const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
562
                     WeightRange aWeight,
563
                     StretchRange aStretch,
564
                     SlantStyleRange aStyle,
565
                     const nsTArray<gfxFontFeature>& aFeatureSettings,
566
                     const nsTArray<gfxFontVariation>& aVariationSettings,
567
                     uint32_t aLanguageOverride,
568
                     gfxCharacterMap* aUnicodeRanges,
569
                     uint8_t aFontDisplay,
570
                     RangeFlags aRangeFlags);
571
572
    virtual ~gfxUserFontEntry();
573
574
    // Return whether the entry matches the given list of attributes
575
    bool Matches(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
576
                 WeightRange aWeight,
577
                 StretchRange aStretch,
578
                 SlantStyleRange aStyle,
579
                 const nsTArray<gfxFontFeature>& aFeatureSettings,
580
                 const nsTArray<gfxFontVariation>& aVariationSettings,
581
                 uint32_t aLanguageOverride,
582
                 gfxCharacterMap* aUnicodeRanges,
583
                 uint8_t aFontDisplay,
584
                 RangeFlags aRangeFlags);
585
586
    gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override;
587
588
0
    gfxFontEntry* GetPlatformFontEntry() const { return mPlatformFontEntry; }
589
590
    // is the font loading or loaded, or did it fail?
591
0
    UserFontLoadState LoadState() const { return mUserFontLoadState; }
592
593
    void LoadCanceled()
594
    {
595
      mUserFontLoadState = STATUS_NOT_LOADED;
596
      mFontDataLoadingState = NOT_LOADING;
597
      mLoader = nullptr;
598
    }
599
600
    // whether to wait before using fallback font or not
601
0
    bool WaitForUserFont() const {
602
0
        return (mUserFontLoadState == STATUS_LOAD_PENDING ||
603
0
                mUserFontLoadState == STATUS_LOADING) &&
604
0
               mFontDataLoadingState < LOADING_SLOWLY;
605
0
    }
606
607
    // for userfonts, cmap is used to store the unicode range data
608
    // no cmap ==> all codepoints permitted
609
0
    bool CharacterInUnicodeRange(uint32_t ch) const {
610
0
        if (mCharacterMap) {
611
0
            return mCharacterMap->test(ch);
612
0
        }
613
0
        return true;
614
0
    }
615
616
0
    gfxCharacterMap* GetUnicodeRangeMap() const {
617
0
        return mCharacterMap.get();
618
0
    }
619
620
0
    uint8_t GetFontDisplay() const { return mFontDisplay; }
621
622
    // load the font - starts the loading of sources which continues until
623
    // a valid font resource is found or all sources fail
624
    void Load();
625
626
    // methods to expose some information to FontFaceSet::UserFontSet
627
    // since we can't make that class a friend
628
    void SetLoader(nsFontFaceLoader* aLoader) { mLoader = aLoader; }
629
    nsFontFaceLoader* GetLoader() { return mLoader; }
630
    gfxFontSrcPrincipal* GetPrincipal() { return mPrincipal; }
631
    uint32_t GetSrcIndex() { return mSrcIndex; }
632
    void GetFamilyNameAndURIForLogging(nsACString& aFamilyName,
633
                                       nsACString& aURI);
634
635
0
    gfxFontEntry* Clone() const override {
636
0
        MOZ_ASSERT_UNREACHABLE("cannot Clone user fonts");
637
0
        return nullptr;
638
0
    }
639
640
#ifdef DEBUG
641
    gfxUserFontSet* GetUserFontSet() const { return mFontSet; }
642
#endif
643
644
    const nsTArray<gfxFontFaceSrc>& SourceList() const
645
    {
646
      return mSrcList;
647
    }
648
649
    // The variation-query APIs should not be called on placeholders.
650
0
    bool HasVariations() override {
651
0
      MOZ_ASSERT_UNREACHABLE("not meaningful for a userfont placeholder");
652
0
      return false;
653
0
    }
654
0
    void GetVariationAxes(nsTArray<gfxFontVariationAxis>&) override {
655
0
      MOZ_ASSERT_UNREACHABLE("not meaningful for a userfont placeholder");
656
0
    }
657
0
    void GetVariationInstances(nsTArray<gfxFontVariationInstance>&) override {
658
0
      MOZ_ASSERT_UNREACHABLE("not meaningful for a userfont placeholder");
659
0
    }
660
661
protected:
662
    const uint8_t* SanitizeOpenTypeData(const uint8_t* aData,
663
                                        uint32_t aLength,
664
                                        uint32_t& aSaneLength,
665
                                        gfxUserFontType aFontType);
666
667
    // attempt to load the next resource in the src list.
668
    void LoadNextSrc();
669
    void ContinueLoad();
670
    void DoLoadNextSrc(bool aForceAsync);
671
672
    // change the load state
673
    virtual void SetLoadState(UserFontLoadState aLoadState);
674
675
    // when download has been completed, pass back data here
676
    // aDownloadStatus == NS_OK ==> download succeeded, error otherwise
677
    // returns true if platform font creation sucessful (or local()
678
    // reference was next in line)
679
    // Ownership of aFontData is passed in here; the font set must
680
    // ensure that it is eventually deleted with free().
681
    bool FontDataDownloadComplete(const uint8_t* aFontData, uint32_t aLength,
682
                                  nsresult aDownloadStatus);
683
684
    // helper method for creating a platform font
685
    // returns true if platform font creation successful
686
    // Ownership of aFontData is passed in here; the font must
687
    // ensure that it is eventually deleted with free().
688
    bool LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength);
689
690
    // store metadata and src details for current src into aFontEntry
691
    void StoreUserFontData(gfxFontEntry*      aFontEntry,
692
                           bool               aPrivate,
693
                           const nsACString&  aOriginalName,
694
                           FallibleTArray<uint8_t>* aMetadata,
695
                           uint32_t           aMetaOrigLen,
696
                           uint8_t            aCompression);
697
698
    // Clears and then adds to aResult all of the user font sets that this user
699
    // font entry has been added to.  This will at least include mFontSet, the
700
    // owner of this user font entry.
701
    virtual void GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult);
702
703
    // Calls IncrementGeneration() on all user font sets that contain this
704
    // user font entry.
705
    void IncrementGeneration();
706
707
    // general load state
708
    UserFontLoadState        mUserFontLoadState;
709
710
    // detailed load state while font data is loading
711
    // used to determine whether to use fallback font or not
712
    // note that code depends on the ordering of these values!
713
    enum FontDataLoadingState {
714
        NOT_LOADING = 0,     // not started to load any font resources yet
715
        LOADING_STARTED,     // loading has started; hide fallback font
716
        LOADING_ALMOST_DONE, // timeout happened but we're nearly done,
717
                             // so keep hiding fallback font
718
        LOADING_SLOWLY,      // timeout happened and we're not nearly done,
719
                             // so use the fallback font
720
        LOADING_TIMED_OUT,   // font load took too long
721
        LOADING_FAILED       // failed to load any source: use fallback
722
    };
723
    FontDataLoadingState     mFontDataLoadingState;
724
725
    bool                     mUnsupportedFormat;
726
    uint8_t                  mFontDisplay; // timing of userfont fallback
727
728
    RefPtr<gfxFontEntry>   mPlatformFontEntry;
729
    nsTArray<gfxFontFaceSrc> mSrcList;
730
    uint32_t                 mSrcIndex; // index of loading src item
731
    // This field is managed by the nsFontFaceLoader. In the destructor and Cancel()
732
    // methods of nsFontFaceLoader this reference is nulled out.
733
    nsFontFaceLoader* MOZ_NON_OWNING_REF mLoader; // current loader for this entry, if any
734
    gfxUserFontSet*   MOZ_NON_OWNING_REF mFontSet; // font-set which owns this userfont entry
735
    RefPtr<gfxFontSrcPrincipal> mPrincipal;
736
};
737
738
739
#endif /* GFX_USER_FONT_SET_H */