gfx/thebes/gfxFontInfoLoader.h

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

mercurial