diff options
Diffstat (limited to 'layout/style/FontFace.h')
-rw-r--r-- | layout/style/FontFace.h | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/layout/style/FontFace.h b/layout/style/FontFace.h new file mode 100644 index 0000000000..ff7dc6e622 --- /dev/null +++ b/layout/style/FontFace.h @@ -0,0 +1,307 @@ +/* -*- 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_FontFace_h +#define mozilla_dom_FontFace_h + +#include "mozilla/dom/FontFaceBinding.h" +#include "mozilla/FontPropertyTypes.h" +#include "mozilla/Maybe.h" +#include "mozilla/ServoStyleConsts.h" +#include "gfxUserFontSet.h" +#include "nsCSSPropertyID.h" +#include "nsCSSValue.h" +#include "nsWrapperCache.h" + +class gfxFontFaceBufferSource; +struct RawServoFontFaceRule; + +namespace mozilla { +struct CSSFontFaceDescriptors; +class PostTraversalTask; +namespace dom { +class CSSFontFaceRule; +class FontFaceBufferSource; +struct FontFaceDescriptors; +class FontFaceSet; +class Promise; +class UTF8StringOrArrayBufferOrArrayBufferView; +} // namespace dom +} // namespace mozilla + +namespace mozilla { +namespace dom { + +class FontFace final : public nsISupports, public nsWrapperCache { + friend class mozilla::PostTraversalTask; + friend class FontFaceBufferSource; + friend class Entry; + + public: + class Entry final : public gfxUserFontEntry { + friend class FontFace; + + public: + Entry(gfxUserFontSet* aFontSet, + const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, WeightRange aWeight, + StretchRange aStretch, SlantStyleRange aStyle, + const nsTArray<gfxFontFeature>& aFeatureSettings, + const nsTArray<gfxFontVariation>& aVariationSettings, + uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, + StyleFontDisplay aFontDisplay, RangeFlags aRangeFlags) + : gfxUserFontEntry(aFontSet, aFontFaceSrcList, aWeight, aStretch, + aStyle, aFeatureSettings, aVariationSettings, + aLanguageOverride, aUnicodeRanges, aFontDisplay, + aRangeFlags) {} + + virtual void SetLoadState(UserFontLoadState aLoadState) override; + virtual void GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult) override; + const AutoTArray<FontFace*, 1>& GetFontFaces() { return mFontFaces; } + + protected: + // The FontFace objects that use this user font entry. We need to store + // an array of these, not just a single pointer, since the user font + // cache can return the same entry for different FontFaces that have + // the same descriptor values and come from the same origin. + AutoTArray<FontFace*, 1> mFontFaces; + }; + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FontFace) + + nsISupports* GetParentObject() const { return mParent; } + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + static already_AddRefed<FontFace> CreateForRule(nsISupports* aGlobal, + FontFaceSet* aFontFaceSet, + RawServoFontFaceRule* aRule); + + RawServoFontFaceRule* GetRule() { return mRule; } + + bool HasLocalSrc() const; + Maybe<StyleComputedFontWeightRange> GetFontWeight() const; + Maybe<StyleComputedFontStretchRange> GetFontStretch() const; + Maybe<StyleComputedFontStyleDescriptor> GetFontStyle() const; + Maybe<StyleFontDisplay> GetFontDisplay() const; + void GetFontFeatureSettings(nsTArray<gfxFontFeature>&) const; + void GetFontVariationSettings(nsTArray<gfxFontVariation>&) const; + void GetSources(nsTArray<StyleFontFaceSourceListComponent>&) const; + Maybe<StyleFontLanguageOverride> GetFontLanguageOverride() const; + + gfxUserFontEntry* CreateUserFontEntry(); + gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; } + void SetUserFontEntry(gfxUserFontEntry* aEntry); + + /** + * Returns whether this object is in the specified FontFaceSet. + */ + bool IsInFontFaceSet(FontFaceSet* aFontFaceSet) const; + + void AddFontFaceSet(FontFaceSet* aFontFaceSet); + void RemoveFontFaceSet(FontFaceSet* aFontFaceSet); + + FontFaceSet* GetPrimaryFontFaceSet() const { return mFontFaceSet; } + + /** + * Gets the family name of the FontFace as a raw string (such as 'Times', as + * opposed to GetFamily, which returns a CSS-escaped string, such as + * '"Times"'). Returns null if a valid family name was not available. + */ + nsAtom* GetFamilyName() const; + + /** + * Returns whether this object is CSS-connected, i.e. reflecting an + * @font-face rule. + */ + bool HasRule() const { return mRule; } + + /** + * Breaks the connection between this FontFace and its @font-face rule. + */ + void DisconnectFromRule(); + + /** + * Returns whether there is an ArrayBuffer or ArrayBufferView of font + * data. + */ + bool HasFontData() const; + + /** + * Creates a gfxFontFaceBufferSource to represent the font data + * in this object. + */ + already_AddRefed<gfxFontFaceBufferSource> CreateBufferSource(); + + /** + * Gets a pointer to and the length of the font data stored in the + * ArrayBuffer or ArrayBufferView. + */ + bool GetData(uint8_t*& aBuffer, uint32_t& aLength); + + /** + * Returns the value of the unicode-range descriptor as a gfxCharacterMap. + */ + gfxCharacterMap* GetUnicodeRangeAsCharacterMap(); + + // Web IDL + static already_AddRefed<FontFace> Constructor( + const GlobalObject& aGlobal, const nsACString& aFamily, + const UTF8StringOrArrayBufferOrArrayBufferView& aSource, + const FontFaceDescriptors& aDescriptors, ErrorResult& aRV); + + void GetFamily(nsACString& aResult); + void SetFamily(const nsACString& aValue, ErrorResult& aRv); + void GetStyle(nsACString& aResult); + void SetStyle(const nsACString& aValue, ErrorResult& aRv); + void GetWeight(nsACString& aResult); + void SetWeight(const nsACString& aValue, ErrorResult& aRv); + void GetStretch(nsACString& aResult); + void SetStretch(const nsACString& aValue, ErrorResult& aRv); + void GetUnicodeRange(nsACString& aResult); + void SetUnicodeRange(const nsACString& aValue, ErrorResult& aRv); + void GetVariant(nsACString& aResult); + void SetVariant(const nsACString& aValue, ErrorResult& aRv); + void GetFeatureSettings(nsACString& aResult); + void SetFeatureSettings(const nsACString& aValue, ErrorResult& aRv); + void GetVariationSettings(nsACString& aResult); + void SetVariationSettings(const nsACString& aValue, ErrorResult& aRv); + void GetDisplay(nsACString& aResult); + void SetDisplay(const nsACString& aValue, ErrorResult& aRv); + + FontFaceLoadStatus Status(); + Promise* Load(ErrorResult& aRv); + Promise* GetLoaded(ErrorResult& aRv); + + private: + FontFace(nsISupports* aParent, FontFaceSet* aFontFaceSet); + ~FontFace(); + + void InitializeSource(const UTF8StringOrArrayBufferOrArrayBufferView&); + + // Helper function for Load. + void DoLoad(); + + // Helper function for the descriptor setter methods. + // Returns true if the descriptor was modified, false if descriptor is + // unchanged (which may not be an error: check aRv for actual failure). + bool SetDescriptor(nsCSSFontDesc aFontDesc, const nsACString& aValue, + ErrorResult& aRv); + + /** + * Sets all of the descriptor values in mDescriptors using values passed + * to the JS constructor. + * Returns true on success, false if parsing any descriptor failed. + */ + bool SetDescriptors(const nsACString& aFamily, + const FontFaceDescriptors& aDescriptors); + + /** + * Called when a descriptor has been modified, so font-face sets can + * be told to refresh. + */ + void DescriptorUpdated(); + + /** + * Sets the current loading status. + */ + void SetStatus(FontFaceLoadStatus aStatus); + + void GetDesc(nsCSSFontDesc aDescID, nsACString& aResult) const; + + already_AddRefed<URLExtraData> GetURLExtraData() const; + + RawServoFontFaceRule* GetData() const { + return HasRule() ? mRule : mDescriptors; + } + + /** + * Returns and takes ownership of the buffer storing the font data. + */ + void TakeBuffer(uint8_t*& aBuffer, uint32_t& aLength); + + // Acts like mLoaded->MaybeReject(aResult), except it doesn't create mLoaded + // if it doesn't already exist. + void Reject(nsresult aResult); + + // Creates mLoaded if it doesn't already exist. It may immediately resolve or + // reject mLoaded based on mStatus and mLoadedRejection. + void EnsurePromise(); + + void DoResolve(); + void DoReject(nsresult aResult); + + nsCOMPtr<nsISupports> mParent; + + // A Promise that is fulfilled once the font represented by this FontFace is + // loaded, and is rejected if the load fails. This promise is created lazily + // when JS asks for it. + RefPtr<Promise> mLoaded; + + // Saves the rejection code for mLoaded if mLoaded hasn't been created yet. + nsresult mLoadedRejection; + + // The @font-face rule this FontFace object is reflecting, if it is a + // rule backed FontFace. + RefPtr<RawServoFontFaceRule> mRule; + + // The FontFace object's user font entry. This is initially null, but is set + // during FontFaceSet::UpdateRules and when a FontFace is explicitly loaded. + RefPtr<Entry> mUserFontEntry; + + // The current load status of the font represented by this FontFace. + // Note that we can't just reflect the value of the gfxUserFontEntry's + // status, since the spec sometimes requires us to go through the event + // loop before updating the status, rather than doing it immediately. + FontFaceLoadStatus mStatus; + + // Represents where a FontFace's data is coming from. + enum SourceType { + eSourceType_FontFaceRule = 1, + eSourceType_URLs, + eSourceType_Buffer + }; + + // Where the font data for this FontFace is coming from. + SourceType mSourceType; + + // If the FontFace was constructed with an ArrayBuffer(View), this is a + // copy of the data from it. + uint8_t* mSourceBuffer; + uint32_t mSourceBufferLength; + + // The values corresponding to the font face descriptors, if we are not + // a rule backed FontFace object. For rule backed objects, we use + // the descriptors stored in mRule. + // FIXME This should hold a unique ptr to just the descriptors inside, + // so that we don't need to create a rule for it and don't need to + // assign a fake line number and column number. See bug 1450904. + RefPtr<RawServoFontFaceRule> mDescriptors; + + // The value of the unicode-range descriptor as a gfxCharacterMap. Valid + // only when mUnicodeRangeDirty is false. + RefPtr<gfxCharacterMap> mUnicodeRange; + + // The primary FontFaceSet this FontFace is associated with, + // regardless of whether it is currently "in" the set. + RefPtr<FontFaceSet> mFontFaceSet; + + // Other FontFaceSets (apart from mFontFaceSet) that this FontFace + // appears in. + nsTArray<RefPtr<FontFaceSet>> mOtherFontFaceSets; + + // Whether mUnicodeRange needs to be rebuilt before being returned from + // GetUnicodeRangeAsCharacterMap. + bool mUnicodeRangeDirty; + + // Whether this FontFace appears in mFontFaceSet. + bool mInFontFaceSet; +}; + +} // namespace dom +} // namespace mozilla + +#endif // !defined(mozilla_dom_FontFace_h) |