1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
|
/* -*- 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,
// or by gfxUserFontSet if it cancels the loader.
// It's removed from the mLoaders set.
void RemoveLoader(nsFontFaceLoader* aLoader) override;
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;
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)
|