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 GFX_USER_FONT_SET_H
7 #define GFX_USER_FONT_SET_H
10 #include "PLDHashTable.h"
11 #include "gfxFontEntry.h"
12 #include "gfxFontUtils.h"
13 #include "mozilla/AlreadyAddRefed.h"
14 #include "mozilla/Atomics.h"
15 #include "mozilla/Attributes.h"
16 #include "mozilla/FontPropertyTypes.h"
17 #include "mozilla/MemoryReporting.h"
18 #include "mozilla/RecursiveMutex.h"
19 #include "mozilla/RefPtr.h"
21 #include "nsHashKeys.h"
22 #include "nsIMemoryReporter.h"
23 #include "nsIObserver.h"
24 #include "nsIScriptError.h"
25 #include "nsISupports.h"
26 #include "nsRefPtrHashtable.h"
31 // Only needed for function bodies.
32 #include <utility> // for move, forward
33 #include "MainThreadUtils.h" // for NS_IsMainThread
34 #include "gfxFontFeatures.h" // for gfxFontFeature
35 #include "gfxFontSrcPrincipal.h" // for gfxFontSrcPrincipal
36 #include "gfxFontSrcURI.h" // for gfxFontSrcURI
37 #include "mozilla/Assertions.h" // for AssertionConditionType, MOZ_ASSERT_HELPER2, MOZ_ASSERT, MOZ_ASSERT_UNREACHABLE, MOZ_ASSER...
38 #include "mozilla/HashFunctions.h" // for HashBytes, HashGeneric
39 #include "mozilla/TimeStamp.h" // for TimeStamp
40 #include "mozilla/gfx/FontVariation.h" // for FontVariation
41 #include "nsDebug.h" // for NS_WARNING
42 #include "nsIReferrerInfo.h" // for nsIReferrerInfo
46 class nsIFontLoadCompleteCallback
;
49 struct gfxFontVariationAxis
;
50 struct gfxFontVariationInstance
;
52 class nsMainThreadPtrHandle
;
56 class PostTraversalTask
;
57 enum class StyleFontDisplay
: uint8_t;
58 } // namespace mozilla
59 class nsFontFaceLoader
;
61 // #define DEBUG_USERFONT_CACHE
63 class gfxFontFaceBufferSource
{
64 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontFaceBufferSource
)
66 virtual void TakeBuffer(uint8_t*& aBuffer
, uint32_t& aLength
) = 0;
69 virtual ~gfxFontFaceBufferSource() = default;
72 // parsed CSS @font-face rule information
73 // lifetime: from when @font-face rule processed until font is loaded
74 struct gfxFontFaceSrc
{
75 enum SourceType
{ eSourceType_Local
, eSourceType_URL
, eSourceType_Buffer
};
77 SourceType mSourceType
;
79 // if url, whether to use the origin principal or not
80 bool mUseOriginPrincipal
= false;
82 // Required font technologies.
83 mozilla::StyleFontFaceSourceTechFlags mTechFlags
;
85 // Format hint, if any was specified.
86 mozilla::StyleFontFaceSourceFormatKeyword mFormatHint
;
88 nsCString mLocalName
; // full font name if local
89 RefPtr
<gfxFontSrcURI
> mURI
; // uri if url
90 nsCOMPtr
<nsIReferrerInfo
> mReferrerInfo
; // referrer info if url
91 RefPtr
<gfxFontSrcPrincipal
>
92 mOriginPrincipal
; // principal if url and mUseOriginPrincipal
94 RefPtr
<gfxFontFaceBufferSource
> mBuffer
;
96 // The principal that should be used for the load. Should only be used for
98 already_AddRefed
<gfxFontSrcPrincipal
> LoadPrincipal(
99 const gfxUserFontSet
&) const;
102 inline bool operator==(const gfxFontFaceSrc
& a
, const gfxFontFaceSrc
& b
) {
103 if (a
.mSourceType
!= b
.mSourceType
) {
106 switch (a
.mSourceType
) {
107 case gfxFontFaceSrc::eSourceType_Local
:
108 return a
.mLocalName
== b
.mLocalName
;
109 case gfxFontFaceSrc::eSourceType_URL
: {
110 if (a
.mUseOriginPrincipal
!= b
.mUseOriginPrincipal
) {
113 if (a
.mUseOriginPrincipal
) {
114 if (!a
.mOriginPrincipal
->Equals(b
.mOriginPrincipal
)) {
119 return a
.mFormatHint
== b
.mFormatHint
&& a
.mTechFlags
== b
.mTechFlags
&&
120 (a
.mURI
== b
.mURI
|| a
.mURI
->Equals(b
.mURI
)) &&
121 NS_SUCCEEDED(a
.mReferrerInfo
->Equals(b
.mReferrerInfo
, &equals
)) &&
124 case gfxFontFaceSrc::eSourceType_Buffer
:
125 return a
.mBuffer
== b
.mBuffer
;
127 NS_WARNING("unexpected mSourceType");
131 // Subclassed to store platform-specific code cleaned out when font entry is
133 // Lifetime: from when platform font is created until it is deactivated.
134 // If the platform does not need to add any platform-specific code/data here,
135 // then the gfxUserFontSet will allocate a base gfxUserFontData and attach
136 // to the entry to track the basic user font info fields here.
137 class gfxUserFontData
{
142 mTechFlags(mozilla::StyleFontFaceSourceTechFlags::Empty()),
143 mFormatHint(mozilla::StyleFontFaceSourceFormatKeyword::None
),
144 mCompression(kUnknownCompression
),
147 virtual ~gfxUserFontData() = default;
149 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const;
151 nsTArray
<uint8_t> mMetadata
; // woff metadata block (compressed), if any
152 RefPtr
<gfxFontSrcURI
> mURI
; // URI of the source, if it was url()
153 RefPtr
<gfxFontSrcPrincipal
>
154 mPrincipal
; // principal for the download, if url()
155 nsCString mLocalName
; // font name used for the source, if local()
156 nsCString mRealName
; // original fullname from the font resource
157 uint32_t mSrcIndex
; // index in the rule's source list
158 uint32_t mMetaOrigLen
; // length needed to decompress metadata
159 mozilla::StyleFontFaceSourceTechFlags mTechFlags
; // required font tech
160 mozilla::StyleFontFaceSourceFormatKeyword
161 mFormatHint
; // format hint for the source used, if any
162 uint8_t mCompression
; // compression type
163 bool mPrivate
; // whether font belongs to a private window
164 bool mIsBuffer
; // whether the font source was a buffer
167 kUnknownCompression
= 0,
168 kZlibCompression
= 1,
169 kBrotliCompression
= 2
173 // initially contains a set of userfont font entry objects, replaced with
174 // platform/user fonts as downloaded
176 class gfxUserFontFamily
: public gfxFontFamily
{
178 friend class gfxUserFontSet
;
180 explicit gfxUserFontFamily(const nsACString
& aName
)
181 : gfxFontFamily(aName
, FontVisibility::Webfont
) {}
183 virtual ~gfxUserFontFamily();
185 // add the given font entry to the end of the family's list
186 void AddFontEntry(gfxFontEntry
* aFontEntry
) {
187 mozilla::AutoWriteLock
lock(mLock
);
188 MOZ_ASSERT(!mIsSimpleFamily
, "not valid for user-font families");
189 // keep ref while removing existing entry
190 RefPtr
<gfxFontEntry
> fe
= aFontEntry
;
191 // remove existing entry, if already present
192 mAvailableFonts
.RemoveElement(aFontEntry
);
193 // insert at the beginning so that the last-defined font is the first
194 // one in the fontlist used for matching, as per CSS Fonts spec
195 mAvailableFonts
.InsertElementAt(0, aFontEntry
);
197 if (aFontEntry
->mFamilyName
.IsEmpty()) {
198 aFontEntry
->mFamilyName
= Name();
201 nsCString thisName
= Name();
202 nsCString entryName
= aFontEntry
->mFamilyName
;
203 ToLowerCase(thisName
);
204 ToLowerCase(entryName
);
205 MOZ_ASSERT(thisName
.Equals(entryName
));
211 void RemoveFontEntry(gfxFontEntry
* aFontEntry
) {
212 mozilla::AutoWriteLock
lock(mLock
);
213 MOZ_ASSERT(!mIsSimpleFamily
, "not valid for user-font families");
214 mAvailableFonts
.RemoveElement(aFontEntry
);
217 // Remove all font entries from the family
218 void DetachFontEntries() {
219 mozilla::AutoWriteLock
lock(mLock
);
220 mAvailableFonts
.Clear();
224 class gfxUserFontEntry
;
225 class gfxOTSMessageContext
;
227 struct gfxUserFontAttributes
{
228 using FontStretch
= mozilla::FontStretch
;
229 using StretchRange
= mozilla::StretchRange
;
230 using FontSlantStyle
= mozilla::FontSlantStyle
;
231 using SlantStyleRange
= mozilla::SlantStyleRange
;
232 using FontWeight
= mozilla::FontWeight
;
233 using WeightRange
= mozilla::WeightRange
;
234 using StyleFontFaceSourceListComponent
=
235 mozilla::StyleFontFaceSourceListComponent
;
236 using RangeFlags
= gfxFontEntry::RangeFlags
;
238 WeightRange mWeight
= WeightRange(FontWeight::NORMAL
);
239 StretchRange mStretch
= StretchRange(FontStretch::NORMAL
);
240 SlantStyleRange mStyle
= SlantStyleRange(FontSlantStyle::NORMAL
);
241 RangeFlags mRangeFlags
= RangeFlags::eAutoWeight
| RangeFlags::eAutoStretch
|
242 RangeFlags::eAutoSlantStyle
;
243 mozilla::StyleFontDisplay mFontDisplay
= mozilla::StyleFontDisplay::Auto
;
244 float mAscentOverride
= -1.0;
245 float mDescentOverride
= -1.0;
246 float mLineGapOverride
= -1.0;
247 float mSizeAdjust
= 1.0;
248 uint32_t mLanguageOverride
= NO_FONT_LANGUAGE_OVERRIDE
;
249 nsTArray
<gfxFontFeature
> mFeatureSettings
;
250 nsTArray
<gfxFontVariation
> mVariationSettings
;
251 RefPtr
<gfxCharacterMap
> mUnicodeRanges
;
253 nsCString mFamilyName
;
254 AutoTArray
<StyleFontFaceSourceListComponent
, 8> mSources
;
257 class gfxUserFontSet
{
258 friend class gfxUserFontEntry
;
259 friend class gfxOTSMessageContext
;
262 using FontStretch
= mozilla::FontStretch
;
263 using StretchRange
= mozilla::StretchRange
;
264 using FontSlantStyle
= mozilla::FontSlantStyle
;
265 using SlantStyleRange
= mozilla::SlantStyleRange
;
266 using FontWeight
= mozilla::FontWeight
;
267 using WeightRange
= mozilla::WeightRange
;
268 using RangeFlags
= gfxFontEntry::RangeFlags
;
270 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
276 // creates a font face without adding it to a particular family
277 // weight - [100, 900] (multiples of 100)
278 // stretch = [FontStretch::UltraCondensed(), FontStretch::UltraExpanded()]
279 // italic style = constants in gfxFontConstants.h, e.g. NS_FONT_STYLE_NORMAL
280 // language override = result of calling
281 // nsLayoutUtils::ParseFontLanguageOverride
282 // TODO: support for unicode ranges not yet implemented
283 virtual already_AddRefed
<gfxUserFontEntry
> CreateUserFontEntry(
284 nsTArray
<gfxFontFaceSrc
>&& aFontFaceSrcList
,
285 gfxUserFontAttributes
&& aAttr
) = 0;
287 // creates a font face for the specified family, or returns an existing
288 // matching entry on the family if there is one
289 already_AddRefed
<gfxUserFontEntry
> FindOrCreateUserFontEntry(
290 nsTArray
<gfxFontFaceSrc
>&& aFontFaceSrcList
,
291 gfxUserFontAttributes
&& aAttr
);
293 // add in a font face for which we have the gfxUserFontEntry already
294 void AddUserFontEntry(const nsCString
& aFamilyName
,
295 gfxUserFontEntry
* aUserFontEntry
);
297 // Look up and return the gfxUserFontFamily in mFontFamilies with
299 virtual already_AddRefed
<gfxUserFontFamily
> LookupFamily(
300 const nsACString
& aName
) const;
302 virtual already_AddRefed
<gfxFontSrcPrincipal
> GetStandardFontLoadPrincipal()
304 virtual nsPresContext
* GetPresContext() const = 0;
306 // check whether content policies allow the given URI to load.
307 virtual bool IsFontLoadAllowed(const gfxFontFaceSrc
&) = 0;
309 // initialize the process that loads external font data, which upon
310 // completion will call FontDataDownloadComplete method
311 virtual nsresult
StartLoad(gfxUserFontEntry
* aUserFontEntry
,
312 uint32_t aSrcIndex
) = 0;
314 // generation - each time a face is loaded, generation is
315 // incremented so that the change can be recognized
316 uint64_t GetGeneration() { return mGeneration
; }
318 // increment the generation on font load
319 void IncrementGeneration(bool aIsRebuild
= false) {
320 mozilla::RecursiveMutexAutoLock
lock(mMutex
);
321 IncrementGenerationLocked(aIsRebuild
);
323 void IncrementGenerationLocked(bool aIsRebuild
= false) MOZ_REQUIRES(mMutex
);
325 // Generation is bumped on font loads but that doesn't affect name-style
326 // mappings. Rebuilds do however affect name-style mappings so need to
327 // lookup fontlists again when that happens.
328 uint64_t GetRebuildGeneration() { return mRebuildGeneration
; }
330 // rebuild if local rules have been used
331 void RebuildLocalRules();
333 // Discard any font entries created for src:local(), so that they will
334 // be reloaded next time they're needed. This is called when the platform
335 // font list has changed, which means local font entries that were set up
336 // may no longer be valid.
337 virtual void ForgetLocalFaces();
339 class UserFontCache
{
341 // Record a loaded user-font in the cache. This requires that the
342 // font-entry's userFontData has been set up already, as it relies
343 // on the URI and Principal recorded there.
344 static void CacheFont(gfxFontEntry
* aFontEntry
);
346 // The given gfxFontEntry is being destroyed, so remove any record that
348 static void ForgetFont(gfxFontEntry
* aFontEntry
);
350 // Return the gfxFontEntry corresponding to a given URI and principal,
351 // and the features of the given userfont entry, or nullptr if none is
352 // available. The aPrivate flag is set for requests coming from private
353 // windows, so we can avoid leaking fonts cached in private windows mode out
354 // to normal windows.
355 static gfxFontEntry
* GetFont(const gfxFontFaceSrc
&,
356 const gfxUserFontEntry
&);
358 // Clear everything so that we don't leak URIs and Principals.
359 static void Shutdown();
361 // Memory-reporting support.
362 class MemoryReporter final
: public nsIMemoryReporter
{
364 ~MemoryReporter() = default;
368 NS_DECL_NSIMEMORYREPORTER
371 #ifdef DEBUG_USERFONT_CACHE
377 // Helper that we use to observe the empty-cache notification
378 // from nsICacheService.
379 class Flusher
: public nsIObserver
{
380 virtual ~Flusher() = default;
388 // Key used to look up entries in the user-font cache.
389 // Note that key comparison does *not* use the mFontEntry field
390 // as a whole; it only compares specific fields within the entry
391 // (weight/width/style/features) that could affect font selection
392 // or rendering, and that must match between a font-set's userfont
393 // entry and the corresponding "real" font entry.
395 RefPtr
<gfxFontSrcURI
> mURI
;
396 RefPtr
<gfxFontSrcPrincipal
> mPrincipal
; // use nullptr with data: URLs
397 // The font entry MUST notify the cache when it is destroyed
398 // (by calling ForgetFont()).
399 gfxFontEntry
* MOZ_NON_OWNING_REF mFontEntry
;
402 Key(gfxFontSrcURI
* aURI
, gfxFontSrcPrincipal
* aPrincipal
,
403 gfxFontEntry
* aFontEntry
, bool aPrivate
)
405 mPrincipal(aPrincipal
),
406 mFontEntry(aFontEntry
),
407 mPrivate(aPrivate
) {}
410 class Entry
: public PLDHashEntryHdr
{
412 typedef const Key
& KeyType
;
413 typedef const Key
* KeyTypePointer
;
415 explicit Entry(KeyTypePointer aKey
)
417 mPrincipal(aKey
->mPrincipal
),
418 mFontEntry(aKey
->mFontEntry
),
419 mPrivate(aKey
->mPrivate
) {}
421 Entry(Entry
&& aOther
)
422 : PLDHashEntryHdr(std::move(aOther
)),
423 mURI(std::move(aOther
.mURI
)),
424 mPrincipal(std::move(aOther
.mPrincipal
)),
425 mFontEntry(std::move(aOther
.mFontEntry
)),
426 mPrivate(std::move(aOther
.mPrivate
)) {}
430 bool KeyEquals(const KeyTypePointer aKey
) const;
432 static KeyTypePointer
KeyToPointer(KeyType aKey
) { return &aKey
; }
434 static PLDHashNumber
HashKey(const KeyTypePointer aKey
) {
435 PLDHashNumber principalHash
=
436 aKey
->mPrincipal
? aKey
->mPrincipal
->Hash() : 0;
437 return mozilla::HashGeneric(
438 principalHash
+ int(aKey
->mPrivate
), aKey
->mURI
->Hash(),
439 HashFeatures(aKey
->mFontEntry
->mFeatureSettings
),
440 HashVariations(aKey
->mFontEntry
->mVariationSettings
),
441 mozilla::HashString(aKey
->mFontEntry
->mFamilyName
),
442 aKey
->mFontEntry
->Weight().AsScalar(),
443 aKey
->mFontEntry
->SlantStyle().AsScalar(),
444 aKey
->mFontEntry
->Stretch().AsScalar(),
445 aKey
->mFontEntry
->AutoRangeFlags(),
446 aKey
->mFontEntry
->mLanguageOverride
);
449 enum { ALLOW_MEMMOVE
= false };
451 gfxFontSrcURI
* GetURI() const { return mURI
; }
452 gfxFontSrcPrincipal
* GetPrincipal() const { return mPrincipal
; }
453 gfxFontEntry
* GetFontEntry() const { return mFontEntry
; }
454 bool IsPrivate() const { return mPrivate
; }
456 void ReportMemory(nsIHandleReportCallback
* aHandleReport
,
457 nsISupports
* aData
, bool aAnonymize
);
459 #ifdef DEBUG_USERFONT_CACHE
464 static uint32_t HashFeatures(const nsTArray
<gfxFontFeature
>& aFeatures
) {
465 return mozilla::HashBytes(aFeatures
.Elements(),
466 aFeatures
.Length() * sizeof(gfxFontFeature
));
469 static uint32_t HashVariations(
470 const nsTArray
<mozilla::gfx::FontVariation
>& aVariations
) {
471 return mozilla::HashBytes(
472 aVariations
.Elements(),
473 aVariations
.Length() * sizeof(mozilla::gfx::FontVariation
));
476 RefPtr
<gfxFontSrcURI
> mURI
;
477 RefPtr
<gfxFontSrcPrincipal
> mPrincipal
; // or nullptr for data: URLs
479 // The "real" font entry corresponding to this downloaded font.
480 // The font entry MUST notify the cache when it is destroyed
481 // (by calling ForgetFont()).
482 gfxFontEntry
* MOZ_NON_OWNING_REF mFontEntry
;
484 // Whether this font was loaded from a private window.
488 static nsTHashtable
<Entry
>* sUserFonts
;
491 void SetLocalRulesUsed() { mLocalRulesUsed
= true; }
493 static mozilla::LogModule
* GetUserFontsLog();
495 // record statistics about font completion
496 virtual void RecordFontLoadDone(uint32_t aFontSize
,
497 mozilla::TimeStamp aDoneTime
) {}
499 void GetLoadStatistics(uint32_t& aLoadCount
, uint64_t& aLoadSize
) const {
500 aLoadCount
= mDownloadCount
;
501 aLoadSize
= mDownloadSize
;
505 // Protected destructor, to discourage deletion outside of Release():
506 virtual ~gfxUserFontSet();
508 // Return whether the font set is associated with a private-browsing tab.
509 virtual bool GetPrivateBrowsing() = 0;
511 // Return whether the font set is associated with a document that was
512 // shift-reloaded, for example, and thus should bypass the font cache.
513 virtual bool BypassCache() = 0;
515 // parse data for a data URL
516 virtual nsresult
SyncLoadFontData(gfxUserFontEntry
* aFontToLoad
,
517 const gfxFontFaceSrc
* aFontFaceSrc
,
519 uint32_t& aBufferLength
) = 0;
521 // report a problem of some kind (implemented in nsUserFontSet)
522 virtual nsresult
LogMessage(gfxUserFontEntry
* aUserFontEntry
,
523 uint32_t aSrcIndex
, const char* aMessage
,
524 uint32_t aFlags
= nsIScriptError::errorFlag
,
525 nsresult aStatus
= NS_OK
) = 0;
527 // helper method for performing the actual userfont set rebuild
528 virtual void DoRebuildUserFontSet() = 0;
530 // forget about a loader that has been cancelled
531 virtual void RemoveLoader(nsFontFaceLoader
* aLoader
) = 0;
533 // helper method for FindOrCreateUserFontEntry
534 gfxUserFontEntry
* FindExistingUserFontEntry(
535 gfxUserFontFamily
* aFamily
,
536 const nsTArray
<gfxFontFaceSrc
>& aFontFaceSrcList
,
537 const gfxUserFontAttributes
& aAttr
);
539 // creates a new gfxUserFontFamily in mFontFamilies, or returns an existing
540 // family if there is one
541 virtual already_AddRefed
<gfxUserFontFamily
> GetFamily(
542 const nsACString
& aFamilyName
);
544 void ForgetLocalFace(gfxUserFontFamily
* aFontFamily
);
546 // font families defined by @font-face rules
547 nsRefPtrHashtable
<nsCStringHashKey
, gfxUserFontFamily
> mFontFamilies
;
549 mozilla::Atomic
<uint64_t> mGeneration
; // bumped on any font load change
550 uint64_t mRebuildGeneration
; // only bumped on rebuilds
552 // true when local names have been looked up, false otherwise
553 bool mLocalRulesUsed
;
555 // true when rules using local names need to be redone
556 bool mRebuildLocalRules
;
559 uint32_t mDownloadCount
;
560 uint64_t mDownloadSize
;
562 mutable mozilla::RecursiveMutex mMutex
;
565 // acts a placeholder until the real font is downloaded
567 class gfxUserFontEntry
: public gfxFontEntry
{
568 friend class mozilla::PostTraversalTask
;
569 friend class gfxUserFontSet
;
570 friend class nsUserFontSet
;
571 friend class nsFontFaceLoader
;
572 friend class gfxOTSMessageContext
;
575 enum UserFontLoadState
{
576 STATUS_NOT_LOADED
= 0,
583 gfxUserFontEntry(nsTArray
<gfxFontFaceSrc
>&& aFontFaceSrcList
,
584 gfxUserFontAttributes
&& aAttr
);
586 ~gfxUserFontEntry() override
;
588 // Update the attributes of the entry to the given values, without disturbing
589 // the associated platform font entry or in-progress downloads.
590 void UpdateAttributes(gfxUserFontAttributes
&& aAttr
);
592 // Return whether the entry matches the given list of attributes
593 bool Matches(const nsTArray
<gfxFontFaceSrc
>& aFontFaceSrcList
,
594 const gfxUserFontAttributes
& aAttr
);
596 gfxFont
* CreateFontInstance(const gfxFontStyle
* aFontStyle
) override
;
598 gfxFontEntry
* GetPlatformFontEntry() const { return mPlatformFontEntry
; }
600 // is the font loading or loaded, or did it fail?
601 UserFontLoadState
LoadState() const { return mUserFontLoadState
; }
603 void LoadCanceled() {
604 MOZ_ASSERT(NS_IsMainThread());
606 mUserFontLoadState
= STATUS_NOT_LOADED
;
607 mFontDataLoadingState
= NOT_LOADING
;
609 // Reset mCurrentSrcIndex so that all potential sources are re-considered.
610 mCurrentSrcIndex
= 0;
611 mSeenLocalSource
= false;
614 // whether to wait before using fallback font or not
615 bool WaitForUserFont() const {
616 return (mUserFontLoadState
== STATUS_LOAD_PENDING
||
617 mUserFontLoadState
== STATUS_LOADING
) &&
618 mFontDataLoadingState
< LOADING_SLOWLY
;
621 // For userfonts, cmap is used to store the unicode range data,
622 // and is inert once set, so locking is not required here.
623 // no cmap ==> all codepoints permitted
624 bool CharacterInUnicodeRange(uint32_t ch
) const {
625 if (const auto* map
= GetUnicodeRangeMap()) {
626 return map
->test(ch
);
631 gfxCharacterMap
* GetUnicodeRangeMap() const { return GetCharacterMap(); }
632 void SetUnicodeRangeMap(RefPtr
<gfxCharacterMap
>&& aCharMap
) {
633 auto* oldCmap
= GetUnicodeRangeMap();
634 if (oldCmap
!= aCharMap
) {
635 auto* newCmap
= aCharMap
.forget().take();
636 if (mCharacterMap
.compareExchange(oldCmap
, newCmap
)) {
637 NS_IF_RELEASE(oldCmap
);
639 NS_IF_RELEASE(newCmap
);
644 mozilla::StyleFontDisplay
GetFontDisplay() const { return mFontDisplay
; }
646 // load the font - starts the loading of sources which continues until
647 // a valid font resource is found or all sources fail
650 // Invalidates appropriately when the load finishes.
651 void FontLoadComplete();
653 // methods to expose some information to FontFaceSet::UserFontSet
654 // since we can't make that class a friend
655 void SetLoader(nsFontFaceLoader
* aLoader
) {
656 MOZ_ASSERT(NS_IsMainThread());
660 nsFontFaceLoader
* GetLoader() const {
661 MOZ_ASSERT(NS_IsMainThread());
665 gfxFontSrcPrincipal
* GetPrincipal() const { return mPrincipal
; }
666 void GetFamilyNameAndURIForLogging(uint32_t aSrcIndex
,
667 nsACString
& aFamilyName
, nsACString
& aURI
);
669 gfxFontEntry
* Clone() const override
{
670 MOZ_ASSERT_UNREACHABLE("cannot Clone user fonts");
674 virtual already_AddRefed
<gfxUserFontSet
> GetUserFontSet() const = 0;
676 const nsTArray
<gfxFontFaceSrc
>& SourceList() const { return mSrcList
; }
678 // Returns a weak reference to the requested source record, which is owned
679 // by the gfxUserFontEntry.
680 const gfxFontFaceSrc
& SourceAt(uint32_t aSrcIndex
) const {
681 return mSrcList
[aSrcIndex
];
684 // The variation-query APIs should not be called on placeholders.
685 bool HasVariations() override
{
686 MOZ_ASSERT_UNREACHABLE("not meaningful for a userfont placeholder");
689 void GetVariationAxes(nsTArray
<gfxFontVariationAxis
>&) override
{
690 MOZ_ASSERT_UNREACHABLE("not meaningful for a userfont placeholder");
692 void GetVariationInstances(nsTArray
<gfxFontVariationInstance
>&) override
{
693 MOZ_ASSERT_UNREACHABLE("not meaningful for a userfont placeholder");
699 int mLevel
; // see OTSContext in gfx/ots/include/opentype-sanitizer.h
702 const uint8_t* SanitizeOpenTypeData(const uint8_t* aData
, uint32_t aLength
,
703 uint32_t& aSanitaryLength
,
704 gfxUserFontType
& aFontType
,
705 nsTArray
<OTSMessage
>& aMessages
);
707 // attempt to load the next resource in the src list.
710 void DoLoadNextSrc(bool aIsContinue
);
712 // change the load state
713 virtual void SetLoadState(UserFontLoadState aLoadState
);
715 // when download has been completed, pass back data here
716 // aDownloadStatus == NS_OK ==> download succeeded, error otherwise
717 // Ownership of aFontData is passed in here; the font set must
718 // ensure that it is eventually deleted with free().
719 void FontDataDownloadComplete(uint32_t aSrcIndex
, const uint8_t* aFontData
,
720 uint32_t aLength
, nsresult aDownloadStatus
,
721 nsIFontLoadCompleteCallback
* aCallback
);
723 // helper method for creating a platform font
724 // returns true if platform font creation successful
725 // Ownership of aFontData is passed in here; the font must
726 // ensure that it is eventually deleted with free().
727 bool LoadPlatformFontSync(uint32_t aSrcIndex
, const uint8_t* aFontData
,
730 void LoadPlatformFontAsync(uint32_t aSrcIndex
, const uint8_t* aFontData
,
732 nsIFontLoadCompleteCallback
* aCallback
);
734 // helper method for LoadPlatformFontAsync; runs on a background thread
735 void StartPlatformFontLoadOnBackgroundThread(
736 uint32_t aSrcIndex
, const uint8_t* aFontData
, uint32_t aLength
,
737 nsMainThreadPtrHandle
<nsIFontLoadCompleteCallback
> aCallback
);
739 // helper method for LoadPlatformFontAsync; runs on the main thread
740 void ContinuePlatformFontLoadOnMainThread(
741 uint32_t aSrcIndex
, const uint8_t* aOriginalFontData
,
742 uint32_t aOriginalLength
, gfxUserFontType aFontType
,
743 const uint8_t* aSanitizedFontData
, uint32_t aSanitizedLength
,
744 nsTArray
<OTSMessage
>&& aMessages
,
745 nsMainThreadPtrHandle
<nsIFontLoadCompleteCallback
> aCallback
);
747 // helper method for LoadPlatformFontSync and
748 // ContinuePlatformFontLoadOnMainThread; runs on the main thread
749 bool LoadPlatformFont(uint32_t aSrcIndex
, const uint8_t* aOriginalFontData
,
750 uint32_t aOriginalLength
, gfxUserFontType aFontType
,
751 const uint8_t* aSanitizedFontData
,
752 uint32_t aSanitizedLength
,
753 nsTArray
<OTSMessage
>&& aMessages
);
755 // helper method for FontDataDownloadComplete and
756 // ContinuePlatformFontLoadOnMainThread; runs on the main thread
757 void FontLoadFailed(nsIFontLoadCompleteCallback
* aCallback
);
759 // store metadata and src details for current src into aFontEntry
760 void StoreUserFontData(gfxFontEntry
* aFontEntry
, uint32_t aSrcIndex
,
761 bool aPrivate
, const nsACString
& aOriginalName
,
762 FallibleTArray
<uint8_t>* aMetadata
,
763 uint32_t aMetaOrigLen
, uint8_t aCompression
);
765 // Clears and then adds to aResult all of the user font sets that this user
766 // font entry has been added to. This will at least include the owner of this
768 virtual void GetUserFontSets(nsTArray
<RefPtr
<gfxUserFontSet
>>& aResult
);
770 // general load state
771 UserFontLoadState mUserFontLoadState
;
773 // detailed load state while font data is loading
774 // used to determine whether to use fallback font or not
775 // note that code depends on the ordering of these values!
776 enum FontDataLoadingState
{
777 NOT_LOADING
= 0, // not started to load any font resources yet
778 LOADING_STARTED
, // loading has started; hide fallback font
779 LOADING_ALMOST_DONE
, // timeout happened but we're nearly done,
780 // so keep hiding fallback font
781 LOADING_SLOWLY
, // timeout happened and we're not nearly done,
782 // so use the fallback font
783 LOADING_TIMED_OUT
, // font load took too long
784 LOADING_FAILED
// failed to load any source: use fallback
786 FontDataLoadingState mFontDataLoadingState
;
788 bool mSeenLocalSource
;
789 bool mUnsupportedFormat
;
790 mozilla::StyleFontDisplay mFontDisplay
; // timing of userfont fallback
792 RefPtr
<gfxFontEntry
> mPlatformFontEntry
;
793 nsTArray
<gfxFontFaceSrc
> mSrcList
;
794 uint32_t mCurrentSrcIndex
; // index of src item to be loaded next
795 // This field is managed by the nsFontFaceLoader. In the destructor and
796 // Cancel() methods of nsFontFaceLoader this reference is nulled out.
797 nsFontFaceLoader
* MOZ_NON_OWNING_REF
798 mLoader
; // current loader for this entry, if any
799 RefPtr
<gfxUserFontSet
> mLoadingFontSet
;
800 RefPtr
<gfxFontSrcPrincipal
> mPrincipal
;
803 #endif /* GFX_USER_FONT_SET_H */