123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef GFX_FONT_INFO_LOADER_H
- #define GFX_FONT_INFO_LOADER_H
- #include "nsCOMPtr.h"
- #include "nsIObserver.h"
- #include "nsITimer.h"
- #include "nsIThread.h"
- #include "nsRefPtrHashtable.h"
- #include "nsString.h"
- #include "gfxFont.h"
- #include "nsIRunnable.h"
- #include "mozilla/Atomics.h"
- #include "mozilla/TimeStamp.h"
- #include "nsISupportsImpl.h"
- // data retrieved for a given face
- struct FontFaceData {
- FontFaceData() : mUVSOffset(0), mSymbolFont(false) {}
- FontFaceData(const FontFaceData& aFontFaceData) {
- mFullName = aFontFaceData.mFullName;
- mPostscriptName = aFontFaceData.mPostscriptName;
- mCharacterMap = aFontFaceData.mCharacterMap;
- mUVSOffset = aFontFaceData.mUVSOffset;
- mSymbolFont = aFontFaceData.mSymbolFont;
- }
- nsString mFullName;
- nsString mPostscriptName;
- RefPtr<gfxCharacterMap> mCharacterMap;
- uint32_t mUVSOffset;
- bool mSymbolFont;
- };
- // base class used to contain cached system-wide font info.
- // methods in this class are called on off-main threads so
- // all methods use only static methods or other thread-safe
- // font data access API's. specifically, no use is made of
- // gfxPlatformFontList, gfxFontFamily, gfxFamily or any
- // harfbuzz API methods within FontInfoData subclasses.
- class FontInfoData {
- public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FontInfoData)
- FontInfoData(bool aLoadOtherNames,
- bool aLoadFaceNames,
- bool aLoadCmaps) :
- mCanceled(false),
- mLoadOtherNames(aLoadOtherNames),
- mLoadFaceNames(aLoadFaceNames),
- mLoadCmaps(aLoadCmaps)
- {
- MOZ_COUNT_CTOR(FontInfoData);
- }
- protected:
- // Protected destructor, to discourage deletion outside of Release():
- virtual ~FontInfoData() {
- MOZ_COUNT_DTOR(FontInfoData);
- }
- public:
- virtual void Load();
- // loads font data for all fonts of a given family
- // (called on async thread)
- virtual void LoadFontFamilyData(const nsAString& aFamilyName) = 0;
- // -- methods overriden by platform-specific versions --
- // fetches cmap data for a particular font from cached font data
- virtual already_AddRefed<gfxCharacterMap>
- GetCMAP(const nsAString& aFontName,
- uint32_t& aUVSOffset,
- bool& aSymbolFont)
- {
- FontFaceData faceData;
- if (!mFontFaceData.Get(aFontName, &faceData) ||
- !faceData.mCharacterMap) {
- return nullptr;
- }
- aUVSOffset = faceData.mUVSOffset;
- aSymbolFont = faceData.mSymbolFont;
- RefPtr<gfxCharacterMap> cmap = faceData.mCharacterMap;
- return cmap.forget();
- }
- // fetches fullname/postscript names from cached font data
- virtual void GetFaceNames(const nsAString& aFontName,
- nsAString& aFullName,
- nsAString& aPostscriptName)
- {
- FontFaceData faceData;
- if (!mFontFaceData.Get(aFontName, &faceData)) {
- return;
- }
- aFullName = faceData.mFullName;
- aPostscriptName = faceData.mPostscriptName;
- }
- // fetches localized family name data from cached font data
- virtual bool GetOtherFamilyNames(const nsAString& aFamilyName,
- nsTArray<nsString>& aOtherFamilyNames)
- {
- return mOtherFamilyNames.Get(aFamilyName, &aOtherFamilyNames);
- }
- nsTArray<nsString> mFontFamiliesToLoad;
- // currently non-issue but beware,
- // this is also set during cleanup after finishing
- mozilla::Atomic<bool> mCanceled;
- // time spent on the loader thread
- mozilla::TimeDuration mLoadTime;
- struct FontCounts {
- uint32_t families;
- uint32_t fonts;
- uint32_t cmaps;
- uint32_t facenames;
- uint32_t othernames;
- };
- FontCounts mLoadStats;
- bool mLoadOtherNames;
- bool mLoadFaceNames;
- bool mLoadCmaps;
- // face name ==> per-face data
- nsDataHashtable<nsStringHashKey, FontFaceData> mFontFaceData;
- // canonical family name ==> array of localized family names
- nsDataHashtable<nsStringHashKey, nsTArray<nsString> > mOtherFamilyNames;
- };
- // gfxFontInfoLoader - helper class for loading font info on async thread
- // For large, "all fonts on system" data, data needed on a given platform
- // (e.g. localized names, face names, cmaps) are loaded async.
- // helper class for loading in font info on a separate async thread
- // once async thread completes, completion process is run on regular
- // intervals to prevent tying up the main thread
- class gfxFontInfoLoader {
- public:
- // state transitions:
- // initial ---StartLoader with delay---> timer on delay
- // initial ---StartLoader without delay---> timer on interval
- // timer on delay ---LoaderTimerFire---> timer on interval
- // timer on delay ---CancelLoader---> timer off
- // timer on interval ---CancelLoader---> timer off
- // timer off ---StartLoader with delay---> timer on delay
- // timer off ---StartLoader without delay---> timer on interval
- typedef enum {
- stateInitial,
- stateTimerOnDelay,
- stateAsyncLoad,
- stateTimerOnInterval,
- stateTimerOff
- } TimerState;
- gfxFontInfoLoader() :
- mInterval(0), mState(stateInitial)
- {
- MOZ_COUNT_CTOR(gfxFontInfoLoader);
- }
- virtual ~gfxFontInfoLoader();
- // start timer with an initial delay, then call Run method at regular intervals
- void StartLoader(uint32_t aDelay, uint32_t aInterval);
- // Finalize - async load complete, transfer data (on intervals if necessary)
- virtual void FinalizeLoader(FontInfoData *aFontInfo);
- // cancel the timer and cleanup
- void CancelLoader();
- uint32_t GetInterval() { return mInterval; }
- protected:
- class ShutdownObserver : public nsIObserver
- {
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
- explicit ShutdownObserver(gfxFontInfoLoader *aLoader)
- : mLoader(aLoader)
- { }
- protected:
- virtual ~ShutdownObserver()
- { }
- gfxFontInfoLoader *mLoader;
- };
- // CreateFontInfo - create platform-specific object used
- // to load system-wide font info
- virtual already_AddRefed<FontInfoData> CreateFontInfoData() {
- return nullptr;
- }
- // Init - initialization before async loader thread runs
- virtual void InitLoader() = 0;
- // LoadFontInfo - transfer font info data within a time limit, return
- // true when done
- virtual bool LoadFontInfo() = 0;
- // Cleanup - finish and cleanup after done, including possible reflows
- virtual void CleanupLoader() {
- mFontInfo = nullptr;
- }
- // Timer interval callbacks
- static void LoadFontInfoCallback(nsITimer *aTimer, void *aThis) {
- gfxFontInfoLoader *loader = static_cast<gfxFontInfoLoader*>(aThis);
- loader->LoadFontInfoTimerFire();
- }
- static void DelayedStartCallback(nsITimer *aTimer, void *aThis) {
- gfxFontInfoLoader *loader = static_cast<gfxFontInfoLoader*>(aThis);
- loader->StartLoader(0, loader->GetInterval());
- }
- void LoadFontInfoTimerFire();
- void AddShutdownObserver();
- void RemoveShutdownObserver();
- nsCOMPtr<nsITimer> mTimer;
- nsCOMPtr<nsIObserver> mObserver;
- nsCOMPtr<nsIThread> mFontLoaderThread;
- uint32_t mInterval;
- TimerState mState;
- // after async font loader completes, data is stored here
- RefPtr<FontInfoData> mFontInfo;
- // time spent on the loader thread
- mozilla::TimeDuration mLoadTime;
- };
- #endif /* GFX_FONT_INFO_LOADER_H */
|