summaryrefslogtreecommitdiffstats
path: root/layout/style/FontFaceSetImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/style/FontFaceSetImpl.h')
-rw-r--r--layout/style/FontFaceSetImpl.h315
1 files changed, 315 insertions, 0 deletions
diff --git a/layout/style/FontFaceSetImpl.h b/layout/style/FontFaceSetImpl.h
new file mode 100644
index 0000000000..6f245c6599
--- /dev/null
+++ b/layout/style/FontFaceSetImpl.h
@@ -0,0 +1,315 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_FontFaceSetImpl_h
+#define mozilla_dom_FontFaceSetImpl_h
+
+#include "mozilla/dom/FontFace.h"
+#include "mozilla/dom/FontFaceSetBinding.h"
+#include "mozilla/DOMEventTargetHelper.h"
+#include "mozilla/FontPropertyTypes.h"
+#include "mozilla/RecursiveMutex.h"
+#include "gfxUserFontSet.h"
+#include "nsICSSLoaderObserver.h"
+#include "nsIDOMEventListener.h"
+
+#include <functional>
+
+struct gfxFontFaceSrc;
+class gfxFontSrcPrincipal;
+class gfxUserFontEntry;
+class nsFontFaceLoader;
+class nsIChannel;
+class nsIPrincipal;
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+struct StyleLockedFontFaceRule;
+class PostTraversalTask;
+class Runnable;
+class SharedFontList;
+namespace dom {
+class FontFace;
+} // namespace dom
+} // namespace mozilla
+
+namespace mozilla::dom {
+
+class FontFaceSetImpl : public nsISupports, public gfxUserFontSet {
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ public:
+ // gfxUserFontSet
+
+ already_AddRefed<gfxFontSrcPrincipal> GetStandardFontLoadPrincipal()
+ const final;
+
+ void RecordFontLoadDone(uint32_t aFontSize, TimeStamp aDoneTime) override;
+
+ bool BypassCache() final { return mBypassCache; }
+
+ void ForgetLocalFaces() final;
+
+ protected:
+ virtual nsresult CreateChannelForSyncLoadFontData(
+ nsIChannel** aOutChannel, gfxUserFontEntry* aFontToLoad,
+ const gfxFontFaceSrc* aFontFaceSrc) = 0;
+
+ // gfxUserFontSet
+
+ bool GetPrivateBrowsing() override { return mPrivateBrowsing; }
+ nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
+ const gfxFontFaceSrc* aFontFaceSrc,
+ uint8_t*& aBuffer,
+ uint32_t& aBufferLength) override;
+ nsresult LogMessage(gfxUserFontEntry* aUserFontEntry, uint32_t aSrcIndex,
+ const char* aMessage,
+ uint32_t aFlags = nsIScriptError::errorFlag,
+ nsresult aStatus = NS_OK) override;
+ void DoRebuildUserFontSet() override;
+ already_AddRefed<gfxUserFontEntry> CreateUserFontEntry(
+ nsTArray<gfxFontFaceSrc>&& aFontFaceSrcList,
+ gfxUserFontAttributes&& aAttr) override;
+
+ already_AddRefed<gfxUserFontFamily> GetFamily(
+ const nsACString& aFamilyName) final;
+
+ explicit FontFaceSetImpl(FontFaceSet* aOwner);
+
+ void DestroyLoaders();
+
+ public:
+ virtual void Destroy();
+ virtual bool IsOnOwningThread() = 0;
+#ifdef DEBUG
+ virtual void AssertIsOnOwningThread() = 0;
+#else
+ void AssertIsOnOwningThread() {}
+#endif
+ virtual void DispatchToOwningThread(const char* aName,
+ std::function<void()>&& aFunc) = 0;
+
+ // Called by nsFontFaceLoader when the loader has completed normally.
+ // It's removed from the mLoaders set.
+ virtual void RemoveLoader(nsFontFaceLoader* aLoader);
+
+ virtual bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules) {
+ MOZ_ASSERT_UNREACHABLE("Not implemented!");
+ return false;
+ }
+
+ // search for @font-face rule that matches a platform font entry
+ virtual StyleLockedFontFaceRule* FindRuleForEntry(gfxFontEntry* aFontEntry) {
+ MOZ_ASSERT_UNREACHABLE("Not implemented!");
+ return nullptr;
+ }
+
+ /**
+ * Finds an existing entry in the user font cache or creates a new user
+ * font entry for the given FontFace object.
+ */
+ static already_AddRefed<gfxUserFontEntry>
+ FindOrCreateUserFontEntryFromFontFace(FontFaceImpl* aFontFace,
+ gfxUserFontAttributes&& aAttr,
+ StyleOrigin);
+
+ /**
+ * Notification method called by a FontFace to indicate that its loading
+ * status has changed.
+ */
+ virtual void OnFontFaceStatusChanged(FontFaceImpl* aFontFace);
+
+ /**
+ * Notification method called by the nsPresContext to indicate that the
+ * refresh driver ticked and flushed style and layout.
+ * were just flushed.
+ */
+ virtual void DidRefresh() { MOZ_ASSERT_UNREACHABLE("Not implemented!"); }
+
+ virtual void FlushUserFontSet() = 0;
+
+ static nsPresContext* GetPresContextFor(gfxUserFontSet* aUserFontSet) {
+ const auto* set = static_cast<FontFaceSetImpl*>(aUserFontSet);
+ return set ? set->GetPresContext() : nullptr;
+ }
+
+ virtual void RefreshStandardFontLoadPrincipal();
+
+ virtual dom::Document* GetDocument() const { return nullptr; }
+
+ virtual already_AddRefed<URLExtraData> GetURLExtraData() = 0;
+
+ // -- Web IDL --------------------------------------------------------------
+
+ virtual void EnsureReady() {}
+ dom::FontFaceSetLoadStatus Status();
+
+ virtual bool Add(FontFaceImpl* aFontFace, ErrorResult& aRv);
+ virtual void Clear();
+ virtual bool Delete(FontFaceImpl* aFontFace);
+
+ // For ServoStyleSet to know ahead of time whether a font is loadable.
+ virtual void CacheFontLoadability() {
+ MOZ_ASSERT_UNREACHABLE("Not implemented!");
+ }
+
+ virtual void MarkUserFontSetDirty() {}
+
+ /**
+ * Checks to see whether it is time to resolve mReady and dispatch any
+ * "loadingdone" and "loadingerror" events.
+ */
+ virtual void CheckLoadingFinished();
+
+ virtual void FindMatchingFontFaces(const nsACString& aFont,
+ const nsAString& aText,
+ nsTArray<FontFace*>& aFontFaces,
+ ErrorResult& aRv);
+
+ virtual void DispatchCheckLoadingFinishedAfterDelay();
+
+ protected:
+ ~FontFaceSetImpl() override;
+
+ virtual uint64_t GetInnerWindowID() = 0;
+
+ /**
+ * Returns whether the given FontFace is currently "in" the FontFaceSet.
+ */
+ bool HasAvailableFontFace(FontFaceImpl* aFontFace);
+
+ /**
+ * Returns whether there might be any pending font loads, which should cause
+ * the mReady Promise not to be resolved yet.
+ */
+ virtual bool MightHavePendingFontLoads();
+
+ /**
+ * Checks to see whether it is time to replace mReady and dispatch a
+ * "loading" event.
+ */
+ void CheckLoadingStarted();
+
+ /**
+ * Callback for invoking CheckLoadingFinished after going through the
+ * event loop. See OnFontFaceStatusChanged.
+ */
+ void CheckLoadingFinishedAfterDelay();
+
+ void OnLoadingStarted();
+ void OnLoadingFinished();
+
+ // Note: if you add new cycle collected objects to FontFaceRecord,
+ // make sure to update FontFaceSet's cycle collection macros
+ // accordingly.
+ struct FontFaceRecord {
+ RefPtr<FontFaceImpl> mFontFace;
+ Maybe<StyleOrigin> mOrigin; // only relevant for mRuleFaces entries
+ };
+
+ // search for @font-face rule that matches a userfont font entry
+ virtual StyleLockedFontFaceRule* FindRuleForUserFontEntry(
+ gfxUserFontEntry* aUserFontEntry) {
+ return nullptr;
+ }
+
+ virtual void FindMatchingFontFaces(
+ const nsTHashSet<FontFace*>& aMatchingFaces,
+ nsTArray<FontFace*>& aFontFaces);
+
+ class UpdateUserFontEntryRunnable;
+ void UpdateUserFontEntry(gfxUserFontEntry* aEntry,
+ gfxUserFontAttributes&& aAttr);
+
+ nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
+ gfxFontSrcPrincipal** aPrincipal, bool* aBypassCache);
+
+ void InsertNonRuleFontFace(FontFaceImpl* aFontFace);
+
+ /**
+ * Returns whether we have any loading FontFace objects in the FontFaceSet.
+ */
+ bool HasLoadingFontFaces();
+
+ // Whether mReady is pending, or would be when created.
+ bool ReadyPromiseIsPending() const;
+
+ // Helper function for HasLoadingFontFaces.
+ virtual void UpdateHasLoadingFontFaces();
+
+ void ParseFontShorthandForMatching(const nsACString& aFont,
+ StyleFontFamilyList& aFamilyList,
+ FontWeight& aWeight, FontStretch& aStretch,
+ FontSlantStyle& aStyle, ErrorResult& aRv);
+
+ virtual TimeStamp GetNavigationStartTimeStamp() = 0;
+
+ mutable RecursiveMutex mMutex;
+
+ FontFaceSet* MOZ_NON_OWNING_REF mOwner MOZ_GUARDED_BY(mMutex);
+
+ // The document's node principal, which is the principal font loads for
+ // this FontFaceSet will generally use. (This principal is not used for
+ // @font-face rules in UA and user sheets, where the principal of the
+ // sheet is used instead.)
+ //
+ // This field is used from GetStandardFontLoadPrincipal. When on a
+ // style worker thread, we use mStandardFontLoadPrincipal assuming
+ // it is up to date.
+ //
+ // Because mDocument's principal can change over time,
+ // its value must be updated by a call to ResetStandardFontLoadPrincipal.
+ mutable RefPtr<gfxFontSrcPrincipal> mStandardFontLoadPrincipal
+ MOZ_GUARDED_BY(mMutex);
+
+ // Set of all loaders pointing to us. These are not strong pointers,
+ // but that's OK because nsFontFaceLoader always calls RemoveLoader on
+ // us before it dies (unless we die first).
+ nsTHashtable<nsPtrHashKey<nsFontFaceLoader>> mLoaders MOZ_GUARDED_BY(mMutex);
+
+ // The non rule backed FontFace objects that have been added to this
+ // FontFaceSet.
+ nsTArray<FontFaceRecord> mNonRuleFaces MOZ_GUARDED_BY(mMutex);
+
+ // The overall status of the loading or loaded fonts in the FontFaceSet.
+ dom::FontFaceSetLoadStatus mStatus MOZ_GUARDED_BY(mMutex);
+
+ // A map from gfxFontFaceSrc pointer identity to whether the load is allowed
+ // by CSP or other checks. We store this here because querying CSP off the
+ // main thread is not a great idea.
+ //
+ // We could use just the pointer and use this as a hash set, but then we'd
+ // have no way to verify that we've checked all the loads we should.
+ nsTHashMap<nsPtrHashKey<const gfxFontFaceSrc>, bool> mAllowedFontLoads
+ MOZ_GUARDED_BY(mMutex);
+
+ // Whether mNonRuleFaces has changed since last time UpdateRules ran.
+ bool mNonRuleFacesDirty MOZ_GUARDED_BY(mMutex);
+
+ // Whether any FontFace objects in mRuleFaces or mNonRuleFaces are
+ // loading. Only valid when mHasLoadingFontFacesIsDirty is false. Don't use
+ // this variable directly; call the HasLoadingFontFaces method instead.
+ bool mHasLoadingFontFaces MOZ_GUARDED_BY(mMutex);
+
+ // This variable is only valid when mLoadingDirty is false.
+ bool mHasLoadingFontFacesIsDirty MOZ_GUARDED_BY(mMutex);
+
+ // Whether CheckLoadingFinished calls should be ignored. See comment in
+ // OnFontFaceStatusChanged.
+ bool mDelayedLoadCheck MOZ_GUARDED_BY(mMutex);
+
+ // Whether the docshell for our document indicated that loads should
+ // bypass the cache.
+ bool mBypassCache;
+
+ // Whether the docshell for our document indicates that we are in private
+ // browsing mode.
+ bool mPrivateBrowsing;
+};
+
+} // namespace mozilla::dom
+
+#endif // !defined(mozilla_dom_FontFaceSetImpl_h)