mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
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:
parent
9e30bdaebc
commit
479711a580
311
layout/base/StaticPresData.cpp
Normal file
311
layout/base/StaticPresData.cpp
Normal 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
|
160
layout/base/StaticPresData.h
Normal file
160
layout/base/StaticPresData.h
Normal 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
|
@ -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',
|
||||
]
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user