/* 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 mozilla_StaticPresData_h #define mozilla_StaticPresData_h #include "mozilla/RWLock.h" #include "mozilla/StaticPtr.h" #include "mozilla/UniquePtr.h" #include "nsAtom.h" #include "nsCOMPtr.h" #include "nsCoord.h" #include "nsFont.h" #include "nsLanguageAtomService.h" namespace mozilla { struct LangGroupFontPrefs { // Font sizes default to zero; they will be set in GetFontPreferences explicit LangGroupFontPrefs(nsStaticAtom* aLangGroupAtom) : mLangGroup(aLangGroupAtom), mMinimumFontSize({0}), mDefaultVariableFont(StyleGenericFontFamily::Serif, {0}), mDefaultSerifFont(StyleGenericFontFamily::Serif, {0}), mDefaultSansSerifFont(StyleGenericFontFamily::SansSerif, {0}), mDefaultMonospaceFont(StyleGenericFontFamily::Monospace, {0}), mDefaultCursiveFont(StyleGenericFontFamily::Cursive, {0}), mDefaultFantasyFont(StyleGenericFontFamily::Fantasy, {0}), mDefaultSystemUiFont(StyleGenericFontFamily::SystemUi, {0}) { Initialize(); } StyleGenericFontFamily GetDefaultGeneric() const { return mDefaultVariableFont.family.families.list.AsSpan()[0].AsGeneric(); } /** * Get the default font for the given language and generic font ID. * aLanguage may not be nullptr. * * This object is read-only, you must copy the font to modify it. * * For aFontID corresponding to a CSS Generic, the nsFont returned has * its name set to that generic font's name, and its size set to * the user's preference for font size for that generic and the * given language. */ const nsFont* GetDefaultFont(StyleGenericFontFamily aFamily) const { switch (aFamily) { // Special (our default variable width font and fixed width font) case StyleGenericFontFamily::None: return &mDefaultVariableFont; // CSS case StyleGenericFontFamily::Serif: return &mDefaultSerifFont; case StyleGenericFontFamily::SansSerif: return &mDefaultSansSerifFont; case StyleGenericFontFamily::Monospace: return &mDefaultMonospaceFont; case StyleGenericFontFamily::Cursive: return &mDefaultCursiveFont; case StyleGenericFontFamily::Fantasy: return &mDefaultFantasyFont; case StyleGenericFontFamily::Math: // TODO(eri): Change to a specific math font once the generic // math family is no longer mapped to "serif.x-math". See // `gfxPlatformFontList::AddGenericFonts`. return &mDefaultSerifFont; case StyleGenericFontFamily::SystemUi: return &mDefaultSystemUiFont; case StyleGenericFontFamily::MozEmoji: // This shouldn't appear in font family names. break; } MOZ_ASSERT_UNREACHABLE("invalid font id"); return nullptr; } nsStaticAtom* mLangGroup; Length mMinimumFontSize; nsFont mDefaultVariableFont; nsFont mDefaultSerifFont; nsFont mDefaultSansSerifFont; nsFont mDefaultMonospaceFont; nsFont mDefaultCursiveFont; nsFont mDefaultFantasyFont; nsFont mDefaultSystemUiFont; UniquePtr mNext; private: void Initialize(); }; /** * Some functionality that has historically lived on nsPresContext does not * actually need to be per-document. This singleton class serves as a host * for that functionality. We delegate to it from nsPresContext where * appropriate, and use it standalone in some cases as well. */ class StaticPresData { public: // Initialization and shutdown of the singleton. Called exactly once. static void Init(); static void Shutdown(); // Gets an instance of the singleton. Infallible between the calls to Init // and Shutdown. static StaticPresData* Get(); /** * Given a language, get the language group name, which can * be used as an argument to LangGroupFontPrefs::Initialize() */ nsStaticAtom* GetLangGroup(nsAtom* aLanguage) const; /** * Fetch the user's font preferences for the given aLanguage's * langugage group. * * The original code here is pretty old, and includes an optimization * whereby language-specific prefs are read per-document, and the * results are stored in a linked list, which is assumed to be very short * since most documents only ever use one language. * * Storing this per-session rather than per-document would almost certainly * be fine. But just to be on the safe side, we leave the old mechanism as-is, * with an additional per-session cache that new callers can use if they don't * have a PresContext. */ const LangGroupFontPrefs* GetFontPrefsForLang(nsAtom* aLanguage); void InvalidateFontPrefs() { AutoWriteLock lock(mLock); mLangGroupFontPrefs.reset(nullptr); } private: // Private constructor/destructor, to prevent other code from inadvertently // instantiating or deleting us. (Though we need to declare StaticAutoPtr as // a friend to give it permission.) StaticPresData(); ~StaticPresData() = default; friend class StaticAutoPtr; nsLanguageAtomService* mLangService; UniquePtr mLangGroupFontPrefs MOZ_GUARDED_BY(mLock); RWLock mLock{"StaticPresData::mLock"}; }; } // namespace mozilla #endif // mozilla_StaticPresData_h