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/. */
6 #ifndef GFX_FONT_INFO_LOADER_H
7 #define GFX_FONT_INFO_LOADER_H
10 #include "nsIObserver.h"
12 #include "nsIThread.h"
14 #include "gfxFontEntry.h"
15 #include "mozilla/Atomics.h"
16 #include "mozilla/TimeStamp.h"
17 #include "nsISupports.h"
19 // data retrieved for a given face
23 nsCString mPostscriptName
;
24 RefPtr
<gfxCharacterMap
> mCharacterMap
;
25 uint32_t mUVSOffset
= 0;
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.
37 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FontInfoData
)
39 FontInfoData(bool aLoadOtherNames
, bool aLoadFaceNames
, bool aLoadCmaps
)
41 mLoadOtherNames(aLoadOtherNames
),
42 mLoadFaceNames(aLoadFaceNames
),
43 mLoadCmaps(aLoadCmaps
) {
44 MOZ_COUNT_CTOR(FontInfoData
);
48 // Protected destructor, to discourage deletion outside of Release():
49 MOZ_COUNTED_DTOR_VIRTUAL(FontInfoData
)
54 // loads font data for all fonts of a given family
55 // (called on async thread)
56 virtual void LoadFontFamilyData(const nsACString
& aFamilyName
) = 0;
58 // -- methods overriden by platform-specific versions --
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
) {
68 aUVSOffset
= faceData
.mUVSOffset
;
69 RefPtr
<gfxCharacterMap
> cmap
= faceData
.mCharacterMap
;
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
)) {
81 aFullName
= faceData
.mFullName
;
82 aPostscriptName
= faceData
.mPostscriptName
;
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();
91 nsTArray
<nsCString
> mFontFamiliesToLoad
;
93 // currently non-issue but beware,
94 // this is also set during cleanup after finishing
95 mozilla::Atomic
<bool> mCanceled
;
97 // time spent on the loader thread
98 mozilla::TimeDuration mLoadTime
;
108 FontCounts mLoadStats
;
110 bool mLoadOtherNames
;
114 // face name ==> per-face data
115 nsTHashMap
<nsCStringHashKey
, FontFaceData
> mFontFaceData
;
117 // canonical family name ==> array of localized family names
118 nsTHashMap
<nsCStringHashKey
, CopyableTArray
<nsCString
> > mOtherFamilyNames
;
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.
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
129 class gfxFontInfoLoader
{
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
145 gfxFontInfoLoader() : mState(stateInitial
) {
146 MOZ_COUNT_CTOR(gfxFontInfoLoader
);
149 virtual ~gfxFontInfoLoader();
151 // start timer with an initial delay
152 void StartLoader(uint32_t aDelay
);
154 // Finalize - async load complete, transfer data (on idle)
155 virtual void FinalizeLoader(FontInfoData
* aFontInfo
);
157 // cancel the timer and cleanup
161 friend class FinalizeLoaderRunnable
;
163 class ShutdownObserver
: public nsIObserver
{
168 explicit ShutdownObserver(gfxFontInfoLoader
* aLoader
) : mLoader(aLoader
) {}
171 virtual ~ShutdownObserver() = default;
173 gfxFontInfoLoader
* mLoader
;
176 // CreateFontInfo - create platform-specific object used
177 // to load system-wide font info
178 virtual already_AddRefed
<FontInfoData
> CreateFontInfoData() {
182 // Init - initialization before async loader thread runs
183 virtual void InitLoader() = 0;
185 // LoadFontInfo - transfer font info data within a time limit, return
187 virtual bool LoadFontInfo() = 0;
189 // Cleanup - finish and cleanup after done, including possible reflows
190 virtual void CleanupLoader() { mFontInfo
= nullptr; }
192 static void DelayedStartCallback(nsITimer
* aTimer
, void* aThis
) {
193 gfxFontInfoLoader
* loader
= static_cast<gfxFontInfoLoader
*>(aThis
);
194 loader
->StartLoader(0);
197 void LoadFontInfoTimerFire();
199 void AddShutdownObserver();
200 void RemoveShutdownObserver();
202 nsCOMPtr
<nsITimer
> mTimer
;
203 nsCOMPtr
<nsIObserver
> mObserver
;
204 nsCOMPtr
<nsIThread
> mFontLoaderThread
;
207 // after async font loader completes, data is stored here
208 RefPtr
<FontInfoData
> mFontInfo
;
210 // time spent on the loader thread
211 mozilla::TimeDuration mLoadTime
;
214 #endif /* GFX_FONT_INFO_LOADER_H */