FontFaceImpl.h (10534B)
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_FontFaceImpl_h 8 #define mozilla_dom_FontFaceImpl_h 9 10 #include "gfxUserFontSet.h" 11 #include "mozilla/FontPropertyTypes.h" 12 #include "mozilla/RWLock.h" 13 #include "mozilla/ServoStyleConsts.h" 14 #include "mozilla/dom/FontFaceBinding.h" 15 #include "nsTHashSet.h" 16 17 class gfxFontFaceBufferSource; 18 19 namespace mozilla { 20 struct CSSFontFaceDescriptors; 21 class PostTraversalTask; 22 struct StyleLockedFontFaceRule; 23 namespace dom { 24 class CSSFontFaceRule; 25 class FontFace; 26 class FontFaceBufferSource; 27 struct FontFaceDescriptors; 28 class FontFaceSetImpl; 29 class UTF8StringOrArrayBufferOrArrayBufferView; 30 } // namespace dom 31 } // namespace mozilla 32 33 namespace mozilla::dom { 34 35 class FontFaceImpl final { 36 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FontFaceImpl) 37 38 friend class mozilla::PostTraversalTask; 39 friend class FontFaceBufferSource; 40 friend class Entry; 41 42 public: 43 class Entry final : public gfxUserFontEntry { 44 friend class FontFaceImpl; 45 46 public: 47 Entry(gfxUserFontSet* aFontSet, nsTArray<gfxFontFaceSrc>&& aFontFaceSrcList, 48 gfxUserFontAttributes&& aAttr) 49 : gfxUserFontEntry(std::move(aFontFaceSrcList), std::move(aAttr)), 50 mFontSet(aFontSet) {} 51 52 void SetLoadState(UserFontLoadState aLoadState) override; 53 void GetUserFontSets(nsTArray<RefPtr<gfxUserFontSet>>& aResult) override; 54 already_AddRefed<gfxUserFontSet> GetUserFontSet() const override; 55 56 #ifdef DEBUG 57 bool HasUserFontSet(gfxUserFontSet* aFontSet) const { 58 AutoReadLock lock(mLock); 59 return mFontSet == aFontSet; 60 } 61 #endif 62 63 void AddFontFace(FontFaceImpl* aOwner); 64 void RemoveFontFace(FontFaceImpl* aOwner); 65 void FindFontFaceOwners(nsTHashSet<FontFace*>& aOwners); 66 67 RWLock& Lock() const MOZ_RETURN_CAPABILITY(mLock) { return mLock; } 68 69 protected: 70 void CheckUserFontSetLocked() MOZ_REQUIRES(mLock); 71 72 // Font set which owns this entry; 73 gfxUserFontSet* MOZ_NON_OWNING_REF mFontSet MOZ_GUARDED_BY(mLock); 74 75 // The FontFace objects that use this user font entry. We need to store 76 // an array of these, not just a single pointer, since the user font 77 // cache can return the same entry for different FontFaces that have 78 // the same descriptor values and come from the same origin. 79 AutoTArray<FontFaceImpl*, 1> mFontFaces MOZ_GUARDED_BY(mLock); 80 }; 81 82 #ifdef DEBUG 83 void AssertIsOnOwningThread() const; 84 #else 85 void AssertIsOnOwningThread() const {} 86 #endif 87 88 FontFace* GetOwner() const { 89 AssertIsOnOwningThread(); 90 return mOwner; 91 } 92 93 void StopKeepingOwnerAlive(); 94 95 static already_AddRefed<FontFaceImpl> CreateForRule( 96 FontFace* aOwner, FontFaceSetImpl* aFontFaceSet, 97 StyleLockedFontFaceRule* aRule); 98 99 StyleLockedFontFaceRule* GetRule() { return mRule; } 100 101 static bool GetAttributesFromRule( 102 StyleLockedFontFaceRule*, gfxUserFontAttributes& aAttr, 103 const Maybe<gfxCharacterMap*>& aKnownCharMap = Nothing()); 104 bool GetAttributes(gfxUserFontAttributes& aAttr); 105 gfxUserFontEntry* CreateUserFontEntry(); 106 gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; } 107 void SetUserFontEntry(gfxUserFontEntry* aEntry); 108 109 /** 110 * Returns whether this object is in the specified FontFaceSet. 111 */ 112 bool IsInFontFaceSet(FontFaceSetImpl* aFontFaceSet) const; 113 114 void AddFontFaceSet(FontFaceSetImpl* aFontFaceSet); 115 void RemoveFontFaceSet(FontFaceSetImpl* aFontFaceSet); 116 117 FontFaceSetImpl* GetPrimaryFontFaceSet() const { return mFontFaceSet; } 118 119 /** 120 * Gets the family name of the FontFace as a raw string (such as 'Times', as 121 * opposed to GetFamily, which returns a CSS-escaped string, such as 122 * '"Times"'). Returns null if a valid family name was not available. 123 */ 124 nsAtom* GetFamilyName() const; 125 126 /** 127 * Returns whether this object is CSS-connected, i.e. reflecting an 128 * @font-face rule. 129 */ 130 bool HasRule() const { return mRule; } 131 132 /** Set the font-face block we're reflecting when reusing a FontFace object */ 133 void SetRule(StyleLockedFontFaceRule* aData) { 134 MOZ_ASSERT(HasRule()); 135 AssertIsOnOwningThread(); 136 mRule = aData; 137 } 138 139 /** 140 * Breaks the connection between this FontFace and its @font-face rule. 141 */ 142 void DisconnectFromRule(); 143 144 /** 145 * Returns whether there is an ArrayBuffer or ArrayBufferView of font 146 * data. 147 */ 148 bool HasFontData() const; 149 150 /** 151 * Takes the gfxFontFaceBufferSource to represent the font data 152 * in this object. 153 */ 154 already_AddRefed<gfxFontFaceBufferSource> TakeBufferSource(); 155 156 /** 157 * Gets a pointer to and the length of the font data stored in the 158 * ArrayBuffer or ArrayBufferView. 159 */ 160 bool GetData(uint8_t*& aBuffer, uint32_t& aLength); 161 162 /** 163 * Returns the value of the unicode-range descriptor as a gfxCharacterMap. 164 */ 165 gfxCharacterMap* GetUnicodeRangeAsCharacterMap(); 166 167 // Web IDL 168 void GetFamily(nsACString& aResult); 169 void SetFamily(const nsACString& aValue, ErrorResult& aRv); 170 void GetStyle(nsACString& aResult); 171 void SetStyle(const nsACString& aValue, ErrorResult& aRv); 172 void GetWeight(nsACString& aResult); 173 void SetWeight(const nsACString& aValue, ErrorResult& aRv); 174 void GetStretch(nsACString& aResult); 175 void SetStretch(const nsACString& aValue, ErrorResult& aRv); 176 void GetUnicodeRange(nsACString& aResult); 177 void SetUnicodeRange(const nsACString& aValue, ErrorResult& aRv); 178 void GetVariant(nsACString& aResult); 179 void SetVariant(const nsACString& aValue, ErrorResult& aRv); 180 void GetFeatureSettings(nsACString& aResult); 181 void SetFeatureSettings(const nsACString& aValue, ErrorResult& aRv); 182 void GetVariationSettings(nsACString& aResult); 183 void SetVariationSettings(const nsACString& aValue, ErrorResult& aRv); 184 void GetDisplay(nsACString& aResult); 185 void SetDisplay(const nsACString& aValue, ErrorResult& aRv); 186 void GetAscentOverride(nsACString& aResult); 187 void SetAscentOverride(const nsACString& aValue, ErrorResult& aRv); 188 void GetDescentOverride(nsACString& aResult); 189 void SetDescentOverride(const nsACString& aValue, ErrorResult& aRv); 190 void GetLineGapOverride(nsACString& aResult); 191 void SetLineGapOverride(const nsACString& aValue, ErrorResult& aRv); 192 void GetSizeAdjust(nsACString& aResult); 193 void SetSizeAdjust(const nsACString& aValue, ErrorResult& aRv); 194 195 FontFaceLoadStatus Status(); 196 void Load(ErrorResult& aRv); 197 198 void Destroy(); 199 200 FontFaceImpl(FontFace* aOwner, FontFaceSetImpl* aFontFaceSet); 201 202 void InitializeSourceURL(const nsACString& aURL); 203 void InitializeSourceBuffer(uint8_t* aBuffer, uint32_t aLength); 204 205 /** 206 * Sets all of the descriptor values in mDescriptors using values passed 207 * to the JS constructor. 208 * Returns true on success, false if parsing any descriptor failed. 209 */ 210 bool SetDescriptors(const nsACString& aFamily, 211 const FontFaceDescriptors& aDescriptors); 212 213 StyleLockedFontFaceRule* GetData() const { 214 AssertIsOnOwningThread(); 215 return HasRule() ? mRule : mDescriptors; 216 } 217 218 private: 219 ~FontFaceImpl(); 220 221 // Helper function for Load. 222 void DoLoad(); 223 void UpdateOwnerPromise(); 224 225 // Helper function for the descriptor setter methods. 226 // Returns true if the descriptor was modified, false if descriptor is 227 // unchanged (which may not be an error: check aRv for actual failure). 228 bool SetDescriptor(nsCSSFontDesc aFontDesc, const nsACString& aValue, 229 ErrorResult& aRv); 230 231 /** 232 * Called when a descriptor has been modified, so font-face sets can 233 * be told to refresh. 234 */ 235 void DescriptorUpdated(); 236 237 /** 238 * Sets the current loading status. 239 */ 240 void SetStatus(FontFaceLoadStatus aStatus); 241 242 void GetDesc(nsCSSFontDesc aDescID, nsACString& aResult) const; 243 244 /** 245 * Returns and takes ownership of the buffer storing the font data. 246 */ 247 void TakeBuffer(uint8_t*& aBuffer, uint32_t& aLength); 248 249 FontFace* MOZ_NON_OWNING_REF mOwner; 250 251 // The @font-face rule this FontFace object is reflecting, if it is a 252 // rule backed FontFace. 253 RefPtr<StyleLockedFontFaceRule> mRule; 254 255 // The FontFace object's user font entry. This is initially null, but is set 256 // during FontFaceSet::UpdateRules and when a FontFace is explicitly loaded. 257 RefPtr<Entry> mUserFontEntry; 258 259 // The current load status of the font represented by this FontFace. 260 // Note that we can't just reflect the value of the gfxUserFontEntry's 261 // status, since the spec sometimes requires us to go through the event 262 // loop before updating the status, rather than doing it immediately. 263 FontFaceLoadStatus mStatus; 264 265 // Represents where a FontFace's data is coming from. 266 enum SourceType { 267 eSourceType_FontFaceRule = 1, 268 eSourceType_URLs, 269 eSourceType_Buffer 270 }; 271 272 // Where the font data for this FontFace is coming from. 273 SourceType mSourceType; 274 275 // If the FontFace was constructed with an ArrayBuffer(View), this is a 276 // copy of the data from it. 277 RefPtr<FontFaceBufferSource> mBufferSource; 278 279 // The values corresponding to the font face descriptors, if we are not 280 // a rule backed FontFace object. For rule backed objects, we use 281 // the descriptors stored in mRule. 282 // FIXME This should hold a unique ptr to just the descriptors inside, 283 // so that we don't need to create a rule for it and don't need to 284 // assign a fake line number and column number. See bug 1450904. 285 RefPtr<StyleLockedFontFaceRule> mDescriptors; 286 287 // The value of the unicode-range descriptor as a gfxCharacterMap. Valid 288 // only when mUnicodeRangeDirty is false. 289 RefPtr<gfxCharacterMap> mUnicodeRange; 290 291 // The primary FontFaceSet this FontFace is associated with, 292 // regardless of whether it is currently "in" the set. 293 RefPtr<FontFaceSetImpl> mFontFaceSet; 294 295 // Other FontFaceSets (apart from mFontFaceSet) that this FontFace 296 // appears in. 297 nsTArray<RefPtr<FontFaceSetImpl>> mOtherFontFaceSets; 298 299 // Whether mUnicodeRange needs to be rebuilt before being returned from 300 // GetUnicodeRangeAsCharacterMap. 301 bool mUnicodeRangeDirty = true; 302 303 // Whether this FontFace appears in mFontFaceSet. 304 bool mInFontFaceSet = false; 305 306 // Whether we're artificially keeping mOwner alive while we load. 307 bool mKeepingOwnerAlive = false; 308 }; 309 310 } // namespace mozilla::dom 311 312 #endif // !defined(mozilla_dom_FontFaceImpl_h)