diff options
Diffstat (limited to 'layout/base/StaticPresData.cpp')
-rw-r--r-- | layout/base/StaticPresData.cpp | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/layout/base/StaticPresData.cpp b/layout/base/StaticPresData.cpp new file mode 100644 index 000000000..73acd5440 --- /dev/null +++ b/layout/base/StaticPresData.cpp @@ -0,0 +1,311 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "mozilla/StaticPresData.h" + +#include "mozilla/Preferences.h" +#include "nsPresContext.h" + +namespace mozilla { + +static StaticPresData* sSingleton = nullptr; + +void +StaticPresData::Init() +{ + MOZ_ASSERT(!sSingleton); + sSingleton = new StaticPresData(); +} + +void +StaticPresData::Shutdown() +{ + MOZ_ASSERT(sSingleton); + delete sSingleton; + sSingleton = nullptr; +} + +StaticPresData* +StaticPresData::Get() +{ + MOZ_ASSERT(sSingleton); + return sSingleton; +} + +StaticPresData::StaticPresData() +{ + mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID); + + mBorderWidthTable[NS_STYLE_BORDER_WIDTH_THIN] = nsPresContext::CSSPixelsToAppUnits(1); + mBorderWidthTable[NS_STYLE_BORDER_WIDTH_MEDIUM] = nsPresContext::CSSPixelsToAppUnits(3); + mBorderWidthTable[NS_STYLE_BORDER_WIDTH_THICK] = nsPresContext::CSSPixelsToAppUnits(5); +} + +#define MAKE_FONT_PREF_KEY(_pref, _s0, _s1) \ + _pref.Assign(_s0); \ + _pref.Append(_s1); + +static const char* const kGenericFont[] = { + ".variable.", + ".fixed.", + ".serif.", + ".sans-serif.", + ".monospace.", + ".cursive.", + ".fantasy." +}; + +// These are private, use the list in nsFont.h if you want a public list. +enum { + eDefaultFont_Variable, + eDefaultFont_Fixed, + eDefaultFont_Serif, + eDefaultFont_SansSerif, + eDefaultFont_Monospace, + eDefaultFont_Cursive, + eDefaultFont_Fantasy, + eDefaultFont_COUNT +}; + +const LangGroupFontPrefs* +StaticPresData::GetFontPrefsForLangHelper(nsIAtom *aLanguage, + const LangGroupFontPrefs* aPrefs) const +{ + // Get language group for aLanguage: + MOZ_ASSERT(aLanguage); + MOZ_ASSERT(mLangService); + MOZ_ASSERT(aPrefs); + + nsresult rv = NS_OK; + nsIAtom *langGroupAtom = nullptr; + langGroupAtom = mLangService->GetLanguageGroup(aLanguage, &rv); + if (NS_FAILED(rv) || !langGroupAtom) { + langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe... + } + + LangGroupFontPrefs *prefs = const_cast<LangGroupFontPrefs*>(aPrefs); + if (prefs->mLangGroup) { // if initialized + DebugOnly<uint32_t> count = 0; + for (;;) { + NS_ASSERTION(++count < 35, "Lang group count exceeded!!!"); + if (prefs->mLangGroup == langGroupAtom) { + return prefs; + } + if (!prefs->mNext) { + break; + } + prefs = prefs->mNext; + } + + // nothing cached, so go on and fetch the prefs for this lang group: + prefs = prefs->mNext = new LangGroupFontPrefs; + } + + prefs->mLangGroup = langGroupAtom; + + /* Fetch the font prefs to be used -- see bug 61883 for details. + Not all prefs are needed upfront. Some are fallback prefs intended + for the GFX font sub-system... + + 1) unit : assumed to be the same for all language groups ------------- + font.size.unit = px | pt XXX could be folded in the size... bug 90440 + + 2) attributes for generic fonts -------------------------------------- + font.default.[langGroup] = serif | sans-serif - fallback generic font + font.name.[generic].[langGroup] = current user' selected font on the pref dialog + font.name-list.[generic].[langGroup] = fontname1, fontname2, ... [factory pre-built list] + font.size.[generic].[langGroup] = integer - settable by the user + font.size-adjust.[generic].[langGroup] = "float" - settable by the user + font.minimum-size.[langGroup] = integer - settable by the user + */ + + nsAutoCString langGroup; + langGroupAtom->ToUTF8String(langGroup); + + prefs->mDefaultVariableFont.size = nsPresContext::CSSPixelsToAppUnits(16); + prefs->mDefaultFixedFont.size = nsPresContext::CSSPixelsToAppUnits(13); + + nsAutoCString pref; + + // get the current applicable font-size unit + enum {eUnit_unknown = -1, eUnit_px, eUnit_pt}; + int32_t unit = eUnit_px; + + nsAdoptingCString cvalue = + Preferences::GetCString("font.size.unit"); + + if (!cvalue.IsEmpty()) { + if (cvalue.EqualsLiteral("px")) { + unit = eUnit_px; + } + else if (cvalue.EqualsLiteral("pt")) { + unit = eUnit_pt; + } + else { + // XXX should really send this warning to the user (Error Console?). + // And just default to unit = eUnit_px? + NS_WARNING("unexpected font-size unit -- expected: 'px' or 'pt'"); + unit = eUnit_unknown; + } + } + + // get font.minimum-size.[langGroup] + + MAKE_FONT_PREF_KEY(pref, "font.minimum-size.", langGroup); + + int32_t size = Preferences::GetInt(pref.get()); + if (unit == eUnit_px) { + prefs->mMinimumFontSize = nsPresContext::CSSPixelsToAppUnits(size); + } + else if (unit == eUnit_pt) { + prefs->mMinimumFontSize = nsPresContext::CSSPointsToAppUnits(size); + } + + nsFont* fontTypes[] = { + &prefs->mDefaultVariableFont, + &prefs->mDefaultFixedFont, + &prefs->mDefaultSerifFont, + &prefs->mDefaultSansSerifFont, + &prefs->mDefaultMonospaceFont, + &prefs->mDefaultCursiveFont, + &prefs->mDefaultFantasyFont + }; + static_assert(MOZ_ARRAY_LENGTH(fontTypes) == eDefaultFont_COUNT, + "FontTypes array count is not correct"); + + // Get attributes specific to each generic font. We do not get the user's + // generic-font-name-to-specific-family-name preferences because its the + // generic name that should be fed into the cascade. It is up to the GFX + // code to look up the font prefs to convert generic names to specific + // family names as necessary. + nsAutoCString generic_dot_langGroup; + for (uint32_t eType = 0; eType < ArrayLength(fontTypes); ++eType) { + generic_dot_langGroup.Assign(kGenericFont[eType]); + generic_dot_langGroup.Append(langGroup); + + nsFont* font = fontTypes[eType]; + + // set the default variable font (the other fonts are seen as 'generic' fonts + // in GFX and will be queried there when hunting for alternative fonts) + if (eType == eDefaultFont_Variable) { + MAKE_FONT_PREF_KEY(pref, "font.name.variable.", langGroup); + + nsAdoptingString value = Preferences::GetString(pref.get()); + if (!value.IsEmpty()) { + FontFamilyName defaultVariableName = FontFamilyName::Convert(value); + FontFamilyType defaultType = defaultVariableName.mType; + NS_ASSERTION(defaultType == eFamily_serif || + defaultType == eFamily_sans_serif, + "default type must be serif or sans-serif"); + prefs->mDefaultVariableFont.fontlist = FontFamilyList(defaultType); + } + else { + MAKE_FONT_PREF_KEY(pref, "font.default.", langGroup); + value = Preferences::GetString(pref.get()); + if (!value.IsEmpty()) { + FontFamilyName defaultVariableName = FontFamilyName::Convert(value); + FontFamilyType defaultType = defaultVariableName.mType; + NS_ASSERTION(defaultType == eFamily_serif || + defaultType == eFamily_sans_serif, + "default type must be serif or sans-serif"); + prefs->mDefaultVariableFont.fontlist = FontFamilyList(defaultType); + } + } + } + else { + if (eType == eDefaultFont_Monospace) { + // This takes care of the confusion whereby people often expect "monospace" + // to have the same default font-size as "-moz-fixed" (this tentative + // size may be overwritten with the specific value for "monospace" when + // "font.size.monospace.[langGroup]" is read -- see below) + prefs->mDefaultMonospaceFont.size = prefs->mDefaultFixedFont.size; + } + else if (eType != eDefaultFont_Fixed) { + // all the other generic fonts are initialized with the size of the + // variable font, but their specific size can supersede later -- see below + font->size = prefs->mDefaultVariableFont.size; + } + } + + // Bug 84398: for spec purists, a different font-size only applies to the + // .variable. and .fixed. fonts and the other fonts should get |font-size-adjust|. + // The problem is that only GfxWin has the support for |font-size-adjust|. So for + // parity, we enable the ability to set a different font-size on all platforms. + + // get font.size.[generic].[langGroup] + // size=0 means 'Auto', i.e., generic fonts retain the size of the variable font + MAKE_FONT_PREF_KEY(pref, "font.size", generic_dot_langGroup); + size = Preferences::GetInt(pref.get()); + if (size > 0) { + if (unit == eUnit_px) { + font->size = nsPresContext::CSSPixelsToAppUnits(size); + } + else if (unit == eUnit_pt) { + font->size = nsPresContext::CSSPointsToAppUnits(size); + } + } + + // get font.size-adjust.[generic].[langGroup] + // XXX only applicable on GFX ports that handle |font-size-adjust| + MAKE_FONT_PREF_KEY(pref, "font.size-adjust", generic_dot_langGroup); + cvalue = Preferences::GetCString(pref.get()); + if (!cvalue.IsEmpty()) { + font->sizeAdjust = (float)atof(cvalue.get()); + } + +#ifdef DEBUG_rbs + printf("%s Family-list:%s size:%d sizeAdjust:%.2f\n", + generic_dot_langGroup.get(), + NS_ConvertUTF16toUTF8(font->name).get(), font->size, + font->sizeAdjust); +#endif + } + + return prefs; +} + +const nsFont* +StaticPresData::GetDefaultFontHelper(uint8_t aFontID, nsIAtom *aLanguage, + const LangGroupFontPrefs* aPrefs) const +{ + MOZ_ASSERT(aLanguage); + MOZ_ASSERT(aPrefs); + + const nsFont *font; + switch (aFontID) { + // Special (our default variable width font and fixed width font) + case kPresContext_DefaultVariableFont_ID: + font = &aPrefs->mDefaultVariableFont; + break; + case kPresContext_DefaultFixedFont_ID: + font = &aPrefs->mDefaultFixedFont; + break; + // CSS + case kGenericFont_serif: + font = &aPrefs->mDefaultSerifFont; + break; + case kGenericFont_sans_serif: + font = &aPrefs->mDefaultSansSerifFont; + break; + case kGenericFont_monospace: + font = &aPrefs->mDefaultMonospaceFont; + break; + case kGenericFont_cursive: + font = &aPrefs->mDefaultCursiveFont; + break; + case kGenericFont_fantasy: + font = &aPrefs->mDefaultFantasyFont; + break; + default: + font = nullptr; + NS_ERROR("invalid arg"); + break; + } + return font; +} + + +} // namespace mozilla |