summaryrefslogtreecommitdiffstats
path: root/gfx/thebes/gfxPlatformFontList.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/thebes/gfxPlatformFontList.h')
-rw-r--r--gfx/thebes/gfxPlatformFontList.h471
1 files changed, 471 insertions, 0 deletions
diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h
new file mode 100644
index 000000000..c16994d8c
--- /dev/null
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -0,0 +1,471 @@
+/* -*- 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 GFXPLATFORMFONTLIST_H_
+#define GFXPLATFORMFONTLIST_H_
+
+#include "nsDataHashtable.h"
+#include "nsRefPtrHashtable.h"
+#include "nsTHashtable.h"
+
+#include "gfxFontUtils.h"
+#include "gfxFontInfoLoader.h"
+#include "gfxFont.h"
+#include "gfxFontConstants.h"
+#include "gfxPlatform.h"
+#include "gfxFontFamilyList.h"
+
+#include "nsIMemoryReporter.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/RangedArray.h"
+#include "nsILanguageAtomService.h"
+
+class CharMapHashKey : public PLDHashEntryHdr
+{
+public:
+ typedef gfxCharacterMap* KeyType;
+ typedef const gfxCharacterMap* KeyTypePointer;
+
+ explicit CharMapHashKey(const gfxCharacterMap *aCharMap) :
+ mCharMap(const_cast<gfxCharacterMap*>(aCharMap))
+ {
+ MOZ_COUNT_CTOR(CharMapHashKey);
+ }
+ CharMapHashKey(const CharMapHashKey& toCopy) :
+ mCharMap(toCopy.mCharMap)
+ {
+ MOZ_COUNT_CTOR(CharMapHashKey);
+ }
+ ~CharMapHashKey()
+ {
+ MOZ_COUNT_DTOR(CharMapHashKey);
+ }
+
+ gfxCharacterMap* GetKey() const { return mCharMap; }
+
+ bool KeyEquals(const gfxCharacterMap *aCharMap) const {
+ NS_ASSERTION(!aCharMap->mBuildOnTheFly && !mCharMap->mBuildOnTheFly,
+ "custom cmap used in shared cmap hashtable");
+ // cmaps built on the fly never match
+ if (aCharMap->mHash != mCharMap->mHash)
+ {
+ return false;
+ }
+ return mCharMap->Equals(aCharMap);
+ }
+
+ static const gfxCharacterMap* KeyToPointer(gfxCharacterMap *aCharMap) {
+ return aCharMap;
+ }
+ static PLDHashNumber HashKey(const gfxCharacterMap *aCharMap) {
+ return aCharMap->mHash;
+ }
+
+ enum { ALLOW_MEMMOVE = true };
+
+protected:
+ gfxCharacterMap *mCharMap;
+};
+
+// gfxPlatformFontList is an abstract class for the global font list on the system;
+// concrete subclasses for each platform implement the actual interface to the system fonts.
+// This class exists because we cannot rely on the platform font-finding APIs to behave
+// in sensible/similar ways, particularly with rich, complex OpenType families,
+// so we do our own font family/style management here instead.
+
+// Much of this is based on the old gfxQuartzFontCache, but adapted for use on all platforms.
+
+struct FontListSizes {
+ uint32_t mFontListSize; // size of the font list and dependent objects
+ // (font family and face names, etc), but NOT
+ // including the font table cache and the cmaps
+ uint32_t mFontTableCacheSize; // memory used for the gfxFontEntry table caches
+ uint32_t mCharMapsSize; // memory used for cmap coverage info
+};
+
+class gfxUserFontSet;
+
+class gfxPlatformFontList : public gfxFontInfoLoader
+{
+public:
+ typedef mozilla::unicode::Script Script;
+
+ static gfxPlatformFontList* PlatformFontList() {
+ return sPlatformFontList;
+ }
+
+ static nsresult Init() {
+ NS_ASSERTION(!sPlatformFontList, "What's this doing here?");
+ gfxPlatform::GetPlatform()->CreatePlatformFontList();
+ if (!sPlatformFontList) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ return NS_OK;
+ }
+
+ static void Shutdown() {
+ delete sPlatformFontList;
+ sPlatformFontList = nullptr;
+ }
+
+ virtual ~gfxPlatformFontList();
+
+ // initialize font lists
+ nsresult InitFontList();
+
+ virtual void GetFontList(nsIAtom *aLangGroup,
+ const nsACString& aGenericFamily,
+ nsTArray<nsString>& aListOfFonts);
+
+ void UpdateFontList();
+
+ virtual void ClearLangGroupPrefFonts();
+
+ virtual void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily> >& aFamilyArray);
+
+ gfxFontEntry*
+ SystemFindFontForChar(uint32_t aCh, uint32_t aNextCh,
+ Script aRunScript,
+ const gfxFontStyle* aStyle);
+
+ // Find family(ies) matching aFamily and append to the aOutput array
+ // (there may be multiple results in the case of fontconfig aliases, etc).
+ // Return true if any match was found and appended, false if none.
+ virtual bool
+ FindAndAddFamilies(const nsAString& aFamily,
+ nsTArray<gfxFontFamily*>* aOutput,
+ gfxFontStyle* aStyle = nullptr,
+ gfxFloat aDevToCssSize = 1.0);
+
+ gfxFontEntry* FindFontForFamily(const nsAString& aFamily, const gfxFontStyle* aStyle, bool& aNeedsBold);
+
+ // name lookup table methods
+
+ void AddOtherFamilyName(gfxFontFamily *aFamilyEntry, nsAString& aOtherFamilyName);
+
+ void AddFullname(gfxFontEntry *aFontEntry, nsAString& aFullname);
+
+ void AddPostscriptName(gfxFontEntry *aFontEntry, nsAString& aPostscriptName);
+
+ bool NeedFullnamePostscriptNames() { return mExtraNames != nullptr; }
+
+ // pure virtual functions, to be provided by concrete subclasses
+
+ // get the system default font family
+ gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle);
+
+ // look up a font by name on the host platform
+ virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
+ uint16_t aWeight,
+ int16_t aStretch,
+ uint8_t aStyle) = 0;
+
+ // create a new platform font from downloaded data (@font-face)
+ // this method is responsible to ensure aFontData is free()'d
+ virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
+ uint16_t aWeight,
+ int16_t aStretch,
+ uint8_t aStyle,
+ const uint8_t* aFontData,
+ uint32_t aLength) = 0;
+
+ // get the standard family name on the platform for a given font name
+ // (platforms may override, eg Mac)
+ virtual bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
+
+ virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
+ FontListSizes* aSizes) const;
+ virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
+ FontListSizes* aSizes) const;
+
+ // search for existing cmap that matches the input
+ // return the input if no match is found
+ gfxCharacterMap* FindCharMap(gfxCharacterMap *aCmap);
+
+ // add a cmap to the shared cmap set
+ gfxCharacterMap* AddCmap(const gfxCharacterMap *aCharMap);
+
+ // remove the cmap from the shared cmap set
+ void RemoveCmap(const gfxCharacterMap *aCharMap);
+
+ // keep track of userfont sets to notify when global fontlist changes occur
+ void AddUserFontSet(gfxUserFontSet *aUserFontSet) {
+ mUserFontSetList.PutEntry(aUserFontSet);
+ }
+
+ void RemoveUserFontSet(gfxUserFontSet *aUserFontSet) {
+ mUserFontSetList.RemoveEntry(aUserFontSet);
+ }
+
+ static const gfxFontEntry::ScriptRange sComplexScriptRanges[];
+
+ void GetFontlistInitInfo(uint32_t& aNumInits, uint32_t& aLoaderState) {
+ aNumInits = mFontlistInitCount;
+ aLoaderState = (uint32_t) mState;
+ }
+
+ virtual void
+ AddGenericFonts(mozilla::FontFamilyType aGenericType,
+ nsIAtom* aLanguage,
+ nsTArray<gfxFontFamily*>& aFamilyList);
+
+ nsTArray<RefPtr<gfxFontFamily>>*
+ GetPrefFontsLangGroup(mozilla::FontFamilyType aGenericType,
+ eFontPrefLang aPrefLang);
+
+ // in some situations, need to make decisions about ambiguous characters, may need to look at multiple pref langs
+ void GetLangPrefs(eFontPrefLang aPrefLangs[], uint32_t &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang);
+
+ // convert a lang group to enum constant (i.e. "zh-TW" ==> eFontPrefLang_ChineseTW)
+ static eFontPrefLang GetFontPrefLangFor(const char* aLang);
+
+ // convert a lang group atom to enum constant
+ static eFontPrefLang GetFontPrefLangFor(nsIAtom *aLang);
+
+ // convert an enum constant to a lang group atom
+ static nsIAtom* GetLangGroupForPrefLang(eFontPrefLang aLang);
+
+ // convert a enum constant to lang group string (i.e. eFontPrefLang_ChineseTW ==> "zh-TW")
+ static const char* GetPrefLangName(eFontPrefLang aLang);
+
+ // map a Unicode range (based on char code) to a font language for Preferences
+ static eFontPrefLang GetFontPrefLangFor(uint8_t aUnicodeRange);
+
+ // returns true if a pref lang is CJK
+ static bool IsLangCJK(eFontPrefLang aLang);
+
+ // helper method to add a pref lang to an array, if not already in array
+ static void AppendPrefLang(eFontPrefLang aPrefLangs[], uint32_t& aLen, eFontPrefLang aAddLang);
+
+ // default serif/sans-serif choice based on font.default.xxx prefs
+ mozilla::FontFamilyType
+ GetDefaultGeneric(eFontPrefLang aLang);
+
+ // map lang group ==> lang string
+ void GetSampleLangForGroup(nsIAtom* aLanguage, nsACString& aLangStr,
+ bool aCheckEnvironment = true);
+
+ // Returns true if the font family whitelist is not empty.
+ bool IsFontFamilyWhitelistActive();
+
+ static void FontWhitelistPrefChanged(const char *aPref, void *aClosure) {
+ gfxPlatformFontList::PlatformFontList()->UpdateFontList();
+ }
+
+protected:
+ class MemoryReporter final : public nsIMemoryReporter
+ {
+ ~MemoryReporter() {}
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMEMORYREPORTER
+ };
+
+ explicit gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
+
+ static gfxPlatformFontList *sPlatformFontList;
+
+ // Convenience method to return the first matching family (if any) as found
+ // by FindAndAddFamilies().
+ gfxFontFamily*
+ FindFamily(const nsAString& aFamily, gfxFontStyle* aStyle = nullptr,
+ gfxFloat aDevToCssSize = 1.0)
+ {
+ AutoTArray<gfxFontFamily*,1> families;
+ return FindAndAddFamilies(aFamily, &families, aStyle, aDevToCssSize)
+ ? families[0] : nullptr;
+ }
+
+ // Lookup family name in global family list without substitutions or
+ // localized family name lookup. Used for common font fallback families.
+ gfxFontFamily* FindFamilyByCanonicalName(const nsAString& aFamily) {
+ nsAutoString key;
+ gfxFontFamily *familyEntry;
+ GenerateFontListKey(aFamily, key);
+ if ((familyEntry = mFontFamilies.GetWeak(key))) {
+ return CheckFamily(familyEntry);
+ }
+ return nullptr;
+ }
+
+ // returns default font for a given character, null otherwise
+ gfxFontEntry* CommonFontFallback(uint32_t aCh, uint32_t aNextCh,
+ Script aRunScript,
+ const gfxFontStyle* aMatchStyle,
+ gfxFontFamily** aMatchedFamily);
+
+ // Search fonts system-wide for a given character, null if not found.
+ gfxFontEntry* GlobalFontFallback(const uint32_t aCh,
+ Script aRunScript,
+ const gfxFontStyle* aMatchStyle,
+ uint32_t& aCmapCount,
+ gfxFontFamily** aMatchedFamily);
+
+ // Platform-specific implementation of global font fallback, if any;
+ // this may return nullptr in which case the default cmap-based fallback
+ // will be performed.
+ virtual gfxFontEntry*
+ PlatformGlobalFontFallback(const uint32_t aCh,
+ Script aRunScript,
+ const gfxFontStyle* aMatchStyle,
+ gfxFontFamily** aMatchedFamily)
+ {
+ return nullptr;
+ }
+
+ // whether system-based font fallback is used or not
+ // if system fallback is used, no need to load all cmaps
+ virtual bool UsesSystemFallback() { return false; }
+
+ void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], uint32_t &aLen,
+ eFontPrefLang aCharLang, eFontPrefLang aPageLang);
+
+ // verifies that a family contains a non-zero font count
+ gfxFontFamily* CheckFamily(gfxFontFamily *aFamily);
+
+ // initialize localized family names
+ void InitOtherFamilyNames();
+
+ // search through font families, looking for a given name, initializing
+ // facename lists along the way. first checks all families with names
+ // close to face name, then searchs all families if not found.
+ gfxFontEntry* SearchFamiliesForFaceName(const nsAString& aFaceName);
+
+ // helper method for finding fullname/postscript names in facename lists
+ gfxFontEntry* FindFaceName(const nsAString& aFaceName);
+
+ // look up a font by name, for cases where platform font list
+ // maintains explicit mappings of fullname/psname ==> font
+ virtual gfxFontEntry* LookupInFaceNameLists(const nsAString& aFontName);
+
+ // commonly used fonts for which the name table should be loaded at startup
+ virtual void PreloadNamesList();
+
+ // load the bad underline blacklist from pref.
+ void LoadBadUnderlineList();
+
+ void GenerateFontListKey(const nsAString& aKeyName, nsAString& aResult);
+
+ virtual void GetFontFamilyNames(nsTArray<nsString>& aFontFamilyNames);
+
+ nsILanguageAtomService* GetLangService();
+
+ // helper function to map lang to lang group
+ nsIAtom* GetLangGroup(nsIAtom* aLanguage);
+
+ // helper method for finding an appropriate lang string
+ bool TryLangForGroup(const nsACString& aOSLang, nsIAtom* aLangGroup,
+ nsACString& aLang);
+
+ static const char* GetGenericName(mozilla::FontFamilyType aGenericType);
+
+ // gfxFontInfoLoader overrides, used to load in font cmaps
+ virtual void InitLoader();
+ virtual bool LoadFontInfo();
+ virtual void CleanupLoader();
+
+ // read the loader initialization prefs, and start it
+ void GetPrefsAndStartLoader();
+
+ // for font list changes that affect all documents
+ void ForceGlobalReflow();
+
+ void RebuildLocalFonts();
+
+ void
+ ResolveGenericFontNames(mozilla::FontFamilyType aGenericType,
+ eFontPrefLang aPrefLang,
+ nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies);
+
+ virtual nsresult InitFontListForPlatform() = 0;
+
+ void ApplyWhitelist();
+
+ typedef nsRefPtrHashtable<nsStringHashKey, gfxFontFamily> FontFamilyTable;
+ typedef nsRefPtrHashtable<nsStringHashKey, gfxFontEntry> FontEntryTable;
+
+ // used by memory reporter to accumulate sizes of family names in the table
+ static size_t
+ SizeOfFontFamilyTableExcludingThis(const FontFamilyTable& aTable,
+ mozilla::MallocSizeOf aMallocSizeOf);
+ static size_t
+ SizeOfFontEntryTableExcludingThis(const FontEntryTable& aTable,
+ mozilla::MallocSizeOf aMallocSizeOf);
+
+ // Platform-specific helper for GetDefaultFont(...).
+ virtual gfxFontFamily*
+ GetDefaultFontForPlatform(const gfxFontStyle* aStyle) = 0;
+
+ // canonical family name ==> family entry (unique, one name per family entry)
+ FontFamilyTable mFontFamilies;
+
+ // other family name ==> family entry (not unique, can have multiple names per
+ // family entry, only names *other* than the canonical names are stored here)
+ FontFamilyTable mOtherFamilyNames;
+
+ // flag set after InitOtherFamilyNames is called upon first name lookup miss
+ bool mOtherFamilyNamesInitialized;
+
+ // flag set after fullname and Postcript name lists are populated
+ bool mFaceNameListsInitialized;
+
+ struct ExtraNames {
+ ExtraNames() : mFullnames(64), mPostscriptNames(64) {}
+
+ // fullname ==> font entry (unique, one name per font entry)
+ FontEntryTable mFullnames;
+ // Postscript name ==> font entry (unique, one name per font entry)
+ FontEntryTable mPostscriptNames;
+ };
+ mozilla::UniquePtr<ExtraNames> mExtraNames;
+
+ // face names missed when face name loading takes a long time
+ mozilla::UniquePtr<nsTHashtable<nsStringHashKey> > mFaceNamesMissed;
+
+ // localized family names missed when face name loading takes a long time
+ mozilla::UniquePtr<nsTHashtable<nsStringHashKey> > mOtherNamesMissed;
+
+ typedef nsTArray<RefPtr<gfxFontFamily>> PrefFontList;
+ typedef mozilla::RangedArray<mozilla::UniquePtr<PrefFontList>,
+ mozilla::eFamily_generic_first,
+ mozilla::eFamily_generic_count> PrefFontsForLangGroup;
+ mozilla::RangedArray<PrefFontsForLangGroup,
+ eFontPrefLang_First,
+ eFontPrefLang_Count> mLangGroupPrefFonts;
+
+ // when system-wide font lookup fails for a character, cache it to skip future searches
+ gfxSparseBitSet mCodepointsWithNoFonts;
+
+ // the family to use for U+FFFD fallback, to avoid expensive search every time
+ // on pages with lots of problems
+ RefPtr<gfxFontFamily> mReplacementCharFallbackFamily;
+
+ nsTHashtable<nsStringHashKey> mBadUnderlineFamilyNames;
+
+ // character map data shared across families
+ // contains weak ptrs to cmaps shared by font entry objects
+ nsTHashtable<CharMapHashKey> mSharedCmaps;
+
+ // data used as part of the font cmap loading process
+ nsTArray<RefPtr<gfxFontFamily> > mFontFamiliesToLoad;
+ uint32_t mStartIndex;
+ uint32_t mIncrement;
+ uint32_t mNumFamilies;
+
+ // xxx - info for diagnosing no default font aborts
+ // see bugs 636957, 1070983, 1189129
+ uint32_t mFontlistInitCount; // num times InitFontList called
+
+ nsTHashtable<nsPtrHashKey<gfxUserFontSet> > mUserFontSetList;
+
+ nsCOMPtr<nsILanguageAtomService> mLangService;
+ nsTArray<uint32_t> mCJKPrefLangs;
+ nsTArray<mozilla::FontFamilyType> mDefaultGenericsLangGroup;
+
+ bool mFontFamilyWhitelistActive;
+};
+
+#endif /* GFXPLATFORMFONTLIST_H_ */