1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/thebes/gfxPlatformFontList.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,351 @@ 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 GFXPLATFORMFONTLIST_H_ 1.10 +#define GFXPLATFORMFONTLIST_H_ 1.11 + 1.12 +#include "nsDataHashtable.h" 1.13 +#include "nsRefPtrHashtable.h" 1.14 +#include "nsTHashtable.h" 1.15 + 1.16 +#include "gfxFontUtils.h" 1.17 +#include "gfxFontInfoLoader.h" 1.18 +#include "gfxFont.h" 1.19 +#include "gfxPlatform.h" 1.20 + 1.21 +#include "nsIMemoryReporter.h" 1.22 +#include "mozilla/Attributes.h" 1.23 +#include "mozilla/MemoryReporting.h" 1.24 + 1.25 +class CharMapHashKey : public PLDHashEntryHdr 1.26 +{ 1.27 +public: 1.28 + typedef gfxCharacterMap* KeyType; 1.29 + typedef const gfxCharacterMap* KeyTypePointer; 1.30 + 1.31 + CharMapHashKey(const gfxCharacterMap *aCharMap) : 1.32 + mCharMap(const_cast<gfxCharacterMap*>(aCharMap)) 1.33 + { 1.34 + MOZ_COUNT_CTOR(CharMapHashKey); 1.35 + } 1.36 + CharMapHashKey(const CharMapHashKey& toCopy) : 1.37 + mCharMap(toCopy.mCharMap) 1.38 + { 1.39 + MOZ_COUNT_CTOR(CharMapHashKey); 1.40 + } 1.41 + ~CharMapHashKey() 1.42 + { 1.43 + MOZ_COUNT_DTOR(CharMapHashKey); 1.44 + } 1.45 + 1.46 + gfxCharacterMap* GetKey() const { return mCharMap; } 1.47 + 1.48 + bool KeyEquals(const gfxCharacterMap *aCharMap) const { 1.49 + NS_ASSERTION(!aCharMap->mBuildOnTheFly && !mCharMap->mBuildOnTheFly, 1.50 + "custom cmap used in shared cmap hashtable"); 1.51 + // cmaps built on the fly never match 1.52 + if (aCharMap->mHash != mCharMap->mHash) 1.53 + { 1.54 + return false; 1.55 + } 1.56 + return mCharMap->Equals(aCharMap); 1.57 + } 1.58 + 1.59 + static const gfxCharacterMap* KeyToPointer(gfxCharacterMap *aCharMap) { 1.60 + return aCharMap; 1.61 + } 1.62 + static PLDHashNumber HashKey(const gfxCharacterMap *aCharMap) { 1.63 + return aCharMap->mHash; 1.64 + } 1.65 + 1.66 + enum { ALLOW_MEMMOVE = true }; 1.67 + 1.68 +protected: 1.69 + gfxCharacterMap *mCharMap; 1.70 +}; 1.71 + 1.72 +// gfxPlatformFontList is an abstract class for the global font list on the system; 1.73 +// concrete subclasses for each platform implement the actual interface to the system fonts. 1.74 +// This class exists because we cannot rely on the platform font-finding APIs to behave 1.75 +// in sensible/similar ways, particularly with rich, complex OpenType families, 1.76 +// so we do our own font family/style management here instead. 1.77 + 1.78 +// Much of this is based on the old gfxQuartzFontCache, but adapted for use on all platforms. 1.79 + 1.80 +struct FontListSizes { 1.81 + uint32_t mFontListSize; // size of the font list and dependent objects 1.82 + // (font family and face names, etc), but NOT 1.83 + // including the font table cache and the cmaps 1.84 + uint32_t mFontTableCacheSize; // memory used for the gfxFontEntry table caches 1.85 + uint32_t mCharMapsSize; // memory used for cmap coverage info 1.86 +}; 1.87 + 1.88 +class gfxUserFontSet; 1.89 + 1.90 +class gfxPlatformFontList : public gfxFontInfoLoader 1.91 +{ 1.92 +public: 1.93 + static gfxPlatformFontList* PlatformFontList() { 1.94 + return sPlatformFontList; 1.95 + } 1.96 + 1.97 + static nsresult Init() { 1.98 + NS_ASSERTION(!sPlatformFontList, "What's this doing here?"); 1.99 + gfxPlatform::GetPlatform()->CreatePlatformFontList(); 1.100 + if (!sPlatformFontList) { 1.101 + return NS_ERROR_OUT_OF_MEMORY; 1.102 + } 1.103 + return NS_OK; 1.104 + } 1.105 + 1.106 + static void Shutdown() { 1.107 + delete sPlatformFontList; 1.108 + sPlatformFontList = nullptr; 1.109 + } 1.110 + 1.111 + virtual ~gfxPlatformFontList(); 1.112 + 1.113 + // initialize font lists 1.114 + virtual nsresult InitFontList(); 1.115 + 1.116 + void GetFontList (nsIAtom *aLangGroup, 1.117 + const nsACString& aGenericFamily, 1.118 + nsTArray<nsString>& aListOfFonts); 1.119 + 1.120 + virtual bool ResolveFontName(const nsAString& aFontName, 1.121 + nsAString& aResolvedFontName); 1.122 + 1.123 + void UpdateFontList(); 1.124 + 1.125 + void ClearPrefFonts() { mPrefFonts.Clear(); } 1.126 + 1.127 + virtual void GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray); 1.128 + 1.129 + virtual gfxFontEntry* 1.130 + SystemFindFontForChar(const uint32_t aCh, 1.131 + int32_t aRunScript, 1.132 + const gfxFontStyle* aStyle); 1.133 + 1.134 + // TODO: make this virtual, for lazily adding to the font list 1.135 + virtual gfxFontFamily* FindFamily(const nsAString& aFamily); 1.136 + 1.137 + gfxFontEntry* FindFontForFamily(const nsAString& aFamily, const gfxFontStyle* aStyle, bool& aNeedsBold); 1.138 + 1.139 + bool GetPrefFontFamilyEntries(eFontPrefLang aLangGroup, nsTArray<nsRefPtr<gfxFontFamily> > *array); 1.140 + void SetPrefFontFamilyEntries(eFontPrefLang aLangGroup, nsTArray<nsRefPtr<gfxFontFamily> >& array); 1.141 + 1.142 + // name lookup table methods 1.143 + 1.144 + void AddOtherFamilyName(gfxFontFamily *aFamilyEntry, nsAString& aOtherFamilyName); 1.145 + 1.146 + void AddFullname(gfxFontEntry *aFontEntry, nsAString& aFullname); 1.147 + 1.148 + void AddPostscriptName(gfxFontEntry *aFontEntry, nsAString& aPostscriptName); 1.149 + 1.150 + bool NeedFullnamePostscriptNames() { return mExtraNames != nullptr; } 1.151 + 1.152 + // pure virtual functions, to be provided by concrete subclasses 1.153 + 1.154 + // get the system default font family 1.155 + virtual gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle) = 0; 1.156 + 1.157 + // look up a font by name on the host platform 1.158 + virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry, 1.159 + const nsAString& aFontName) = 0; 1.160 + 1.161 + // create a new platform font from downloaded data (@font-face) 1.162 + // this method is responsible to ensure aFontData is NS_Free()'d 1.163 + virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry, 1.164 + const uint8_t *aFontData, 1.165 + uint32_t aLength) = 0; 1.166 + 1.167 + // get the standard family name on the platform for a given font name 1.168 + // (platforms may override, eg Mac) 1.169 + virtual bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName); 1.170 + 1.171 + virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, 1.172 + FontListSizes* aSizes) const; 1.173 + virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, 1.174 + FontListSizes* aSizes) const; 1.175 + 1.176 + // search for existing cmap that matches the input 1.177 + // return the input if no match is found 1.178 + gfxCharacterMap* FindCharMap(gfxCharacterMap *aCmap); 1.179 + 1.180 + // add a cmap to the shared cmap set 1.181 + gfxCharacterMap* AddCmap(const gfxCharacterMap *aCharMap); 1.182 + 1.183 + // remove the cmap from the shared cmap set 1.184 + void RemoveCmap(const gfxCharacterMap *aCharMap); 1.185 + 1.186 + // keep track of userfont sets to notify when global fontlist changes occur 1.187 + void AddUserFontSet(gfxUserFontSet *aUserFontSet) { 1.188 + mUserFontSetList.PutEntry(aUserFontSet); 1.189 + } 1.190 + 1.191 + void RemoveUserFontSet(gfxUserFontSet *aUserFontSet) { 1.192 + mUserFontSetList.RemoveEntry(aUserFontSet); 1.193 + } 1.194 + 1.195 + static const gfxFontEntry::ScriptRange sComplexScriptRanges[]; 1.196 + 1.197 +protected: 1.198 + class MemoryReporter MOZ_FINAL : public nsIMemoryReporter 1.199 + { 1.200 + public: 1.201 + NS_DECL_ISUPPORTS 1.202 + NS_DECL_NSIMEMORYREPORTER 1.203 + }; 1.204 + 1.205 + gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true); 1.206 + 1.207 + static gfxPlatformFontList *sPlatformFontList; 1.208 + 1.209 + static PLDHashOperator FindFontForCharProc(nsStringHashKey::KeyType aKey, 1.210 + nsRefPtr<gfxFontFamily>& aFamilyEntry, 1.211 + void* userArg); 1.212 + 1.213 + // returns default font for a given character, null otherwise 1.214 + gfxFontEntry* CommonFontFallback(const uint32_t aCh, 1.215 + int32_t aRunScript, 1.216 + const gfxFontStyle* aMatchStyle, 1.217 + gfxFontFamily** aMatchedFamily); 1.218 + 1.219 + // search fonts system-wide for a given character, null otherwise 1.220 + virtual gfxFontEntry* GlobalFontFallback(const uint32_t aCh, 1.221 + int32_t aRunScript, 1.222 + const gfxFontStyle* aMatchStyle, 1.223 + uint32_t& aCmapCount, 1.224 + gfxFontFamily** aMatchedFamily); 1.225 + 1.226 + // whether system-based font fallback is used or not 1.227 + // if system fallback is used, no need to load all cmaps 1.228 + virtual bool UsesSystemFallback() { return false; } 1.229 + 1.230 + // verifies that a family contains a non-zero font count 1.231 + gfxFontFamily* CheckFamily(gfxFontFamily *aFamily); 1.232 + 1.233 + // initialize localized family names 1.234 + void InitOtherFamilyNames(); 1.235 + 1.236 + static PLDHashOperator 1.237 + InitOtherFamilyNamesProc(nsStringHashKey::KeyType aKey, 1.238 + nsRefPtr<gfxFontFamily>& aFamilyEntry, 1.239 + void* userArg); 1.240 + 1.241 + // search through font families, looking for a given name, initializing 1.242 + // facename lists along the way. first checks all families with names 1.243 + // close to face name, then searchs all families if not found. 1.244 + gfxFontEntry* SearchFamiliesForFaceName(const nsAString& aFaceName); 1.245 + 1.246 + static PLDHashOperator 1.247 + ReadFaceNamesProc(nsStringHashKey::KeyType aKey, 1.248 + nsRefPtr<gfxFontFamily>& aFamilyEntry, 1.249 + void* userArg); 1.250 + 1.251 + // helper method for finding fullname/postscript names in facename lists 1.252 + gfxFontEntry* FindFaceName(const nsAString& aFaceName); 1.253 + 1.254 + // look up a font by name, for cases where platform font list 1.255 + // maintains explicit mappings of fullname/psname ==> font 1.256 + virtual gfxFontEntry* LookupInFaceNameLists(const nsAString& aFontName); 1.257 + 1.258 + static PLDHashOperator LookupMissedFaceNamesProc(nsStringHashKey *aKey, 1.259 + void *aUserArg); 1.260 + 1.261 + static PLDHashOperator LookupMissedOtherNamesProc(nsStringHashKey *aKey, 1.262 + void *aUserArg); 1.263 + 1.264 + // commonly used fonts for which the name table should be loaded at startup 1.265 + virtual void PreloadNamesList(); 1.266 + 1.267 + // load the bad underline blacklist from pref. 1.268 + void LoadBadUnderlineList(); 1.269 + 1.270 + // explicitly set fixed-pitch flag for all faces 1.271 + void SetFixedPitch(const nsAString& aFamilyName); 1.272 + 1.273 + void GenerateFontListKey(const nsAString& aKeyName, nsAString& aResult); 1.274 + 1.275 + static PLDHashOperator 1.276 + HashEnumFuncForFamilies(nsStringHashKey::KeyType aKey, 1.277 + nsRefPtr<gfxFontFamily>& aFamilyEntry, 1.278 + void* aUserArg); 1.279 + 1.280 + virtual void GetFontFamilyNames(nsTArray<nsString>& aFontFamilyNames); 1.281 + 1.282 + // gfxFontInfoLoader overrides, used to load in font cmaps 1.283 + virtual void InitLoader(); 1.284 + virtual bool LoadFontInfo(); 1.285 + virtual void CleanupLoader(); 1.286 + 1.287 + // read the loader initialization prefs, and start it 1.288 + void GetPrefsAndStartLoader(); 1.289 + 1.290 + // for font list changes that affect all documents 1.291 + void ForceGlobalReflow(); 1.292 + 1.293 + // used by memory reporter to accumulate sizes of family names in the hash 1.294 + static size_t 1.295 + SizeOfFamilyNameEntryExcludingThis(const nsAString& aKey, 1.296 + const nsRefPtr<gfxFontFamily>& aFamily, 1.297 + mozilla::MallocSizeOf aMallocSizeOf, 1.298 + void* aUserArg); 1.299 + 1.300 + // canonical family name ==> family entry (unique, one name per family entry) 1.301 + nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> mFontFamilies; 1.302 + 1.303 + // other family name ==> family entry (not unique, can have multiple names per 1.304 + // family entry, only names *other* than the canonical names are stored here) 1.305 + nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> mOtherFamilyNames; 1.306 + 1.307 + // flag set after InitOtherFamilyNames is called upon first name lookup miss 1.308 + bool mOtherFamilyNamesInitialized; 1.309 + 1.310 + // flag set after fullname and Postcript name lists are populated 1.311 + bool mFaceNameListsInitialized; 1.312 + 1.313 + struct ExtraNames { 1.314 + ExtraNames() : mFullnames(100), mPostscriptNames(100) {} 1.315 + // fullname ==> font entry (unique, one name per font entry) 1.316 + nsRefPtrHashtable<nsStringHashKey, gfxFontEntry> mFullnames; 1.317 + // Postscript name ==> font entry (unique, one name per font entry) 1.318 + nsRefPtrHashtable<nsStringHashKey, gfxFontEntry> mPostscriptNames; 1.319 + }; 1.320 + nsAutoPtr<ExtraNames> mExtraNames; 1.321 + 1.322 + // face names missed when face name loading takes a long time 1.323 + nsAutoPtr<nsTHashtable<nsStringHashKey> > mFaceNamesMissed; 1.324 + 1.325 + // localized family names missed when face name loading takes a long time 1.326 + nsAutoPtr<nsTHashtable<nsStringHashKey> > mOtherNamesMissed; 1.327 + 1.328 + // cached pref font lists 1.329 + // maps list of family names ==> array of family entries, one per lang group 1.330 + nsDataHashtable<nsUint32HashKey, nsTArray<nsRefPtr<gfxFontFamily> > > mPrefFonts; 1.331 + 1.332 + // when system-wide font lookup fails for a character, cache it to skip future searches 1.333 + gfxSparseBitSet mCodepointsWithNoFonts; 1.334 + 1.335 + // the family to use for U+FFFD fallback, to avoid expensive search every time 1.336 + // on pages with lots of problems 1.337 + nsRefPtr<gfxFontFamily> mReplacementCharFallbackFamily; 1.338 + 1.339 + nsTHashtable<nsStringHashKey> mBadUnderlineFamilyNames; 1.340 + 1.341 + // character map data shared across families 1.342 + // contains weak ptrs to cmaps shared by font entry objects 1.343 + nsTHashtable<CharMapHashKey> mSharedCmaps; 1.344 + 1.345 + // data used as part of the font cmap loading process 1.346 + nsTArray<nsRefPtr<gfxFontFamily> > mFontFamiliesToLoad; 1.347 + uint32_t mStartIndex; 1.348 + uint32_t mIncrement; 1.349 + uint32_t mNumFamilies; 1.350 + 1.351 + nsTHashtable<nsPtrHashKey<gfxUserFontSet> > mUserFontSetList; 1.352 +}; 1.353 + 1.354 +#endif /* GFXPLATFORMFONTLIST_H_ */