tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FontFaceSetImpl.h (10851B)


      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_FontFaceSetImpl_h
      8 #define mozilla_dom_FontFaceSetImpl_h
      9 
     10 #include <functional>
     11 
     12 #include "gfxUserFontSet.h"
     13 #include "mozilla/DOMEventTargetHelper.h"
     14 #include "mozilla/FontPropertyTypes.h"
     15 #include "mozilla/RecursiveMutex.h"
     16 #include "mozilla/dom/FontFace.h"
     17 #include "mozilla/dom/FontFaceSetBinding.h"
     18 #include "nsICSSLoaderObserver.h"
     19 #include "nsIDOMEventListener.h"
     20 
     21 struct gfxFontFaceSrc;
     22 class gfxFontSrcPrincipal;
     23 class gfxUserFontEntry;
     24 class nsFontFaceLoader;
     25 class nsIChannel;
     26 class nsIPrincipal;
     27 class nsPIDOMWindowInner;
     28 
     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
     38 
     39 namespace mozilla::dom {
     40 
     41 class FontFaceSetImpl : public nsISupports, public gfxUserFontSet {
     42  NS_DECL_THREADSAFE_ISUPPORTS
     43 
     44 public:
     45  // gfxUserFontSet
     46 
     47  already_AddRefed<gfxFontSrcPrincipal> GetStandardFontLoadPrincipal()
     48      const final;
     49 
     50  void RecordFontLoadDone(uint32_t aFontSize, TimeStamp aDoneTime) override;
     51 
     52  bool BypassCache() final { return mBypassCache; }
     53 
     54  void ForgetLocalFaces() final;
     55 
     56 protected:
     57  virtual nsresult CreateChannelForSyncLoadFontData(
     58      nsIChannel** aOutChannel, gfxUserFontEntry* aFontToLoad,
     59      const gfxFontFaceSrc* aFontFaceSrc) = 0;
     60 
     61  // gfxUserFontSet
     62 
     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;
     76 
     77  already_AddRefed<gfxUserFontFamily> GetFamily(
     78      const nsACString& aFamilyName) final;
     79 
     80  explicit FontFaceSetImpl(FontFaceSet* aOwner);
     81 
     82  void DestroyLoaders();
     83 
     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;
     94 
     95  // Called by nsFontFaceLoader when the loader has completed normally,
     96  // or by gfxUserFontSet if it cancels the loader.
     97  // It's removed from the mLoaders set.
     98  void RemoveLoader(nsFontFaceLoader* aLoader) override;
     99 
    100  virtual bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules) {
    101    MOZ_ASSERT_UNREACHABLE("Not implemented!");
    102    return false;
    103  }
    104 
    105  // search for @font-face rule that matches a platform font entry
    106  virtual StyleLockedFontFaceRule* FindRuleForEntry(gfxFontEntry* aFontEntry) {
    107    MOZ_ASSERT_UNREACHABLE("Not implemented!");
    108    return nullptr;
    109  }
    110 
    111  /**
    112   * Finds an existing entry in the user font cache or creates a new user
    113   * font entry for the given FontFace object.
    114   */
    115  static already_AddRefed<gfxUserFontEntry>
    116  FindOrCreateUserFontEntryFromFontFace(FontFaceImpl* aFontFace,
    117                                        gfxUserFontAttributes&& aAttr,
    118                                        StyleOrigin);
    119 
    120  /**
    121   * Notification method called by a FontFace to indicate that its loading
    122   * status has changed.
    123   */
    124  virtual void OnFontFaceStatusChanged(FontFaceImpl* aFontFace);
    125 
    126  /**
    127   * Notification method called by the nsPresContext to indicate that the
    128   * refresh driver ticked and flushed style and layout.
    129   * were just flushed.
    130   */
    131  virtual void DidRefresh() { MOZ_ASSERT_UNREACHABLE("Not implemented!"); }
    132 
    133  virtual void FlushUserFontSet() = 0;
    134 
    135  static FontVisibilityProvider* GetFontVisibilityProviderFor(
    136      gfxUserFontSet* aUserFontSet) {
    137    const auto* set = static_cast<FontFaceSetImpl*>(aUserFontSet);
    138    return set ? set->GetFontVisibilityProvider() : nullptr;
    139  }
    140 
    141  virtual void RefreshStandardFontLoadPrincipal();
    142 
    143  virtual dom::Document* GetDocument() const { return nullptr; }
    144 
    145  virtual already_AddRefed<URLExtraData> GetURLExtraData() = 0;
    146 
    147  // -- Web IDL --------------------------------------------------------------
    148 
    149  virtual void EnsureReady() {}
    150  dom::FontFaceSetLoadStatus Status();
    151 
    152  virtual bool Add(FontFaceImpl* aFontFace, ErrorResult& aRv);
    153  virtual void Clear();
    154  virtual bool Delete(FontFaceImpl* aFontFace);
    155 
    156  // For ServoStyleSet to know ahead of time whether a font is loadable.
    157  virtual void CacheFontLoadability() {
    158    MOZ_ASSERT_UNREACHABLE("Not implemented!");
    159  }
    160 
    161  virtual void MarkUserFontSetDirty() {}
    162 
    163  /**
    164   * Checks to see whether it is time to resolve mReady and dispatch any
    165   * "loadingdone" and "loadingerror" events.
    166   */
    167  virtual void CheckLoadingFinished();
    168 
    169  virtual void FindMatchingFontFaces(const nsACString& aFont,
    170                                     const nsAString& aText,
    171                                     nsTArray<FontFace*>& aFontFaces,
    172                                     ErrorResult& aRv);
    173 
    174  virtual void DispatchCheckLoadingFinishedAfterDelay();
    175 
    176 protected:
    177  ~FontFaceSetImpl() override;
    178 
    179  virtual uint64_t GetInnerWindowID() = 0;
    180 
    181  /**
    182   * Returns whether the given FontFace is currently "in" the FontFaceSet.
    183   */
    184  bool HasAvailableFontFace(FontFaceImpl* aFontFace);
    185 
    186  /**
    187   * Returns whether there might be any pending font loads, which should cause
    188   * the mReady Promise not to be resolved yet.
    189   */
    190  virtual bool MightHavePendingFontLoads();
    191 
    192  /**
    193   * Checks to see whether it is time to replace mReady and dispatch a
    194   * "loading" event.
    195   */
    196  void CheckLoadingStarted();
    197 
    198  /**
    199   * Callback for invoking CheckLoadingFinished after going through the
    200   * event loop.  See OnFontFaceStatusChanged.
    201   */
    202  void CheckLoadingFinishedAfterDelay();
    203 
    204  void OnLoadingStarted();
    205  void OnLoadingFinished();
    206 
    207  // Note: if you add new cycle collected objects to FontFaceRecord,
    208  // make sure to update FontFaceSet's cycle collection macros
    209  // accordingly.
    210  struct FontFaceRecord {
    211    RefPtr<FontFaceImpl> mFontFace;
    212    Maybe<StyleOrigin> mOrigin;  // only relevant for mRuleFaces entries
    213  };
    214 
    215  // search for @font-face rule that matches a userfont font entry
    216  virtual StyleLockedFontFaceRule* FindRuleForUserFontEntry(
    217      gfxUserFontEntry* aUserFontEntry) {
    218    return nullptr;
    219  }
    220 
    221  virtual void FindMatchingFontFaces(
    222      const nsTHashSet<FontFace*>& aMatchingFaces,
    223      nsTArray<FontFace*>& aFontFaces);
    224 
    225  class UpdateUserFontEntryRunnable;
    226  void UpdateUserFontEntry(gfxUserFontEntry* aEntry,
    227                           gfxUserFontAttributes&& aAttr);
    228 
    229  nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
    230                         gfxFontSrcPrincipal** aPrincipal, bool* aBypassCache);
    231 
    232  void InsertNonRuleFontFace(FontFaceImpl* aFontFace);
    233 
    234  /**
    235   * Returns whether we have any loading FontFace objects in the FontFaceSet.
    236   */
    237  bool HasLoadingFontFaces();
    238 
    239  // Whether mReady is pending, or would be when created.
    240  bool ReadyPromiseIsPending() const;
    241 
    242  // Helper function for HasLoadingFontFaces.
    243  virtual void UpdateHasLoadingFontFaces();
    244 
    245  void ParseFontShorthandForMatching(const nsACString& aFont,
    246                                     StyleFontFamilyList& aFamilyList,
    247                                     FontWeight& aWeight, FontStretch& aStretch,
    248                                     FontSlantStyle& aStyle, ErrorResult& aRv);
    249 
    250  virtual TimeStamp GetNavigationStartTimeStamp() = 0;
    251 
    252  FontFaceSet* MOZ_NON_OWNING_REF mOwner MOZ_GUARDED_BY(mMutex);
    253 
    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.)
    258  //
    259  // This field is used from GetStandardFontLoadPrincipal.  When on a
    260  // style worker thread, we use mStandardFontLoadPrincipal assuming
    261  // it is up to date.
    262  //
    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);
    267 
    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);
    272 
    273  // The non rule backed FontFace objects that have been added to this
    274  // FontFaceSet.
    275  nsTArray<FontFaceRecord> mNonRuleFaces MOZ_GUARDED_BY(mMutex);
    276 
    277  // The overall status of the loading or loaded fonts in the FontFaceSet.
    278  dom::FontFaceSetLoadStatus mStatus MOZ_GUARDED_BY(mMutex);
    279 
    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.
    283  //
    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);
    288 
    289  // Whether mNonRuleFaces has changed since last time UpdateRules ran.
    290  bool mNonRuleFacesDirty MOZ_GUARDED_BY(mMutex);
    291 
    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);
    296 
    297  // This variable is only valid when mLoadingDirty is false.
    298  bool mHasLoadingFontFacesIsDirty MOZ_GUARDED_BY(mMutex);
    299 
    300  // Whether CheckLoadingFinished calls should be ignored.  See comment in
    301  // OnFontFaceStatusChanged.
    302  bool mDelayedLoadCheck MOZ_GUARDED_BY(mMutex);
    303 
    304  // Whether the docshell for our document indicated that loads should
    305  // bypass the cache.
    306  bool mBypassCache;
    307 
    308  // Whether the docshell for our document indicates that we are in private
    309  // browsing mode.
    310  bool mPrivateBrowsing;
    311 };
    312 
    313 }  // namespace mozilla::dom
    314 
    315 #endif  // !defined(mozilla_dom_FontFaceSetImpl_h)