Bug 1261552 - Introduce StaticPresData and hoist some shared functionality into it. r=heycam

The complexity around the font pref cache stuff is really annoying. If we
think it's unnecessary, we could remove it in a followup.
This commit is contained in:
Bobby Holley 2016-03-31 12:47:20 -07:00
parent 9e30bdaebc
commit 479711a580
7 changed files with 502 additions and 345 deletions

View File

@ -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

View File

@ -0,0 +1,160 @@
/* -*- 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/. */
#ifndef mozilla_StaticPresData_h
#define mozilla_StaticPresData_h
#include "nsAutoPtr.h"
#include "nsCoord.h"
#include "nsCOMPtr.h"
#include "nsFont.h"
#include "nsIAtom.h"
#include "nsILanguageAtomService.h"
namespace mozilla {
struct LangGroupFontPrefs {
// Font sizes default to zero; they will be set in GetFontPreferences
LangGroupFontPrefs()
: mLangGroup(nullptr)
, mMinimumFontSize(0)
, mDefaultVariableFont(mozilla::eFamily_serif, 0)
, mDefaultFixedFont(mozilla::eFamily_monospace, 0)
, mDefaultSerifFont(mozilla::eFamily_serif, 0)
, mDefaultSansSerifFont(mozilla::eFamily_sans_serif, 0)
, mDefaultMonospaceFont(mozilla::eFamily_monospace, 0)
, mDefaultCursiveFont(mozilla::eFamily_cursive, 0)
, mDefaultFantasyFont(mozilla::eFamily_fantasy, 0)
{}
void Reset()
{
// Throw away any other LangGroupFontPrefs objects:
mNext = nullptr;
// Make GetFontPreferences reinitialize mLangGroupFontPrefs:
mLangGroup = nullptr;
}
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
size_t n = 0;
LangGroupFontPrefs* curr = mNext;
while (curr) {
n += aMallocSizeOf(curr);
// Measurement of the following members may be added later if DMD finds
// it is worthwhile:
// - mLangGroup
// - mDefault*Font
curr = curr->mNext;
}
return n;
}
nsCOMPtr<nsIAtom> mLangGroup;
nscoord mMinimumFontSize;
nsFont mDefaultVariableFont;
nsFont mDefaultFixedFont;
nsFont mDefaultSerifFont;
nsFont mDefaultSansSerifFont;
nsFont mDefaultMonospaceFont;
nsFont mDefaultCursiveFont;
nsFont mDefaultFantasyFont;
nsAutoPtr<LangGroupFontPrefs> mNext;
};
/**
* 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();
/**
* This table maps border-width enums 'thin', 'medium', 'thick'
* to actual nscoord values.
*/
const nscoord* GetBorderWidthTable() { return mBorderWidthTable; }
/**
* 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* GetFontPrefsForLangHelper(nsIAtom* aLanguage,
const LangGroupFontPrefs* aPrefs) const;
/**
* 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.
*
* When aFontID is kPresContext_DefaultVariableFontID or
* kPresContext_DefaultFixedFontID (which equals
* kGenericFont_moz_fixed, which is used for the -moz-fixed generic),
* the nsFont returned has its name as a CSS generic family (serif or
* sans-serif for the former, monospace for the latter), and its size
* as the default font size for variable or fixed fonts for the
* language group.
*
* 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* GetDefaultFontHelper(uint8_t aFontID,
nsIAtom* aLanguage,
const LangGroupFontPrefs* aPrefs) const;
/*
* These versions operate on the font pref cache on StaticPresData.
*/
const nsFont* GetDefaultFont(uint8_t aFontID, nsIAtom* aLanguage) const
{
MOZ_ASSERT(aLanguage);
return GetDefaultFontHelper(aFontID, aLanguage, GetFontPrefsForLang(aLanguage));
}
const LangGroupFontPrefs* GetFontPrefsForLang(nsIAtom* aLanguage) const
{
MOZ_ASSERT(aLanguage);
return GetFontPrefsForLangHelper(aLanguage, &mStaticLangGroupFontPrefs);
}
void ResetCachedFontPrefs() { mStaticLangGroupFontPrefs.Reset(); }
private:
StaticPresData();
~StaticPresData() {}
nsCOMPtr<nsILanguageAtomService> mLangService;
nscoord mBorderWidthTable[3];
LangGroupFontPrefs mStaticLangGroupFontPrefs;
};
} // namespace mozilla
#endif // mozilla_StaticPresData_h

View File

@ -109,6 +109,7 @@ EXPORTS.mozilla += [
'RestyleManagerHandle.h',
'RestyleManagerHandleInlines.h',
'ServoRestyleManager.h',
'StaticPresData.h',
]
UNIFIED_SOURCES += [
@ -154,6 +155,7 @@ UNIFIED_SOURCES += [
'ScrollbarStyles.cpp',
'ServoRestyleManager.cpp',
'StackArena.cpp',
'StaticPresData.cpp',
'TouchManager.cpp',
'ZoomConstraintsClient.cpp',
]

View File

@ -397,21 +397,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsPresContext)
tmp->Destroy();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
#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."
};
// whether no native theme service exists;
// if this gets set to true, we'll stop asking for it.
static bool sNoTheme = false;
@ -426,212 +411,6 @@ static bool sLookAndFeelChanged;
// one prescontext.
static bool sThemeChanged;
const nsPresContext::LangGroupFontPrefs*
nsPresContext::GetFontPrefsForLang(nsIAtom *aLanguage) const
{
// Get language group for aLanguage:
nsresult rv = NS_OK;
nsIAtom *langGroupAtom = nullptr;
if (!aLanguage) {
aLanguage = mLanguage;
}
if (aLanguage && mLangService) {
langGroupAtom = mLangService->GetLanguageGroup(aLanguage, &rv);
}
if (NS_FAILED(rv) || !langGroupAtom) {
langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
}
// Look for cached prefs for this lang group.
// Most documents will only use one (or very few) language groups. Rather
// than have the overhead of a hash lookup, we simply look along what will
// typically be a very short (usually of length 1) linked list. There are 31
// language groups, so in the worst case scenario we'll need to traverse 31
// link items.
LangGroupFontPrefs *prefs =
const_cast<LangGroupFontPrefs*>(&mLangGroupFontPrefs);
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 = CSSPixelsToAppUnits(16);
prefs->mDefaultFixedFont.size = 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 = CSSPixelsToAppUnits(size);
}
else if (unit == eUnit_pt) {
prefs->mMinimumFontSize = 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 = CSSPixelsToAppUnits(size);
}
else if (unit == eUnit_pt) {
font->size = 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;
}
void
nsPresContext::GetDocumentColorPreferences()
{
@ -800,7 +579,8 @@ nsPresContext::GetUserPreferences()
mPrefScrollbarSide = Preferences::GetInt("layout.scrollbar.side");
ResetCachedFontPrefs();
mLangGroupFontPrefs.Reset();
StaticPresData::Get()->ResetCachedFontPrefs();
// * image animation
const nsAdoptingCString& animatePref =
@ -1236,7 +1016,7 @@ nsPresContext::UpdateCharSet(const nsCString& aCharSet)
if (mLanguage == nsGkAtoms::Unicode) {
mLanguage = mLangService->GetLocaleLanguage();
}
ResetCachedFontPrefs();
mLangGroupFontPrefs.Reset();
}
switch (GET_BIDI_OPTION_TEXTTYPE(GetBidi())) {
@ -1475,44 +1255,6 @@ nsPresContext::SetImageAnimationModeExternal(uint16_t aMode)
SetImageAnimationModeInternal(aMode);
}
const nsFont*
nsPresContext::GetDefaultFont(uint8_t aFontID, nsIAtom *aLanguage) const
{
const LangGroupFontPrefs *prefs = GetFontPrefsForLang(aLanguage);
const nsFont *font;
switch (aFontID) {
// Special (our default variable width font and fixed width font)
case kPresContext_DefaultVariableFont_ID:
font = &prefs->mDefaultVariableFont;
break;
case kPresContext_DefaultFixedFont_ID:
font = &prefs->mDefaultFixedFont;
break;
// CSS
case kGenericFont_serif:
font = &prefs->mDefaultSerifFont;
break;
case kGenericFont_sans_serif:
font = &prefs->mDefaultSansSerifFont;
break;
case kGenericFont_monospace:
font = &prefs->mDefaultMonospaceFont;
break;
case kGenericFont_cursive:
font = &prefs->mDefaultCursiveFont;
break;
case kGenericFont_fantasy:
font = &prefs->mDefaultFantasyFont;
break;
default:
font = nullptr;
NS_ERROR("invalid arg");
break;
}
return font;
}
already_AddRefed<nsIAtom>
nsPresContext::GetContentLanguage() const
{

View File

@ -42,6 +42,7 @@
#include "Units.h"
#include "mozilla/RestyleManagerHandle.h"
#include "prenv.h"
#include "mozilla/StaticPresData.h"
class nsAString;
class nsIPrintSettings;
@ -135,7 +136,9 @@ class nsRootPresContext;
class nsPresContext : public nsIObserver {
public:
typedef mozilla::FramePropertyTable FramePropertyTable;
typedef mozilla::LangGroupFontPrefs LangGroupFontPrefs;
typedef mozilla::ScrollbarStyles ScrollbarStyles;
typedef mozilla::StaticPresData StaticPresData;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIOBSERVER
@ -365,23 +368,15 @@ public:
* Get the default font for the given language and generic font ID.
* If aLanguage is nullptr, the document's language is used.
*
* This object is read-only, you must copy the font to modify it.
*
* When aFontID is kPresContext_DefaultVariableFontID or
* kPresContext_DefaultFixedFontID (which equals
* kGenericFont_moz_fixed, which is used for the -moz-fixed generic),
* the nsFont returned has its name as a CSS generic family (serif or
* sans-serif for the former, monospace for the latter), and its size
* as the default font size for variable or fixed fonts for the
* language group.
*
* 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.
* See the comment in StaticPresData::GetDefaultFont.
*/
const nsFont* GetDefaultFont(uint8_t aFontID,
nsIAtom *aLanguage) const;
nsIAtom *aLanguage) const
{
nsIAtom* lang = aLanguage ? aLanguage : mLanguage.get();
return StaticPresData::Get()->GetDefaultFontHelper(aFontID, lang,
GetFontPrefsForLang(lang));
}
/** Get a cached boolean pref, by its type */
// * - initially created for bugs 31816, 20760, 22963
@ -1125,64 +1120,14 @@ protected:
void GetUserPreferences();
// Allow nsAutoPtr<LangGroupFontPrefs> dtor to access this protected struct's
// dtor:
struct LangGroupFontPrefs;
friend class nsAutoPtr<LangGroupFontPrefs>;
struct LangGroupFontPrefs {
// Font sizes default to zero; they will be set in GetFontPreferences
LangGroupFontPrefs()
: mLangGroup(nullptr)
, mMinimumFontSize(0)
, mDefaultVariableFont(mozilla::eFamily_serif, 0)
, mDefaultFixedFont(mozilla::eFamily_monospace, 0)
, mDefaultSerifFont(mozilla::eFamily_serif, 0)
, mDefaultSansSerifFont(mozilla::eFamily_sans_serif, 0)
, mDefaultMonospaceFont(mozilla::eFamily_monospace, 0)
, mDefaultCursiveFont(mozilla::eFamily_cursive, 0)
, mDefaultFantasyFont(mozilla::eFamily_fantasy, 0)
{}
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
size_t n = 0;
LangGroupFontPrefs *curr = mNext;
while (curr) {
n += aMallocSizeOf(curr);
// Measurement of the following members may be added later if DMD finds
// it is worthwhile:
// - mLangGroup
// - mDefault*Font
curr = curr->mNext;
}
return n;
}
nsCOMPtr<nsIAtom> mLangGroup;
nscoord mMinimumFontSize;
nsFont mDefaultVariableFont;
nsFont mDefaultFixedFont;
nsFont mDefaultSerifFont;
nsFont mDefaultSansSerifFont;
nsFont mDefaultMonospaceFont;
nsFont mDefaultCursiveFont;
nsFont mDefaultFantasyFont;
nsAutoPtr<LangGroupFontPrefs> mNext;
};
/**
* Fetch the user's font preferences for the given aLanguage's
* langugage group.
*/
const LangGroupFontPrefs* GetFontPrefsForLang(nsIAtom *aLanguage) const;
void ResetCachedFontPrefs() {
// Throw away any other LangGroupFontPrefs objects:
mLangGroupFontPrefs.mNext = nullptr;
// Make GetFontPreferences reinitialize mLangGroupFontPrefs:
mLangGroupFontPrefs.mLangGroup = nullptr;
const LangGroupFontPrefs* GetFontPrefsForLang(nsIAtom *aLanguage) const
{
nsIAtom* lang = aLanguage ? aLanguage : mLanguage.get();
return StaticPresData::Get()->GetFontPrefsForLangHelper(lang, &mLangGroupFontPrefs);
}
void UpdateCharSet(const nsCString& aCharSet);
@ -1332,6 +1277,11 @@ protected:
uint16_t mImageAnimationMode;
uint16_t mImageAnimationModePref;
// Most documents will only use one (or very few) language groups. Rather
// than have the overhead of a hash lookup, we simply look along what will
// typically be a very short (usually of length 1) linked list. There are 31
// language groups, so in the worst case scenario we'll need to traverse 31
// link items.
LangGroupFontPrefs mLangGroupFontPrefs;
nscoord mBorderWidthTable[3];
@ -1433,18 +1383,6 @@ protected:
virtual ~nsPresContext();
// 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
};
nscolor MakeColorPref(const nsString& aColor);
void LastRelease();

View File

@ -131,6 +131,7 @@ using namespace mozilla::system;
#include "MediaDecoder.h"
#include "mozilla/layers/CompositorLRU.h"
#include "mozilla/dom/devicestorage/DeviceStorageStatics.h"
#include "mozilla/StaticPresData.h"
#ifdef MOZ_B2G_BT
#include "mozilla/dom/BluetoothUUID.h"
@ -197,6 +198,7 @@ nsLayoutStatics::Initialize()
nsCellMap::Init();
StaticPresData::Init();
nsCSSRendering::Init();
nsTextFrameTextRunCache::Init();
@ -347,6 +349,7 @@ nsLayoutStatics::Shutdown()
nsTextFrameTextRunCache::Shutdown();
nsHTMLDNSPrefetch::Shutdown();
nsCSSRendering::Shutdown();
StaticPresData::Shutdown();
#ifdef DEBUG
nsFrame::DisplayReflowShutdown();
#endif

View File

@ -109,7 +109,7 @@ nsStyleFont::nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext)
, mExplicitLanguage(false)
, mAllowZoom(true)
, mScriptUnconstrainedSize(mSize)
, mScriptMinSize(aPresContext->CSSTwipsToAppUnits(
, mScriptMinSize(nsPresContext::CSSTwipsToAppUnits(
NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT)))
, mScriptSizeMultiplier(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER)
, mLanguage(GetLanguage(aPresContext))
@ -373,7 +373,7 @@ nsStyleBorder::nsStyleBorder(nsPresContext* aPresContext)
}
nscoord medium =
(aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
(StaticPresData::Get()->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
NS_FOR_CSS_SIDES(side) {
mBorderImageSlice.Set(side, nsStyleCoord(1.0f, eStyleUnit_Percent));
mBorderImageWidth.Set(side, nsStyleCoord(1.0f, eStyleUnit_Factor));
@ -760,7 +760,8 @@ nsStyleColumn::nsStyleColumn(nsPresContext* aPresContext)
mColumnGap.SetNormalValue();
mColumnFill = NS_STYLE_COLUMN_FILL_BALANCE;
mColumnRuleWidth = (aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
mColumnRuleWidth =
(StaticPresData::Get()->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
mColumnRuleStyle = NS_STYLE_BORDER_STYLE_NONE;
mColumnRuleColor = NS_RGB(0, 0, 0);
mColumnRuleColorIsForeground = true;