FontFaceSet.h (5646B)
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/. */ 6 7 #ifndef mozilla_dom_FontFaceSet_h 8 #define mozilla_dom_FontFaceSet_h 9 10 #include "mozilla/DOMEventTargetHelper.h" 11 #include "mozilla/dom/FontFace.h" 12 #include "mozilla/dom/FontFaceSetBinding.h" 13 #include "mozilla/dom/FontFaceSetImpl.h" 14 #include "nsICSSLoaderObserver.h" 15 #include "nsIDOMEventListener.h" 16 17 class nsFontFaceLoader; 18 class nsIPrincipal; 19 class nsIGlobalObject; 20 21 namespace mozilla { 22 class PostTraversalTask; 23 class SharedFontList; 24 namespace dom { 25 class Promise; 26 class WorkerPrivate; 27 } // namespace dom 28 } // namespace mozilla 29 30 namespace mozilla::dom { 31 32 class FontFaceSet final : public DOMEventTargetHelper { 33 friend class mozilla::PostTraversalTask; 34 35 public: 36 NS_DECL_ISUPPORTS_INHERITED 37 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FontFaceSet, DOMEventTargetHelper) 38 39 static already_AddRefed<FontFaceSet> CreateForDocument( 40 dom::Document* aDocument); 41 42 static already_AddRefed<FontFaceSet> CreateForWorker( 43 nsIGlobalObject* aParent, WorkerPrivate* aWorkerPrivate); 44 45 virtual JSObject* WrapObject(JSContext* aCx, 46 JS::Handle<JSObject*> aGivenProto) override; 47 48 bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules); 49 50 /** 51 * Notification method called by the nsPresContext to indicate that the 52 * refresh driver ticked and flushed style and layout. 53 * were just flushed. 54 */ 55 void DidRefresh(); 56 57 void FlushUserFontSet(); 58 59 void RefreshStandardFontLoadPrincipal(); 60 61 void CopyNonRuleFacesTo(FontFaceSet* aFontFaceSet) const; 62 63 void CacheFontLoadability() { mImpl->CacheFontLoadability(); } 64 65 FontFaceSetImpl* GetImpl() const { return mImpl; } 66 67 // -- Web IDL -------------------------------------------------------------- 68 69 IMPL_EVENT_HANDLER(loading) 70 IMPL_EVENT_HANDLER(loadingdone) 71 IMPL_EVENT_HANDLER(loadingerror) 72 already_AddRefed<dom::Promise> Load(JSContext* aCx, const nsACString& aFont, 73 const nsAString& aText, ErrorResult& aRv); 74 bool Check(const nsACString& aFont, const nsAString& aText, ErrorResult& aRv); 75 dom::Promise* GetReady(ErrorResult& aRv); 76 dom::FontFaceSetLoadStatus Status(); 77 78 void Add(FontFace& aFontFace, ErrorResult& aRv); 79 void Clear(); 80 bool Delete(FontFace& aFontFace); 81 bool Has(FontFace& aFontFace); 82 /** 83 * This returns the number of Author origin fonts only. 84 * (see also SizeIncludingNonAuthorOrigins() below) 85 */ 86 uint32_t Size(); 87 already_AddRefed<dom::FontFaceSetIterator> Entries(); 88 already_AddRefed<dom::FontFaceSetIterator> Values(); 89 MOZ_CAN_RUN_SCRIPT 90 void ForEach(JSContext* aCx, FontFaceSetForEachCallback& aCallback, 91 JS::Handle<JS::Value> aThisArg, ErrorResult& aRv); 92 93 /** 94 * Unlike Size(), this returns the size including non-Author origin fonts. 95 */ 96 uint32_t SizeIncludingNonAuthorOrigins(); 97 98 void MaybeResolve(); 99 100 void DispatchLoadingFinishedEvent( 101 const nsAString& aType, nsTArray<OwningNonNull<FontFace>>&& aFontFaces); 102 103 void DispatchLoadingEventAndReplaceReadyPromise(); 104 void DispatchCheckLoadingFinishedAfterDelay(); 105 106 // Whether mReady is pending, or would be when created. 107 bool ReadyPromiseIsPending() const; 108 109 void InsertRuleFontFace(FontFace* aFontFace, StyleOrigin aOrigin); 110 111 private: 112 friend mozilla::dom::FontFaceSetIterator; // needs GetFontFaceAt() 113 114 explicit FontFaceSet(nsIGlobalObject* aParent); 115 ~FontFaceSet(); 116 117 /** 118 * Returns whether the given FontFace is currently "in" the FontFaceSet. 119 */ 120 bool HasAvailableFontFace(FontFace* aFontFace); 121 122 /** 123 * Removes any listeners and observers. 124 */ 125 void Destroy(); 126 127 /** 128 * Returns the font at aIndex if it's an Author origin font, or nullptr 129 * otherwise. 130 */ 131 FontFace* GetFontFaceAt(uint32_t aIndex); 132 133 // Note: if you add new cycle collected objects to FontFaceRecord, 134 // make sure to update FontFaceSet's cycle collection macros 135 // accordingly. 136 struct FontFaceRecord { 137 RefPtr<FontFace> mFontFace; 138 Maybe<StyleOrigin> mOrigin; // only relevant for mRuleFaces entries 139 140 // When true, indicates that when finished loading, the FontFace should be 141 // included in the subsequent loadingdone/loadingerror event fired at the 142 // FontFaceSet. 143 bool mLoadEventShouldFire; 144 }; 145 146 #ifdef DEBUG 147 bool HasRuleFontFace(FontFace* aFontFace); 148 #endif 149 150 // The underlying implementation for FontFaceSet. 151 RefPtr<FontFaceSetImpl> mImpl; 152 153 // A Promise that is fulfilled once all of the FontFace objects 154 // in mRuleFaces and mNonRuleFaces that started or were loading at the 155 // time the Promise was created have finished loading. It is rejected if 156 // any of those fonts failed to load. mReady is replaced with 157 // a new Promise object whenever mReady is settled and another 158 // FontFace in mRuleFaces or mNonRuleFaces starts to load. 159 // Note that mReady is created lazily when GetReady() is called. 160 RefPtr<dom::Promise> mReady; 161 // Whether the ready promise must be resolved when it's created. 162 bool mResolveLazilyCreatedReadyPromise = false; 163 164 // The @font-face rule backed FontFace objects in the FontFaceSet. 165 nsTArray<FontFaceRecord> mRuleFaces; 166 167 // The non rule backed FontFace objects that have been added to this 168 // FontFaceSet. 169 nsTArray<FontFaceRecord> mNonRuleFaces; 170 }; 171 172 } // namespace mozilla::dom 173 174 #endif // !defined(mozilla_dom_FontFaceSet_h)