Files
palemoon27/layout/style/FontFaceSet.h
T
roytam1 3a02ab4d4d import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1131308 (part 0) - Fix minor problems with RemovingIterator. r=froydnj. (5c232c9ca)
- Bug 1176163 - Remove remaining uses of PL_DHashTableEnumerate() from xpcom/. r=froydnj. (bd2478b3a)
- Bug 1179657 - Remove PL_DHASHMETER. r=froydnj. (30f581478)
- Bug 1131308 (part 1) - Improve PLDHashTable's internal checking. r=froydnj. (faba4a3b9)
- Bug 1180084 - Convert TestPLDHash.cpp to a gtest. r=froydnj. (de6ee3c5c)
- Bug 1171578 - Avoid crashing if indexedDB is used at a particular point in the worker shutdown sequence, r=baku. (f325c218e)
- Bug 804975 - Part 1: Expose WritingMode bits. r=dbaron (0635d01dd)
- Bug 1072101 - Part 1: Implement FontFaceSet.size. r=peterv (7e0b4848a)
- Bug 1144977 - Part 1: Don't include FontFace objects in more than one loadingdone/loadingerror event. r=jdaggett (4d10b3269)
- Bug 1072101 - Part 2: Implement FontFaceSet.{entries,values}. r=peterv (1c636f4f1)
- Bug 1072101 - Part 3: Implement FontFaceSet.forEach. r=peterv (842a5cdbe)
- Bug 1072101 - Part 4: Implement FontFaceSet.{keys,@@iterator}. r=peterv (4dfb3afe9)
- Bug 1072101 - Part 5: Remove indexed property access on FontFaceSet. r=peterv (edef47d70)
- Bug 1072101 - Unified build fix; no review. (7c1538f6c)
- Bug 861449 - Incremental css::Rule destroyer. r=dbaron (5e60f4394)
- Bug 1175800 - Remove typedefs from nsComputedDOMStyle.cpp as they interfere with others under unified compilation. r=bzbarsky (2bd45e7ed)
- Bug 1147766 - Part 1: Add a mozilla::RangedArray class, for fixed length arrays with a non-zero base index. r=waldo (42be428bc)
- Bug 1147766 - Part 2: Replace FixedStyleStructArray with mozilla::RangedArray. r=dbaron (4d28a0a5e)
- Bug 1171282 - Avoid some unnecessary |operator new| null-checks in layout/. r=dholbert. (60e1690c1)
- Bug 1168664 - Stop mistakenly using the transform reference box's width to calculate the Z component in ProcessMatrix3D. r=mattwoodrow (18f9021b1)
- Bug 1171842 - Use jump table instead of nested if statements for peeking compute function of style struct. r=dbaron (a5160b962)
- Bug 1170173 - Parse CSS 'contain' property. r=dholbert (3d8a37dee)
- Bug 1144607 part 1 - Remove CounterStyleManager::BuildCounterStyle for anonymous counter styles. r=dbaron (331397d01)
- Bug 1144607 part 2 - Support string value for list-style-tyle. r=dbaron (0b4bca0c7)
- Bug 1144607 part 3 - Reftests for string value on list-style-type. r=dbaron (2a483f621)
- Bug 1144607 followup - Fix submitted reftest for string value of list-style-type. DONTBUILD (ad23ac443)
- Bug 1151220 - [css-grid] Fix a couple of typos in InitializeTrackSize. r=dholbert (840f3b8a4)
- Bug 1151201 - [css-grid] Update parsing of 'auto' in track-sizing functions to latest version of the spec. r=simon.sapin (abdb0c0ea)
2021-02-02 20:52:33 +08:00

347 lines
12 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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_FontFaceSet_h
#define mozilla_dom_FontFaceSet_h
#include "mozilla/dom/FontFace.h"
#include "mozilla/dom/FontFaceSetBinding.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "gfxUserFontSet.h"
#include "nsCSSRules.h"
#include "nsICSSLoaderObserver.h"
#include "nsPIDOMWindow.h"
struct gfxFontFaceSrc;
class gfxUserFontEntry;
class nsFontFaceLoader;
class nsIPrincipal;
class nsPIDOMWindow;
namespace mozilla {
namespace dom {
class FontFace;
class Promise;
}
}
namespace mozilla {
namespace dom {
class FontFaceSet final : public DOMEventTargetHelper
, public nsIDOMEventListener
, public nsICSSLoaderObserver
{
friend class UserFontSet;
public:
/**
* A gfxUserFontSet that integrates with the layout and style systems to
* manage @font-face rules and handle network requests for font loading.
*
* We would combine this class and FontFaceSet into the one class if it were
* possible; it's not because FontFaceSet is cycle collected and
* gfxUserFontSet isn't (and can't be, as gfx classes don't use the cycle
* collector). So UserFontSet exists just to override the needed virtual
* methods from gfxUserFontSet and to forward them on FontFaceSet.
*/
class UserFontSet final : public gfxUserFontSet
{
friend class FontFaceSet;
public:
explicit UserFontSet(FontFaceSet* aFontFaceSet)
: mFontFaceSet(aFontFaceSet)
{
}
FontFaceSet* GetFontFaceSet() { return mFontFaceSet; }
virtual nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
nsIPrincipal** aPrincipal,
bool* aBypassCache) override;
virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
const gfxFontFaceSrc* aFontFaceSrc) override;
protected:
virtual bool GetPrivateBrowsing() override;
virtual nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
const gfxFontFaceSrc* aFontFaceSrc,
uint8_t*& aBuffer,
uint32_t& aBufferLength) override;
virtual nsresult LogMessage(gfxUserFontEntry* aUserFontEntry,
const char* aMessage,
uint32_t aFlags = nsIScriptError::errorFlag,
nsresult aStatus = NS_OK) override;
virtual void DoRebuildUserFontSet() override;
virtual already_AddRefed<gfxUserFontEntry> CreateUserFontEntry(
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
uint32_t aWeight,
int32_t aStretch,
uint32_t aItalicStyle,
const nsTArray<gfxFontFeature>& aFeatureSettings,
uint32_t aLanguageOverride,
gfxSparseBitSet* aUnicodeRanges) override;
private:
nsRefPtr<FontFaceSet> mFontFaceSet;
};
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FontFaceSet, DOMEventTargetHelper)
NS_DECL_NSIDOMEVENTLISTENER
FontFaceSet(nsPIDOMWindow* aWindow, nsPresContext* aPresContext);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
UserFontSet* EnsureUserFontSet(nsPresContext* aPresContext);
UserFontSet* GetUserFontSet() { return mUserFontSet; }
// Called when this font set is no longer associated with a presentation.
void DestroyUserFontSet();
// Called by nsFontFaceLoader when the loader has completed normally.
// It's removed from the mLoaders set.
void RemoveLoader(nsFontFaceLoader* aLoader);
bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules);
nsPresContext* GetPresContext() { return mPresContext; }
// search for @font-face rule that matches a platform font entry
nsCSSFontFaceRule* FindRuleForEntry(gfxFontEntry* aFontEntry);
void IncrementGeneration(bool aIsRebuild = false);
/**
* Adds the specified FontFace to the mUnavailableFaces array. This is called
* when a new FontFace object has just been created in JS by the author.
*/
void AddUnavailableFontFace(FontFace* aFontFace);
/**
* Removes the specified FontFace from the mUnavailableFaces array. This
* is called when a FontFace object is about be destroyed.
*/
void RemoveUnavailableFontFace(FontFace* aFontFace);
/**
* 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(FontFace* aFontFace);
/**
* Notification method called by a FontFace once it has been initialized.
*
* This is needed for the FontFaceSet to handle a FontFace that was created
* and inserted into the set immediately, before the event loop has spun and
* the FontFace's initialization tasks have run.
*/
void OnFontFaceInitialized(FontFace* aFontFace);
/**
* Notification method called by a FontFace to indicate that its loading
* status has changed.
*/
void OnFontFaceStatusChanged(FontFace* aFontFace);
/**
* Notification method called by the nsPresContext to indicate that the
* refresh driver ticked and flushed style and layout.
* were just flushed.
*/
void DidRefresh();
/**
* Returns whether the "layout.css.font-loading-api.enabled" pref is true.
*/
static bool PrefEnabled();
// nsICSSLoaderObserver
NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
bool aWasAlternate,
nsresult aStatus) override;
FontFace* GetFontFaceAt(uint32_t aIndex);
// -- Web IDL --------------------------------------------------------------
IMPL_EVENT_HANDLER(loading)
IMPL_EVENT_HANDLER(loadingdone)
IMPL_EVENT_HANDLER(loadingerror)
already_AddRefed<mozilla::dom::Promise> Load(const nsAString& aFont,
const nsAString& aText,
mozilla::ErrorResult& aRv);
bool Check(const nsAString& aFont,
const nsAString& aText,
mozilla::ErrorResult& aRv);
mozilla::dom::Promise* GetReady(mozilla::ErrorResult& aRv);
mozilla::dom::FontFaceSetLoadStatus Status();
FontFaceSet* Add(FontFace& aFontFace, mozilla::ErrorResult& aRv);
void Clear();
bool Delete(FontFace& aFontFace, mozilla::ErrorResult& aRv);
bool Has(FontFace& aFontFace);
uint32_t Size();
mozilla::dom::FontFaceSetIterator* Entries();
mozilla::dom::FontFaceSetIterator* Values();
void ForEach(JSContext* aCx, FontFaceSetForEachCallback& aCallback,
JS::Handle<JS::Value> aThisArg,
mozilla::ErrorResult& aRv);
private:
~FontFaceSet();
/**
* Returns whether the given FontFace is currently "in" the FontFaceSet.
*/
bool HasAvailableFontFace(FontFace* aFontFace);
/**
* Removes any listeners and observers.
*/
void Disconnect();
void RemoveDOMContentLoadedListener();
/**
* Returns whether there might be any pending font loads, which should cause
* the mReady Promise not to be resolved yet.
*/
bool MightHavePendingFontLoads();
/**
* Checks to see whether it is time to replace mReady and dispatch a
* "loading" event.
*/
void CheckLoadingStarted();
/**
* Checks to see whether it is time to resolve mReady and dispatch any
* "loadingdone" and "loadingerror" events.
*/
void CheckLoadingFinished();
/**
* Dispatches a CSSFontFaceLoadEvent to this object.
*/
void DispatchLoadingFinishedEvent(
const nsAString& aType,
const nsTArray<FontFace*>& aFontFaces);
// Note: if you add new cycle collected objects to FontFaceRecord,
// make sure to update FontFaceSet's cycle collection macros
// accordingly.
struct FontFaceRecord {
nsRefPtr<FontFace> mFontFace;
uint8_t mSheetType; // only relevant for mRuleFaces entries
// When true, indicates that when finished loading, the FontFace should be
// included in the subsequent loadingdone/loadingerror event fired at the
// FontFaceSet.
bool mLoadEventShouldFire;
};
static already_AddRefed<gfxUserFontEntry> FindOrCreateUserFontEntryFromFontFace(
const nsAString& aFamilyName,
FontFace* aFontFace,
uint8_t aSheetType);
// search for @font-face rule that matches a userfont font entry
nsCSSFontFaceRule* FindRuleForUserFontEntry(gfxUserFontEntry* aUserFontEntry);
nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
const gfxFontFaceSrc* aFontFaceSrc);
nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
nsIPrincipal** aPrincipal,
bool* aBypassCache);
bool GetPrivateBrowsing();
nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
const gfxFontFaceSrc* aFontFaceSrc,
uint8_t*& aBuffer,
uint32_t& aBufferLength);
nsresult LogMessage(gfxUserFontEntry* aUserFontEntry,
const char* aMessage,
uint32_t aFlags,
nsresult aStatus);
void DoRebuildUserFontSet();
void InsertRuleFontFace(FontFace* aFontFace, uint8_t aSheetType,
nsTArray<FontFaceRecord>& aOldRecords,
bool& aFontSetModified);
void InsertNonRuleFontFace(FontFace* aFontFace, bool& aFontSetModified);
#ifdef DEBUG
bool HasRuleFontFace(FontFace* aFontFace);
#endif
/**
* Returns whether we have any loading FontFace objects in the FontFaceSet.
*/
bool HasLoadingFontFaces();
// Helper function for HasLoadingFontFaces.
void UpdateHasLoadingFontFaces();
nsRefPtr<UserFontSet> mUserFontSet;
nsPresContext* mPresContext;
// The document this is a FontFaceSet for.
nsCOMPtr<nsIDocument> mDocument;
// A Promise that is fulfilled once all of the FontFace objects
// in mRuleFaces and mNonRuleFaces that started or were loading at the
// time the Promise was created have finished loading. It is rejected if
// any of those fonts failed to load. mReady is replaced with
// a new Promise object whenever mReady is settled and another
// FontFace in mRuleFaces or mNonRuleFaces starts to load.
nsRefPtr<mozilla::dom::Promise> mReady;
// 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;
// The @font-face rule backed FontFace objects in the FontFaceSet.
nsTArray<FontFaceRecord> mRuleFaces;
// The non rule backed FontFace objects that have been added to this
// FontFaceSet.
nsTArray<FontFaceRecord> mNonRuleFaces;
// The non rule backed FontFace objects that have not been added to
// this FontFaceSet.
nsTArray<FontFace*> mUnavailableFaces;
// The overall status of the loading or loaded fonts in the FontFaceSet.
mozilla::dom::FontFaceSetLoadStatus mStatus;
// Whether mNonRuleFaces has changed since last time UpdateRules ran.
bool mNonRuleFacesDirty;
// Whether we have called MaybeResolve() on mReady.
bool mReadyIsResolved;
// Whether we have already dispatched loading events for the current set
// of loading FontFaces.
bool mDispatchedLoadingEvent;
// 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;
// This variable is only valid when mLoadingDirty is false.
bool mHasLoadingFontFacesIsDirty;
};
} // namespace dom
} // namespace mozilla
#endif // !defined(mozilla_dom_FontFaceSet_h)