Bug 416581, part 2 - Pay attention to the 'lang' attribute when fetching the user's font prefs for the CSS cascade. r=dbaron.

This commit is contained in:
Jonathan Watt 2012-01-25 23:52:26 +00:00
parent 503db232a8
commit b84e0cbe12
11 changed files with 224 additions and 153 deletions

View File

@ -859,7 +859,7 @@ TransferZoomLevels(nsIDocument* aFromDoc,
return;
toCtxt->SetFullZoom(fromCtxt->GetFullZoom());
toCtxt->SetMinFontSize(fromCtxt->MinFontSize());
toCtxt->SetMinFontSize(fromCtxt->MinFontSize(nsnull));
toCtxt->SetTextZoom(fromCtxt->TextZoom());
}

View File

@ -1100,6 +1100,7 @@ GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
GK_ATOM(headerCSP, "x-content-security-policy")
GK_ATOM(headerCSPReportOnly, "x-content-security-policy-report-only")
GK_ATOM(headerXFO, "x-frame-options")
GK_ATOM(x_western, "x-western")
GK_ATOM(xml, "xml")
GK_ATOM(xml_stylesheet, "xml-stylesheet")
GK_ATOM(xmlns, "xmlns")

View File

@ -2873,7 +2873,7 @@ DocumentViewerImpl::SetMinFontSize(PRInt32 aMinFontSize)
// Now change our own min font
nsPresContext* pc = GetPresContext();
if (pc && aMinFontSize != mPresContext->MinFontSize()) {
if (pc && aMinFontSize != mPresContext->MinFontSize(nsnull)) {
pc->SetMinFontSize(aMinFontSize);
}
@ -2889,7 +2889,7 @@ DocumentViewerImpl::GetMinFontSize(PRInt32* aMinFontSize)
{
NS_ENSURE_ARG_POINTER(aMinFontSize);
nsPresContext* pc = GetPresContext();
*aMinFontSize = pc ? pc->MinFontSize() : 0;
*aMinFontSize = pc ? pc->MinFontSize(nsnull) : 0;
return NS_OK;
}

View File

@ -212,27 +212,7 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
: mType(aType), mDocument(aDocument), mMinFontSize(0),
mTextZoom(1.0), mFullZoom(1.0), mPageSize(-1, -1), mPPScale(1.0f),
mViewportStyleOverflow(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO),
mImageAnimationModePref(imgIContainer::kNormalAnimMode),
// Font sizes default to zero; they will be set in GetFontPreferences
mDefaultVariableFont("serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultFixedFont("monospace", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultSerifFont("serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultSansSerifFont("sans-serif", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultMonospaceFont("monospace", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultCursiveFont("cursive", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultFantasyFont("fantasy", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
mImageAnimationModePref(imgIContainer::kNormalAnimMode)
{
// NOTE! nsPresContext::operator new() zeroes out all members, so don't
// bother initializing members to 0.
@ -443,9 +423,51 @@ static bool sLookAndFeelChanged;
// one prescontext.
static bool sThemeChanged;
void
nsPresContext::GetFontPreferences()
const nsPresContext::LangGroupFontPrefs*
nsPresContext::GetFontPrefsForLang(nsIAtom *aLanguage) const
{
// Get language group for aLanguage:
nsresult rv;
nsIAtom *langGroupAtom = nsnull;
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<PRUint32> 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...
@ -454,7 +476,7 @@ nsPresContext::GetFontPreferences()
font.size.unit = px | pt XXX could be folded in the size... bug 90440
2) attributes for generic fonts --------------------------------------
font.default = serif | sans-serif - fallback generic font
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
@ -462,24 +484,11 @@ nsPresContext::GetFontPreferences()
font.minimum-size.[langGroup] = integer - settable by the user
*/
mDefaultVariableFont.size = CSSPixelsToAppUnits(16);
mDefaultFixedFont.size = CSSPixelsToAppUnits(13);
// the font prefs are based on langGroup, not actual language
nsCAutoString langGroup;
if (mLanguage && mLangService) {
nsresult rv;
nsIAtom *group = mLangService->GetLanguageGroup(mLanguage, &rv);
if (NS_SUCCEEDED(rv) && group) {
group->ToUTF8String(langGroup);
}
else {
langGroup.AssignLiteral("x-western"); // Assume x-western is safe...
}
}
else {
langGroup.AssignLiteral("x-western"); // Assume x-western is safe...
}
langGroupAtom->ToUTF8String(langGroup);
prefs->mDefaultVariableFont.size = CSSPixelsToAppUnits(16);
prefs->mDefaultFixedFont.size = CSSPixelsToAppUnits(13);
nsCAutoString pref;
@ -498,6 +507,8 @@ nsPresContext::GetFontPreferences()
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;
}
@ -505,29 +516,32 @@ nsPresContext::GetFontPreferences()
// get font.minimum-size.[langGroup]
pref.Assign("font.minimum-size.");
pref.Append(langGroup);
MAKE_FONT_PREF_KEY(pref, "font.minimum-size.", langGroup);
PRInt32 size = Preferences::GetInt(pref.get());
if (unit == eUnit_px) {
mMinimumFontSizePref = CSSPixelsToAppUnits(size);
prefs->mMinimumFontSize = CSSPixelsToAppUnits(size);
}
else if (unit == eUnit_pt) {
mMinimumFontSizePref = CSSPointsToAppUnits(size);
prefs->mMinimumFontSize = CSSPointsToAppUnits(size);
}
nsFont* fontTypes[] = {
&mDefaultVariableFont,
&mDefaultFixedFont,
&mDefaultSerifFont,
&mDefaultSansSerifFont,
&mDefaultMonospaceFont,
&mDefaultCursiveFont,
&mDefaultFantasyFont
&prefs->mDefaultVariableFont,
&prefs->mDefaultFixedFont,
&prefs->mDefaultSerifFont,
&prefs->mDefaultSansSerifFont,
&prefs->mDefaultMonospaceFont,
&prefs->mDefaultCursiveFont,
&prefs->mDefaultFantasyFont
};
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(fontTypes) == eDefaultFont_COUNT);
// get attributes specific to each generic font
// 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.
nsCAutoString generic_dot_langGroup;
for (PRUint32 eType = 0; eType < ArrayLength(fontTypes); ++eType) {
generic_dot_langGroup.Assign(kGenericFont[eType]);
@ -538,17 +552,17 @@ nsPresContext::GetFontPreferences()
// 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", generic_dot_langGroup);
MAKE_FONT_PREF_KEY(pref, "font.name.variable.", langGroup);
nsAdoptingString value = Preferences::GetString(pref.get());
if (!value.IsEmpty()) {
font->name.Assign(value);
prefs->mDefaultVariableFont.name.Assign(value);
}
else {
MAKE_FONT_PREF_KEY(pref, "font.default.", langGroup);
value = Preferences::GetString(pref.get());
if (!value.IsEmpty()) {
mDefaultVariableFont.name.Assign(value);
prefs->mDefaultVariableFont.name.Assign(value);
}
}
}
@ -558,12 +572,12 @@ nsPresContext::GetFontPreferences()
// 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)
font->size = mDefaultFixedFont.size;
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 = mDefaultVariableFont.size;
font->size = prefs->mDefaultVariableFont.size;
}
}
@ -600,6 +614,8 @@ nsPresContext::GetFontPreferences()
font->sizeAdjust);
#endif
}
return prefs;
}
void
@ -740,7 +756,7 @@ nsPresContext::GetUserPreferences()
mPrefScrollbarSide = Preferences::GetInt("layout.scrollbar.side");
GetFontPreferences();
ResetCachedFontPrefs();
// * image animation
const nsAdoptingCString& animatePref =
@ -1123,7 +1139,7 @@ nsPresContext::UpdateCharSet(const nsCString& aCharSet)
NS_RELEASE(mLanguage);
NS_IF_ADDREF(mLanguage = mLangService->GetLocaleLanguage());
}
GetFontPreferences();
ResetCachedFontPrefs();
}
#ifdef IBMBIDI
//ahmed
@ -1305,32 +1321,34 @@ nsPresContext::SetImageAnimationModeExternal(PRUint16 aMode)
}
const nsFont*
nsPresContext::GetDefaultFont(PRUint8 aFontID) const
nsPresContext::GetDefaultFont(PRUint8 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 = &mDefaultVariableFont;
font = &prefs->mDefaultVariableFont;
break;
case kPresContext_DefaultFixedFont_ID:
font = &mDefaultFixedFont;
font = &prefs->mDefaultFixedFont;
break;
// CSS
case kGenericFont_serif:
font = &mDefaultSerifFont;
font = &prefs->mDefaultSerifFont;
break;
case kGenericFont_sans_serif:
font = &mDefaultSansSerifFont;
font = &prefs->mDefaultSansSerifFont;
break;
case kGenericFont_monospace:
font = &mDefaultMonospaceFont;
font = &prefs->mDefaultMonospaceFont;
break;
case kGenericFont_cursive:
font = &mDefaultCursiveFont;
font = &prefs->mDefaultCursiveFont;
break;
case kGenericFont_fantasy:
font = &mDefaultFantasyFont;
font = &prefs->mDefaultFantasyFont;
break;
default:
font = nsnull;

View File

@ -119,8 +119,7 @@ enum nsPresContext_CachedBoolPrefType {
// supported values for cached integer pref types
enum nsPresContext_CachedIntPrefType {
kPresContext_MinimumFontSize = 1,
kPresContext_ScrollbarSide,
kPresContext_ScrollbarSide = 1,
kPresContext_BidiDirection
};
@ -304,23 +303,26 @@ public:
}
/**
* Get the default font corresponding to the given ID. This object is
* read-only, you must copy the font to modify it.
* Get the default font for the given language and generic font ID.
* If aLanguage is nsnull, 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 pres
* context's language group.
* as the default font size for variable or fixed fonts for the
* language group.
*
* For aFontID corresponds to a CSS Generic, the nsFont returned has
* its name as the name or names of the fonts in the user's
* preferences for the given generic and the pres context's language
* group, and its size set to the default variable font size.
* 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.
*/
NS_HIDDEN_(const nsFont*) GetDefaultFont(PRUint8 aFontID) const;
NS_HIDDEN_(const nsFont*) GetDefaultFont(PRUint8 aFontID,
nsIAtom *aLanguage) const;
/** Get a cached boolean pref, by its type */
// * - initially created for bugs 31816, 20760, 22963
@ -349,8 +351,6 @@ public:
// If called with a constant parameter, the compiler should optimize
// this switch statement away.
switch (aPrefType) {
case kPresContext_MinimumFontSize:
return mMinimumFontSizePref;
case kPresContext_ScrollbarSide:
return mPrefScrollbarSide;
case kPresContext_BidiDirection:
@ -528,15 +528,20 @@ public:
mTextZoom = aZoom;
if (HasCachedStyleData()) {
// Media queries could have changed since we changed the meaning
// Media queries could have changed, since we changed the meaning
// of 'em' units in them.
MediaFeatureValuesChanged(true);
RebuildAllStyleData(NS_STYLE_HINT_REFLOW);
}
}
PRInt32 MinFontSize() const {
return NS_MAX(mMinFontSize, mMinimumFontSizePref);
/**
* Get the minimum font size for the specified language. If aLanguage
* is nsnull, then the document's language is used.
*/
PRInt32 MinFontSize(nsIAtom *aLanguage) const {
const LangGroupFontPrefs *prefs = GetFontPrefsForLang(aLanguage);
return NS_MAX(mMinFontSize, prefs->mMinimumFontSize);
}
void SetMinFontSize(PRInt32 aMinFontSize) {
@ -545,7 +550,7 @@ public:
mMinFontSize = aMinFontSize;
if (HasCachedStyleData()) {
// Media queries could have changed since we changed the meaning
// Media queries could have changed, since we changed the meaning
// of 'em' units in them.
MediaFeatureValuesChanged(true);
RebuildAllStyleData(NS_STYLE_HINT_REFLOW);
@ -965,7 +970,14 @@ public:
virtual NS_MUST_OVERRIDE size_t
SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
return 0;
size_t n = 0;
LangGroupFontPrefs *langGroupfontPrefs = mLangGroupFontPrefs.mNext;
while (langGroupfontPrefs) {
// XXX this doesn't include allocations made by the nsFont members
n += sizeof(LangGroupFontPrefs);
langGroupfontPrefs = langGroupfontPrefs->mNext;
}
return n;
// Measurement of other members may be added later if DMD finds it is
// worthwhile.
@ -994,7 +1006,62 @@ protected:
static NS_HIDDEN_(void) PrefChangedUpdateTimerCallback(nsITimer *aTimer, void *aClosure);
NS_HIDDEN_(void) GetUserPreferences();
NS_HIDDEN_(void) GetFontPreferences();
// 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(nsnull)
, mMinimumFontSize(0)
, mDefaultVariableFont("serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultFixedFont("monospace", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultSerifFont("serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultSansSerifFont("sans-serif", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultMonospaceFont("monospace", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultCursiveFont("cursive", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultFantasyFont("fantasy", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
{}
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 = nsnull;
// Make GetFontPreferences reinitialize mLangGroupFontPrefs:
mLangGroupFontPrefs.mLangGroup = nsnull;
}
NS_HIDDEN_(void) UpdateCharSet(const nsCString& aCharSet);
@ -1089,9 +1156,6 @@ protected:
// container for per-context fonts (downloadable, SVG, etc.)
nsUserFontSet* mUserFontSet;
PRInt32 mFontScaler;
nscoord mMinimumFontSizePref;
nsRect mVisibleArea;
nsSize mPageSize;
float mPageScale;
@ -1115,13 +1179,7 @@ protected:
PRUint16 mImageAnimationMode;
PRUint16 mImageAnimationModePref;
nsFont mDefaultVariableFont;
nsFont mDefaultFixedFont;
nsFont mDefaultSerifFont;
nsFont mDefaultSansSerifFont;
nsFont mDefaultMonospaceFont;
nsFont mDefaultCursiveFont;
nsFont mDefaultFantasyFont;
LangGroupFontPrefs mLangGroupFontPrefs;
nscoord mBorderWidthTable[3];

View File

@ -123,7 +123,9 @@ nsSimplePageSequenceFrame::nsSimplePageSequenceFrame(nsStyleContext* aContext) :
// XXX Unsafe to assume successful allocation
mPageData = new nsSharedPageData();
mPageData->mHeadFootFont = new nsFont(*PresContext()->GetDefaultFont(kGenericFont_serif));
mPageData->mHeadFootFont =
new nsFont(*PresContext()->GetDefaultFont(kGenericFont_serif,
aContext->GetStyleFont()->mLanguage));
mPageData->mHeadFootFont->size = nsPresContext::CSSPointsToAppUnits(10);
nsresult rv;

View File

@ -1222,7 +1222,8 @@ nsComputedDOMStyle::DoGetFontFamily()
const nsString& fontName = font->mFont.name;
if (font->mGenericID == kGenericFont_NONE && !font->mFont.systemFont) {
const nsFont* defaultFont =
presContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID);
presContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID,
font->mLanguage);
PRInt32 lendiff = fontName.Length() - defaultFont->name.Length();
if (lendiff > 0) {

View File

@ -1982,7 +1982,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
{
nsStyleFont* fontData = new (mPresContext) nsStyleFont(mPresContext);
if (NS_LIKELY(fontData != nsnull)) {
nscoord minimumFontSize = mPresContext->MinFontSize();
nscoord minimumFontSize = mPresContext->MinFontSize(fontData->mLanguage);
if (minimumFontSize > 0 && !mPresContext->IsChrome()) {
fontData->mFont.size = NS_MAX(fontData->mSize, minimumFontSize);
@ -2543,7 +2543,7 @@ nsRuleNode::SetFontSize(nsPresContext* aPresContext,
{
bool zoom = false;
PRInt32 baseSize = (PRInt32) aPresContext->
GetDefaultFont(aFont->mGenericID)->size;
GetDefaultFont(aFont->mGenericID, aFont->mLanguage)->size;
const nsCSSValue* sizeValue = aRuleData->ValueForFontSize();
if (eCSSUnit_Enumerated == sizeValue->GetUnit()) {
PRInt32 value = sizeValue->GetIntValue();
@ -2654,7 +2654,6 @@ static PRInt8 ClampTo8Bit(PRInt32 aValue) {
/* static */ void
nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
nscoord aMinFontSize,
PRUint8 aGenericFontID, const nsRuleData* aRuleData,
const nsStyleFont* aParentFont,
nsStyleFont* aFont, bool aUsedStartStruct,
@ -2662,12 +2661,12 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
{
bool atRoot = !aContext->GetParent();
// mLanguage must be set before before any of the CalcLengthWith (direct
// calls or calls via SetFontSize) for the cases where |aParentFont| is the
// same as |aFont|.
// mLanguage must be set before before any of the CalcLengthWith calls
// (direct calls or calls via SetFontSize) for the cases where |aParentFont|
// is the same as |aFont|.
//
// -x-lang: string, inherit
// this is not a real CSS property, it is a html attribute mapped to CSS
// This is not a real CSS property, it is an HTML attribute mapped to CSS.
const nsCSSValue* langValue = aRuleData->ValueForLang();
if (eCSSUnit_Ident == langValue->GetUnit()) {
nsAutoString lang;
@ -2678,7 +2677,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
}
const nsFont* defaultVariableFont =
aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID);
aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID,
aFont->mLanguage);
// -moz-system-font: enum (never inherit!)
nsFont systemFont;
@ -2958,12 +2958,21 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
NS_ASSERTION(aFont->mScriptUnconstrainedSize <= aFont->mSize,
"scriptminsize should never be making things bigger");
nscoord fontSize = aFont->mSize;
// enforce the user' specified minimum font-size on the value that we expose
// (but don't change font-size:0)
if (0 < aFont->mSize && aFont->mSize < aMinFontSize)
aFont->mFont.size = aMinFontSize;
else
aFont->mFont.size = aFont->mSize;
// (but don't change font-size:0, since that would unhide hidden text)
if (fontSize > 0) {
nscoord minFontSize = aPresContext->MinFontSize(aFont->mLanguage);
if (minFontSize < 0) {
minFontSize = 0;
}
if (fontSize < minFontSize && !aPresContext->IsChrome()) {
// override the minimum font-size constraint
fontSize = minFontSize;
}
}
aFont->mFont.size = fontSize;
// font-size-adjust: number, none, inherit, initial, -moz-system-font
const nsCSSValue* sizeAdjustValue = aRuleData->ValueForFontSizeAdjust();
@ -2975,6 +2984,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
SETFCT_NONE);
}
// This should die (bug 380915).
//
// SetGenericFont:
// - backtrack to an ancestor with the same generic font name (possibly
// up to the root where default values come from the presentation context)
@ -2982,7 +2993,7 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
/* static */ void
nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
PRUint8 aGenericFontID, nscoord aMinFontSize,
PRUint8 aGenericFontID,
nsStyleFont* aFont)
{
// walk up the contexts until a context with the desired generic font
@ -3003,7 +3014,8 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
// If we stopped earlier because we reached the root of the style tree,
// we will start with the default generic font from the presentation
// context. Otherwise we start with the higher context.
const nsFont* defaultFont = aPresContext->GetDefaultFont(aGenericFontID);
const nsFont* defaultFont =
aPresContext->GetDefaultFont(aGenericFontID, aFont->mLanguage);
nsStyleFont parentFont(*defaultFont, aPresContext);
if (higherContext) {
const nsStyleFont* tmpFont = higherContext->GetStyleFont();
@ -3053,7 +3065,7 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
if (i != 0)
ruleData.ValueForFontFamily()->Reset();
nsRuleNode::SetFont(aPresContext, context, aMinFontSize,
nsRuleNode::SetFont(aPresContext, context,
aGenericFontID, &ruleData, &parentFont, aFont,
false, dummy);
@ -3099,24 +3111,16 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
// (although there is a pretty good chance they'll fully specify it
// using the 'font' shorthand).
// See if there is a minimum font-size constraint to honor
nscoord minimumFontSize = mPresContext->MinFontSize();
if (minimumFontSize < 0)
minimumFontSize = 0;
bool useDocumentFonts =
mPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
// See if we are in the chrome
// We only need to know this to determine if we have to use the
// document fonts (overriding the useDocumentFonts flag), or to
// determine if we have to override the minimum font-size constraint.
if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) {
// document fonts (overriding the useDocumentFonts flag).
if (!useDocumentFonts && mPresContext->IsChrome()) {
// if we are not using document fonts, but this is a XUL document,
// then we use the document fonts anyway
useDocumentFonts = true;
minimumFontSize = 0;
}
// Figure out if we are a generic font
@ -3157,7 +3161,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
// Now compute our font struct
if (generic == kGenericFont_NONE) {
// continue the normal processing
nsRuleNode::SetFont(mPresContext, aContext, minimumFontSize, generic,
nsRuleNode::SetFont(mPresContext, aContext, generic,
aRuleData, parentFont, font,
aStartStruct != nsnull, canStoreInRuleTree);
}
@ -3165,7 +3169,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
// re-calculate the font as a generic font
canStoreInRuleTree = false;
nsRuleNode::SetGenericFont(mPresContext, aContext, generic,
minimumFontSize, font);
font);
}
COMPUTE_END_INHERITED(Font, font)
@ -3326,14 +3330,12 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
!lineHeightValue->IsRelativeLengthUnit()) {
nscoord lh = nsStyleFont::ZoomText(mPresContext,
text->mLineHeight.GetCoordValue());
nscoord minimumFontSize = mPresContext->MinFontSize();
canStoreInRuleTree = false;
const nsStyleFont *font = aContext->GetStyleFont();
nscoord minimumFontSize = mPresContext->MinFontSize(font->mLanguage);
if (minimumFontSize > 0 && !mPresContext->IsChrome()) {
// If we applied a minimum font size, scale the line height by
// the same ratio. (If we *might* have applied a minimum font
// size, we can't cache in the rule tree.)
canStoreInRuleTree = false;
const nsStyleFont *font = aContext->GetStyleFont();
if (font->mSize != 0) {
lh = nscoord(float(lh) * float(font->mFont.size) / float(font->mSize));
} else {

View File

@ -610,7 +610,6 @@ protected:
static void SetFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
nscoord aMinFontSize,
PRUint8 aGenericFontID,
const nsRuleData* aRuleData,
const nsStyleFont* aParentFont,
@ -621,7 +620,6 @@ protected:
static void SetGenericFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
PRUint8 aGenericFontID,
nscoord aMinFontSize,
nsStyleFont* aFont);
void AdjustLogicalBoxProp(nsStyleContext* aContext,

View File

@ -147,7 +147,8 @@ nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
}
nsStyleFont::nsStyleFont(nsPresContext* aPresContext)
: mFont(*(aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID))),
// passing nsnull to GetDefaultFont make it use the doc language
: mFont(*(aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, nsnull))),
mGenericID(kGenericFont_NONE)
{
MOZ_COUNT_CTOR(nsStyleFont);

View File

@ -16,22 +16,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=401046
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=401046">Mozilla Bug 401046</a>
<!-- FIXME tried changing the zh-CN pref instead of x-western, but the language
is based only on the document *charset* -->
<!--
<p id="display" lang="zh-Hans">
<span id="s0" style="font-size: 0">汉字</span>
<span id="s4" style="font-size: 4px">汉字</span>
<span id="s12" style="font-size: 12px">汉字</span>
<span id="s28" style="font-size: 28px">汉字</span>
</p>
-->
<p id="display">
<span id="s0" style="font-size: 0">Ép</span>
<span id="s4" style="font-size: 4px">Ép</span>
<span id="s12" style="font-size: 12px">Ép</span>
<span id="s28" style="font-size: 28px">Ép</span>
</p>
<div id="content" style="display: none">
</div>
@ -56,7 +46,7 @@ function fs(idx) {
return getComputedStyle(elts[idx], "").marginBottom;
}
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.x-western']]}, step1);
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.zh-CN']]}, step1);
function step1() {
is(fs(0), "0px", "at min font size 0, 0px should compute to 0px");
@ -64,7 +54,7 @@ function step1() {
is(fs(2), "12px", "at min font size 0, 12px should compute to 12px");
is(fs(3), "28px", "at min font size 0, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.x-western', 7]]}, step2);
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.zh-CN', 7]]}, step2);
}
function step2() {
@ -73,7 +63,7 @@ function step2() {
is(fs(2), "12px", "at min font size 7, 12px should compute to 12px");
is(fs(3), "28px", "at min font size 7, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.x-western', 18]]}, step3);
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.zh-CN', 18]]}, step3);
}
function step3() {
@ -82,7 +72,7 @@ function step3() {
is(fs(2), "18px", "at min font size 18, 12px should compute to 18px");
is(fs(3), "28px", "at min font size 18, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.x-western']]}, SimpleTest.finish);
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.zh-CN']]}, SimpleTest.finish);
}
</script>