gfx/thebes/gfxFontInfoLoader.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial