Bug 1839315: part 4) Link from `SheetLoadData::mWasAlternate` to spec. r=emilio DONTBUILD
[gecko.git] / layout / style / FontFaceSetImpl.h
blob6f245c659923521a38f229409f2eef6c127a254f
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_FontFaceSetImpl_h
8 #define mozilla_dom_FontFaceSetImpl_h
10 #include "mozilla/dom/FontFace.h"
11 #include "mozilla/dom/FontFaceSetBinding.h"
12 #include "mozilla/DOMEventTargetHelper.h"
13 #include "mozilla/FontPropertyTypes.h"
14 #include "mozilla/RecursiveMutex.h"
15 #include "gfxUserFontSet.h"
16 #include "nsICSSLoaderObserver.h"
17 #include "nsIDOMEventListener.h"
19 #include <functional>
21 struct gfxFontFaceSrc;
22 class gfxFontSrcPrincipal;
23 class gfxUserFontEntry;
24 class nsFontFaceLoader;
25 class nsIChannel;
26 class nsIPrincipal;
27 class nsPIDOMWindowInner;
29 namespace mozilla {
30 struct StyleLockedFontFaceRule;
31 class PostTraversalTask;
32 class Runnable;
33 class SharedFontList;
34 namespace dom {
35 class FontFace;
36 } // namespace dom
37 } // namespace mozilla
39 namespace mozilla::dom {
41 class FontFaceSetImpl : public nsISupports, public gfxUserFontSet {
42 NS_DECL_THREADSAFE_ISUPPORTS
44 public:
45 // gfxUserFontSet
47 already_AddRefed<gfxFontSrcPrincipal> GetStandardFontLoadPrincipal()
48 const final;
50 void RecordFontLoadDone(uint32_t aFontSize, TimeStamp aDoneTime) override;
52 bool BypassCache() final { return mBypassCache; }
54 void ForgetLocalFaces() final;
56 protected:
57 virtual nsresult CreateChannelForSyncLoadFontData(
58 nsIChannel** aOutChannel, gfxUserFontEntry* aFontToLoad,
59 const gfxFontFaceSrc* aFontFaceSrc) = 0;
61 // gfxUserFontSet
63 bool GetPrivateBrowsing() override { return mPrivateBrowsing; }
64 nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
65 const gfxFontFaceSrc* aFontFaceSrc,
66 uint8_t*& aBuffer,
67 uint32_t& aBufferLength) override;
68 nsresult LogMessage(gfxUserFontEntry* aUserFontEntry, uint32_t aSrcIndex,
69 const char* aMessage,
70 uint32_t aFlags = nsIScriptError::errorFlag,
71 nsresult aStatus = NS_OK) override;
72 void DoRebuildUserFontSet() override;
73 already_AddRefed<gfxUserFontEntry> CreateUserFontEntry(
74 nsTArray<gfxFontFaceSrc>&& aFontFaceSrcList,
75 gfxUserFontAttributes&& aAttr) override;
77 already_AddRefed<gfxUserFontFamily> GetFamily(
78 const nsACString& aFamilyName) final;
80 explicit FontFaceSetImpl(FontFaceSet* aOwner);
82 void DestroyLoaders();
84 public:
85 virtual void Destroy();
86 virtual bool IsOnOwningThread() = 0;
87 #ifdef DEBUG
88 virtual void AssertIsOnOwningThread() = 0;
89 #else
90 void AssertIsOnOwningThread() {}
91 #endif
92 virtual void DispatchToOwningThread(const char* aName,
93 std::function<void()>&& aFunc) = 0;
95 // Called by nsFontFaceLoader when the loader has completed normally.
96 // It's removed from the mLoaders set.
97 virtual void RemoveLoader(nsFontFaceLoader* aLoader);
99 virtual bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules) {
100 MOZ_ASSERT_UNREACHABLE("Not implemented!");
101 return false;
104 // search for @font-face rule that matches a platform font entry
105 virtual StyleLockedFontFaceRule* FindRuleForEntry(gfxFontEntry* aFontEntry) {
106 MOZ_ASSERT_UNREACHABLE("Not implemented!");
107 return nullptr;
111 * Finds an existing entry in the user font cache or creates a new user
112 * font entry for the given FontFace object.
114 static already_AddRefed<gfxUserFontEntry>
115 FindOrCreateUserFontEntryFromFontFace(FontFaceImpl* aFontFace,
116 gfxUserFontAttributes&& aAttr,
117 StyleOrigin);
120 * Notification method called by a FontFace to indicate that its loading
121 * status has changed.
123 virtual void OnFontFaceStatusChanged(FontFaceImpl* aFontFace);
126 * Notification method called by the nsPresContext to indicate that the
127 * refresh driver ticked and flushed style and layout.
128 * were just flushed.
130 virtual void DidRefresh() { MOZ_ASSERT_UNREACHABLE("Not implemented!"); }
132 virtual void FlushUserFontSet() = 0;
134 static nsPresContext* GetPresContextFor(gfxUserFontSet* aUserFontSet) {
135 const auto* set = static_cast<FontFaceSetImpl*>(aUserFontSet);
136 return set ? set->GetPresContext() : nullptr;
139 virtual void RefreshStandardFontLoadPrincipal();
141 virtual dom::Document* GetDocument() const { return nullptr; }
143 virtual already_AddRefed<URLExtraData> GetURLExtraData() = 0;
145 // -- Web IDL --------------------------------------------------------------
147 virtual void EnsureReady() {}
148 dom::FontFaceSetLoadStatus Status();
150 virtual bool Add(FontFaceImpl* aFontFace, ErrorResult& aRv);
151 virtual void Clear();
152 virtual bool Delete(FontFaceImpl* aFontFace);
154 // For ServoStyleSet to know ahead of time whether a font is loadable.
155 virtual void CacheFontLoadability() {
156 MOZ_ASSERT_UNREACHABLE("Not implemented!");
159 virtual void MarkUserFontSetDirty() {}
162 * Checks to see whether it is time to resolve mReady and dispatch any
163 * "loadingdone" and "loadingerror" events.
165 virtual void CheckLoadingFinished();
167 virtual void FindMatchingFontFaces(const nsACString& aFont,
168 const nsAString& aText,
169 nsTArray<FontFace*>& aFontFaces,
170 ErrorResult& aRv);
172 virtual void DispatchCheckLoadingFinishedAfterDelay();
174 protected:
175 ~FontFaceSetImpl() override;
177 virtual uint64_t GetInnerWindowID() = 0;
180 * Returns whether the given FontFace is currently "in" the FontFaceSet.
182 bool HasAvailableFontFace(FontFaceImpl* aFontFace);
185 * Returns whether there might be any pending font loads, which should cause
186 * the mReady Promise not to be resolved yet.
188 virtual bool MightHavePendingFontLoads();
191 * Checks to see whether it is time to replace mReady and dispatch a
192 * "loading" event.
194 void CheckLoadingStarted();
197 * Callback for invoking CheckLoadingFinished after going through the
198 * event loop. See OnFontFaceStatusChanged.
200 void CheckLoadingFinishedAfterDelay();
202 void OnLoadingStarted();
203 void OnLoadingFinished();
205 // Note: if you add new cycle collected objects to FontFaceRecord,
206 // make sure to update FontFaceSet's cycle collection macros
207 // accordingly.
208 struct FontFaceRecord {
209 RefPtr<FontFaceImpl> mFontFace;
210 Maybe<StyleOrigin> mOrigin; // only relevant for mRuleFaces entries
213 // search for @font-face rule that matches a userfont font entry
214 virtual StyleLockedFontFaceRule* FindRuleForUserFontEntry(
215 gfxUserFontEntry* aUserFontEntry) {
216 return nullptr;
219 virtual void FindMatchingFontFaces(
220 const nsTHashSet<FontFace*>& aMatchingFaces,
221 nsTArray<FontFace*>& aFontFaces);
223 class UpdateUserFontEntryRunnable;
224 void UpdateUserFontEntry(gfxUserFontEntry* aEntry,
225 gfxUserFontAttributes&& aAttr);
227 nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
228 gfxFontSrcPrincipal** aPrincipal, bool* aBypassCache);
230 void InsertNonRuleFontFace(FontFaceImpl* aFontFace);
233 * Returns whether we have any loading FontFace objects in the FontFaceSet.
235 bool HasLoadingFontFaces();
237 // Whether mReady is pending, or would be when created.
238 bool ReadyPromiseIsPending() const;
240 // Helper function for HasLoadingFontFaces.
241 virtual void UpdateHasLoadingFontFaces();
243 void ParseFontShorthandForMatching(const nsACString& aFont,
244 StyleFontFamilyList& aFamilyList,
245 FontWeight& aWeight, FontStretch& aStretch,
246 FontSlantStyle& aStyle, ErrorResult& aRv);
248 virtual TimeStamp GetNavigationStartTimeStamp() = 0;
250 mutable RecursiveMutex mMutex;
252 FontFaceSet* MOZ_NON_OWNING_REF mOwner MOZ_GUARDED_BY(mMutex);
254 // The document's node principal, which is the principal font loads for
255 // this FontFaceSet will generally use. (This principal is not used for
256 // @font-face rules in UA and user sheets, where the principal of the
257 // sheet is used instead.)
259 // This field is used from GetStandardFontLoadPrincipal. When on a
260 // style worker thread, we use mStandardFontLoadPrincipal assuming
261 // it is up to date.
263 // Because mDocument's principal can change over time,
264 // its value must be updated by a call to ResetStandardFontLoadPrincipal.
265 mutable RefPtr<gfxFontSrcPrincipal> mStandardFontLoadPrincipal
266 MOZ_GUARDED_BY(mMutex);
268 // Set of all loaders pointing to us. These are not strong pointers,
269 // but that's OK because nsFontFaceLoader always calls RemoveLoader on
270 // us before it dies (unless we die first).
271 nsTHashtable<nsPtrHashKey<nsFontFaceLoader>> mLoaders MOZ_GUARDED_BY(mMutex);
273 // The non rule backed FontFace objects that have been added to this
274 // FontFaceSet.
275 nsTArray<FontFaceRecord> mNonRuleFaces MOZ_GUARDED_BY(mMutex);
277 // The overall status of the loading or loaded fonts in the FontFaceSet.
278 dom::FontFaceSetLoadStatus mStatus MOZ_GUARDED_BY(mMutex);
280 // A map from gfxFontFaceSrc pointer identity to whether the load is allowed
281 // by CSP or other checks. We store this here because querying CSP off the
282 // main thread is not a great idea.
284 // We could use just the pointer and use this as a hash set, but then we'd
285 // have no way to verify that we've checked all the loads we should.
286 nsTHashMap<nsPtrHashKey<const gfxFontFaceSrc>, bool> mAllowedFontLoads
287 MOZ_GUARDED_BY(mMutex);
289 // Whether mNonRuleFaces has changed since last time UpdateRules ran.
290 bool mNonRuleFacesDirty MOZ_GUARDED_BY(mMutex);
292 // Whether any FontFace objects in mRuleFaces or mNonRuleFaces are
293 // loading. Only valid when mHasLoadingFontFacesIsDirty is false. Don't use
294 // this variable directly; call the HasLoadingFontFaces method instead.
295 bool mHasLoadingFontFaces MOZ_GUARDED_BY(mMutex);
297 // This variable is only valid when mLoadingDirty is false.
298 bool mHasLoadingFontFacesIsDirty MOZ_GUARDED_BY(mMutex);
300 // Whether CheckLoadingFinished calls should be ignored. See comment in
301 // OnFontFaceStatusChanged.
302 bool mDelayedLoadCheck MOZ_GUARDED_BY(mMutex);
304 // Whether the docshell for our document indicated that loads should
305 // bypass the cache.
306 bool mBypassCache;
308 // Whether the docshell for our document indicates that we are in private
309 // browsing mode.
310 bool mPrivateBrowsing;
313 } // namespace mozilla::dom
315 #endif // !defined(mozilla_dom_FontFaceSetImpl_h)