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/. */
6 #ifndef GFX_FONT_INFO_LOADER_H
7 #define GFX_FONT_INFO_LOADER_H
11 #include "nsIObserver.h"
13 #include "nsIThread.h"
14 #include "nsRefPtrHashtable.h"
17 #include "nsIRunnable.h"
18 #include "mozilla/TimeStamp.h"
19 #include "nsISupportsImpl.h"
21 // data retrieved for a given face
24 FontFaceData() : mUVSOffset(0), mSymbolFont(false) {}
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
;
35 nsString mPostscriptName
;
36 nsRefPtr
<gfxCharacterMap
> mCharacterMap
;
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.
50 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FontInfoData
)
52 FontInfoData(bool aLoadOtherNames
,
55 mLoadOtherNames(aLoadOtherNames
),
56 mLoadFaceNames(aLoadFaceNames
),
57 mLoadCmaps(aLoadCmaps
)
59 MOZ_COUNT_CTOR(FontInfoData
);
63 // Protected destructor, to discourage deletion outside of Release():
64 virtual ~FontInfoData() {
65 MOZ_COUNT_DTOR(FontInfoData
);
71 // loads font data for all fonts of a given family
72 // (called on async thread)
73 virtual void LoadFontFamilyData(const nsAString
& aFamilyName
) = 0;
75 // -- methods overriden by platform-specific versions --
77 // fetches cmap data for a particular font from cached font data
78 virtual already_AddRefed
<gfxCharacterMap
>
79 GetCMAP(const nsAString
& aFontName
,
83 FontFaceData faceData
;
84 if (!mFontFaceData
.Get(aFontName
, &faceData
) ||
85 !faceData
.mCharacterMap
) {
89 aUVSOffset
= faceData
.mUVSOffset
;
90 aSymbolFont
= faceData
.mSymbolFont
;
91 nsRefPtr
<gfxCharacterMap
> cmap
= faceData
.mCharacterMap
;
95 // fetches fullname/postscript names from cached font data
96 virtual void GetFaceNames(const nsAString
& aFontName
,
98 nsAString
& aPostscriptName
)
100 FontFaceData faceData
;
101 if (!mFontFaceData
.Get(aFontName
, &faceData
)) {
105 aFullName
= faceData
.mFullName
;
106 aPostscriptName
= faceData
.mPostscriptName
;
109 // fetches localized family name data from cached font data
110 virtual bool GetOtherFamilyNames(const nsAString
& aFamilyName
,
111 nsTArray
<nsString
>& aOtherFamilyNames
)
113 return mOtherFamilyNames
.Get(aFamilyName
, &aOtherFamilyNames
);
116 nsTArray
<nsString
> mFontFamiliesToLoad
;
118 // time spent on the loader thread
119 mozilla::TimeDuration mLoadTime
;
129 FontCounts mLoadStats
;
131 bool mLoadOtherNames
;
135 // face name ==> per-face data
136 nsDataHashtable
<nsStringHashKey
, FontFaceData
> mFontFaceData
;
138 // canonical family name ==> array of localized family names
139 nsDataHashtable
<nsStringHashKey
, nsTArray
<nsString
> > mOtherFamilyNames
;
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.
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
150 class gfxFontInfoLoader
{
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
165 stateTimerOnInterval
,
169 gfxFontInfoLoader() :
170 mInterval(0), mState(stateInitial
)
172 MOZ_COUNT_CTOR(gfxFontInfoLoader
);
175 virtual ~gfxFontInfoLoader();
177 // start timer with an initial delay, then call Run method at regular intervals
178 void StartLoader(uint32_t aDelay
, uint32_t aInterval
);
180 // Finalize - async load complete, transfer data (on intervals if necessary)
181 virtual void FinalizeLoader(FontInfoData
*aFontInfo
);
183 // cancel the timer and cleanup
186 uint32_t GetInterval() { return mInterval
; }
189 class ShutdownObserver
: public nsIObserver
195 explicit ShutdownObserver(gfxFontInfoLoader
*aLoader
)
200 virtual ~ShutdownObserver()
203 gfxFontInfoLoader
*mLoader
;
206 // CreateFontInfo - create platform-specific object used
207 // to load system-wide font info
208 virtual already_AddRefed
<FontInfoData
> CreateFontInfoData() {
212 // Init - initialization before async loader thread runs
213 virtual void InitLoader() = 0;
215 // LoadFontInfo - transfer font info data within a time limit, return
217 virtual bool LoadFontInfo() = 0;
219 // Cleanup - finish and cleanup after done, including possible reflows
220 virtual void CleanupLoader() {
224 // Timer interval callbacks
225 static void LoadFontInfoCallback(nsITimer
*aTimer
, void *aThis
) {
226 gfxFontInfoLoader
*loader
= static_cast<gfxFontInfoLoader
*>(aThis
);
227 loader
->LoadFontInfoTimerFire();
230 static void DelayedStartCallback(nsITimer
*aTimer
, void *aThis
) {
231 gfxFontInfoLoader
*loader
= static_cast<gfxFontInfoLoader
*>(aThis
);
232 loader
->StartLoader(0, loader
->GetInterval());
235 void LoadFontInfoTimerFire();
237 void AddShutdownObserver();
238 void RemoveShutdownObserver();
240 nsCOMPtr
<nsITimer
> mTimer
;
241 nsCOMPtr
<nsIObserver
> mObserver
;
242 nsCOMPtr
<nsIThread
> mFontLoaderThread
;
246 // after async font loader completes, data is stored here
247 nsRefPtr
<FontInfoData
> mFontInfo
;
249 // time spent on the loader thread
250 mozilla::TimeDuration mLoadTime
;
253 #endif /* GFX_FONT_INFO_LOADER_H */