tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

StaticPresData.cpp (7696B)


      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 "gfxFontFeatures.h"
     10 #include "mozilla/Preferences.h"
     11 #include "mozilla/ServoBindings.h"
     12 #include "mozilla/ServoUtils.h"
     13 #include "mozilla/StaticPtr.h"
     14 #include "nsPresContext.h"
     15 
     16 namespace mozilla {
     17 
     18 static StaticAutoPtr<StaticPresData> sSingleton;
     19 
     20 void StaticPresData::Init() {
     21  MOZ_ASSERT(!sSingleton);
     22  sSingleton = new StaticPresData();
     23 }
     24 
     25 void StaticPresData::Shutdown() {
     26  MOZ_ASSERT(sSingleton);
     27  sSingleton = nullptr;
     28 }
     29 
     30 StaticPresData* StaticPresData::Get() {
     31  MOZ_ASSERT(sSingleton);
     32  return sSingleton;
     33 }
     34 
     35 StaticPresData::StaticPresData() {
     36  mLangService = nsLanguageAtomService::GetService();
     37 }
     38 
     39 #define MAKE_FONT_PREF_KEY(_pref, _s0, _s1) \
     40  _pref.Assign(_s0);                        \
     41  _pref.Append(_s1);
     42 
     43 // clang-format off
     44 static const char* const kGenericFont[] = {
     45  ".variable.",
     46  ".serif.",
     47  ".sans-serif.",
     48  ".monospace.",
     49  ".cursive.",
     50  ".fantasy.",
     51  ".system-ui.",
     52 };
     53 // clang-format on
     54 
     55 enum class DefaultFont {
     56  Variable = 0,
     57  Serif,
     58  SansSerif,
     59  Monospace,
     60  Cursive,
     61  Fantasy,
     62  SystemUi,
     63  COUNT
     64 };
     65 
     66 void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
     67  mLangGroup = aLangGroupAtom;
     68 
     69  /* Fetch the font prefs to be used -- see bug 61883 for details.
     70     Not all prefs are needed upfront. Some are fallback prefs intended
     71     for the GFX font sub-system...
     72 
     73  -- attributes for generic fonts --------------------------------------
     74 
     75  font.default.[langGroup] = serif | sans-serif
     76    fallback generic font
     77 
     78  font.name.[generic].[langGroup]
     79    current user' selected font on the pref dialog
     80 
     81  font.name-list.[generic].[langGroup] = fontname1, fontname2, ...
     82    [factory pre-built list]
     83 
     84  font.size.[generic].[langGroup] = integer
     85    settable by the user
     86 
     87  font.size-adjust.[generic].[langGroup] = "float"
     88    settable by the user
     89 
     90  font.minimum-size.[langGroup] = integer
     91    settable by the user
     92  */
     93 
     94  nsAutoCString langGroup;
     95  aLangGroupAtom->ToUTF8String(langGroup);
     96 
     97  mDefaultVariableFont.size = Length::FromPixels(16.0f);
     98  mDefaultMonospaceFont.size = Length::FromPixels(13.0f);
     99 
    100  nsAutoCString pref;
    101 
    102  // get font.minimum-size.[langGroup]
    103 
    104  MAKE_FONT_PREF_KEY(pref, "font.minimum-size.", langGroup);
    105 
    106  int32_t size = Preferences::GetInt(pref.get());
    107  mMinimumFontSize = Length::FromPixels(size);
    108 
    109  // clang-format off
    110  nsFont* fontTypes[] = {
    111    &mDefaultVariableFont,
    112    &mDefaultSerifFont,
    113    &mDefaultSansSerifFont,
    114    &mDefaultMonospaceFont,
    115    &mDefaultCursiveFont,
    116    &mDefaultFantasyFont,
    117    &mDefaultSystemUiFont,
    118  };
    119  // clang-format on
    120  static_assert(std::size(fontTypes) == size_t(DefaultFont::COUNT),
    121                "FontTypes array count is not correct");
    122 
    123  // Get attributes specific to each generic font. We do not get the user's
    124  // generic-font-name-to-specific-family-name preferences because its the
    125  // generic name that should be fed into the cascade. It is up to the GFX
    126  // code to look up the font prefs to convert generic names to specific
    127  // family names as necessary.
    128  nsAutoCString generic_dot_langGroup;
    129  for (auto type : MakeEnumeratedRange(DefaultFont::COUNT)) {
    130    generic_dot_langGroup.Assign(kGenericFont[size_t(type)]);
    131    generic_dot_langGroup.Append(langGroup);
    132 
    133    nsFont* font = fontTypes[size_t(type)];
    134 
    135    // Set the default variable font (the other fonts are seen as 'generic'
    136    // fonts in GFX and will be queried there when hunting for alternative
    137    // fonts)
    138    if (type == DefaultFont::Variable) {
    139      // XXX "font.name.variable."?  There is no such pref...
    140      MAKE_FONT_PREF_KEY(pref, "font.name.variable.", langGroup);
    141 
    142      nsAutoCString value;
    143      Preferences::GetCString(pref.get(), value);
    144      if (value.IsEmpty()) {
    145        MAKE_FONT_PREF_KEY(pref, "font.default.", langGroup);
    146        Preferences::GetCString(pref.get(), value);
    147      }
    148      if (!value.IsEmpty()) {
    149        auto defaultVariableName = StyleSingleFontFamily::Parse(value);
    150        auto defaultType = defaultVariableName.IsGeneric()
    151                               ? defaultVariableName.AsGeneric()
    152                               : StyleGenericFontFamily::None;
    153        if (defaultType == StyleGenericFontFamily::Serif ||
    154            defaultType == StyleGenericFontFamily::SansSerif) {
    155          mDefaultVariableFont.family = *Servo_FontFamily_Generic(defaultType);
    156        } else {
    157          NS_WARNING("default type must be serif or sans-serif");
    158        }
    159      }
    160    } else {
    161      if (type != DefaultFont::Monospace) {
    162        // all the other generic fonts are initialized with the size of the
    163        // variable font, but their specific size can supersede later -- see
    164        // below
    165        font->size = mDefaultVariableFont.size;
    166      }
    167    }
    168 
    169    // Bug 84398: for spec purists, a different font-size only applies to the
    170    // .variable. and .fixed. fonts and the other fonts should get
    171    // |font-size-adjust|. The problem is that only GfxWin has the support for
    172    // |font-size-adjust|. So for parity, we enable the ability to set a
    173    // different font-size on all platforms.
    174 
    175    // get font.size.[generic].[langGroup]
    176    // size=0 means 'Auto', i.e., generic fonts retain the size of the variable
    177    // font
    178    MAKE_FONT_PREF_KEY(pref, "font.size", generic_dot_langGroup);
    179    size = Preferences::GetInt(pref.get());
    180    if (size > 0) {
    181      font->size = Length::FromPixels(size);
    182    }
    183 
    184    // get font.size-adjust.[generic].[langGroup]
    185    // XXX only applicable on GFX ports that handle |font-size-adjust|
    186    MAKE_FONT_PREF_KEY(pref, "font.size-adjust", generic_dot_langGroup);
    187    nsAutoCString cvalue;
    188    Preferences::GetCString(pref.get(), cvalue);
    189    if (!cvalue.IsEmpty()) {
    190      font->sizeAdjust =
    191          StyleFontSizeAdjust::ExHeight(float(atof(cvalue.get())));
    192    }
    193 
    194 #ifdef DEBUG_rbs
    195    printf("%s Family-list:%s size:%d sizeAdjust:%.2f\n",
    196           generic_dot_langGroup.get(), NS_ConvertUTF16toUTF8(font->name).get(),
    197           font->size, font->sizeAdjust);
    198 #endif
    199  }
    200 }
    201 
    202 nsStaticAtom* StaticPresData::GetLangGroup(nsAtom* aLanguage) const {
    203  nsStaticAtom* langGroupAtom = mLangService->GetLanguageGroup(aLanguage);
    204  // Assume x-western is safe...
    205  return langGroupAtom ? langGroupAtom : nsGkAtoms::x_western;
    206 }
    207 
    208 const LangGroupFontPrefs* StaticPresData::GetFontPrefsForLang(
    209    nsAtom* aLanguage, bool* aNeedsToCache) {
    210  // Get language group for aLanguage:
    211  MOZ_ASSERT(aLanguage);
    212  MOZ_ASSERT(mLangService);
    213 
    214  nsStaticAtom* langGroupAtom = GetLangGroup(aLanguage);
    215 
    216  if (!aNeedsToCache) {
    217    AssertIsMainThreadOrServoFontMetricsLocked();
    218  }
    219 
    220  LangGroupFontPrefs* prefs = &mLangGroupFontPrefs;
    221  if (prefs->mLangGroup) {  // if initialized
    222    DebugOnly<uint32_t> count = 0;
    223    for (;;) {
    224      if (prefs->mLangGroup == langGroupAtom) {
    225        return prefs;
    226      }
    227      if (!prefs->mNext) {
    228        break;
    229      }
    230      prefs = prefs->mNext.get();
    231    }
    232    if (aNeedsToCache) {
    233      *aNeedsToCache = true;
    234      return nullptr;
    235    }
    236    // nothing cached, so go on and fetch the prefs for this lang group:
    237    prefs->mNext = MakeUnique<LangGroupFontPrefs>();
    238    prefs = prefs->mNext.get();
    239  }
    240 
    241  if (aNeedsToCache) {
    242    *aNeedsToCache = true;
    243    return nullptr;
    244  }
    245 
    246  AssertIsMainThreadOrServoFontMetricsLocked();
    247  prefs->Initialize(langGroupAtom);
    248 
    249  return prefs;
    250 }
    251 
    252 }  // namespace mozilla