Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/base/StaticPresData.cpp
Line
Count
Source (jump to first uncovered line)
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
#include "mozilla/StaticPresData.h"
8
9
#include "mozilla/Preferences.h"
10
#include "mozilla/ServoBindings.h"
11
#include "nsPresContext.h"
12
namespace mozilla {
13
14
static StaticPresData* sSingleton = nullptr;
15
16
void
17
StaticPresData::Init()
18
3
{
19
3
  MOZ_ASSERT(!sSingleton);
20
3
  sSingleton = new StaticPresData();
21
3
}
22
23
void
24
StaticPresData::Shutdown()
25
0
{
26
0
  MOZ_ASSERT(sSingleton);
27
0
  delete sSingleton;
28
0
  sSingleton = nullptr;
29
0
}
30
31
StaticPresData*
32
StaticPresData::Get()
33
0
{
34
0
  MOZ_ASSERT(sSingleton);
35
0
  return sSingleton;
36
0
}
37
38
StaticPresData::StaticPresData()
39
3
{
40
3
  mLangService = nsLanguageAtomService::GetService();
41
3
42
3
  mBorderWidthTable[NS_STYLE_BORDER_WIDTH_THIN] = nsPresContext::CSSPixelsToAppUnits(1);
43
3
  mBorderWidthTable[NS_STYLE_BORDER_WIDTH_MEDIUM] = nsPresContext::CSSPixelsToAppUnits(3);
44
3
  mBorderWidthTable[NS_STYLE_BORDER_WIDTH_THICK] = nsPresContext::CSSPixelsToAppUnits(5);
45
3
}
46
47
#define MAKE_FONT_PREF_KEY(_pref, _s0, _s1) \
48
0
 _pref.Assign(_s0); \
49
0
 _pref.Append(_s1);
50
51
static const char* const kGenericFont[] = {
52
  ".variable.",
53
  ".fixed.",
54
  ".serif.",
55
  ".sans-serif.",
56
  ".monospace.",
57
  ".cursive.",
58
  ".fantasy."
59
};
60
61
// These are private, use the list in nsFont.h if you want a public list.
62
enum {
63
  eDefaultFont_Variable,
64
  eDefaultFont_Fixed,
65
  eDefaultFont_Serif,
66
  eDefaultFont_SansSerif,
67
  eDefaultFont_Monospace,
68
  eDefaultFont_Cursive,
69
  eDefaultFont_Fantasy,
70
  eDefaultFont_COUNT
71
};
72
73
void
74
LangGroupFontPrefs::Initialize(nsAtom* aLangGroupAtom)
75
0
{
76
0
  mLangGroup = aLangGroupAtom;
77
0
78
0
  /* Fetch the font prefs to be used -- see bug 61883 for details.
79
0
     Not all prefs are needed upfront. Some are fallback prefs intended
80
0
     for the GFX font sub-system...
81
0
82
0
  -- attributes for generic fonts --------------------------------------
83
0
  font.default.[langGroup] = serif | sans-serif - fallback generic font
84
0
  font.name.[generic].[langGroup] = current user' selected font on the pref dialog
85
0
  font.name-list.[generic].[langGroup] = fontname1, fontname2, ... [factory pre-built list]
86
0
  font.size.[generic].[langGroup] = integer - settable by the user
87
0
  font.size-adjust.[generic].[langGroup] = "float" - settable by the user
88
0
  font.minimum-size.[langGroup] = integer - settable by the user
89
0
  */
90
0
91
0
  nsAutoCString langGroup;
92
0
  aLangGroupAtom->ToUTF8String(langGroup);
93
0
94
0
  mDefaultVariableFont.size = nsPresContext::CSSPixelsToAppUnits(16);
95
0
  mDefaultFixedFont.size = nsPresContext::CSSPixelsToAppUnits(13);
96
0
97
0
  nsAutoCString pref;
98
0
99
0
  // get font.minimum-size.[langGroup]
100
0
101
0
  MAKE_FONT_PREF_KEY(pref, "font.minimum-size.", langGroup);
102
0
103
0
  int32_t size = Preferences::GetInt(pref.get());
104
0
  mMinimumFontSize = nsPresContext::CSSPixelsToAppUnits(size);
105
0
106
0
  nsFont* fontTypes[] = {
107
0
    &mDefaultVariableFont,
108
0
    &mDefaultFixedFont,
109
0
    &mDefaultSerifFont,
110
0
    &mDefaultSansSerifFont,
111
0
    &mDefaultMonospaceFont,
112
0
    &mDefaultCursiveFont,
113
0
    &mDefaultFantasyFont
114
0
  };
115
0
  static_assert(MOZ_ARRAY_LENGTH(fontTypes) == eDefaultFont_COUNT,
116
0
                "FontTypes array count is not correct");
117
0
118
0
  // Get attributes specific to each generic font. We do not get the user's
119
0
  // generic-font-name-to-specific-family-name preferences because its the
120
0
  // generic name that should be fed into the cascade. It is up to the GFX
121
0
  // code to look up the font prefs to convert generic names to specific
122
0
  // family names as necessary.
123
0
  nsAutoCString generic_dot_langGroup;
124
0
  for (uint32_t eType = 0; eType < ArrayLength(fontTypes); ++eType) {
125
0
    generic_dot_langGroup.Assign(kGenericFont[eType]);
126
0
    generic_dot_langGroup.Append(langGroup);
127
0
128
0
    nsFont* font = fontTypes[eType];
129
0
130
0
    // set the default variable font (the other fonts are seen as 'generic' fonts
131
0
    // in GFX and will be queried there when hunting for alternative fonts)
132
0
    if (eType == eDefaultFont_Variable) {
133
0
      // XXX "font.name.variable."?  There is no such pref...
134
0
      MAKE_FONT_PREF_KEY(pref, "font.name.variable.", langGroup);
135
0
136
0
      nsAutoCString value;
137
0
      Preferences::GetCString(pref.get(), value);
138
0
      if (!value.IsEmpty()) {
139
0
        FontFamilyName defaultVariableName = FontFamilyName::Convert(value);
140
0
        FontFamilyType defaultType = defaultVariableName.mType;
141
0
        NS_ASSERTION(defaultType == eFamily_serif ||
142
0
                     defaultType == eFamily_sans_serif,
143
0
                     "default type must be serif or sans-serif");
144
0
        mDefaultVariableFont.fontlist = FontFamilyList();
145
0
        mDefaultVariableFont.fontlist.SetDefaultFontType(defaultType);
146
0
        // We create mDefaultVariableFont.fontlist with defaultType as the
147
0
        // fallback font, and not as part of the font list proper. This way,
148
0
        // it can be overwritten should there be a language change.
149
0
      }
150
0
      else {
151
0
        MAKE_FONT_PREF_KEY(pref, "font.default.", langGroup);
152
0
        Preferences::GetCString(pref.get(), value);
153
0
        if (!value.IsEmpty()) {
154
0
          FontFamilyName defaultVariableName = FontFamilyName::Convert(value);
155
0
          FontFamilyType defaultType = defaultVariableName.mType;
156
0
          NS_ASSERTION(defaultType == eFamily_serif ||
157
0
                       defaultType == eFamily_sans_serif,
158
0
                       "default type must be serif or sans-serif");
159
0
          mDefaultVariableFont.fontlist = FontFamilyList();
160
0
          mDefaultVariableFont.fontlist.SetDefaultFontType(defaultType);
161
0
          // We create mDefaultVariableFont.fontlist with defaultType as the
162
0
          // (fallback) font, and not as part of the font list proper. This way,
163
0
          // it can be overwritten should there be a language change.
164
0
        }
165
0
      }
166
0
    }
167
0
    else {
168
0
      if (eType == eDefaultFont_Monospace) {
169
0
        // This takes care of the confusion whereby people often expect "monospace"
170
0
        // to have the same default font-size as "-moz-fixed" (this tentative
171
0
        // size may be overwritten with the specific value for "monospace" when
172
0
        // "font.size.monospace.[langGroup]" is read -- see below)
173
0
        mDefaultMonospaceFont.size = mDefaultFixedFont.size;
174
0
      }
175
0
      else if (eType != eDefaultFont_Fixed) {
176
0
        // all the other generic fonts are initialized with the size of the
177
0
        // variable font, but their specific size can supersede later -- see below
178
0
        font->size = mDefaultVariableFont.size;
179
0
      }
180
0
    }
181
0
182
0
    // Bug 84398: for spec purists, a different font-size only applies to the
183
0
    // .variable. and .fixed. fonts and the other fonts should get |font-size-adjust|.
184
0
    // The problem is that only GfxWin has the support for |font-size-adjust|. So for
185
0
    // parity, we enable the ability to set a different font-size on all platforms.
186
0
187
0
    // get font.size.[generic].[langGroup]
188
0
    // size=0 means 'Auto', i.e., generic fonts retain the size of the variable font
189
0
    MAKE_FONT_PREF_KEY(pref, "font.size", generic_dot_langGroup);
190
0
    size = Preferences::GetInt(pref.get());
191
0
    if (size > 0) {
192
0
      font->size = nsPresContext::CSSPixelsToAppUnits(size);
193
0
    }
194
0
195
0
    // get font.size-adjust.[generic].[langGroup]
196
0
    // XXX only applicable on GFX ports that handle |font-size-adjust|
197
0
    MAKE_FONT_PREF_KEY(pref, "font.size-adjust", generic_dot_langGroup);
198
0
    nsAutoCString cvalue;
199
0
    Preferences::GetCString(pref.get(), cvalue);
200
0
    if (!cvalue.IsEmpty()) {
201
0
      font->sizeAdjust = (float)atof(cvalue.get());
202
0
    }
203
0
204
#ifdef DEBUG_rbs
205
    printf("%s Family-list:%s size:%d sizeAdjust:%.2f\n",
206
           generic_dot_langGroup.get(),
207
           NS_ConvertUTF16toUTF8(font->name).get(), font->size,
208
           font->sizeAdjust);
209
#endif
210
  }
211
0
}
212
213
nsAtom*
214
StaticPresData::GetLangGroup(nsAtom* aLanguage,
215
                             bool* aNeedsToCache) const
216
0
{
217
0
  nsAtom* langGroupAtom = nullptr;
218
0
  langGroupAtom = mLangService->GetLanguageGroup(aLanguage, aNeedsToCache);
219
0
  if (!langGroupAtom) {
220
0
    langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
221
0
  }
222
0
  return langGroupAtom;
223
0
}
224
225
already_AddRefed<nsAtom>
226
StaticPresData::GetUncachedLangGroup(nsAtom* aLanguage) const
227
0
{
228
0
  RefPtr<nsAtom> langGroupAtom = mLangService->GetUncachedLanguageGroup(aLanguage);
229
0
  if (!langGroupAtom) {
230
0
    langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
231
0
  }
232
0
  return langGroupAtom.forget();
233
0
}
234
235
const LangGroupFontPrefs*
236
StaticPresData::GetFontPrefsForLangHelper(nsAtom* aLanguage,
237
                                          const LangGroupFontPrefs* aPrefs,
238
                                          bool* aNeedsToCache) const
239
0
{
240
0
  // Get language group for aLanguage:
241
0
  MOZ_ASSERT(aLanguage);
242
0
  MOZ_ASSERT(mLangService);
243
0
  MOZ_ASSERT(aPrefs);
244
0
245
0
  nsAtom* langGroupAtom = GetLangGroup(aLanguage, aNeedsToCache);
246
0
247
0
  if (aNeedsToCache && *aNeedsToCache) {
248
0
    return nullptr;
249
0
  }
250
0
251
0
  LangGroupFontPrefs* prefs = const_cast<LangGroupFontPrefs*>(aPrefs);
252
0
  if (prefs->mLangGroup) { // if initialized
253
0
    DebugOnly<uint32_t> count = 0;
254
0
    for (;;) {
255
0
      NS_ASSERTION(++count < 35, "Lang group count exceeded!!!");
256
0
      if (prefs->mLangGroup == langGroupAtom) {
257
0
        return prefs;
258
0
      }
259
0
      if (!prefs->mNext) {
260
0
        break;
261
0
      }
262
0
      prefs = prefs->mNext;
263
0
    }
264
0
    if (aNeedsToCache) {
265
0
      *aNeedsToCache = true;
266
0
      return nullptr;
267
0
    }
268
0
    AssertIsMainThreadOrServoLangFontPrefsCacheLocked();
269
0
    // nothing cached, so go on and fetch the prefs for this lang group:
270
0
    prefs = prefs->mNext = new LangGroupFontPrefs;
271
0
  }
272
0
273
0
  if (aNeedsToCache) {
274
0
    *aNeedsToCache = true;
275
0
    return nullptr;
276
0
  }
277
0
278
0
  AssertIsMainThreadOrServoLangFontPrefsCacheLocked();
279
0
  prefs->Initialize(langGroupAtom);
280
0
281
0
  return prefs;
282
0
}
283
284
const nsFont*
285
StaticPresData::GetDefaultFontHelper(uint8_t aFontID, nsAtom *aLanguage,
286
                                     const LangGroupFontPrefs* aPrefs) const
287
0
{
288
0
  MOZ_ASSERT(aLanguage);
289
0
  MOZ_ASSERT(aPrefs);
290
0
291
0
  const nsFont *font;
292
0
  switch (aFontID) {
293
0
    // Special (our default variable width font and fixed width font)
294
0
    case kPresContext_DefaultVariableFont_ID:
295
0
      font = &aPrefs->mDefaultVariableFont;
296
0
      break;
297
0
    case kPresContext_DefaultFixedFont_ID:
298
0
      font = &aPrefs->mDefaultFixedFont;
299
0
      break;
300
0
    // CSS
301
0
    case kGenericFont_serif:
302
0
      font = &aPrefs->mDefaultSerifFont;
303
0
      break;
304
0
    case kGenericFont_sans_serif:
305
0
      font = &aPrefs->mDefaultSansSerifFont;
306
0
      break;
307
0
    case kGenericFont_monospace:
308
0
      font = &aPrefs->mDefaultMonospaceFont;
309
0
      break;
310
0
    case kGenericFont_cursive:
311
0
      font = &aPrefs->mDefaultCursiveFont;
312
0
      break;
313
0
    case kGenericFont_fantasy:
314
0
      font = &aPrefs->mDefaultFantasyFont;
315
0
      break;
316
0
    default:
317
0
      font = nullptr;
318
0
      NS_ERROR("invalid arg");
319
0
      break;
320
0
  }
321
0
  return font;
322
0
}
323
324
325
} // namespace mozilla