diff options
Diffstat (limited to 'gfx/thebes/gfxFontInfoLoader.h')
-rw-r--r-- | gfx/thebes/gfxFontInfoLoader.h | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/gfx/thebes/gfxFontInfoLoader.h b/gfx/thebes/gfxFontInfoLoader.h new file mode 100644 index 0000000000..230cdb25b8 --- /dev/null +++ b/gfx/thebes/gfxFontInfoLoader.h @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * 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 "nsString.h" +#include "gfxFontEntry.h" +#include "mozilla/Atomics.h" +#include "mozilla/TimeStamp.h" +#include "nsISupports.h" + +// data retrieved for a given face + +struct FontFaceData { + nsCString mFullName; + nsCString mPostscriptName; + RefPtr<gfxCharacterMap> mCharacterMap; + uint32_t mUVSOffset = 0; +}; + +// 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(): + MOZ_COUNTED_DTOR_VIRTUAL(FontInfoData) + + public: + virtual void Load(); + + // loads font data for all fonts of a given family + // (called on async thread) + virtual void LoadFontFamilyData(const nsACString& 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 nsACString& aFontName, + uint32_t& aUVSOffset) { + FontFaceData faceData; + if (!mFontFaceData.Get(aFontName, &faceData) || !faceData.mCharacterMap) { + return nullptr; + } + + aUVSOffset = faceData.mUVSOffset; + RefPtr<gfxCharacterMap> cmap = faceData.mCharacterMap; + return cmap.forget(); + } + + // fetches fullname/postscript names from cached font data + virtual void GetFaceNames(const nsACString& aFontName, nsACString& aFullName, + nsACString& aPostscriptName) { + FontFaceData faceData; + if (!mFontFaceData.Get(aFontName, &faceData)) { + return; + } + + aFullName = faceData.mFullName; + aPostscriptName = faceData.mPostscriptName; + } + + // fetches localized family name data from cached font data + const nsTArray<nsCString>* GetOtherFamilyNames( + const nsACString& aFamilyName) { + return mOtherFamilyNames.Lookup(aFamilyName).DataPtrOrNull(); + } + + nsTArray<nsCString> 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 + nsTHashMap<nsCStringHashKey, FontFaceData> mFontFaceData; + + // canonical family name ==> array of localized family names + nsTHashMap<nsCStringHashKey, CopyableTArray<nsCString> > 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 the main +// thread's idle queue in short slices + +class gfxFontInfoLoader { + public: + // state transitions: + // initial ---StartLoader with delay---> timer on delay + // initial ---StartLoader without delay---> timer off + // timer on delay ---LoaderTimerFire---> timer off + // timer on delay ---CancelLoader---> timer off + // timer off ---StartLoader with delay---> timer on delay + // timer off ---StartLoader without delay---> timer off + typedef enum { + stateInitial, + stateTimerOnDelay, + stateAsyncLoad, + stateTimerOff + } TimerState; + + gfxFontInfoLoader() : mState(stateInitial) { + MOZ_COUNT_CTOR(gfxFontInfoLoader); + } + + virtual ~gfxFontInfoLoader(); + + // start timer with an initial delay + void StartLoader(uint32_t aDelay); + + // Finalize - async load complete, transfer data (on idle) + virtual void FinalizeLoader(FontInfoData* aFontInfo); + + // cancel the timer and cleanup + void CancelLoader(); + + protected: + friend class FinalizeLoaderRunnable; + + class ShutdownObserver : public nsIObserver { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + explicit ShutdownObserver(gfxFontInfoLoader* aLoader) : mLoader(aLoader) {} + + protected: + virtual ~ShutdownObserver() = default; + + 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; } + + static void DelayedStartCallback(nsITimer* aTimer, void* aThis) { + gfxFontInfoLoader* loader = static_cast<gfxFontInfoLoader*>(aThis); + loader->StartLoader(0); + } + + void LoadFontInfoTimerFire(); + + void AddShutdownObserver(); + void RemoveShutdownObserver(); + + nsCOMPtr<nsITimer> mTimer; + nsCOMPtr<nsIObserver> mObserver; + nsCOMPtr<nsIThread> mFontLoaderThread; + 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 */ |