Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef GFX_USER_FONT_SET_H |
michael@0 | 7 | #define GFX_USER_FONT_SET_H |
michael@0 | 8 | |
michael@0 | 9 | #include "gfxFont.h" |
michael@0 | 10 | #include "nsPresContext.h" |
michael@0 | 11 | #include "nsRefPtrHashtable.h" |
michael@0 | 12 | #include "nsAutoPtr.h" |
michael@0 | 13 | #include "nsCOMPtr.h" |
michael@0 | 14 | #include "nsIURI.h" |
michael@0 | 15 | #include "nsIPrincipal.h" |
michael@0 | 16 | #include "nsIScriptError.h" |
michael@0 | 17 | #include "nsURIHashKey.h" |
michael@0 | 18 | |
michael@0 | 19 | class nsFontFaceLoader; |
michael@0 | 20 | |
michael@0 | 21 | //#define DEBUG_USERFONT_CACHE |
michael@0 | 22 | |
michael@0 | 23 | // parsed CSS @font-face rule information |
michael@0 | 24 | // lifetime: from when @font-face rule processed until font is loaded |
michael@0 | 25 | struct gfxFontFaceSrc { |
michael@0 | 26 | bool mIsLocal; // url or local |
michael@0 | 27 | |
michael@0 | 28 | // if url, whether to use the origin principal or not |
michael@0 | 29 | bool mUseOriginPrincipal; |
michael@0 | 30 | |
michael@0 | 31 | // format hint flags, union of all possible formats |
michael@0 | 32 | // (e.g. TrueType, EOT, SVG, etc.) |
michael@0 | 33 | // see FLAG_FORMAT_* enum values below |
michael@0 | 34 | uint32_t mFormatFlags; |
michael@0 | 35 | |
michael@0 | 36 | nsString mLocalName; // full font name if local |
michael@0 | 37 | nsCOMPtr<nsIURI> mURI; // uri if url |
michael@0 | 38 | nsCOMPtr<nsIURI> mReferrer; // referrer url if url |
michael@0 | 39 | nsCOMPtr<nsIPrincipal> mOriginPrincipal; // principal if url |
michael@0 | 40 | }; |
michael@0 | 41 | |
michael@0 | 42 | inline bool |
michael@0 | 43 | operator==(const gfxFontFaceSrc& a, const gfxFontFaceSrc& b) |
michael@0 | 44 | { |
michael@0 | 45 | bool equals; |
michael@0 | 46 | return (a.mIsLocal && b.mIsLocal && |
michael@0 | 47 | a.mLocalName == b.mLocalName) || |
michael@0 | 48 | (!a.mIsLocal && !b.mIsLocal && |
michael@0 | 49 | a.mUseOriginPrincipal == b.mUseOriginPrincipal && |
michael@0 | 50 | a.mFormatFlags == b.mFormatFlags && |
michael@0 | 51 | NS_SUCCEEDED(a.mURI->Equals(b.mURI, &equals)) && equals && |
michael@0 | 52 | NS_SUCCEEDED(a.mReferrer->Equals(b.mReferrer, &equals)) && equals && |
michael@0 | 53 | a.mOriginPrincipal->Equals(b.mOriginPrincipal)); |
michael@0 | 54 | } |
michael@0 | 55 | |
michael@0 | 56 | // Subclassed to store platform-specific code cleaned out when font entry is |
michael@0 | 57 | // deleted. |
michael@0 | 58 | // Lifetime: from when platform font is created until it is deactivated. |
michael@0 | 59 | // If the platform does not need to add any platform-specific code/data here, |
michael@0 | 60 | // then the gfxUserFontSet will allocate a base gfxUserFontData and attach |
michael@0 | 61 | // to the entry to track the basic user font info fields here. |
michael@0 | 62 | class gfxUserFontData { |
michael@0 | 63 | public: |
michael@0 | 64 | gfxUserFontData() |
michael@0 | 65 | : mSrcIndex(0), mFormat(0), mMetaOrigLen(0) |
michael@0 | 66 | { } |
michael@0 | 67 | virtual ~gfxUserFontData() { } |
michael@0 | 68 | |
michael@0 | 69 | nsTArray<uint8_t> mMetadata; // woff metadata block (compressed), if any |
michael@0 | 70 | nsCOMPtr<nsIURI> mURI; // URI of the source, if it was url() |
michael@0 | 71 | nsCOMPtr<nsIPrincipal> mPrincipal; // principal for the download, if url() |
michael@0 | 72 | nsString mLocalName; // font name used for the source, if local() |
michael@0 | 73 | nsString mRealName; // original fullname from the font resource |
michael@0 | 74 | uint32_t mSrcIndex; // index in the rule's source list |
michael@0 | 75 | uint32_t mFormat; // format hint for the source used, if any |
michael@0 | 76 | uint32_t mMetaOrigLen; // length needed to decompress metadata |
michael@0 | 77 | bool mPrivate; // whether font belongs to a private window |
michael@0 | 78 | }; |
michael@0 | 79 | |
michael@0 | 80 | // initially contains a set of proxy font entry objects, replaced with |
michael@0 | 81 | // platform/user fonts as downloaded |
michael@0 | 82 | |
michael@0 | 83 | class gfxMixedFontFamily : public gfxFontFamily { |
michael@0 | 84 | public: |
michael@0 | 85 | friend class gfxUserFontSet; |
michael@0 | 86 | |
michael@0 | 87 | gfxMixedFontFamily(const nsAString& aName) |
michael@0 | 88 | : gfxFontFamily(aName) { } |
michael@0 | 89 | |
michael@0 | 90 | virtual ~gfxMixedFontFamily() { } |
michael@0 | 91 | |
michael@0 | 92 | // Add the given font entry to the end of the family's list. |
michael@0 | 93 | // Any earlier occurrence is removed, so this has the effect of "advancing" |
michael@0 | 94 | // the entry to the end of the list. |
michael@0 | 95 | void AddFontEntry(gfxFontEntry *aFontEntry) { |
michael@0 | 96 | // We append to mAvailableFonts -before- searching for and removing |
michael@0 | 97 | // any existing reference to avoid the risk that we'll remove the last |
michael@0 | 98 | // reference to the font entry, and thus delete it. |
michael@0 | 99 | mAvailableFonts.AppendElement(aFontEntry); |
michael@0 | 100 | uint32_t i = mAvailableFonts.Length() - 1; |
michael@0 | 101 | while (i > 0) { |
michael@0 | 102 | if (mAvailableFonts[--i] == aFontEntry) { |
michael@0 | 103 | mAvailableFonts.RemoveElementAt(i); |
michael@0 | 104 | break; |
michael@0 | 105 | } |
michael@0 | 106 | } |
michael@0 | 107 | aFontEntry->mFamilyName = Name(); |
michael@0 | 108 | ResetCharacterMap(); |
michael@0 | 109 | } |
michael@0 | 110 | |
michael@0 | 111 | // Replace aProxyFontEntry in the family's list with aRealFontEntry. |
michael@0 | 112 | void ReplaceFontEntry(gfxFontEntry *aProxyFontEntry, |
michael@0 | 113 | gfxFontEntry *aRealFontEntry) { |
michael@0 | 114 | uint32_t numFonts = mAvailableFonts.Length(); |
michael@0 | 115 | uint32_t i; |
michael@0 | 116 | for (i = 0; i < numFonts; i++) { |
michael@0 | 117 | gfxFontEntry *fe = mAvailableFonts[i]; |
michael@0 | 118 | if (fe == aProxyFontEntry) { |
michael@0 | 119 | // Note that this may delete aProxyFontEntry, if there's no |
michael@0 | 120 | // other reference to it except from its family. |
michael@0 | 121 | mAvailableFonts[i] = aRealFontEntry; |
michael@0 | 122 | aRealFontEntry->mFamilyName = Name(); |
michael@0 | 123 | break; |
michael@0 | 124 | } |
michael@0 | 125 | } |
michael@0 | 126 | NS_ASSERTION(i < numFonts, "font entry not found in family!"); |
michael@0 | 127 | ResetCharacterMap(); |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | // Remove all font entries from the family |
michael@0 | 131 | void DetachFontEntries() { |
michael@0 | 132 | mAvailableFonts.Clear(); |
michael@0 | 133 | } |
michael@0 | 134 | }; |
michael@0 | 135 | |
michael@0 | 136 | class gfxProxyFontEntry; |
michael@0 | 137 | |
michael@0 | 138 | class gfxUserFontSet { |
michael@0 | 139 | |
michael@0 | 140 | public: |
michael@0 | 141 | |
michael@0 | 142 | NS_INLINE_DECL_REFCOUNTING(gfxUserFontSet) |
michael@0 | 143 | |
michael@0 | 144 | gfxUserFontSet(); |
michael@0 | 145 | |
michael@0 | 146 | enum { |
michael@0 | 147 | // no flags ==> no hint set |
michael@0 | 148 | // unknown ==> unknown format hint set |
michael@0 | 149 | FLAG_FORMAT_UNKNOWN = 1, |
michael@0 | 150 | FLAG_FORMAT_OPENTYPE = 1 << 1, |
michael@0 | 151 | FLAG_FORMAT_TRUETYPE = 1 << 2, |
michael@0 | 152 | FLAG_FORMAT_TRUETYPE_AAT = 1 << 3, |
michael@0 | 153 | FLAG_FORMAT_EOT = 1 << 4, |
michael@0 | 154 | FLAG_FORMAT_SVG = 1 << 5, |
michael@0 | 155 | FLAG_FORMAT_WOFF = 1 << 6, |
michael@0 | 156 | |
michael@0 | 157 | // mask of all unused bits, update when adding new formats |
michael@0 | 158 | FLAG_FORMAT_NOT_USED = ~((1 << 7)-1) |
michael@0 | 159 | }; |
michael@0 | 160 | |
michael@0 | 161 | enum LoadStatus { |
michael@0 | 162 | STATUS_LOADING = 0, |
michael@0 | 163 | STATUS_LOADED, |
michael@0 | 164 | STATUS_FORMAT_NOT_SUPPORTED, |
michael@0 | 165 | STATUS_ERROR, |
michael@0 | 166 | STATUS_END_OF_LIST |
michael@0 | 167 | }; |
michael@0 | 168 | |
michael@0 | 169 | |
michael@0 | 170 | // add in a font face |
michael@0 | 171 | // weight - 0 == unknown, [100, 900] otherwise (multiples of 100) |
michael@0 | 172 | // stretch = [NS_FONT_STRETCH_ULTRA_CONDENSED, NS_FONT_STRETCH_ULTRA_EXPANDED] |
michael@0 | 173 | // italic style = constants in gfxFontConstants.h, e.g. NS_FONT_STYLE_NORMAL |
michael@0 | 174 | // TODO: support for unicode ranges not yet implemented |
michael@0 | 175 | gfxFontEntry *AddFontFace(const nsAString& aFamilyName, |
michael@0 | 176 | const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, |
michael@0 | 177 | uint32_t aWeight, |
michael@0 | 178 | int32_t aStretch, |
michael@0 | 179 | uint32_t aItalicStyle, |
michael@0 | 180 | const nsTArray<gfxFontFeature>& aFeatureSettings, |
michael@0 | 181 | const nsString& aLanguageOverride, |
michael@0 | 182 | gfxSparseBitSet *aUnicodeRanges = nullptr); |
michael@0 | 183 | |
michael@0 | 184 | // add in a font face for which we have the gfxFontEntry already |
michael@0 | 185 | void AddFontFace(const nsAString& aFamilyName, gfxFontEntry* aFontEntry); |
michael@0 | 186 | |
michael@0 | 187 | // Whether there is a face with this family name |
michael@0 | 188 | bool HasFamily(const nsAString& aFamilyName) const |
michael@0 | 189 | { |
michael@0 | 190 | return GetFamily(aFamilyName) != nullptr; |
michael@0 | 191 | } |
michael@0 | 192 | |
michael@0 | 193 | gfxFontFamily *GetFamily(const nsAString& aName) const; |
michael@0 | 194 | |
michael@0 | 195 | // Lookup a font entry for a given style, returns null if not loaded. |
michael@0 | 196 | // aFamily must be a family returned by our GetFamily method. |
michael@0 | 197 | gfxFontEntry *FindFontEntry(gfxFontFamily *aFamily, |
michael@0 | 198 | const gfxFontStyle& aFontStyle, |
michael@0 | 199 | bool& aNeedsBold, |
michael@0 | 200 | bool& aWaitForUserFont); |
michael@0 | 201 | |
michael@0 | 202 | // Find a family (possibly one of several!) that owns the given entry. |
michael@0 | 203 | // This may be somewhat expensive, as it enumerates all the fonts in |
michael@0 | 204 | // the set. Currently used only by the Linux (gfxPangoFontGroup) backend, |
michael@0 | 205 | // which does not directly track families in the font group's list. |
michael@0 | 206 | gfxFontFamily *FindFamilyFor(gfxFontEntry *aFontEntry) const; |
michael@0 | 207 | |
michael@0 | 208 | // check whether the given source is allowed to be loaded; |
michael@0 | 209 | // returns the Principal (for use in the key when caching the loaded font), |
michael@0 | 210 | // and whether the load should bypass the cache (force-reload). |
michael@0 | 211 | virtual nsresult CheckFontLoad(const gfxFontFaceSrc *aFontFaceSrc, |
michael@0 | 212 | nsIPrincipal **aPrincipal, |
michael@0 | 213 | bool *aBypassCache) = 0; |
michael@0 | 214 | |
michael@0 | 215 | // initialize the process that loads external font data, which upon |
michael@0 | 216 | // completion will call OnLoadComplete method |
michael@0 | 217 | virtual nsresult StartLoad(gfxMixedFontFamily *aFamily, |
michael@0 | 218 | gfxProxyFontEntry *aProxy, |
michael@0 | 219 | const gfxFontFaceSrc *aFontFaceSrc) = 0; |
michael@0 | 220 | |
michael@0 | 221 | // when download has been completed, pass back data here |
michael@0 | 222 | // aDownloadStatus == NS_OK ==> download succeeded, error otherwise |
michael@0 | 223 | // returns true if platform font creation sucessful (or local() |
michael@0 | 224 | // reference was next in line) |
michael@0 | 225 | // Ownership of aFontData is passed in here; the font set must |
michael@0 | 226 | // ensure that it is eventually deleted with NS_Free(). |
michael@0 | 227 | bool OnLoadComplete(gfxMixedFontFamily *aFamily, |
michael@0 | 228 | gfxProxyFontEntry *aProxy, |
michael@0 | 229 | const uint8_t *aFontData, uint32_t aLength, |
michael@0 | 230 | nsresult aDownloadStatus); |
michael@0 | 231 | |
michael@0 | 232 | // Replace a proxy with a real fontEntry; this is implemented in |
michael@0 | 233 | // nsUserFontSet in order to keep track of the entry corresponding |
michael@0 | 234 | // to each @font-face rule. |
michael@0 | 235 | virtual void ReplaceFontEntry(gfxMixedFontFamily *aFamily, |
michael@0 | 236 | gfxProxyFontEntry *aProxy, |
michael@0 | 237 | gfxFontEntry *aFontEntry) = 0; |
michael@0 | 238 | |
michael@0 | 239 | // generation - each time a face is loaded, generation is |
michael@0 | 240 | // incremented so that the change can be recognized |
michael@0 | 241 | uint64_t GetGeneration() { return mGeneration; } |
michael@0 | 242 | |
michael@0 | 243 | // increment the generation on font load |
michael@0 | 244 | void IncrementGeneration(); |
michael@0 | 245 | |
michael@0 | 246 | // rebuild if local rules have been used |
michael@0 | 247 | void RebuildLocalRules(); |
michael@0 | 248 | |
michael@0 | 249 | virtual nsPresContext *GetPresContext() { return NULL; } |
michael@0 | 250 | |
michael@0 | 251 | class UserFontCache { |
michael@0 | 252 | public: |
michael@0 | 253 | // Record a loaded user-font in the cache. This requires that the |
michael@0 | 254 | // font-entry's userFontData has been set up already, as it relies |
michael@0 | 255 | // on the URI and Principal recorded there. |
michael@0 | 256 | static void CacheFont(gfxFontEntry *aFontEntry); |
michael@0 | 257 | |
michael@0 | 258 | // The given gfxFontEntry is being destroyed, so remove any record that |
michael@0 | 259 | // refers to it. |
michael@0 | 260 | static void ForgetFont(gfxFontEntry *aFontEntry); |
michael@0 | 261 | |
michael@0 | 262 | // Return the gfxFontEntry corresponding to a given URI and principal, |
michael@0 | 263 | // and the features of the given proxy, or nullptr if none is available. |
michael@0 | 264 | // The aPrivate flag is set for requests coming from private windows, |
michael@0 | 265 | // so we can avoid leaking fonts cached in private windows mode out to |
michael@0 | 266 | // normal windows. |
michael@0 | 267 | static gfxFontEntry* GetFont(nsIURI *aSrcURI, |
michael@0 | 268 | nsIPrincipal *aPrincipal, |
michael@0 | 269 | gfxProxyFontEntry *aProxy, |
michael@0 | 270 | bool aPrivate); |
michael@0 | 271 | |
michael@0 | 272 | // Clear everything so that we don't leak URIs and Principals. |
michael@0 | 273 | static void Shutdown(); |
michael@0 | 274 | |
michael@0 | 275 | #ifdef DEBUG_USERFONT_CACHE |
michael@0 | 276 | // dump contents |
michael@0 | 277 | static void Dump(); |
michael@0 | 278 | #endif |
michael@0 | 279 | |
michael@0 | 280 | private: |
michael@0 | 281 | // Helper that we use to observe the empty-cache notification |
michael@0 | 282 | // from nsICacheService. |
michael@0 | 283 | class Flusher : public nsIObserver |
michael@0 | 284 | { |
michael@0 | 285 | public: |
michael@0 | 286 | NS_DECL_ISUPPORTS |
michael@0 | 287 | NS_DECL_NSIOBSERVER |
michael@0 | 288 | Flusher() {} |
michael@0 | 289 | virtual ~Flusher() {} |
michael@0 | 290 | }; |
michael@0 | 291 | |
michael@0 | 292 | // Key used to look up entries in the user-font cache. |
michael@0 | 293 | // Note that key comparison does *not* use the mFontEntry field |
michael@0 | 294 | // as a whole; it only compares specific fields within the entry |
michael@0 | 295 | // (weight/width/style/features) that could affect font selection |
michael@0 | 296 | // or rendering, and that must match between a font-set's proxy |
michael@0 | 297 | // entry and the corresponding "real" font entry. |
michael@0 | 298 | struct Key { |
michael@0 | 299 | nsCOMPtr<nsIURI> mURI; |
michael@0 | 300 | nsCOMPtr<nsIPrincipal> mPrincipal; |
michael@0 | 301 | gfxFontEntry *mFontEntry; |
michael@0 | 302 | bool mPrivate; |
michael@0 | 303 | |
michael@0 | 304 | Key(nsIURI* aURI, nsIPrincipal* aPrincipal, |
michael@0 | 305 | gfxFontEntry* aFontEntry, bool aPrivate) |
michael@0 | 306 | : mURI(aURI), |
michael@0 | 307 | mPrincipal(aPrincipal), |
michael@0 | 308 | mFontEntry(aFontEntry), |
michael@0 | 309 | mPrivate(aPrivate) |
michael@0 | 310 | { } |
michael@0 | 311 | }; |
michael@0 | 312 | |
michael@0 | 313 | class Entry : public PLDHashEntryHdr { |
michael@0 | 314 | public: |
michael@0 | 315 | typedef const Key& KeyType; |
michael@0 | 316 | typedef const Key* KeyTypePointer; |
michael@0 | 317 | |
michael@0 | 318 | Entry(KeyTypePointer aKey) |
michael@0 | 319 | : mURI(aKey->mURI), |
michael@0 | 320 | mPrincipal(aKey->mPrincipal), |
michael@0 | 321 | mFontEntry(aKey->mFontEntry), |
michael@0 | 322 | mPrivate(aKey->mPrivate) |
michael@0 | 323 | { } |
michael@0 | 324 | |
michael@0 | 325 | Entry(const Entry& aOther) |
michael@0 | 326 | : mURI(aOther.mURI), |
michael@0 | 327 | mPrincipal(aOther.mPrincipal), |
michael@0 | 328 | mFontEntry(aOther.mFontEntry), |
michael@0 | 329 | mPrivate(aOther.mPrivate) |
michael@0 | 330 | { } |
michael@0 | 331 | |
michael@0 | 332 | ~Entry() { } |
michael@0 | 333 | |
michael@0 | 334 | bool KeyEquals(const KeyTypePointer aKey) const; |
michael@0 | 335 | |
michael@0 | 336 | static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } |
michael@0 | 337 | |
michael@0 | 338 | static PLDHashNumber HashKey(const KeyTypePointer aKey) { |
michael@0 | 339 | uint32_t principalHash; |
michael@0 | 340 | aKey->mPrincipal->GetHashValue(&principalHash); |
michael@0 | 341 | return mozilla::HashGeneric(principalHash + int(aKey->mPrivate), |
michael@0 | 342 | nsURIHashKey::HashKey(aKey->mURI), |
michael@0 | 343 | HashFeatures(aKey->mFontEntry->mFeatureSettings), |
michael@0 | 344 | mozilla::HashString(aKey->mFontEntry->mFamilyName), |
michael@0 | 345 | ((uint32_t)aKey->mFontEntry->mItalic | |
michael@0 | 346 | (aKey->mFontEntry->mWeight << 1) | |
michael@0 | 347 | (aKey->mFontEntry->mStretch << 10) ) ^ |
michael@0 | 348 | aKey->mFontEntry->mLanguageOverride); |
michael@0 | 349 | } |
michael@0 | 350 | |
michael@0 | 351 | enum { ALLOW_MEMMOVE = false }; |
michael@0 | 352 | |
michael@0 | 353 | gfxFontEntry* GetFontEntry() const { return mFontEntry; } |
michael@0 | 354 | |
michael@0 | 355 | static PLDHashOperator RemoveIfPrivate(Entry* aEntry, void* aUserData); |
michael@0 | 356 | static PLDHashOperator RemoveIfMatches(Entry* aEntry, void* aUserData); |
michael@0 | 357 | static PLDHashOperator DisconnectSVG(Entry* aEntry, void* aUserData); |
michael@0 | 358 | |
michael@0 | 359 | #ifdef DEBUG_USERFONT_CACHE |
michael@0 | 360 | static PLDHashOperator DumpEntry(Entry* aEntry, void* aUserData); |
michael@0 | 361 | #endif |
michael@0 | 362 | |
michael@0 | 363 | private: |
michael@0 | 364 | static uint32_t |
michael@0 | 365 | HashFeatures(const nsTArray<gfxFontFeature>& aFeatures) { |
michael@0 | 366 | return mozilla::HashBytes(aFeatures.Elements(), |
michael@0 | 367 | aFeatures.Length() * sizeof(gfxFontFeature)); |
michael@0 | 368 | } |
michael@0 | 369 | |
michael@0 | 370 | nsCOMPtr<nsIURI> mURI; |
michael@0 | 371 | nsCOMPtr<nsIPrincipal> mPrincipal; |
michael@0 | 372 | |
michael@0 | 373 | // The "real" font entry corresponding to this downloaded font. |
michael@0 | 374 | // The font entry MUST notify the cache when it is destroyed |
michael@0 | 375 | // (by calling Forget()). |
michael@0 | 376 | gfxFontEntry *mFontEntry; |
michael@0 | 377 | |
michael@0 | 378 | // Whether this font was loaded from a private window. |
michael@0 | 379 | bool mPrivate; |
michael@0 | 380 | }; |
michael@0 | 381 | |
michael@0 | 382 | static nsTHashtable<Entry> *sUserFonts; |
michael@0 | 383 | }; |
michael@0 | 384 | |
michael@0 | 385 | protected: |
michael@0 | 386 | // Protected destructor, to discourage deletion outside of Release(): |
michael@0 | 387 | virtual ~gfxUserFontSet(); |
michael@0 | 388 | |
michael@0 | 389 | // Return whether the font set is associated with a private-browsing tab. |
michael@0 | 390 | virtual bool GetPrivateBrowsing() = 0; |
michael@0 | 391 | |
michael@0 | 392 | // for a given proxy font entry, attempt to load the next resource |
michael@0 | 393 | // in the src list |
michael@0 | 394 | LoadStatus LoadNext(gfxMixedFontFamily *aFamily, |
michael@0 | 395 | gfxProxyFontEntry *aProxyEntry); |
michael@0 | 396 | |
michael@0 | 397 | // helper method for creating a platform font |
michael@0 | 398 | // returns font entry if platform font creation successful |
michael@0 | 399 | // Ownership of aFontData is passed in here; the font set must |
michael@0 | 400 | // ensure that it is eventually deleted with NS_Free(). |
michael@0 | 401 | gfxFontEntry* LoadFont(gfxMixedFontFamily *aFamily, |
michael@0 | 402 | gfxProxyFontEntry *aProxy, |
michael@0 | 403 | const uint8_t *aFontData, uint32_t &aLength); |
michael@0 | 404 | |
michael@0 | 405 | // parse data for a data URL |
michael@0 | 406 | virtual nsresult SyncLoadFontData(gfxProxyFontEntry *aFontToLoad, |
michael@0 | 407 | const gfxFontFaceSrc *aFontFaceSrc, |
michael@0 | 408 | uint8_t* &aBuffer, |
michael@0 | 409 | uint32_t &aBufferLength) = 0; |
michael@0 | 410 | |
michael@0 | 411 | // report a problem of some kind (implemented in nsUserFontSet) |
michael@0 | 412 | virtual nsresult LogMessage(gfxMixedFontFamily *aFamily, |
michael@0 | 413 | gfxProxyFontEntry *aProxy, |
michael@0 | 414 | const char *aMessage, |
michael@0 | 415 | uint32_t aFlags = nsIScriptError::errorFlag, |
michael@0 | 416 | nsresult aStatus = NS_OK) = 0; |
michael@0 | 417 | |
michael@0 | 418 | const uint8_t* SanitizeOpenTypeData(gfxMixedFontFamily *aFamily, |
michael@0 | 419 | gfxProxyFontEntry *aProxy, |
michael@0 | 420 | const uint8_t* aData, |
michael@0 | 421 | uint32_t aLength, |
michael@0 | 422 | uint32_t& aSaneLength, |
michael@0 | 423 | bool aIsCompressed); |
michael@0 | 424 | |
michael@0 | 425 | static bool OTSMessage(void *aUserData, const char *format, ...); |
michael@0 | 426 | |
michael@0 | 427 | // helper method for performing the actual userfont set rebuild |
michael@0 | 428 | virtual void DoRebuildUserFontSet() = 0; |
michael@0 | 429 | |
michael@0 | 430 | // font families defined by @font-face rules |
michael@0 | 431 | nsRefPtrHashtable<nsStringHashKey, gfxMixedFontFamily> mFontFamilies; |
michael@0 | 432 | |
michael@0 | 433 | uint64_t mGeneration; |
michael@0 | 434 | |
michael@0 | 435 | // true when local names have been looked up, false otherwise |
michael@0 | 436 | bool mLocalRulesUsed; |
michael@0 | 437 | |
michael@0 | 438 | static PRLogModuleInfo* GetUserFontsLog(); |
michael@0 | 439 | |
michael@0 | 440 | private: |
michael@0 | 441 | static void CopyWOFFMetadata(const uint8_t* aFontData, |
michael@0 | 442 | uint32_t aLength, |
michael@0 | 443 | FallibleTArray<uint8_t>* aMetadata, |
michael@0 | 444 | uint32_t* aMetaOrigLen); |
michael@0 | 445 | }; |
michael@0 | 446 | |
michael@0 | 447 | // acts a placeholder until the real font is downloaded |
michael@0 | 448 | |
michael@0 | 449 | class gfxProxyFontEntry : public gfxFontEntry { |
michael@0 | 450 | friend class gfxUserFontSet; |
michael@0 | 451 | |
michael@0 | 452 | public: |
michael@0 | 453 | gfxProxyFontEntry(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, |
michael@0 | 454 | uint32_t aWeight, |
michael@0 | 455 | int32_t aStretch, |
michael@0 | 456 | uint32_t aItalicStyle, |
michael@0 | 457 | const nsTArray<gfxFontFeature>& aFeatureSettings, |
michael@0 | 458 | uint32_t aLanguageOverride, |
michael@0 | 459 | gfxSparseBitSet *aUnicodeRanges); |
michael@0 | 460 | |
michael@0 | 461 | virtual ~gfxProxyFontEntry(); |
michael@0 | 462 | |
michael@0 | 463 | // Return whether the entry matches the given list of attributes |
michael@0 | 464 | bool Matches(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, |
michael@0 | 465 | uint32_t aWeight, |
michael@0 | 466 | int32_t aStretch, |
michael@0 | 467 | uint32_t aItalicStyle, |
michael@0 | 468 | const nsTArray<gfxFontFeature>& aFeatureSettings, |
michael@0 | 469 | uint32_t aLanguageOverride, |
michael@0 | 470 | gfxSparseBitSet *aUnicodeRanges); |
michael@0 | 471 | |
michael@0 | 472 | virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold); |
michael@0 | 473 | |
michael@0 | 474 | // note that code depends on the ordering of these values! |
michael@0 | 475 | enum LoadingState { |
michael@0 | 476 | NOT_LOADING = 0, // not started to load any font resources yet |
michael@0 | 477 | LOADING_STARTED, // loading has started; hide fallback font |
michael@0 | 478 | LOADING_ALMOST_DONE, // timeout happened but we're nearly done, |
michael@0 | 479 | // so keep hiding fallback font |
michael@0 | 480 | LOADING_SLOWLY, // timeout happened and we're not nearly done, |
michael@0 | 481 | // so use the fallback font |
michael@0 | 482 | LOADING_FAILED // failed to load any source: use fallback |
michael@0 | 483 | }; |
michael@0 | 484 | LoadingState mLoadingState; |
michael@0 | 485 | bool mUnsupportedFormat; |
michael@0 | 486 | |
michael@0 | 487 | nsTArray<gfxFontFaceSrc> mSrcList; |
michael@0 | 488 | uint32_t mSrcIndex; // index of loading src item |
michael@0 | 489 | nsFontFaceLoader *mLoader; // current loader for this entry, if any |
michael@0 | 490 | nsCOMPtr<nsIPrincipal> mPrincipal; |
michael@0 | 491 | }; |
michael@0 | 492 | |
michael@0 | 493 | |
michael@0 | 494 | #endif /* GFX_USER_FONT_SET_H */ |