gfxFontInfoLoader.h 7.7 KB

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