gfxFontInfoLoader.h (6423B)
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 GFX_FONT_INFO_LOADER_H 7 #define GFX_FONT_INFO_LOADER_H 8 9 #include "nsCOMPtr.h" 10 #include "nsIObserver.h" 11 #include "nsITimer.h" 12 #include "nsIThread.h" 13 #include "nsString.h" 14 #include "gfxFontEntry.h" 15 #include "mozilla/Atomics.h" 16 #include "mozilla/TimeStamp.h" 17 #include "nsISupports.h" 18 19 // data retrieved for a given face 20 21 struct FontFaceData { 22 nsCString mFullName; 23 nsCString mPostscriptName; 24 RefPtr<gfxCharacterMap> mCharacterMap; 25 uint32_t mUVSOffset = 0; 26 }; 27 28 // base class used to contain cached system-wide font info. 29 // methods in this class are called on off-main threads so 30 // all methods use only static methods or other thread-safe 31 // font data access API's. specifically, no use is made of 32 // gfxPlatformFontList, gfxFontFamily, gfxFamily or any 33 // harfbuzz API methods within FontInfoData subclasses. 34 35 class FontInfoData { 36 public: 37 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FontInfoData) 38 39 FontInfoData(bool aLoadOtherNames, bool aLoadFaceNames, bool aLoadCmaps) 40 : mCanceled(false), 41 mLoadOtherNames(aLoadOtherNames), 42 mLoadFaceNames(aLoadFaceNames), 43 mLoadCmaps(aLoadCmaps) { 44 MOZ_COUNT_CTOR(FontInfoData); 45 } 46 47 protected: 48 // Protected destructor, to discourage deletion outside of Release(): 49 MOZ_COUNTED_DTOR_VIRTUAL(FontInfoData) 50 51 public: 52 virtual void Load(); 53 54 // loads font data for all fonts of a given family 55 // (called on async thread) 56 virtual void LoadFontFamilyData(const nsACString& aFamilyName) = 0; 57 58 // -- methods overriden by platform-specific versions -- 59 60 // fetches cmap data for a particular font from cached font data 61 virtual already_AddRefed<gfxCharacterMap> GetCMAP(const nsACString& aFontName, 62 uint32_t& aUVSOffset) { 63 FontFaceData faceData; 64 if (!mFontFaceData.Get(aFontName, &faceData) || !faceData.mCharacterMap) { 65 return nullptr; 66 } 67 68 aUVSOffset = faceData.mUVSOffset; 69 RefPtr<gfxCharacterMap> cmap = faceData.mCharacterMap; 70 return cmap.forget(); 71 } 72 73 // fetches fullname/postscript names from cached font data 74 virtual void GetFaceNames(const nsACString& aFontName, nsACString& aFullName, 75 nsACString& aPostscriptName) { 76 FontFaceData faceData; 77 if (!mFontFaceData.Get(aFontName, &faceData)) { 78 return; 79 } 80 81 aFullName = faceData.mFullName; 82 aPostscriptName = faceData.mPostscriptName; 83 } 84 85 // fetches localized family name data from cached font data 86 const nsTArray<nsCString>* GetOtherFamilyNames( 87 const nsACString& aFamilyName) { 88 return mOtherFamilyNames.Lookup(aFamilyName).DataPtrOrNull(); 89 } 90 91 nsTArray<nsCString> mFontFamiliesToLoad; 92 93 // currently non-issue but beware, 94 // this is also set during cleanup after finishing 95 mozilla::Atomic<bool> mCanceled; 96 97 // time spent on the loader thread 98 mozilla::TimeDuration mLoadTime; 99 100 struct FontCounts { 101 uint32_t families; 102 uint32_t fonts; 103 uint32_t cmaps; 104 uint32_t facenames; 105 uint32_t othernames; 106 }; 107 108 FontCounts mLoadStats; 109 110 bool mLoadOtherNames; 111 bool mLoadFaceNames; 112 bool mLoadCmaps; 113 114 // face name ==> per-face data 115 nsTHashMap<nsCStringHashKey, FontFaceData> mFontFaceData; 116 117 // canonical family name ==> array of localized family names 118 nsTHashMap<nsCStringHashKey, CopyableTArray<nsCString> > mOtherFamilyNames; 119 }; 120 121 // gfxFontInfoLoader - helper class for loading font info on async thread 122 // For large, "all fonts on system" data, data needed on a given platform 123 // (e.g. localized names, face names, cmaps) are loaded async. 124 125 // helper class for loading in font info on a separate async thread 126 // once async thread completes, completion process is run on the main 127 // thread's idle queue in short slices 128 129 class gfxFontInfoLoader { 130 public: 131 // state transitions: 132 // initial ---StartLoader with delay---> timer on delay 133 // initial ---StartLoader without delay---> timer off 134 // timer on delay ---LoaderTimerFire---> timer off 135 // timer on delay ---CancelLoader---> timer off 136 // timer off ---StartLoader with delay---> timer on delay 137 // timer off ---StartLoader without delay---> timer off 138 typedef enum { 139 stateInitial, 140 stateTimerOnDelay, 141 stateAsyncLoad, 142 stateTimerOff 143 } TimerState; 144 145 gfxFontInfoLoader() : mState(stateInitial) { 146 MOZ_COUNT_CTOR(gfxFontInfoLoader); 147 } 148 149 virtual ~gfxFontInfoLoader(); 150 151 // start timer with an initial delay 152 void StartLoader(uint32_t aDelay); 153 154 // Finalize - async load complete, transfer data (on idle) 155 virtual void FinalizeLoader(FontInfoData* aFontInfo); 156 157 // cancel the timer and cleanup 158 void CancelLoader(); 159 160 protected: 161 friend class FinalizeLoaderRunnable; 162 163 class ShutdownObserver : public nsIObserver { 164 public: 165 NS_DECL_ISUPPORTS 166 NS_DECL_NSIOBSERVER 167 168 explicit ShutdownObserver(gfxFontInfoLoader* aLoader) : mLoader(aLoader) {} 169 170 protected: 171 virtual ~ShutdownObserver() = default; 172 173 gfxFontInfoLoader* mLoader; 174 }; 175 176 // CreateFontInfo - create platform-specific object used 177 // to load system-wide font info 178 virtual already_AddRefed<FontInfoData> CreateFontInfoData() { 179 return nullptr; 180 } 181 182 // Init - initialization before async loader thread runs 183 virtual void InitLoader() = 0; 184 185 // LoadFontInfo - transfer font info data within a time limit, return 186 // true when done 187 virtual bool LoadFontInfo() = 0; 188 189 // Cleanup - finish and cleanup after done, including possible reflows 190 virtual void CleanupLoader() { mFontInfo = nullptr; } 191 192 static void DelayedStartCallback(nsITimer* aTimer, void* aThis) { 193 gfxFontInfoLoader* loader = static_cast<gfxFontInfoLoader*>(aThis); 194 loader->StartLoader(0); 195 } 196 197 void LoadFontInfoTimerFire(); 198 199 void AddShutdownObserver(); 200 void RemoveShutdownObserver(); 201 202 nsCOMPtr<nsITimer> mTimer; 203 nsCOMPtr<nsIObserver> mObserver; 204 nsCOMPtr<nsIThread> mFontLoaderThread; 205 TimerState mState; 206 207 // after async font loader completes, data is stored here 208 RefPtr<FontInfoData> mFontInfo; 209 210 // time spent on the loader thread 211 mozilla::TimeDuration mLoadTime; 212 }; 213 214 #endif /* GFX_FONT_INFO_LOADER_H */