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