Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / layout / style / FontFaceSet.h
blob6e4853d1fbe953166deae1691912a4a6a980e27e
1 /* -*- Mode: C++; tab-width: 2; 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 mozilla_dom_FontFaceSet_h
7 #define mozilla_dom_FontFaceSet_h
9 #include "mozilla/dom/FontFace.h"
10 #include "mozilla/dom/FontFaceSetBinding.h"
11 #include "mozilla/DOMEventTargetHelper.h"
12 #include "gfxUserFontSet.h"
13 #include "nsCSSRules.h"
14 #include "nsICSSLoaderObserver.h"
15 #include "nsPIDOMWindow.h"
17 struct gfxFontFaceSrc;
18 class gfxUserFontEntry;
19 class nsFontFaceLoader;
20 class nsIPrincipal;
21 class nsPIDOMWindow;
23 namespace mozilla {
24 namespace dom {
25 class FontFace;
26 class Promise;
30 namespace mozilla {
31 namespace dom {
33 class FontFaceSet MOZ_FINAL : public DOMEventTargetHelper
34 , public nsIDOMEventListener
35 , public nsICSSLoaderObserver
37 friend class UserFontSet;
39 public:
40 /**
41 * A gfxUserFontSet that integrates with the layout and style systems to
42 * manage @font-face rules and handle network requests for font loading.
44 * We would combine this class and FontFaceSet into the one class if it were
45 * possible; it's not because FontFaceSet is cycle collected and
46 * gfxUserFontSet isn't (and can't be, as gfx classes don't use the cycle
47 * collector). So UserFontSet exists just to override the needed virtual
48 * methods from gfxUserFontSet and to forward them on FontFaceSet.
50 class UserFontSet MOZ_FINAL : public gfxUserFontSet
52 friend class FontFaceSet;
54 public:
55 explicit UserFontSet(FontFaceSet* aFontFaceSet)
56 : mFontFaceSet(aFontFaceSet)
60 FontFaceSet* GetFontFaceSet() { return mFontFaceSet; }
62 virtual nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
63 nsIPrincipal** aPrincipal,
64 bool* aBypassCache) MOZ_OVERRIDE;
65 virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
66 const gfxFontFaceSrc* aFontFaceSrc) MOZ_OVERRIDE;
68 protected:
69 virtual bool GetPrivateBrowsing() MOZ_OVERRIDE;
70 virtual nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
71 const gfxFontFaceSrc* aFontFaceSrc,
72 uint8_t*& aBuffer,
73 uint32_t& aBufferLength) MOZ_OVERRIDE;
74 virtual nsresult LogMessage(gfxUserFontEntry* aUserFontEntry,
75 const char* aMessage,
76 uint32_t aFlags = nsIScriptError::errorFlag,
77 nsresult aStatus = NS_OK) MOZ_OVERRIDE;
78 virtual void DoRebuildUserFontSet() MOZ_OVERRIDE;
79 virtual already_AddRefed<gfxUserFontEntry> CreateUserFontEntry(
80 const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
81 uint32_t aWeight,
82 int32_t aStretch,
83 uint32_t aItalicStyle,
84 const nsTArray<gfxFontFeature>& aFeatureSettings,
85 uint32_t aLanguageOverride,
86 gfxSparseBitSet* aUnicodeRanges) MOZ_OVERRIDE;
88 private:
89 nsRefPtr<FontFaceSet> mFontFaceSet;
92 NS_DECL_ISUPPORTS_INHERITED
93 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FontFaceSet, DOMEventTargetHelper)
94 NS_DECL_NSIDOMEVENTLISTENER
96 FontFaceSet(nsPIDOMWindow* aWindow, nsPresContext* aPresContext);
98 virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
100 UserFontSet* EnsureUserFontSet(nsPresContext* aPresContext);
101 UserFontSet* GetUserFontSet() { return mUserFontSet; }
103 // Called when this font set is no longer associated with a presentation.
104 void DestroyUserFontSet();
106 // Called by nsFontFaceLoader when the loader has completed normally.
107 // It's removed from the mLoaders set.
108 void RemoveLoader(nsFontFaceLoader* aLoader);
110 bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules);
112 nsPresContext* GetPresContext() { return mPresContext; }
114 // search for @font-face rule that matches a platform font entry
115 nsCSSFontFaceRule* FindRuleForEntry(gfxFontEntry* aFontEntry);
117 void IncrementGeneration(bool aIsRebuild = false);
120 * Adds the specified FontFace to the mUnavailableFaces array. This is called
121 * when a new FontFace object has just been created in JS by the author.
123 void AddUnavailableFontFace(FontFace* aFontFace);
126 * Removes the specified FontFace from the mUnavailableFaces array. This
127 * is called when a FontFace object is about be destroyed.
129 void RemoveUnavailableFontFace(FontFace* aFontFace);
132 * Finds an existing entry in the user font cache or creates a new user
133 * font entry for the given FontFace object.
135 already_AddRefed<gfxUserFontEntry>
136 FindOrCreateUserFontEntryFromFontFace(FontFace* aFontFace);
139 * Notification method called by a FontFace once it has been initialized.
141 * This is needed for the FontFaceSet to handle a FontFace that was created
142 * and inserted into the set immediately, before the event loop has spun and
143 * the FontFace's initialization tasks have run.
145 void OnFontFaceInitialized(FontFace* aFontFace);
148 * Notification method called by a FontFace to indicate that its loading
149 * status has changed.
151 void OnFontFaceStatusChanged(FontFace* aFontFace);
154 * Notification method called by the nsPresContext to indicate that the
155 * refresh driver ticked and flushed style and layout.
156 * were just flushed.
158 void DidRefresh();
161 * Returns whether the "layout.css.font-loading-api.enabled" pref is true.
163 static bool PrefEnabled();
165 // nsICSSLoaderObserver
166 NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
167 bool aWasAlternate,
168 nsresult aStatus) MOZ_OVERRIDE;
170 // -- Web IDL --------------------------------------------------------------
172 IMPL_EVENT_HANDLER(loading)
173 IMPL_EVENT_HANDLER(loadingdone)
174 IMPL_EVENT_HANDLER(loadingerror)
175 already_AddRefed<mozilla::dom::Promise> Load(const nsAString& aFont,
176 const nsAString& aText,
177 mozilla::ErrorResult& aRv);
178 bool Check(const nsAString& aFont,
179 const nsAString& aText,
180 mozilla::ErrorResult& aRv);
181 mozilla::dom::Promise* GetReady(mozilla::ErrorResult& aRv);
182 mozilla::dom::FontFaceSetLoadStatus Status();
184 FontFaceSet* Add(FontFace& aFontFace, mozilla::ErrorResult& aRv);
185 void Clear();
186 bool Delete(FontFace& aFontFace, mozilla::ErrorResult& aRv);
187 bool Has(FontFace& aFontFace);
188 FontFace* IndexedGetter(uint32_t aIndex, bool& aFound);
189 uint32_t Length();
191 private:
192 ~FontFaceSet();
195 * Returns whether the given FontFace is currently "in" the FontFaceSet.
197 bool HasAvailableFontFace(FontFace* aFontFace);
200 * Removes any listeners and observers.
202 void Disconnect();
205 * Returns whether there might be any pending font loads, which should cause
206 * the mReady Promise not to be resolved yet.
208 bool MightHavePendingFontLoads();
211 * Checks to see whether it is time to replace mReady and dispatch a
212 * "loading" event.
214 void CheckLoadingStarted();
217 * Checks to see whether it is time to resolve mReady and dispatch any
218 * "loadingdone" and "loadingerror" events.
220 void CheckLoadingFinished();
223 * Dispatches a CSSFontFaceLoadEvent to this object.
225 void DispatchLoadingFinishedEvent(
226 const nsAString& aType,
227 const nsTArray<FontFace*>& aFontFaces);
229 // Note: if you add new cycle collected objects to FontFaceRecord,
230 // make sure to update FontFaceSet's cycle collection macros
231 // accordingly.
232 struct FontFaceRecord {
233 nsRefPtr<FontFace> mFontFace;
234 uint8_t mSheetType;
237 already_AddRefed<gfxUserFontEntry> FindOrCreateUserFontEntryFromFontFace(
238 const nsAString& aFamilyName,
239 FontFace* aFontFace,
240 uint8_t aSheetType);
242 // search for @font-face rule that matches a userfont font entry
243 nsCSSFontFaceRule* FindRuleForUserFontEntry(gfxUserFontEntry* aUserFontEntry);
245 nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
246 const gfxFontFaceSrc* aFontFaceSrc);
247 nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
248 nsIPrincipal** aPrincipal,
249 bool* aBypassCache);
250 bool GetPrivateBrowsing();
251 nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
252 const gfxFontFaceSrc* aFontFaceSrc,
253 uint8_t*& aBuffer,
254 uint32_t& aBufferLength);
255 nsresult LogMessage(gfxUserFontEntry* aUserFontEntry,
256 const char* aMessage,
257 uint32_t aFlags,
258 nsresult aStatus);
259 void DoRebuildUserFontSet();
261 void InsertRuleFontFace(FontFace* aFontFace, uint8_t aSheetType,
262 nsTArray<FontFaceRecord>& aOldRecords,
263 bool& aFontSetModified);
264 void InsertNonRuleFontFace(FontFace* aFontFace, bool& aFontSetModified);
266 #ifdef DEBUG
267 bool HasRuleFontFace(FontFace* aFontFace);
268 #endif
271 * Returns whether we have any loading FontFace objects in the FontFaceSet.
273 bool HasLoadingFontFaces();
275 // Helper function for HasLoadingFontFaces.
276 void UpdateHasLoadingFontFaces();
278 nsRefPtr<UserFontSet> mUserFontSet;
279 nsPresContext* mPresContext;
281 // The document this is a FontFaceSet for.
282 nsCOMPtr<nsIDocument> mDocument;
284 // A Promise that is fulfilled once all of the FontFace objects
285 // in mRuleFaces and mNonRuleFaces that started or were loading at the
286 // time the Promise was created have finished loading. It is rejected if
287 // any of those fonts failed to load. mReady is replaced with
288 // a new Promise object whenever mReady is settled and another
289 // FontFace in mRuleFaces or mNonRuleFaces starts to load.
290 nsRefPtr<mozilla::dom::Promise> mReady;
292 // Set of all loaders pointing to us. These are not strong pointers,
293 // but that's OK because nsFontFaceLoader always calls RemoveLoader on
294 // us before it dies (unless we die first).
295 nsTHashtable< nsPtrHashKey<nsFontFaceLoader> > mLoaders;
297 // The @font-face rule backed FontFace objects in the FontFaceSet.
298 nsTArray<FontFaceRecord> mRuleFaces;
300 // The non rule backed FontFace objects that have been added to this
301 // FontFaceSet and their corresponding user font entries.
302 nsTArray<nsRefPtr<FontFace>> mNonRuleFaces;
304 // The non rule backed FontFace objects that have not been added to
305 // this FontFaceSet.
306 nsTArray<FontFace*> mUnavailableFaces;
308 // The overall status of the loading or loaded fonts in the FontFaceSet.
309 mozilla::dom::FontFaceSetLoadStatus mStatus;
311 // Whether mNonRuleFaces has changed since last time UpdateRules ran.
312 bool mNonRuleFacesDirty;
314 // Whether we have called MaybeResolve() on mReady.
315 bool mReadyIsResolved;
317 // Whether we have already dispatched loading events for the current set
318 // of loading FontFaces.
319 bool mDispatchedLoadingEvent;
321 // Whether any FontFace objects in mRuleFaces or mNonRuleFaces are
322 // loading. Only valid when mHasLoadingFontFacesIsDirty is false. Don't use
323 // this variable directly; call the HasLoadingFontFaces method instead.
324 bool mHasLoadingFontFaces;
326 // This variable is only valid when mLoadingDirty is false.
327 bool mHasLoadingFontFacesIsDirty;
330 } // namespace dom
331 } // namespace mozilla
333 #endif // !defined(mozilla_dom_FontFaceSet_h)