1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/thebes/gfxFontInfoLoader.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,252 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef GFX_FONT_INFO_LOADER_H 1.10 +#define GFX_FONT_INFO_LOADER_H 1.11 + 1.12 +#include "nsAutoPtr.h" 1.13 +#include "nsCOMPtr.h" 1.14 +#include "nsIObserver.h" 1.15 +#include "nsITimer.h" 1.16 +#include "nsIThread.h" 1.17 +#include "nsRefPtrHashtable.h" 1.18 +#include "nsString.h" 1.19 +#include "gfxFont.h" 1.20 +#include "nsIRunnable.h" 1.21 +#include "mozilla/TimeStamp.h" 1.22 +#include "nsISupportsImpl.h" 1.23 + 1.24 +// data retrieved for a given face 1.25 + 1.26 +struct FontFaceData { 1.27 + FontFaceData() : mUVSOffset(0), mSymbolFont(false) {} 1.28 + 1.29 + FontFaceData(const FontFaceData& aFontFaceData) { 1.30 + mFullName = aFontFaceData.mFullName; 1.31 + mPostscriptName = aFontFaceData.mPostscriptName; 1.32 + mCharacterMap = aFontFaceData.mCharacterMap; 1.33 + mUVSOffset = aFontFaceData.mUVSOffset; 1.34 + mSymbolFont = aFontFaceData.mSymbolFont; 1.35 + } 1.36 + 1.37 + nsString mFullName; 1.38 + nsString mPostscriptName; 1.39 + nsRefPtr<gfxCharacterMap> mCharacterMap; 1.40 + uint32_t mUVSOffset; 1.41 + bool mSymbolFont; 1.42 +}; 1.43 + 1.44 +// base class used to contain cached system-wide font info. 1.45 +// methods in this class are called on off-main threads so 1.46 +// all methods use only static methods or other thread-safe 1.47 +// font data access API's. specifically, no use is made of 1.48 +// gfxPlatformFontList, gfxFontFamily, gfxFamily or any 1.49 +// harfbuzz API methods within FontInfoData subclasses. 1.50 + 1.51 +class FontInfoData { 1.52 +public: 1.53 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FontInfoData) 1.54 + 1.55 + FontInfoData(bool aLoadOtherNames, 1.56 + bool aLoadFaceNames, 1.57 + bool aLoadCmaps) : 1.58 + mLoadOtherNames(aLoadOtherNames), 1.59 + mLoadFaceNames(aLoadFaceNames), 1.60 + mLoadCmaps(aLoadCmaps) 1.61 + { 1.62 + MOZ_COUNT_CTOR(FontInfoData); 1.63 + } 1.64 + 1.65 +protected: 1.66 + // Protected destructor, to discourage deletion outside of Release(): 1.67 + virtual ~FontInfoData() { 1.68 + MOZ_COUNT_DTOR(FontInfoData); 1.69 + } 1.70 + 1.71 +public: 1.72 + virtual void Load(); 1.73 + 1.74 + // loads font data for all fonts of a given family 1.75 + // (called on async thread) 1.76 + virtual void LoadFontFamilyData(const nsAString& aFamilyName) = 0; 1.77 + 1.78 + // -- methods overriden by platform-specific versions -- 1.79 + 1.80 + // fetches cmap data for a particular font from cached font data 1.81 + virtual already_AddRefed<gfxCharacterMap> 1.82 + GetCMAP(const nsAString& aFontName, 1.83 + uint32_t& aUVSOffset, 1.84 + bool& aSymbolFont) 1.85 + { 1.86 + FontFaceData faceData; 1.87 + if (!mFontFaceData.Get(aFontName, &faceData) || 1.88 + !faceData.mCharacterMap) { 1.89 + return nullptr; 1.90 + } 1.91 + 1.92 + aUVSOffset = faceData.mUVSOffset; 1.93 + aSymbolFont = faceData.mSymbolFont; 1.94 + nsRefPtr<gfxCharacterMap> cmap = faceData.mCharacterMap; 1.95 + return cmap.forget(); 1.96 + } 1.97 + 1.98 + // fetches fullname/postscript names from cached font data 1.99 + virtual void GetFaceNames(const nsAString& aFontName, 1.100 + nsAString& aFullName, 1.101 + nsAString& aPostscriptName) 1.102 + { 1.103 + FontFaceData faceData; 1.104 + if (!mFontFaceData.Get(aFontName, &faceData)) { 1.105 + return; 1.106 + } 1.107 + 1.108 + aFullName = faceData.mFullName; 1.109 + aPostscriptName = faceData.mPostscriptName; 1.110 + } 1.111 + 1.112 + // fetches localized family name data from cached font data 1.113 + virtual bool GetOtherFamilyNames(const nsAString& aFamilyName, 1.114 + nsTArray<nsString>& aOtherFamilyNames) 1.115 + { 1.116 + return mOtherFamilyNames.Get(aFamilyName, &aOtherFamilyNames); 1.117 + } 1.118 + 1.119 + nsTArray<nsString> mFontFamiliesToLoad; 1.120 + 1.121 + // time spent on the loader thread 1.122 + mozilla::TimeDuration mLoadTime; 1.123 + 1.124 + struct FontCounts { 1.125 + uint32_t families; 1.126 + uint32_t fonts; 1.127 + uint32_t cmaps; 1.128 + uint32_t facenames; 1.129 + uint32_t othernames; 1.130 + }; 1.131 + 1.132 + FontCounts mLoadStats; 1.133 + 1.134 + bool mLoadOtherNames; 1.135 + bool mLoadFaceNames; 1.136 + bool mLoadCmaps; 1.137 + 1.138 + // face name ==> per-face data 1.139 + nsDataHashtable<nsStringHashKey, FontFaceData> mFontFaceData; 1.140 + 1.141 + // canonical family name ==> array of localized family names 1.142 + nsDataHashtable<nsStringHashKey, nsTArray<nsString> > mOtherFamilyNames; 1.143 +}; 1.144 + 1.145 +// gfxFontInfoLoader - helper class for loading font info on async thread 1.146 +// For large, "all fonts on system" data, data needed on a given platform 1.147 +// (e.g. localized names, face names, cmaps) are loaded async. 1.148 + 1.149 +// helper class for loading in font info on a separate async thread 1.150 +// once async thread completes, completion process is run on regular 1.151 +// intervals to prevent tying up the main thread 1.152 + 1.153 +class gfxFontInfoLoader { 1.154 +public: 1.155 + 1.156 + // state transitions: 1.157 + // initial ---StartLoader with delay---> timer on delay 1.158 + // initial ---StartLoader without delay---> timer on interval 1.159 + // timer on delay ---LoaderTimerFire---> timer on interval 1.160 + // timer on delay ---CancelLoader---> timer off 1.161 + // timer on interval ---CancelLoader---> timer off 1.162 + // timer off ---StartLoader with delay---> timer on delay 1.163 + // timer off ---StartLoader without delay---> timer on interval 1.164 + typedef enum { 1.165 + stateInitial, 1.166 + stateTimerOnDelay, 1.167 + stateAsyncLoad, 1.168 + stateTimerOnInterval, 1.169 + stateTimerOff 1.170 + } TimerState; 1.171 + 1.172 + gfxFontInfoLoader() : 1.173 + mInterval(0), mState(stateInitial) 1.174 + { 1.175 + } 1.176 + 1.177 + virtual ~gfxFontInfoLoader(); 1.178 + 1.179 + // start timer with an initial delay, then call Run method at regular intervals 1.180 + void StartLoader(uint32_t aDelay, uint32_t aInterval); 1.181 + 1.182 + // Finalize - async load complete, transfer data (on intervals if necessary) 1.183 + virtual void FinalizeLoader(FontInfoData *aFontInfo); 1.184 + 1.185 + // cancel the timer and cleanup 1.186 + void CancelLoader(); 1.187 + 1.188 + uint32_t GetInterval() { return mInterval; } 1.189 + 1.190 +protected: 1.191 + class ShutdownObserver : public nsIObserver 1.192 + { 1.193 + public: 1.194 + NS_DECL_ISUPPORTS 1.195 + NS_DECL_NSIOBSERVER 1.196 + 1.197 + ShutdownObserver(gfxFontInfoLoader *aLoader) 1.198 + : mLoader(aLoader) 1.199 + { } 1.200 + 1.201 + virtual ~ShutdownObserver() 1.202 + { } 1.203 + 1.204 + protected: 1.205 + gfxFontInfoLoader *mLoader; 1.206 + }; 1.207 + 1.208 + // CreateFontInfo - create platform-specific object used 1.209 + // to load system-wide font info 1.210 + virtual already_AddRefed<FontInfoData> CreateFontInfoData() { 1.211 + return nullptr; 1.212 + } 1.213 + 1.214 + // Init - initialization before async loader thread runs 1.215 + virtual void InitLoader() = 0; 1.216 + 1.217 + // LoadFontInfo - transfer font info data within a time limit, return 1.218 + // true when done 1.219 + virtual bool LoadFontInfo() = 0; 1.220 + 1.221 + // Cleanup - finish and cleanup after done, including possible reflows 1.222 + virtual void CleanupLoader() { 1.223 + mFontInfo = nullptr; 1.224 + } 1.225 + 1.226 + // Timer interval callbacks 1.227 + static void LoadFontInfoCallback(nsITimer *aTimer, void *aThis) { 1.228 + gfxFontInfoLoader *loader = static_cast<gfxFontInfoLoader*>(aThis); 1.229 + loader->LoadFontInfoTimerFire(); 1.230 + } 1.231 + 1.232 + static void DelayedStartCallback(nsITimer *aTimer, void *aThis) { 1.233 + gfxFontInfoLoader *loader = static_cast<gfxFontInfoLoader*>(aThis); 1.234 + loader->StartLoader(0, loader->GetInterval()); 1.235 + } 1.236 + 1.237 + void LoadFontInfoTimerFire(); 1.238 + 1.239 + void AddShutdownObserver(); 1.240 + void RemoveShutdownObserver(); 1.241 + 1.242 + nsCOMPtr<nsITimer> mTimer; 1.243 + nsCOMPtr<nsIObserver> mObserver; 1.244 + nsCOMPtr<nsIThread> mFontLoaderThread; 1.245 + uint32_t mInterval; 1.246 + TimerState mState; 1.247 + 1.248 + // after async font loader completes, data is stored here 1.249 + nsRefPtr<FontInfoData> mFontInfo; 1.250 + 1.251 + // time spent on the loader thread 1.252 + mozilla::TimeDuration mLoadTime; 1.253 +}; 1.254 + 1.255 +#endif /* GFX_FONT_INFO_LOADER_H */