1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_StaticPresData_h
8 #define mozilla_StaticPresData_h
9 
10 #include "nsAutoPtr.h"
11 #include "nsCoord.h"
12 #include "nsCOMPtr.h"
13 #include "nsFont.h"
14 #include "nsAtom.h"
15 #include "nsLanguageAtomService.h"
16 
17 namespace mozilla {
18 
19 struct LangGroupFontPrefs {
20   // Font sizes default to zero; they will be set in GetFontPreferences
LangGroupFontPrefsLangGroupFontPrefs21   LangGroupFontPrefs()
22       : mLangGroup(nullptr),
23         mMinimumFontSize(0),
24         mDefaultVariableFont(),
25         mDefaultFixedFont(mozilla::eFamily_monospace, 0),
26         mDefaultSerifFont(mozilla::eFamily_serif, 0),
27         mDefaultSansSerifFont(mozilla::eFamily_sans_serif, 0),
28         mDefaultMonospaceFont(mozilla::eFamily_monospace, 0),
29         mDefaultCursiveFont(mozilla::eFamily_cursive, 0),
30         mDefaultFantasyFont(mozilla::eFamily_fantasy, 0) {
31     mDefaultVariableFont.fontlist.SetDefaultFontType(mozilla::eFamily_serif);
32     // We create mDefaultVariableFont.fontlist with defaultType as the
33     // fallback font, and not as part of the font list proper. This way,
34     // it can be overwritten should there be a language change.
35   }
36 
ResetLangGroupFontPrefs37   void Reset() {
38     // Throw away any other LangGroupFontPrefs objects:
39     mNext = nullptr;
40 
41     // Make GetFontPreferences reinitialize mLangGroupFontPrefs:
42     mLangGroup = nullptr;
43   }
44 
SizeOfExcludingThisLangGroupFontPrefs45   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
46     size_t n = 0;
47     LangGroupFontPrefs* curr = mNext;
48     while (curr) {
49       n += aMallocSizeOf(curr);
50 
51       // Measurement of the following members may be added later if DMD finds
52       // it is worthwhile:
53       // - mLangGroup
54       // - mDefault*Font
55 
56       curr = curr->mNext;
57     }
58     return n;
59   }
60 
61   // Initialize this with the data for a given language
62   void Initialize(nsAtom* aLangGroupAtom);
63 
64   RefPtr<nsAtom> mLangGroup;
65   nscoord mMinimumFontSize;
66   nsFont mDefaultVariableFont;
67   nsFont mDefaultFixedFont;
68   nsFont mDefaultSerifFont;
69   nsFont mDefaultSansSerifFont;
70   nsFont mDefaultMonospaceFont;
71   nsFont mDefaultCursiveFont;
72   nsFont mDefaultFantasyFont;
73   nsAutoPtr<LangGroupFontPrefs> mNext;
74 };
75 
76 /**
77  * Some functionality that has historically lived on nsPresContext does not
78  * actually need to be per-document. This singleton class serves as a host
79  * for that functionality. We delegate to it from nsPresContext where
80  * appropriate, and use it standalone in some cases as well.
81  */
82 class StaticPresData {
83  public:
84   // Initialization and shutdown of the singleton. Called exactly once.
85   static void Init();
86   static void Shutdown();
87 
88   // Gets an instance of the singleton. Infallible between the calls to Init
89   // and Shutdown.
90   static StaticPresData* Get();
91 
92   /**
93    * This table maps border-width enums 'thin', 'medium', 'thick'
94    * to actual nscoord values.
95    */
GetBorderWidthTable()96   const nscoord* GetBorderWidthTable() { return mBorderWidthTable; }
97 
98   /**
99    * Given a language, get the language group name, which can
100    * be used as an argument to LangGroupFontPrefs::Initialize()
101    *
102    * aNeedsToCache is used for two things.  If null, it indicates that
103    * the nsLanguageAtomService is safe to cache the result of the
104    * language group lookup, either because we're on the main thread,
105    * or because we're on a style worker thread but the font lock has
106    * been acquired.  If non-null, it indicates that it's not safe to
107    * cache the result of the language group lookup (because we're on
108    * a style worker thread without the lock acquired).  In this case,
109    * GetLanguageGroup will store true in *aNeedsToCache true if we
110    * would have cached the result of a new lookup, and false if we
111    * were able to use an existing cached result.  Thus, callers that
112    * get a true *aNeedsToCache outparam value should make an effort
113    * to re-call GetLanguageGroup when it is safe to cache, to avoid
114    * recomputing the language group again later.
115    */
116   nsAtom* GetLangGroup(nsAtom* aLanguage, bool* aNeedsToCache = nullptr) const;
117 
118   /**
119    * Same as GetLangGroup, but will not cache the result
120    *
121    */
122   already_AddRefed<nsAtom> GetUncachedLangGroup(nsAtom* aLanguage) const;
123 
124   /**
125    * Fetch the user's font preferences for the given aLanguage's
126    * langugage group.
127    *
128    * The original code here is pretty old, and includes an optimization
129    * whereby language-specific prefs are read per-document, and the
130    * results are stored in a linked list, which is assumed to be very short
131    * since most documents only ever use one language.
132    *
133    * Storing this per-session rather than per-document would almost certainly
134    * be fine. But just to be on the safe side, we leave the old mechanism as-is,
135    * with an additional per-session cache that new callers can use if they don't
136    * have a PresContext.
137    *
138    * See comment on GetLangGroup for the usage of aNeedsToCache.
139    */
140   const LangGroupFontPrefs* GetFontPrefsForLangHelper(
141       nsAtom* aLanguage, const LangGroupFontPrefs* aPrefs,
142       bool* aNeedsToCache = nullptr) const;
143   /**
144    * Get the default font for the given language and generic font ID.
145    * aLanguage may not be nullptr.
146    *
147    * This object is read-only, you must copy the font to modify it.
148    *
149    * When aFontID is kPresContext_DefaultVariableFontID or
150    * kPresContext_DefaultFixedFontID (which equals
151    * kGenericFont_moz_fixed, which is used for the -moz-fixed generic),
152    * the nsFont returned has its name as a CSS generic family (serif or
153    * sans-serif for the former, monospace for the latter), and its size
154    * as the default font size for variable or fixed fonts for the
155    * language group.
156    *
157    * For aFontID corresponding to a CSS Generic, the nsFont returned has
158    * its name set to that generic font's name, and its size set to
159    * the user's preference for font size for that generic and the
160    * given language.
161    */
162   const nsFont* GetDefaultFontHelper(uint8_t aFontID, nsAtom* aLanguage,
163                                      const LangGroupFontPrefs* aPrefs) const;
164 
165   /*
166    * These versions operate on the font pref cache on StaticPresData.
167    */
168 
GetDefaultFont(uint8_t aFontID,nsAtom * aLanguage)169   const nsFont* GetDefaultFont(uint8_t aFontID, nsAtom* aLanguage) const {
170     MOZ_ASSERT(aLanguage);
171     return GetDefaultFontHelper(aFontID, aLanguage,
172                                 GetFontPrefsForLang(aLanguage));
173   }
174   const LangGroupFontPrefs* GetFontPrefsForLang(
175       nsAtom* aLanguage, bool* aNeedsToCache = nullptr) const {
176     MOZ_ASSERT(aLanguage);
177     return GetFontPrefsForLangHelper(aLanguage, &mStaticLangGroupFontPrefs,
178                                      aNeedsToCache);
179   }
180 
ResetCachedFontPrefs()181   void ResetCachedFontPrefs() { mStaticLangGroupFontPrefs.Reset(); }
182 
183  private:
184   StaticPresData();
~StaticPresData()185   ~StaticPresData() {}
186 
187   nsLanguageAtomService* mLangService;
188   nscoord mBorderWidthTable[3];
189   LangGroupFontPrefs mStaticLangGroupFontPrefs;
190 };
191 
192 }  // namespace mozilla
193 
194 #endif  // mozilla_StaticPresData_h
195