Coverage Report

Created: 2018-09-25 14:53

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