tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gfxPlatformFontList.h (43603B)


      1 /* -*- Mode: C++; tab-width: 20; 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 GFXPLATFORMFONTLIST_H_
      7 #define GFXPLATFORMFONTLIST_H_
      8 
      9 #include "nsClassHashtable.h"
     10 #include "nsTHashMap.h"
     11 #include "nsTHashSet.h"
     12 #include "nsRefPtrHashtable.h"
     13 #include "nsTHashtable.h"
     14 
     15 #include "gfxFontUtils.h"
     16 #include "gfxFontInfoLoader.h"
     17 #include "gfxFont.h"
     18 #include "gfxFontConstants.h"
     19 #include "gfxPlatform.h"
     20 #include "SharedFontList.h"
     21 
     22 #include "base/process.h"
     23 #include "nsIMemoryReporter.h"
     24 #include "mozilla/EnumeratedArray.h"
     25 #include "mozilla/FontPropertyTypes.h"
     26 #include "mozilla/MemoryReporting.h"
     27 #include "mozilla/RangedArray.h"
     28 #include "mozilla/RecursiveMutex.h"
     29 #include "mozilla/ipc/SharedMemoryHandle.h"
     30 #include "nsLanguageAtomService.h"
     31 
     32 namespace mozilla {
     33 namespace fontlist {
     34 struct AliasData;
     35 }
     36 }  // namespace mozilla
     37 class FontVisibilityProvider;
     38 
     39 class CharMapHashKey : public PLDHashEntryHdr {
     40 public:
     41  typedef gfxCharacterMap* KeyType;
     42  typedef const gfxCharacterMap* KeyTypePointer;
     43 
     44  explicit CharMapHashKey(const gfxCharacterMap* aCharMap)
     45      : mCharMap(const_cast<gfxCharacterMap*>(aCharMap)) {
     46    MOZ_COUNT_CTOR(CharMapHashKey);
     47  }
     48  CharMapHashKey(const CharMapHashKey& toCopy) : mCharMap(toCopy.mCharMap) {
     49    MOZ_COUNT_CTOR(CharMapHashKey);
     50  }
     51  MOZ_COUNTED_DTOR(CharMapHashKey)
     52 
     53  gfxCharacterMap* GetKey() const { return mCharMap.get(); }
     54 
     55  bool KeyEquals(const gfxCharacterMap* aCharMap) const {
     56    MOZ_ASSERT(!aCharMap->mBuildOnTheFly && !mCharMap->mBuildOnTheFly,
     57               "custom cmap used in shared cmap hashtable");
     58    // cmaps built on the fly never match
     59    if (aCharMap->mHash != mCharMap->mHash) {
     60      return false;
     61    }
     62    return mCharMap->Equals(aCharMap);
     63  }
     64 
     65  static const gfxCharacterMap* KeyToPointer(gfxCharacterMap* aCharMap) {
     66    return aCharMap;
     67  }
     68  static PLDHashNumber HashKey(const gfxCharacterMap* aCharMap) {
     69    return aCharMap->mHash;
     70  }
     71 
     72  enum { ALLOW_MEMMOVE = true };
     73 
     74 protected:
     75  friend class gfxPlatformFontList;
     76 
     77  // gfxCharacterMap::Release() will notify us when the refcount of a
     78  // charmap drops to 1; at that point, we'll lock the cache, check if
     79  // the charmap is owned by the cache and this is still the only ref,
     80  // and if so, delete it.
     81  RefPtr<gfxCharacterMap> mCharMap;
     82 };
     83 
     84 /**
     85 * A helper class used to create a SharedBitSet instance in a FontList's shared
     86 * memory, while ensuring that we avoid bloating memory by avoiding creating
     87 * duplicate instances.
     88 */
     89 class ShmemCharMapHashEntry final : public PLDHashEntryHdr {
     90 public:
     91  typedef const gfxSparseBitSet* KeyType;
     92  typedef const gfxSparseBitSet* KeyTypePointer;
     93 
     94  /**
     95   * Creation from a gfxSparseBitSet creates not only the ShmemCharMapHashEntry
     96   * itself, but also a SharedBitSet in shared memory.
     97   * Only the parent process creates and manages these entries.
     98   */
     99  explicit ShmemCharMapHashEntry(const gfxSparseBitSet* aCharMap);
    100 
    101  ShmemCharMapHashEntry(ShmemCharMapHashEntry&&) = default;
    102  ShmemCharMapHashEntry& operator=(ShmemCharMapHashEntry&&) = default;
    103 
    104  /**
    105   * Return a shared-memory Pointer that refers to the wrapped SharedBitSet.
    106   * This can be passed to content processes to give them access to the same
    107   * SharedBitSet as the parent stored.
    108   */
    109  mozilla::fontlist::Pointer GetCharMap() const { return mCharMap; }
    110 
    111  bool KeyEquals(KeyType aCharMap) const {
    112    // mHash is a 32-bit Adler checksum of the bitset; if it doesn't match we
    113    // can immediately reject it as non-matching, but if it is equal we still
    114    // need to do a full equality check below.
    115    if (mHash != aCharMap->GetChecksum()) {
    116      return false;
    117    }
    118 
    119    return mCharMap.ToPtr<const SharedBitSet>(mList)->Equals(aCharMap);
    120  }
    121 
    122  static KeyTypePointer KeyToPointer(KeyType aCharMap) { return aCharMap; }
    123  static PLDHashNumber HashKey(KeyType aCharMap) {
    124    return aCharMap->GetChecksum();
    125  }
    126 
    127  enum { ALLOW_MEMMOVE = false };  // because of the Pointer member
    128 
    129 private:
    130  // charMaps are stored in the shared memory that FontList objects point to,
    131  // and are never deleted until the FontList (all referencing font lists,
    132  // actually) have gone away.
    133  mozilla::fontlist::FontList* mList;
    134  mozilla::fontlist::Pointer mCharMap;
    135  uint32_t mHash;
    136 };
    137 
    138 // gfxPlatformFontList is an abstract class for the global font list on the
    139 // system; concrete subclasses for each platform implement the actual interface
    140 // to the system fonts. This class exists because we cannot rely on the platform
    141 // font-finding APIs to behave in sensible/similar ways, particularly with rich,
    142 // complex OpenType families, so we do our own font family/style management here
    143 // instead.
    144 
    145 // Much of this is based on the old gfxQuartzFontCache, but adapted for use on
    146 // all platforms.
    147 
    148 struct FontListSizes {
    149  uint32_t mFontListSize;  // size of the font list and dependent objects
    150                           // (font family and face names, etc), but NOT
    151                           // including the font table cache and the cmaps
    152  uint32_t
    153      mFontTableCacheSize;  // memory used for the gfxFontEntry table caches
    154  uint32_t mCharMapsSize;   // memory used for cmap coverage info
    155  uint32_t mLoaderSize;     // memory used for (platform-specific) loader
    156  uint32_t mSharedSize;     // shared-memory use (reported by parent only)
    157 };
    158 
    159 class gfxUserFontSet;
    160 class LoadCmapsRunnable;
    161 
    162 class gfxPlatformFontList : public gfxFontInfoLoader {
    163  friend class InitOtherFamilyNamesRunnable;
    164 
    165 public:
    166  typedef mozilla::StretchRange StretchRange;
    167  typedef mozilla::SlantStyleRange SlantStyleRange;
    168  typedef mozilla::WeightRange WeightRange;
    169  typedef mozilla::intl::Script Script;
    170 
    171  using AutoLock = mozilla::RecursiveMutexAutoLock;
    172  using AutoUnlock = mozilla::RecursiveMutexAutoUnlock;
    173 
    174  // Class used to hold cached copies of the font-name prefs, so that they can
    175  // be accessed from non-main-thread callers who are not allowed to touch the
    176  // Preferences service.
    177  class FontPrefs final {
    178   public:
    179    using HashMap = nsTHashMap<nsCStringHashKey, nsCString>;
    180 
    181    FontPrefs();
    182    ~FontPrefs() = default;
    183 
    184    FontPrefs(const FontPrefs& aOther) = delete;
    185    FontPrefs& operator=(const FontPrefs& aOther) = delete;
    186 
    187    // Lookup the font.name.<foo> or font.name-list.<foo> pref for a given
    188    // generic+langgroup pair.
    189    bool LookupName(const nsACString& aPref, nsACString& aValue) const;
    190    bool LookupNameList(const nsACString& aPref, nsACString& aValue) const;
    191 
    192    // Does the font.name-list.emoji pref have a user-set value?
    193    bool EmojiHasUserValue() const { return mEmojiHasUserValue; }
    194 
    195    // Expose iterators over all the defined prefs of each type.
    196    HashMap::ConstIterator NameIter() const { return mFontName.ConstIter(); }
    197    HashMap::ConstIterator NameListIter() const {
    198      return mFontNameList.ConstIter();
    199    }
    200 
    201    const nsTArray<eFontPrefLang>& CJKPrefLangs() const {
    202      return mCJKPrefLangs;
    203    }
    204 
    205   private:
    206    static constexpr char kNamePrefix[] = "font.name.";
    207    static constexpr char kNameListPrefix[] = "font.name-list.";
    208 
    209    void Init();
    210 
    211    HashMap mFontName;
    212    HashMap mFontNameList;
    213    nsTArray<eFontPrefLang> mCJKPrefLangs;
    214    bool mEmojiHasUserValue = false;
    215  };
    216 
    217  // For font family lists loaded from user preferences (prefs such as
    218  // font.name-list.<generic>.<langGroup>) that map CSS generics to
    219  // platform-specific font families.
    220  typedef nsTArray<FontFamily> PrefFontList;
    221 
    222  // Return the global font-list singleton, or NULL if aMustInitialize is false
    223  // and it has not yet been fully initialized.
    224  static gfxPlatformFontList* PlatformFontList(bool aMustInitialize = true) {
    225    if (!aMustInitialize &&
    226        !(sPlatformFontList && sPlatformFontList->IsInitialized())) {
    227      return nullptr;
    228    }
    229    // If there is a font-list initialization thread, we need to let it run
    230    // to completion before the font list can be used for anything else.
    231    if (sInitFontListThread) {
    232      // If we're currently on the initialization thread, just continue;
    233      // otherwise wait for it to finish.
    234      if (IsInitFontListThread()) {
    235        return sPlatformFontList;
    236      }
    237      PR_JoinThread(sInitFontListThread);
    238      sInitFontListThread = nullptr;
    239      // If font-list initialization failed, the thread will have cleared
    240      // the static sPlatformFontList pointer; we cannot proceed without any
    241      // usable fonts.
    242      if (!sPlatformFontList) {
    243        MOZ_CRASH("Could not initialize gfxPlatformFontList");
    244      }
    245    }
    246    if (!sPlatformFontList->IsInitialized()) {
    247      if (!sPlatformFontList->InitFontList()) {
    248        MOZ_CRASH("Could not initialize gfxPlatformFontList");
    249      }
    250    }
    251    return sPlatformFontList;
    252  }
    253 
    254  FontVisibility GetFontVisibility(nsCString& aFont, bool& aFound);
    255  bool GetMissingFonts(nsTArray<nsCString>& aMissingFonts);
    256  void GetMissingFonts(nsCString& aMissingFonts);
    257 
    258  static bool Initialize(gfxPlatformFontList* aList);
    259 
    260  static void Shutdown() {
    261    // Ensure any font-list initialization thread is finished before we delete
    262    // the platform fontlist singleton, which that thread may try to use.
    263    if (sInitFontListThread && !IsInitFontListThread()) {
    264      PR_JoinThread(sInitFontListThread);
    265      sInitFontListThread = nullptr;
    266    }
    267    delete sPlatformFontList;
    268    sPlatformFontList = nullptr;
    269  }
    270 
    271  bool IsInitialized() const { return mFontlistInitCount; }
    272 
    273  virtual ~gfxPlatformFontList();
    274 
    275  // Initialize font lists; return true on success, false if something fails.
    276  bool InitFontList();
    277 
    278  /**
    279   * Gathers (from a platform's underlying font system) the information needed
    280   * to initialize a fontlist::Family with its Face members.
    281   */
    282  virtual void GetFacesInitDataForFamily(
    283      const mozilla::fontlist::Family* aFamily,
    284      nsTArray<mozilla::fontlist::Face::InitData>& aFaces,
    285      bool aLoadCmaps) const {}
    286 
    287  virtual void GetFontList(nsAtom* aLangGroup, const nsACString& aGenericFamily,
    288                           nsTArray<nsString>& aListOfFonts);
    289 
    290  // Pass false to notify content that the shared font list has been modified
    291  // but not completely invalidated.
    292  void UpdateFontList(bool aFullRebuild = true);
    293 
    294  void ClearLangGroupPrefFonts() {
    295    AutoLock lock(mLock);
    296    ClearLangGroupPrefFontsLocked();
    297  }
    298  virtual void ClearLangGroupPrefFontsLocked() MOZ_REQUIRES(mLock);
    299 
    300  void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily>>& aFamilyArray);
    301 
    302  already_AddRefed<gfxFont> SystemFindFontForChar(
    303      FontVisibilityProvider* aFontVisibilityProvider, uint32_t aCh,
    304      uint32_t aNextCh, Script aRunScript, FontPresentation aPresentation,
    305      const gfxFontStyle* aStyle, FontVisibility* aVisibility);
    306 
    307  // Flags to control optional behaviors in FindAndAddFamilies. The sense
    308  // of the bit flags have been chosen such that the default parameter of
    309  // FindFamiliesFlags(0) in FindFamily will give the most commonly-desired
    310  // behavior, and only a few callsites need to explicitly pass other values.
    311  enum class FindFamiliesFlags {
    312    // If set, "other" (e.g. localized) family names should be loaded
    313    // immediately; if clear, InitOtherFamilyNames is allowed to defer
    314    // loading to avoid blocking.
    315    eForceOtherFamilyNamesLoading = 1 << 0,
    316 
    317    // If set, FindAndAddFamilies should not check for legacy "styled
    318    // family" names to add to the font list. This is used to avoid
    319    // a recursive search when using FindFamily to find a potential base
    320    // family name for a styled variant.
    321    eNoSearchForLegacyFamilyNames = 1 << 1,
    322 
    323    // If set, FindAndAddFamilies will not add a missing entry to
    324    // mOtherNamesMissed
    325    eNoAddToNamesMissedWhenSearching = 1 << 2,
    326 
    327    // If set, the family name was quoted and so must not be treated as a CSS
    328    // generic.
    329    eQuotedFamilyName = 1 << 3,
    330 
    331    // If set, "hidden" font families (like ".SF NS Text" on macOS) are
    332    // searched in addition to standard user-visible families.
    333    eSearchHiddenFamilies = 1 << 4,
    334  };
    335 
    336  // Find family(ies) matching aFamily and append to the aOutput array
    337  // (there may be multiple results in the case of fontconfig aliases, etc).
    338  // Return true if any match was found and appended, false if none.
    339  bool FindAndAddFamilies(FontVisibilityProvider* aFontVisibilityProvider,
    340                          mozilla::StyleGenericFontFamily aGeneric,
    341                          const nsACString& aFamily,
    342                          nsTArray<FamilyAndGeneric>* aOutput,
    343                          FindFamiliesFlags aFlags,
    344                          gfxFontStyle* aStyle = nullptr,
    345                          nsAtom* aLanguage = nullptr,
    346                          gfxFloat aDevToCssSize = 1.0);
    347 
    348  virtual bool FindAndAddFamiliesLocked(
    349      FontVisibilityProvider* aFontVisibilityProvider,
    350      mozilla::StyleGenericFontFamily aGeneric, const nsACString& aFamily,
    351      nsTArray<FamilyAndGeneric>* aOutput, FindFamiliesFlags aFlags,
    352      gfxFontStyle* aStyle = nullptr, nsAtom* aLanguage = nullptr,
    353      gfxFloat aDevToCssSize = 1.0) MOZ_REQUIRES(mLock);
    354 
    355  gfxFontEntry* FindFontForFamily(
    356      FontVisibilityProvider* aFontVisibilityProvider,
    357      const nsACString& aFamily, const gfxFontStyle* aStyle);
    358 
    359  mozilla::fontlist::FontList* SharedFontList() const {
    360    return mSharedFontList.get();
    361  }
    362 
    363  // Create a handle for a single shmem block (identified by index) ready to
    364  // be shared to the given processId.
    365  void ShareFontListShmBlockToProcess(
    366      uint32_t aGeneration, uint32_t aIndex, base::ProcessId aPid,
    367      mozilla::ipc::ReadOnlySharedMemoryHandle* aOut);
    368 
    369  // Populate the array aBlocks with the complete list of shmem handles ready
    370  // to be shared to the given processId.
    371  void ShareFontListToProcess(
    372      nsTArray<mozilla::ipc::ReadOnlySharedMemoryHandle>* aBlocks,
    373      base::ProcessId aPid);
    374 
    375  void ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
    376                     mozilla::ipc::ReadOnlySharedMemoryHandle aHandle);
    377 
    378  mozilla::ipc::ReadOnlySharedMemoryHandle ShareShmBlockToProcess(
    379      uint32_t aIndex, base::ProcessId aPid);
    380 
    381  void SetCharacterMap(uint32_t aGeneration, uint32_t aFamilyIndex, bool aAlias,
    382                       uint32_t aFaceIndex, const gfxSparseBitSet& aMap);
    383 
    384  void SetupFamilyCharMap(uint32_t aGeneration, uint32_t aIndex, bool aAlias);
    385 
    386  // Start the async cmap loading process, if not already under way, from the
    387  // given family index. (For use in any process that needs font lookups.)
    388  void StartCmapLoadingFromFamily(uint32_t aStartIndex);
    389 
    390  // [Parent] Handle request from content process to start cmap loading.
    391  void StartCmapLoading(uint32_t aGeneration, uint32_t aStartIndex);
    392 
    393  void CancelLoadCmapsTask();
    394 
    395  // Populate aFamily with face records, and if aLoadCmaps is true, also load
    396  // their character maps (rather than leaving this to be done lazily).
    397  // Note that even when aFamily->IsInitialized() is true, it can make sense
    398  // to call InitializeFamily again if passing aLoadCmaps=true, in order to
    399  // ensure cmaps are loaded.
    400  [[nodiscard]] bool InitializeFamily(mozilla::fontlist::Family* aFamily,
    401                                      bool aLoadCmaps = false);
    402  void InitializeFamily(uint32_t aGeneration, uint32_t aFamilyIndex,
    403                        bool aLoadCmaps);
    404 
    405  // name lookup table methods
    406 
    407  void AddOtherFamilyNames(gfxFontFamily* aFamilyEntry,
    408                           const nsTArray<nsCString>& aOtherFamilyNames);
    409 
    410  void AddFullname(gfxFontEntry* aFontEntry, const nsCString& aFullname) {
    411    AutoLock lock(mLock);
    412    AddFullnameLocked(aFontEntry, aFullname);
    413  }
    414  void AddFullnameLocked(gfxFontEntry* aFontEntry, const nsCString& aFullname)
    415      MOZ_REQUIRES(mLock);
    416 
    417  void AddPostscriptName(gfxFontEntry* aFontEntry,
    418                         const nsCString& aPostscriptName) {
    419    AutoLock lock(mLock);
    420    AddPostscriptNameLocked(aFontEntry, aPostscriptName);
    421  }
    422  void AddPostscriptNameLocked(gfxFontEntry* aFontEntry,
    423                               const nsCString& aPostscriptName)
    424      MOZ_REQUIRES(mLock);
    425 
    426  bool NeedFullnamePostscriptNames() { return mExtraNames != nullptr; }
    427 
    428  /**
    429   * Read PSName and FullName of the given face, for src:local lookup,
    430   * returning true if actually implemented and succeeded.
    431   */
    432  virtual bool ReadFaceNames(const mozilla::fontlist::Family* aFamily,
    433                             const mozilla::fontlist::Face* aFace,
    434                             nsCString& aPSName, nsCString& aFullName) {
    435    return false;
    436  }
    437 
    438  // initialize localized family names
    439  bool InitOtherFamilyNames(bool aDeferOtherFamilyNamesLoading);
    440  bool InitOtherFamilyNames(uint32_t aGeneration, bool aDefer);
    441 
    442  // pure virtual functions, to be provided by concrete subclasses
    443 
    444  // get the system default font family
    445  FontFamily GetDefaultFont(FontVisibilityProvider* aFontVisibilityProvider,
    446                            const gfxFontStyle* aStyle);
    447  FontFamily GetDefaultFontLocked(
    448      FontVisibilityProvider* aFontVisibilityProvider,
    449      const gfxFontStyle* aStyle) MOZ_REQUIRES(mLock);
    450 
    451  // get the "ultimate" default font, for use if the font list is otherwise
    452  // unusable (e.g. in the middle of being updated)
    453  gfxFontEntry* GetDefaultFontEntry() {
    454    AutoLock lock(mLock);
    455    return mDefaultFontEntry.get();
    456  }
    457 
    458  /**
    459   * Look up a font by name on the host platform.
    460   *
    461   * Note that the style attributes (weight, stretch, style) are NOT used in
    462   * selecting the platform font, which is looked up by name only; these are
    463   * values to be recorded in the new font entry.
    464   */
    465  virtual gfxFontEntry* LookupLocalFont(
    466      FontVisibilityProvider* aFontVisibilityProvider,
    467      const nsACString& aFontName, WeightRange aWeightForEntry,
    468      StretchRange aStretchForEntry, SlantStyleRange aStyleForEntry) = 0;
    469 
    470  /**
    471   * Create a new platform font from downloaded data (@font-face).
    472   *
    473   * Note that the style attributes (weight, stretch, style) are NOT related
    474   * (necessarily) to any values within the font resource itself; these are
    475   * values to be recorded in the new font entry and used for face selection,
    476   * in place of whatever inherent style attributes the resource may have.
    477   *
    478   * This method takes ownership of the data block passed in as aFontData,
    479   * and must ensure it is free()'d when no longer required.
    480   */
    481  virtual gfxFontEntry* MakePlatformFont(const nsACString& aFontName,
    482                                         WeightRange aWeightForEntry,
    483                                         StretchRange aStretchForEntry,
    484                                         SlantStyleRange aStyleForEntry,
    485                                         const uint8_t* aFontData,
    486                                         uint32_t aLength) = 0;
    487 
    488  // get the standard family name on the platform for a given font name
    489  // (platforms may override, eg Mac)
    490  virtual bool GetStandardFamilyName(const nsCString& aFontName,
    491                                     nsACString& aFamilyName);
    492 
    493  // Get the localized family name for a given font family.
    494  bool GetLocalizedFamilyName(const FontFamily& aFamily,
    495                              nsACString& aFamilyName);
    496 
    497  // get the default font name which is available on the system from
    498  // font.name-list.*.  if there are no available fonts in the pref,
    499  // returns an empty FamilyAndGeneric record.
    500  FamilyAndGeneric GetDefaultFontFamily(const nsACString& aLangGroup,
    501                                        const nsACString& aGenericFamily);
    502 
    503  virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
    504                                      FontListSizes* aSizes) const;
    505  virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
    506                                      FontListSizes* aSizes) const;
    507 
    508  mozilla::fontlist::Pointer GetShmemCharMap(const gfxSparseBitSet* aCmap) {
    509    AutoLock lock(mLock);
    510    return GetShmemCharMapLocked(aCmap);
    511  }
    512  mozilla::fontlist::Pointer GetShmemCharMapLocked(const gfxSparseBitSet* aCmap)
    513      MOZ_REQUIRES(mLock);
    514 
    515  // Search for existing cmap that matches the input; return the input if no
    516  // match is found.
    517  already_AddRefed<gfxCharacterMap> FindCharMap(gfxCharacterMap* aCmap);
    518 
    519  // Remove the cmap from the shared cmap set if it holds the only remaining
    520  // reference to the object.
    521  void MaybeRemoveCmap(gfxCharacterMap* aCharMap);
    522 
    523  // Keep track of userfont sets to notify when global fontlist changes occur.
    524  void AddUserFontSet(gfxUserFontSet* aUserFontSet) {
    525    AutoLock lock(mLock);
    526    mUserFontSetList.Insert(aUserFontSet);
    527  }
    528 
    529  void RemoveUserFontSet(gfxUserFontSet* aUserFontSet) {
    530    AutoLock lock(mLock);
    531    mUserFontSetList.Remove(aUserFontSet);
    532  }
    533 
    534  static const gfxFontEntry::ScriptRange sComplexScriptRanges[];
    535 
    536  void GetFontlistInitInfo(uint32_t& aNumInits, uint32_t& aLoaderState) {
    537    aNumInits = mFontlistInitCount;
    538    aLoaderState = (uint32_t)mState;
    539  }
    540 
    541  virtual void AddGenericFonts(FontVisibilityProvider* aFontVisibilityProvider,
    542                               mozilla::StyleGenericFontFamily aGenericType,
    543                               nsAtom* aLanguage,
    544                               nsTArray<FamilyAndGeneric>& aFamilyList);
    545 
    546  /**
    547   * Given a Face from the shared font list, return a gfxFontEntry usable
    548   * by the current process. This returns a cached entry if available,
    549   * otherwise it calls the (platform-specific) CreateFontEntry method to
    550   * make one, and adds it to the cache.
    551   */
    552  gfxFontEntry* GetOrCreateFontEntry(mozilla::fontlist::Face* aFace,
    553                                     const mozilla::fontlist::Family* aFamily) {
    554    AutoLock lock(mLock);
    555    return GetOrCreateFontEntryLocked(aFace, aFamily);
    556  }
    557  gfxFontEntry* GetOrCreateFontEntryLocked(
    558      mozilla::fontlist::Face* aFace, const mozilla::fontlist::Family* aFamily)
    559      MOZ_REQUIRES(mLock);
    560 
    561  const FontPrefs* GetFontPrefs() const MOZ_REQUIRES(mLock) {
    562    return mFontPrefs.get();
    563  }
    564 
    565  bool EmojiPrefHasUserValue() const {
    566    AutoLock lock(mLock);
    567    return mFontPrefs->EmojiHasUserValue();
    568  }
    569 
    570  PrefFontList* GetPrefFontsLangGroup(
    571      FontVisibilityProvider* aFontVisibilityProvider,
    572      mozilla::StyleGenericFontFamily aGenericType, eFontPrefLang aPrefLang) {
    573    AutoLock lock(mLock);
    574    return GetPrefFontsLangGroupLocked(aFontVisibilityProvider, aGenericType,
    575                                       aPrefLang);
    576  }
    577  PrefFontList* GetPrefFontsLangGroupLocked(
    578      FontVisibilityProvider* aFontVisibilityProvider,
    579      mozilla::StyleGenericFontFamily aGenericType, eFontPrefLang aPrefLang)
    580      MOZ_REQUIRES(mLock);
    581 
    582  // in some situations, need to make decisions about ambiguous characters, may
    583  // need to look at multiple pref langs
    584  void GetLangPrefs(eFontPrefLang aPrefLangs[], uint32_t& aLen,
    585                    eFontPrefLang aCharLang, eFontPrefLang aPageLang);
    586 
    587  // convert a lang group to enum constant (i.e. "zh-TW" ==>
    588  // eFontPrefLang_ChineseTW)
    589  static eFontPrefLang GetFontPrefLangFor(const char* aLang);
    590 
    591  // convert a lang group atom to enum constant
    592  static eFontPrefLang GetFontPrefLangFor(nsAtom* aLang);
    593 
    594  // convert an enum constant to a lang group atom
    595  static nsAtom* GetLangGroupForPrefLang(eFontPrefLang aLang);
    596 
    597  // convert a enum constant to lang group string (i.e. eFontPrefLang_ChineseTW
    598  // ==> "zh-TW")
    599  static const char* GetPrefLangName(eFontPrefLang aLang);
    600 
    601  // map a char code to a font language for Preferences
    602  static eFontPrefLang GetFontPrefLangFor(uint32_t aCh);
    603 
    604  // returns true if a pref lang is CJK
    605  static bool IsLangCJK(eFontPrefLang aLang);
    606 
    607  // helper method to add a pref lang to an array, if not already in array
    608  static void AppendPrefLang(eFontPrefLang aPrefLangs[], uint32_t& aLen,
    609                             eFontPrefLang aAddLang);
    610 
    611  // default serif/sans-serif choice based on font.default.xxx prefs
    612  mozilla::StyleGenericFontFamily GetDefaultGeneric(eFontPrefLang aLang);
    613 
    614  // Returns true if the font family whitelist is not empty. In this case we
    615  // ignore the "CSS visibility level"; only the given fonts are present in
    616  // the browser's font list.
    617  bool IsFontFamilyWhitelistActive() const {
    618    return mFontFamilyWhitelistActive;
    619  };
    620 
    621  static void FontWhitelistPrefChanged(const char* aPref, void* aClosure);
    622 
    623  bool AddWithLegacyFamilyName(const nsACString& aLegacyName,
    624                               gfxFontEntry* aFontEntry,
    625                               FontVisibility aVisibility);
    626 
    627  static const char* GetGenericName(
    628      mozilla::StyleGenericFontFamily aGenericType);
    629 
    630  bool SkipFontFallbackForChar(FontVisibility aVisibility, uint32_t aCh) const {
    631    AutoLock lock(mLock);
    632    return mCodepointsWithNoFonts[aVisibility].test(aCh);
    633  }
    634 
    635  // Return whether the given font-family record should be visible to CSS,
    636  // in a context with the given FontVisibility setting.
    637  bool IsVisibleToCSS(const gfxFontFamily& aFamily,
    638                      FontVisibility aVisibility) const;
    639  bool IsVisibleToCSS(const mozilla::fontlist::Family& aFamily,
    640                      FontVisibility aVisibility) const;
    641 
    642  // (Re-)initialize the set of codepoints that we know cannot be rendered.
    643  void InitializeCodepointsWithNoFonts() MOZ_REQUIRES(mLock);
    644 
    645  // If using the shared font list, returns a generation count that is
    646  // incremented if/when the platform list is reinitialized (e.g. because
    647  // fonts are installed/removed while the browser is running), such that
    648  // existing references to shared font family or face objects and character
    649  // maps will no longer be valid.
    650  // (The legacy (non-shared) list just returns 0 here.)
    651  uint32_t GetGeneration() const;
    652 
    653  // Sometimes we need to know if we're on the InitFontList startup thread.
    654  static bool IsInitFontListThread() {
    655    return PR_GetCurrentThread() == sInitFontListThread;
    656  }
    657 
    658  bool IsKnownIconFontFamily(const nsAtom* aFamilyName) const;
    659  void LoadIconFontOverrideList();
    660 
    661  void Lock() MOZ_CAPABILITY_ACQUIRE(mLock) { mLock.Lock(); }
    662  void Unlock() MOZ_CAPABILITY_RELEASE(mLock) { mLock.Unlock(); }
    663 
    664  // This is only public because some external callers want to be able to
    665  // assert about the locked status.
    666  mutable mozilla::RecursiveMutex mLock;
    667 
    668 protected:
    669  virtual nsTArray<std::pair<const char**, uint32_t>>
    670  GetFilteredPlatformFontLists() = 0;
    671 
    672  friend class mozilla::fontlist::FontList;
    673  friend class InitOtherFamilyNamesForStylo;
    674 
    675  template <size_t N>
    676  static bool FamilyInList(const nsACString& aName, const char* (&aList)[N]) {
    677    return FamilyInList(aName, aList, N);
    678  }
    679  static bool FamilyInList(const nsACString& aName, const char* aList[],
    680                           size_t aCount);
    681 
    682  // Check list is correctly sorted (in debug build only; no-op on release).
    683  template <size_t N>
    684  static void CheckFamilyList(const char* (&aList)[N]) {
    685    CheckFamilyList(aList, N);
    686  }
    687  static void CheckFamilyList(const char* aList[], size_t aCount);
    688 
    689  class InitOtherFamilyNamesRunnable : public mozilla::CancelableRunnable {
    690   public:
    691    InitOtherFamilyNamesRunnable()
    692        : CancelableRunnable(
    693              "gfxPlatformFontList::InitOtherFamilyNamesRunnable"),
    694          mIsCanceled(false) {}
    695 
    696    NS_IMETHOD Run() override {
    697      if (mIsCanceled) {
    698        return NS_OK;
    699      }
    700 
    701      gfxPlatformFontList* fontList = gfxPlatformFontList::PlatformFontList();
    702      if (!fontList) {
    703        return NS_OK;
    704      }
    705 
    706      fontList->InitOtherFamilyNamesInternal(true);
    707 
    708      return NS_OK;
    709    }
    710 
    711    nsresult Cancel() override {
    712      mIsCanceled = true;
    713 
    714      return NS_OK;
    715    }
    716 
    717   private:
    718    bool mIsCanceled;
    719  };
    720 
    721  class MemoryReporter final : public nsIMemoryReporter {
    722    ~MemoryReporter() = default;
    723 
    724   public:
    725    NS_DECL_ISUPPORTS
    726    NS_DECL_NSIMEMORYREPORTER
    727  };
    728 
    729  class PrefName final : public nsAutoCString {
    730    void Init(const nsACString& aGeneric, const nsACString& aLangGroup) {
    731      Assign(aGeneric);
    732      if (!aLangGroup.IsEmpty()) {
    733        Append('.');
    734        Append(aLangGroup);
    735      }
    736    }
    737 
    738   public:
    739    PrefName(const nsACString& aGeneric, const nsACString& aLangGroup) {
    740      Init(aGeneric, aLangGroup);
    741    }
    742 
    743    PrefName(const char* aGeneric, const char* aLangGroup) {
    744      Init(nsDependentCString(aGeneric), nsDependentCString(aLangGroup));
    745    }
    746 
    747    PrefName(const char* aGeneric, nsAtom* aLangGroup) {
    748      if (aLangGroup) {
    749        Init(nsDependentCString(aGeneric), nsAtomCString(aLangGroup));
    750      } else {
    751        Init(nsDependentCString(aGeneric), nsAutoCString());
    752      }
    753    }
    754  };
    755 
    756  explicit gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
    757 
    758  static gfxPlatformFontList* sPlatformFontList;
    759 
    760  /**
    761   * Convenience method to return the first matching family (if any) as found
    762   * by FindAndAddFamilies(). The family will be initialized (synchronously)
    763   * if this has not already been done, so the returned pointer, if non-null,
    764   * is ready for use.
    765   */
    766  mozilla::fontlist::Family* FindSharedFamily(
    767      FontVisibilityProvider* aFontVisibilityProvider,
    768      const nsACString& aFamily,
    769      FindFamiliesFlags aFlags = FindFamiliesFlags(0),
    770      gfxFontStyle* aStyle = nullptr, nsAtom* aLanguage = nullptr,
    771      gfxFloat aDevToCssSize = 1.0) MOZ_REQUIRES(mLock);
    772 
    773  gfxFontFamily* FindUnsharedFamily(
    774      FontVisibilityProvider* aFontVisibilityProvider,
    775      const nsACString& aFamily,
    776      FindFamiliesFlags aFlags = FindFamiliesFlags(0),
    777      gfxFontStyle* aStyle = nullptr, nsAtom* aLanguage = nullptr,
    778      gfxFloat aDevToCssSize = 1.0) MOZ_REQUIRES(mLock) {
    779    if (SharedFontList()) {
    780      return nullptr;
    781    }
    782    AutoTArray<FamilyAndGeneric, 1> families;
    783    if (FindAndAddFamiliesLocked(
    784            aFontVisibilityProvider, mozilla::StyleGenericFontFamily::None,
    785            aFamily, &families, aFlags, aStyle, aLanguage, aDevToCssSize)) {
    786      return families[0].mFamily.mUnshared;
    787    }
    788    return nullptr;
    789  }
    790 
    791  FontFamily FindFamily(FontVisibilityProvider* aFontVisibilityProvider,
    792                        const nsACString& aFamily,
    793                        FindFamiliesFlags aFlags = FindFamiliesFlags(0),
    794                        gfxFontStyle* aStyle = nullptr,
    795                        nsAtom* aLanguage = nullptr,
    796                        gfxFloat aDevToCssSize = 1.0) MOZ_REQUIRES(mLock) {
    797    if (SharedFontList()) {
    798      return FontFamily(FindSharedFamily(aFontVisibilityProvider, aFamily,
    799                                         aFlags, aStyle, aLanguage,
    800                                         aDevToCssSize));
    801    }
    802    return FontFamily(FindUnsharedFamily(aFontVisibilityProvider, aFamily,
    803                                         aFlags, aStyle, aLanguage,
    804                                         aDevToCssSize));
    805  }
    806 
    807  // Lookup family name in global family list without substitutions or
    808  // localized family name lookup. Used for common font fallback families.
    809  gfxFontFamily* FindFamilyByCanonicalName(const nsACString& aFamily)
    810      MOZ_REQUIRES(mLock) {
    811    nsAutoCString key;
    812    gfxFontFamily* familyEntry;
    813    GenerateFontListKey(aFamily, key);
    814    if ((familyEntry = mFontFamilies.GetWeak(key))) {
    815      return CheckFamily(familyEntry);
    816    }
    817    return nullptr;
    818  }
    819 
    820  // returns default font for a given character, null otherwise
    821  already_AddRefed<gfxFont> CommonFontFallback(
    822      FontVisibilityProvider* aFontVisibilityProvider, uint32_t aCh,
    823      uint32_t aNextCh, Script aRunScript, FontPresentation aPresentation,
    824      const gfxFontStyle* aMatchStyle, FontFamily& aMatchedFamily)
    825      MOZ_REQUIRES(mLock);
    826 
    827  // Search fonts system-wide for a given character, null if not found.
    828  already_AddRefed<gfxFont> GlobalFontFallback(
    829      FontVisibilityProvider* aFontVisibilityProvider, uint32_t aCh,
    830      uint32_t aNextCh, Script aRunScript, FontPresentation aPresentation,
    831      const gfxFontStyle* aMatchStyle, uint32_t& aCmapCount,
    832      FontFamily& aMatchedFamily) MOZ_REQUIRES(mLock);
    833 
    834  // Platform-specific implementation of global font fallback, if any;
    835  // this may return nullptr in which case the default cmap-based fallback
    836  // will be performed.
    837  virtual gfxFontEntry* PlatformGlobalFontFallback(
    838      FontVisibilityProvider* aFontVisibilityProvider, const uint32_t aCh,
    839      Script aRunScript, const gfxFontStyle* aMatchStyle,
    840      FontFamily& aMatchedFamily) {
    841    return nullptr;
    842  }
    843 
    844  // whether system-based font fallback is used or not
    845  // if system fallback is used, no need to load all cmaps
    846  virtual bool UsesSystemFallback() { return false; }
    847 
    848  void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], uint32_t& aLen,
    849                          eFontPrefLang aCharLang, eFontPrefLang aPageLang)
    850      MOZ_REQUIRES(mLock);
    851 
    852  // verifies that a family contains a non-zero font count
    853  gfxFontFamily* CheckFamily(gfxFontFamily* aFamily) MOZ_REQUIRES(mLock);
    854 
    855  // initialize localized family names
    856  void InitOtherFamilyNamesInternal(bool aDeferOtherFamilyNamesLoading);
    857  void CancelInitOtherFamilyNamesTask();
    858 
    859  void AddToMissedNames(const nsCString& aKey) MOZ_REQUIRES(mLock);
    860 
    861  // search through font families, looking for a given name, initializing
    862  // facename lists along the way. first checks all families with names
    863  // close to face name, then searchs all families if not found.
    864  gfxFontEntry* SearchFamiliesForFaceName(const nsACString& aFaceName)
    865      MOZ_REQUIRES(mLock);
    866 
    867  // helper method for finding fullname/postscript names in facename lists
    868  gfxFontEntry* FindFaceName(const nsACString& aFaceName) MOZ_REQUIRES(mLock);
    869 
    870  // look up a font by name, for cases where platform font list
    871  // maintains explicit mappings of fullname/psname ==> font
    872  virtual gfxFontEntry* LookupInFaceNameLists(const nsACString& aFaceName)
    873      MOZ_REQUIRES(mLock);
    874 
    875  gfxFontEntry* LookupInSharedFaceNameList(
    876      FontVisibilityProvider* aFontVisibilityProvider,
    877      const nsACString& aFaceName, WeightRange aWeightForEntry,
    878      StretchRange aStretchForEntry, SlantStyleRange aStyleForEntry)
    879      MOZ_REQUIRES(mLock);
    880 
    881  // Add an entry for aName to the local names table, but only if it is not
    882  // already present, or aName and aData.mFamilyName look like a better match
    883  // than the existing entry.
    884  void MaybeAddToLocalNameTable(
    885      const nsACString& aName,
    886      const mozilla::fontlist::LocalFaceRec::InitData& aData)
    887      MOZ_REQUIRES(mLock);
    888 
    889  // load the bad underline blocklist from pref.
    890  void LoadBadUnderlineList();
    891 
    892  // This version of the function will not modify aKeyName
    893  void GenerateFontListKey(const nsACString& aKeyName, nsACString& aResult);
    894  // This version of the function WILL modify aKeyName
    895  void GenerateFontListKey(nsACString& aKeyName);
    896 
    897  virtual void GetFontFamilyNames(nsTArray<nsCString>& aFontFamilyNames)
    898      MOZ_REQUIRES(mLock);
    899 
    900  // helper function to map lang to lang group
    901  nsAtom* GetLangGroup(nsAtom* aLanguage);
    902 
    903  // gfxFontInfoLoader overrides, used to load in font cmaps
    904  void InitLoader() MOZ_REQUIRES(mLock) override;
    905  bool LoadFontInfo() override;
    906  void CleanupLoader() override;
    907 
    908  void ForceGlobalReflow(gfxPlatform::GlobalReflowFlags aFlags);
    909 
    910  void ForceGlobalReflowLocked(gfxPlatform::GlobalReflowFlags aFlags)
    911      MOZ_REQUIRES(mLock);
    912 
    913  // read the loader initialization prefs, and start it
    914  void GetPrefsAndStartLoader();
    915 
    916  // If aForgetLocalFaces is true, all gfxFontEntries for src:local fonts must
    917  // be discarded (not potentially reused to satisfy the rebuilt rules),
    918  // because they may no longer be valid.
    919  void RebuildLocalFonts(bool aForgetLocalFaces = false) MOZ_REQUIRES(mLock);
    920 
    921  void ResolveGenericFontNames(FontVisibilityProvider* aFontVisibilityProvider,
    922                               mozilla::StyleGenericFontFamily aGenericType,
    923                               eFontPrefLang aPrefLang,
    924                               PrefFontList* aGenericFamilies)
    925      MOZ_REQUIRES(mLock);
    926 
    927  void ResolveEmojiFontNames(FontVisibilityProvider* aFontVisibilityProvider,
    928                             PrefFontList* aGenericFamilies)
    929      MOZ_REQUIRES(mLock);
    930 
    931  void GetFontFamiliesFromGenericFamilies(
    932      FontVisibilityProvider* aFontVisibilityProvider,
    933      mozilla::StyleGenericFontFamily aGenericType,
    934      nsTArray<nsCString>& aGenericNameFamilies, nsAtom* aLangGroup,
    935      PrefFontList* aFontFamilies) MOZ_REQUIRES(mLock);
    936 
    937  virtual nsresult InitFontListForPlatform() MOZ_REQUIRES(mLock) = 0;
    938  virtual void InitSharedFontListForPlatform() MOZ_REQUIRES(mLock) {}
    939 
    940  virtual gfxFontEntry* CreateFontEntry(
    941      mozilla::fontlist::Face* aFace,
    942      const mozilla::fontlist::Family* aFamily) {
    943    return nullptr;
    944  }
    945 
    946  /**
    947   * Methods to apply the font.system.whitelist anti-fingerprinting pref,
    948   * by filtering the list of installed fonts so that only whitelisted families
    949   * are exposed.
    950   * There are separate implementations of this for the per-process font list
    951   * and for the shared-memory font list.
    952   */
    953  void ApplyWhitelist() MOZ_REQUIRES(mLock);
    954  void ApplyWhitelist(nsTArray<mozilla::fontlist::Family::InitData>& aFamilies);
    955 
    956  // Create a new gfxFontFamily of the appropriate subclass for the platform,
    957  // used when AddWithLegacyFamilyName needs to create a new family.
    958  virtual gfxFontFamily* CreateFontFamily(const nsACString& aName,
    959                                          FontVisibility aVisibility) const = 0;
    960 
    961  /**
    962   * For the post-startup font info loader task.
    963   * Perform platform-specific work to read alternate names (if any) for a
    964   * font family, recording them in mAliasTable. Once alternate names have been
    965   * loaded for all families, the accumulated records are stored in the shared
    966   * font list's mAliases list.
    967   * Some platforms (currently Linux/fontconfig) may load alternate names as
    968   * part of initially populating the font list with family records, in which
    969   * case this method is unused.
    970   */
    971  virtual void ReadFaceNamesForFamily(mozilla::fontlist::Family* aFamily,
    972                                      bool aNeedFullnamePostscriptNames)
    973      MOZ_REQUIRES(mLock) {}
    974 
    975  typedef nsRefPtrHashtable<nsCStringHashKey, gfxFontFamily> FontFamilyTable;
    976  typedef nsRefPtrHashtable<nsCStringHashKey, gfxFontEntry> FontEntryTable;
    977 
    978  // used by memory reporter to accumulate sizes of family names in the table
    979  static size_t SizeOfFontFamilyTableExcludingThis(
    980      const FontFamilyTable& aTable, mozilla::MallocSizeOf aMallocSizeOf);
    981  static size_t SizeOfFontEntryTableExcludingThis(
    982      const FontEntryTable& aTable, mozilla::MallocSizeOf aMallocSizeOf);
    983 
    984  // Platform-specific helper for GetDefaultFont(...).
    985  virtual FontFamily GetDefaultFontForPlatform(
    986      FontVisibilityProvider* aFontVisibilityProvider,
    987      const gfxFontStyle* aStyle, nsAtom* aLanguage = nullptr)
    988      MOZ_REQUIRES(mLock) = 0;
    989 
    990  // canonical family name ==> family entry (unique, one name per family entry)
    991  FontFamilyTable mFontFamilies MOZ_GUARDED_BY(mLock);
    992 
    993  // other family name ==> family entry (not unique, can have multiple names per
    994  // family entry, only names *other* than the canonical names are stored here)
    995  FontFamilyTable mOtherFamilyNames MOZ_GUARDED_BY(mLock);
    996 
    997  // flag set after InitOtherFamilyNames is called upon first name lookup miss
    998  mozilla::Atomic<bool> mOtherFamilyNamesInitialized;
    999 
   1000  // The pending InitOtherFamilyNames() task.
   1001  RefPtr<mozilla::CancelableRunnable> mPendingOtherFamilyNameTask;
   1002 
   1003  // flag set after fullname and Postcript name lists are populated
   1004  mozilla::Atomic<bool> mFaceNameListsInitialized;
   1005 
   1006  struct ExtraNames {
   1007    ExtraNames() = default;
   1008 
   1009    // fullname ==> font entry (unique, one name per font entry)
   1010    FontEntryTable mFullnames{64};
   1011    // Postscript name ==> font entry (unique, one name per font entry)
   1012    FontEntryTable mPostscriptNames{64};
   1013  };
   1014  // The lock is needed to guard access to the actual name tables, but does not
   1015  // need to be held to just test whether mExtraNames is non-null as it is set
   1016  // during initialization before other threads have a chance to see it.
   1017  mozilla::UniquePtr<ExtraNames> mExtraNames MOZ_PT_GUARDED_BY(mLock);
   1018 
   1019  // face names missed when face name loading takes a long time
   1020  mozilla::UniquePtr<nsTHashSet<nsCString>> mFaceNamesMissed
   1021      MOZ_GUARDED_BY(mLock);
   1022 
   1023  // localized family names missed when face name loading takes a long time
   1024  mozilla::UniquePtr<nsTHashSet<nsCString>> mOtherNamesMissed
   1025      MOZ_GUARDED_BY(mLock);
   1026 
   1027  typedef mozilla::RangedArray<mozilla::UniquePtr<PrefFontList>,
   1028                               size_t(mozilla::StyleGenericFontFamily::None),
   1029                               size_t(
   1030                                   mozilla::StyleGenericFontFamily::MozEmoji)>
   1031      PrefFontsForLangGroup;
   1032  mozilla::RangedArray<PrefFontsForLangGroup, eFontPrefLang_First,
   1033                       eFontPrefLang_Count>
   1034      mLangGroupPrefFonts MOZ_GUARDED_BY(mLock);
   1035  mozilla::UniquePtr<PrefFontList> mEmojiPrefFont MOZ_GUARDED_BY(mLock);
   1036 
   1037  // When system-wide font lookup fails for a character, cache it to skip future
   1038  // searches. This is an array of bitsets, one for each FontVisibility level.
   1039  mozilla::EnumeratedArray<FontVisibility, gfxSparseBitSet,
   1040                           size_t(FontVisibility::Count)>
   1041      mCodepointsWithNoFonts MOZ_GUARDED_BY(mLock);
   1042 
   1043  // the family to use for U+FFFD fallback, to avoid expensive search every time
   1044  // on pages with lots of problems
   1045  mozilla::EnumeratedArray<FontVisibility, FontFamily,
   1046                           size_t(FontVisibility::Count)>
   1047      mReplacementCharFallbackFamily MOZ_GUARDED_BY(mLock);
   1048 
   1049  // Sorted array of lowercased family names; use ContainsSorted to test
   1050  nsTArray<nsCString> mBadUnderlineFamilyNames;
   1051 
   1052  // character map data shared across families
   1053  // contains weak ptrs to cmaps shared by font entry objects
   1054  nsTHashtable<CharMapHashKey> mSharedCmaps MOZ_GUARDED_BY(mLock);
   1055 
   1056  nsTHashtable<ShmemCharMapHashEntry> mShmemCharMaps MOZ_GUARDED_BY(mLock);
   1057 
   1058  // data used as part of the font cmap loading process
   1059  nsTArray<RefPtr<gfxFontFamily>> mFontFamiliesToLoad MOZ_GUARDED_BY(mLock);
   1060  uint32_t mStartIndex MOZ_GUARDED_BY(mLock) = 0;
   1061  uint32_t mNumFamilies MOZ_GUARDED_BY(mLock) = 0;
   1062 
   1063  // xxx - info for diagnosing no default font aborts
   1064  // see bugs 636957, 1070983, 1189129
   1065  uint32_t mFontlistInitCount = 0;  // num times InitFontList called
   1066 
   1067  nsTHashSet<gfxUserFontSet*> mUserFontSetList MOZ_GUARDED_BY(mLock);
   1068 
   1069  nsLanguageAtomService* mLangService = nullptr;
   1070 
   1071  nsTArray<mozilla::StyleGenericFontFamily> mDefaultGenericsLangGroup
   1072      MOZ_GUARDED_BY(mLock);
   1073 
   1074  nsTArray<nsCString> mEnabledFontsList;
   1075  nsTHashSet<nsCString> mIconFontsSet;
   1076 
   1077  mozilla::UniquePtr<mozilla::fontlist::FontList> mSharedFontList;
   1078 
   1079  nsClassHashtable<nsCStringHashKey, mozilla::fontlist::AliasData> mAliasTable;
   1080  nsTHashMap<nsCStringHashKey, mozilla::fontlist::LocalFaceRec::InitData>
   1081      mLocalNameTable;
   1082 
   1083  nsRefPtrHashtable<nsPtrHashKey<const mozilla::fontlist::Face>, gfxFontEntry>
   1084      mFontEntries MOZ_GUARDED_BY(mLock);
   1085 
   1086  mozilla::UniquePtr<FontPrefs> mFontPrefs;
   1087 
   1088  RefPtr<gfxFontEntry> mDefaultFontEntry MOZ_GUARDED_BY(mLock);
   1089 
   1090  RefPtr<LoadCmapsRunnable> mLoadCmapsRunnable;
   1091  uint32_t mStartedLoadingCmapsFrom MOZ_GUARDED_BY(mLock) = 0xffffffffu;
   1092 
   1093  bool mFontFamilyWhitelistActive = false;
   1094 
   1095  static PRThread* sInitFontListThread;
   1096 };
   1097 
   1098 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(gfxPlatformFontList::FindFamiliesFlags)
   1099 
   1100 #endif /* GFXPLATFORMFONTLIST_H_ */