Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef mozilla_dom_FontFace_h
7 : #define mozilla_dom_FontFace_h
8 :
9 : #include "mozilla/dom/FontFaceBinding.h"
10 : #include "gfxUserFontSet.h"
11 : #include "nsAutoPtr.h"
12 : #include "nsCSSPropertyID.h"
13 : #include "nsCSSValue.h"
14 : #include "nsWrapperCache.h"
15 :
16 : class gfxFontFaceBufferSource;
17 : class nsCSSFontFaceRule;
18 :
19 : namespace mozilla {
20 : struct CSSFontFaceDescriptors;
21 : class PostTraversalTask;
22 : namespace dom {
23 : class FontFaceBufferSource;
24 : struct FontFaceDescriptors;
25 : class FontFaceSet;
26 : class Promise;
27 : class StringOrArrayBufferOrArrayBufferView;
28 : } // namespace dom
29 : } // namespace mozilla
30 :
31 : namespace mozilla {
32 : namespace dom {
33 :
34 : class FontFace final : public nsISupports,
35 : public nsWrapperCache
36 : {
37 : friend class mozilla::PostTraversalTask;
38 : friend class mozilla::dom::FontFaceBufferSource;
39 : friend class Entry;
40 :
41 : public:
42 0 : class Entry final : public gfxUserFontEntry {
43 : friend class FontFace;
44 :
45 : public:
46 0 : Entry(gfxUserFontSet* aFontSet,
47 : const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
48 : uint32_t aWeight,
49 : int32_t aStretch,
50 : uint8_t aStyle,
51 : const nsTArray<gfxFontFeature>& aFeatureSettings,
52 : uint32_t aLanguageOverride,
53 : gfxCharacterMap* aUnicodeRanges,
54 : uint8_t aFontDisplay)
55 0 : : gfxUserFontEntry(aFontSet, aFontFaceSrcList, aWeight, aStretch,
56 : aStyle, aFeatureSettings, aLanguageOverride,
57 0 : aUnicodeRanges, aFontDisplay) {}
58 :
59 : virtual void SetLoadState(UserFontLoadState aLoadState) override;
60 : virtual void GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult) override;
61 0 : const AutoTArray<FontFace*,1>& GetFontFaces() { return mFontFaces; }
62 :
63 : protected:
64 : // The FontFace objects that use this user font entry. We need to store
65 : // an array of these, not just a single pointer, since the user font
66 : // cache can return the same entry for different FontFaces that have
67 : // the same descriptor values and come from the same origin.
68 : AutoTArray<FontFace*,1> mFontFaces;
69 : };
70 :
71 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
72 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FontFace)
73 :
74 0 : nsISupports* GetParentObject() const { return mParent; }
75 : virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
76 :
77 : static already_AddRefed<FontFace>
78 : CreateForRule(nsISupports* aGlobal, FontFaceSet* aFontFaceSet,
79 : nsCSSFontFaceRule* aRule);
80 :
81 0 : nsCSSFontFaceRule* GetRule() { return mRule; }
82 :
83 : void GetDesc(nsCSSFontDesc aDescID, nsCSSValue& aResult) const;
84 :
85 : gfxUserFontEntry* CreateUserFontEntry();
86 0 : gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; }
87 : void SetUserFontEntry(gfxUserFontEntry* aEntry);
88 :
89 : /**
90 : * Returns whether this object is in the specified FontFaceSet.
91 : */
92 : bool IsInFontFaceSet(FontFaceSet* aFontFaceSet) const;
93 :
94 : void AddFontFaceSet(FontFaceSet* aFontFaceSet);
95 : void RemoveFontFaceSet(FontFaceSet* aFontFaceSet);
96 :
97 : /**
98 : * Gets the family name of the FontFace as a raw string (such as 'Times', as
99 : * opposed to GetFamily, which returns a CSS-escaped string, such as
100 : * '"Times"'). Returns whether a valid family name was available.
101 : */
102 : bool GetFamilyName(nsString& aResult);
103 :
104 : /**
105 : * Returns whether this object is CSS-connected, i.e. reflecting an
106 : * @font-face rule.
107 : */
108 0 : bool HasRule() const { return mRule; }
109 :
110 : /**
111 : * Breaks the connection between this FontFace and its @font-face rule.
112 : */
113 : void DisconnectFromRule();
114 :
115 : /**
116 : * Returns whether there is an ArrayBuffer or ArrayBufferView of font
117 : * data.
118 : */
119 : bool HasFontData() const;
120 :
121 : /**
122 : * Creates a gfxFontFaceBufferSource to represent the font data
123 : * in this object.
124 : */
125 : already_AddRefed<gfxFontFaceBufferSource> CreateBufferSource();
126 :
127 : /**
128 : * Gets a pointer to and the length of the font data stored in the
129 : * ArrayBuffer or ArrayBufferView.
130 : */
131 : bool GetData(uint8_t*& aBuffer, uint32_t& aLength);
132 :
133 : /**
134 : * Returns the value of the unicode-range descriptor as a gfxCharacterMap.
135 : */
136 : gfxCharacterMap* GetUnicodeRangeAsCharacterMap();
137 :
138 : // Web IDL
139 : static already_AddRefed<FontFace>
140 : Constructor(const GlobalObject& aGlobal,
141 : const nsAString& aFamily,
142 : const mozilla::dom::StringOrArrayBufferOrArrayBufferView& aSource,
143 : const mozilla::dom::FontFaceDescriptors& aDescriptors,
144 : ErrorResult& aRV);
145 :
146 : void GetFamily(nsString& aResult);
147 : void SetFamily(const nsAString& aValue, mozilla::ErrorResult& aRv);
148 : void GetStyle(nsString& aResult);
149 : void SetStyle(const nsAString& aValue, mozilla::ErrorResult& aRv);
150 : void GetWeight(nsString& aResult);
151 : void SetWeight(const nsAString& aValue, mozilla::ErrorResult& aRv);
152 : void GetStretch(nsString& aResult);
153 : void SetStretch(const nsAString& aValue, mozilla::ErrorResult& aRv);
154 : void GetUnicodeRange(nsString& aResult);
155 : void SetUnicodeRange(const nsAString& aValue, mozilla::ErrorResult& aRv);
156 : void GetVariant(nsString& aResult);
157 : void SetVariant(const nsAString& aValue, mozilla::ErrorResult& aRv);
158 : void GetFeatureSettings(nsString& aResult);
159 : void SetFeatureSettings(const nsAString& aValue, mozilla::ErrorResult& aRv);
160 : void GetDisplay(nsString& aResult);
161 : void SetDisplay(const nsAString& aValue, mozilla::ErrorResult& aRv);
162 :
163 : mozilla::dom::FontFaceLoadStatus Status();
164 : mozilla::dom::Promise* Load(mozilla::ErrorResult& aRv);
165 : mozilla::dom::Promise* GetLoaded(mozilla::ErrorResult& aRv);
166 :
167 : private:
168 : FontFace(nsISupports* aParent, FontFaceSet* aFontFaceSet);
169 : ~FontFace();
170 :
171 : void InitializeSource(const StringOrArrayBufferOrArrayBufferView& aSource);
172 :
173 : // Helper function for Load.
174 : void DoLoad();
175 :
176 : /**
177 : * Parses a @font-face descriptor value, storing the result in aResult.
178 : * Returns whether the parsing was successful.
179 : */
180 : bool ParseDescriptor(nsCSSFontDesc aDescID, const nsAString& aString,
181 : nsCSSValue& aResult);
182 :
183 : // Helper function for the descriptor setter methods.
184 : void SetDescriptor(nsCSSFontDesc aFontDesc,
185 : const nsAString& aValue,
186 : mozilla::ErrorResult& aRv);
187 :
188 : /**
189 : * Sets all of the descriptor values in mDescriptors using values passed
190 : * to the JS constructor.
191 : */
192 : bool SetDescriptors(const nsAString& aFamily,
193 : const FontFaceDescriptors& aDescriptors);
194 :
195 : /**
196 : * Sets the current loading status.
197 : */
198 : void SetStatus(mozilla::dom::FontFaceLoadStatus aStatus);
199 :
200 : void GetDesc(nsCSSFontDesc aDescID,
201 : nsCSSPropertyID aPropID,
202 : nsString& aResult) const;
203 :
204 : /**
205 : * Returns and takes ownership of the buffer storing the font data.
206 : */
207 : void TakeBuffer(uint8_t*& aBuffer, uint32_t& aLength);
208 :
209 : // Acts like mLoaded->MaybeReject(aResult), except it doesn't create mLoaded
210 : // if it doesn't already exist.
211 : void Reject(nsresult aResult);
212 :
213 : // Creates mLoaded if it doesn't already exist. It may immediately resolve or
214 : // reject mLoaded based on mStatus and mLoadedRejection.
215 : void EnsurePromise();
216 :
217 : void DoResolve();
218 : void DoReject(nsresult aResult);
219 :
220 : nsCOMPtr<nsISupports> mParent;
221 :
222 : // A Promise that is fulfilled once the font represented by this FontFace is
223 : // loaded, and is rejected if the load fails. This promise is created lazily
224 : // when JS asks for it.
225 : RefPtr<mozilla::dom::Promise> mLoaded;
226 :
227 : // Saves the rejection code for mLoaded if mLoaded hasn't been created yet.
228 : nsresult mLoadedRejection;
229 :
230 : // The @font-face rule this FontFace object is reflecting, if it is a
231 : // rule backed FontFace.
232 : RefPtr<nsCSSFontFaceRule> mRule;
233 :
234 : // The FontFace object's user font entry. This is initially null, but is set
235 : // during FontFaceSet::UpdateRules and when a FontFace is explicitly loaded.
236 : RefPtr<Entry> mUserFontEntry;
237 :
238 : // The current load status of the font represented by this FontFace.
239 : // Note that we can't just reflect the value of the gfxUserFontEntry's
240 : // status, since the spec sometimes requires us to go through the event
241 : // loop before updating the status, rather than doing it immediately.
242 : mozilla::dom::FontFaceLoadStatus mStatus;
243 :
244 : // Represents where a FontFace's data is coming from.
245 : enum SourceType {
246 : eSourceType_FontFaceRule = 1,
247 : eSourceType_URLs,
248 : eSourceType_Buffer
249 : };
250 :
251 : // Where the font data for this FontFace is coming from.
252 : SourceType mSourceType;
253 :
254 : // If the FontFace was constructed with an ArrayBuffer(View), this is a
255 : // copy of the data from it.
256 : uint8_t* mSourceBuffer;
257 : uint32_t mSourceBufferLength;
258 :
259 : // The values corresponding to the font face descriptors, if we are not
260 : // a rule backed FontFace object. For rule backed objects, we use
261 : // the descriptors stored in mRule.
262 : nsAutoPtr<mozilla::CSSFontFaceDescriptors> mDescriptors;
263 :
264 : // The value of the unicode-range descriptor as a gfxCharacterMap. Valid
265 : // only when mUnicodeRangeDirty is false.
266 : RefPtr<gfxCharacterMap> mUnicodeRange;
267 :
268 : // The primary FontFaceSet this FontFace is associated with,
269 : // regardless of whether it is currently "in" the set.
270 : RefPtr<FontFaceSet> mFontFaceSet;
271 :
272 : // Other FontFaceSets (apart from mFontFaceSet) that this FontFace
273 : // appears in.
274 : nsTArray<RefPtr<FontFaceSet>> mOtherFontFaceSets;
275 :
276 : // Whether mUnicodeRange needs to be rebuilt before being returned from
277 : // GetUnicodeRangeAsCharacterMap.
278 : bool mUnicodeRangeDirty;
279 :
280 : // Whether this FontFace appears in mFontFaceSet.
281 : bool mInFontFaceSet;
282 : };
283 :
284 : } // namespace dom
285 : } // namespace mozilla
286 :
287 : #endif // !defined(mozilla_dom_FontFace_h)
|