Bug 1041951 - parse font-variant as a shorthand for font feature subproperties. r=dbaron

This commit is contained in:
John Daggett 2014-08-20 16:54:25 +09:00
parent 4228ccca2e
commit e76e48d5b2
16 changed files with 368 additions and 146 deletions

View File

@ -19,27 +19,25 @@
using namespace mozilla;
nsFont::nsFont(const FontFamilyList& aFontlist, uint8_t aStyle,
uint8_t aVariant, uint16_t aWeight, int16_t aStretch,
uint16_t aWeight, int16_t aStretch,
uint8_t aDecoration, nscoord aSize)
: fontlist(aFontlist)
{
Init();
style = aStyle;
variant = aVariant;
weight = aWeight;
stretch = aStretch;
decorations = aDecoration;
size = aSize;
}
nsFont::nsFont(FontFamilyType aGenericType, uint8_t aStyle, uint8_t aVariant,
nsFont::nsFont(FontFamilyType aGenericType, uint8_t aStyle,
uint16_t aWeight, int16_t aStretch, uint8_t aDecoration,
nscoord aSize)
: fontlist(aGenericType)
{
Init();
style = aStyle;
variant = aVariant;
weight = aWeight;
stretch = aStretch;
decorations = aDecoration;
@ -68,7 +66,6 @@ nsFont::nsFont(const nsFont& aOther)
{
style = aOther.style;
systemFont = aOther.systemFont;
variant = aOther.variant;
weight = aOther.weight;
stretch = aOther.stretch;
decorations = aOther.decorations;
@ -110,7 +107,6 @@ bool nsFont::BaseEquals(const nsFont& aOther) const
(synthesis == aOther.synthesis) &&
(fontFeatureSettings == aOther.fontFeatureSettings) &&
(languageOverride == aOther.languageOverride) &&
(variant == aOther.variant) &&
(variantAlternates == aOther.variantAlternates) &&
(variantCaps == aOther.variantCaps) &&
(variantEastAsian == aOther.variantEastAsian) &&
@ -139,7 +135,6 @@ nsFont& nsFont::operator=(const nsFont& aOther)
fontlist = aOther.fontlist;
style = aOther.style;
systemFont = aOther.systemFont;
variant = aOther.variant;
weight = aOther.weight;
stretch = aOther.stretch;
decorations = aOther.decorations;
@ -274,14 +269,7 @@ void nsFont::AddFontFeaturesToStyle(gfxFontStyle *aStyle) const
aStyle->featureValueLookup = featureValueLookup;
// -- caps
// passed into gfxFontStyle to deal with appropriate fallback.
// for now, font-variant setting overrides font-variant-caps
// when font-variant becomes a shorthand, this will be removed
if (variant == NS_FONT_VARIANT_SMALL_CAPS) {
aStyle->variantCaps = NS_FONT_VARIANT_CAPS_SMALLCAPS;
} else {
aStyle->variantCaps = variantCaps;
}
aStyle->variantCaps = variantCaps;
// -- east-asian
if (variantEastAsian) {

View File

@ -52,11 +52,7 @@ struct NS_GFX nsFont {
// the name is the same as a CSS generic font family.
bool systemFont;
// The variant of the font (normal, small-caps)
uint8_t variant;
// Variant subproperties
// (currently -moz- versions, will replace variant above eventually)
uint8_t variantCaps;
uint8_t variantNumeric;
uint8_t variantPosition;
@ -116,11 +112,11 @@ struct NS_GFX nsFont {
// initialize the font with a fontlist
nsFont(const mozilla::FontFamilyList& aFontlist, uint8_t aStyle,
uint8_t aVariant, uint16_t aWeight, int16_t aStretch,
uint16_t aWeight, int16_t aStretch,
uint8_t aDecoration, nscoord aSize);
// initialize the font with a single generic
nsFont(mozilla::FontFamilyType aGenericType, uint8_t aStyle, uint8_t aVariant,
nsFont(mozilla::FontFamilyType aGenericType, uint8_t aStyle,
uint16_t aWeight, int16_t aStretch, uint8_t aDecoration,
nscoord aSize);

View File

@ -1069,28 +1069,26 @@ protected:
: mLangGroup(nullptr)
, mMinimumFontSize(0)
, mDefaultVariableFont(mozilla::eFamily_serif, NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultFixedFont(mozilla::eFamily_monospace, NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultSerifFont(mozilla::eFamily_serif, NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultSansSerifFont(mozilla::eFamily_sans_serif,
NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultMonospaceFont(mozilla::eFamily_monospace, NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultCursiveFont(mozilla::eFamily_cursive, NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultFantasyFont(mozilla::eFamily_fantasy, NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
{}

View File

@ -9943,7 +9943,7 @@ void ReflowCountMgr::PaintCount(const char* aName,
if (counter != nullptr && counter->mName.EqualsASCII(aName)) {
aRenderingContext->PushState();
aRenderingContext->Translate(aOffset);
nsFont font(eFamily_serif, NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
nsFont font(eFamily_serif, NS_FONT_STYLE_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0,
nsPresContext::CSSPixelsToAppUnits(11));

View File

@ -599,8 +599,6 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
data->ValueFor(eCSSProperty__x_system_font);
const nsCSSValue *style =
data->ValueFor(eCSSProperty_font_style);
const nsCSSValue *variant =
data->ValueFor(eCSSProperty_font_variant);
const nsCSSValue *weight =
data->ValueFor(eCSSProperty_font_weight);
const nsCSSValue *size =
@ -644,7 +642,6 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
systemFont->GetUnit() != eCSSUnit_None &&
systemFont->GetUnit() != eCSSUnit_Null) {
if (style->GetUnit() != eCSSUnit_System_Font ||
variant->GetUnit() != eCSSUnit_System_Font ||
weight->GetUnit() != eCSSUnit_System_Font ||
size->GetUnit() != eCSSUnit_System_Font ||
lh->GetUnit() != eCSSUnit_System_Font ||
@ -681,7 +678,6 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
fontSynthesis->GetIntValue() !=
(NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE) ||
fontVariantAlternates->GetUnit() != eCSSUnit_Normal ||
fontVariantCaps->GetUnit() != eCSSUnit_Normal ||
fontVariantEastAsian->GetUnit() != eCSSUnit_Normal ||
fontVariantLigatures->GetUnit() != eCSSUnit_Normal ||
fontVariantNumeric->GetUnit() != eCSSUnit_Normal ||
@ -689,15 +685,22 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
return;
}
// only a normal or small-caps values of font-variant-caps can
// be represented in the font shorthand
if (fontVariantCaps->GetUnit() != eCSSUnit_Normal &&
(fontVariantCaps->GetUnit() != eCSSUnit_Enumerated ||
fontVariantCaps->GetIntValue() != NS_FONT_VARIANT_CAPS_SMALLCAPS)) {
return;
}
if (style->GetUnit() != eCSSUnit_Enumerated ||
style->GetIntValue() != NS_FONT_STYLE_NORMAL) {
style->AppendToString(eCSSProperty_font_style, aValue,
aSerialization);
aValue.Append(char16_t(' '));
}
if (variant->GetUnit() != eCSSUnit_Enumerated ||
variant->GetIntValue() != NS_FONT_VARIANT_NORMAL) {
variant->AppendToString(eCSSProperty_font_variant, aValue,
if (fontVariantCaps->GetUnit() != eCSSUnit_Normal) {
fontVariantCaps->AppendToString(eCSSProperty_font_variant_caps, aValue,
aSerialization);
aValue.Append(char16_t(' '));
}
@ -718,6 +721,60 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
}
break;
}
case eCSSProperty_font_variant: {
const nsCSSProperty *subprops =
nsCSSProps::SubpropertyEntryFor(aProperty);
const nsCSSValue *fontVariantLigatures =
data->ValueFor(eCSSProperty_font_variant_ligatures);
// all subproperty values normal? system font?
bool normalLigs = true, normalNonLigs = true, systemFont = true,
hasSystem = false;
for (const nsCSSProperty *sp = subprops; *sp != eCSSProperty_UNKNOWN; sp++) {
const nsCSSValue *spVal = data->ValueFor(*sp);
bool isNormal = (spVal->GetUnit() == eCSSUnit_Normal);
if (*sp == eCSSProperty_font_variant_ligatures) {
normalLigs = normalLigs && isNormal;
} else {
normalNonLigs = normalNonLigs && isNormal;
}
bool isSystem = (spVal->GetUnit() == eCSSUnit_System_Font);
systemFont = systemFont && isSystem;
hasSystem = hasSystem || isSystem;
}
bool ligsNone =
fontVariantLigatures->GetUnit() == eCSSUnit_None;
// normal, none, or system font ==> single value
if ((normalLigs && normalNonLigs) ||
(normalNonLigs && ligsNone) ||
systemFont) {
fontVariantLigatures->AppendToString(eCSSProperty_font_variant_ligatures,
aValue,
aSerialization);
} else if (ligsNone || hasSystem) {
// ligatures none but other values are non-normal ==> empty
// at least one but not all values are system font ==> empty
return;
} else {
// iterate over and append non-normal values
bool appendSpace = false;
for (const nsCSSProperty *sp = subprops;
*sp != eCSSProperty_UNKNOWN; sp++) {
const nsCSSValue *spVal = data->ValueFor(*sp);
if (spVal && spVal->GetUnit() != eCSSUnit_Normal) {
if (appendSpace) {
aValue.Append(char16_t(' '));
} else {
appendSpace = true;
}
spVal->AppendToString(*sp, aValue, aSerialization);
}
}
}
break;
}
case eCSSProperty_list_style:
if (AppendValueToString(eCSSProperty_list_style_position, aValue,
aSerialization)) {
@ -1294,9 +1351,17 @@ Declaration::ToString(nsAString& aString) const
// least, which is exactly the order we want to test them.
nsCSSProperty shorthand = *shorthands;
GetValue(shorthand, value);
// in the system font case, skip over font-variant shorthand, since all
// subproperties are already dealt with via the font shorthand
if (shorthand == eCSSProperty_font_variant &&
value.EqualsLiteral("-moz-use-system-font")) {
continue;
}
// If GetValue gives us a non-empty string back, we can use that
// value; otherwise it's not possible to use this shorthand.
GetValue(shorthand, value);
if (!value.IsEmpty()) {
AppendPropertyAndValueToString(shorthand, value, aString);
shorthandsUsed.AppendElement(shorthand);
@ -1304,9 +1369,6 @@ Declaration::ToString(nsAString& aString) const
break;
}
NS_ABORT_IF_FALSE(shorthand != eCSSProperty_font ||
*(shorthands + 1) == eCSSProperty_UNKNOWN,
"font should always be the only containing shorthand");
if (shorthand == eCSSProperty_font) {
if (haveSystemFont && !didSystemFont) {
// Output the shorthand font declaration that we will
@ -1329,6 +1391,7 @@ Declaration::ToString(nsAString& aString) const
if (property == eCSSProperty__x_system_font ||
(haveSystemFont && val && val->GetUnit() == eCSSUnit_System_Font)) {
doneProperty = true;
break;
}
}
}

View File

@ -757,12 +757,15 @@ protected:
bool ParseFontSynthesis(nsCSSValue& aValue);
bool ParseSingleAlternate(int32_t& aWhichFeature, nsCSSValue& aValue);
bool ParseFontVariantAlternates(nsCSSValue& aValue);
bool MergeBitmaskValue(int32_t aNewValue, const int32_t aMasks[],
int32_t& aMergedValue);
bool ParseBitmaskValues(nsCSSValue& aValue,
const KTableValue aKeywordTable[],
const int32_t aMasks[]);
bool ParseFontVariantEastAsian(nsCSSValue& aValue);
bool ParseFontVariantLigatures(nsCSSValue& aValue);
bool ParseFontVariantNumeric(nsCSSValue& aValue);
bool ParseFontVariant();
bool ParseFontWeight(nsCSSValue& aValue);
bool ParseOneFamily(nsAString& aFamily, bool& aOneKeyword, bool& aQuoted);
bool ParseFamily(nsCSSValue& aValue);
@ -9738,6 +9741,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
return ParseFlexFlow();
case eCSSProperty_font:
return ParseFont();
case eCSSProperty_font_variant:
return ParseFontVariant();
case eCSSProperty_grid_auto_flow:
return ParseGridAutoFlow();
case eCSSProperty_grid_auto_columns:
@ -11727,7 +11732,7 @@ CSSParserImpl::ParseFont()
{
static const nsCSSProperty fontIDs[] = {
eCSSProperty_font_style,
eCSSProperty_font_variant,
eCSSProperty_font_variant_caps,
eCSSProperty_font_weight
};
@ -11742,7 +11747,6 @@ CSSParserImpl::ParseFont()
AppendValue(eCSSProperty__x_system_font, nsCSSValue(eCSSUnit_None));
AppendValue(eCSSProperty_font_family, family);
AppendValue(eCSSProperty_font_style, family);
AppendValue(eCSSProperty_font_variant, family);
AppendValue(eCSSProperty_font_weight, family);
AppendValue(eCSSProperty_font_size, family);
AppendValue(eCSSProperty_line_height, family);
@ -11766,7 +11770,6 @@ CSSParserImpl::ParseFont()
nsCSSValue systemFont(eCSSUnit_System_Font);
AppendValue(eCSSProperty_font_family, systemFont);
AppendValue(eCSSProperty_font_style, systemFont);
AppendValue(eCSSProperty_font_variant, systemFont);
AppendValue(eCSSProperty_font_weight, systemFont);
AppendValue(eCSSProperty_font_size, systemFont);
AppendValue(eCSSProperty_line_height, systemFont);
@ -11804,7 +11807,15 @@ CSSParserImpl::ParseFont()
}
if ((found & 2) == 0) {
// Provide default font-variant
values[1].SetIntValue(NS_FONT_VARIANT_NORMAL, eCSSUnit_Enumerated);
values[1].SetNormalValue();
} else {
if (values[1].GetUnit() == eCSSUnit_Enumerated &&
!values[1].GetIntValue() == NS_FONT_VARIANT_CAPS_SMALLCAPS) {
// only normal or small-caps is allowed in font shorthand
// this also assumes other values for font-variant-caps never overlap
// possible values for style or weight
return false;
}
}
if ((found & 4) == 0) {
// Provide default font-weight
@ -11840,7 +11851,7 @@ CSSParserImpl::ParseFont()
AppendValue(eCSSProperty__x_system_font, nsCSSValue(eCSSUnit_None));
AppendValue(eCSSProperty_font_family, family);
AppendValue(eCSSProperty_font_style, values[0]);
AppendValue(eCSSProperty_font_variant, values[1]);
AppendValue(eCSSProperty_font_variant_caps, values[1]);
AppendValue(eCSSProperty_font_weight, values[2]);
AppendValue(eCSSProperty_font_size, size);
AppendValue(eCSSProperty_line_height, lineHeight);
@ -11857,7 +11868,6 @@ CSSParserImpl::ParseFont()
eCSSUnit_Enumerated));
AppendValue(eCSSProperty_font_variant_alternates,
nsCSSValue(eCSSUnit_Normal));
AppendValue(eCSSProperty_font_variant_caps, nsCSSValue(eCSSUnit_Normal));
AppendValue(eCSSProperty_font_variant_east_asian,
nsCSSValue(eCSSUnit_Normal));
AppendValue(eCSSProperty_font_variant_ligatures,
@ -11910,7 +11920,7 @@ CSSParserImpl::ParseFontSynthesis(nsCSSValue& aValue)
// parameter lists with one or more idents which are later resolved
// based on values defined in @font-feature-value rules.
//
// font-variant-alternates: swash(flowing), historical-forms, styleset(alt-g, alt-m);
// font-variant-alternates: swash(flowing) historical-forms styleset(alt-g, alt-m);
//
// So for this the nsCSSValue is set to a pair value, with one
// value for a bitmask of both simple and functional property values
@ -11932,6 +11942,17 @@ CSSParserImpl::ParseFontSynthesis(nsCSSValue& aValue)
#define MAX_ALLOWED_FEATURES 512
static uint16_t
MaxElementsForAlternateType(nsCSSKeyword keyword)
{
uint16_t maxElems = 1;
if (keyword == eCSSKeyword_styleset ||
keyword == eCSSKeyword_character_variant) {
maxElems = MAX_ALLOWED_FEATURES;
}
return maxElems;
}
bool
CSSParserImpl::ParseSingleAlternate(int32_t& aWhichFeature,
nsCSSValue& aValue)
@ -11967,13 +11988,8 @@ CSSParserImpl::ParseSingleAlternate(int32_t& aWhichFeature,
return true;
}
uint16_t maxElems = 1;
if (keyword == eCSSKeyword_styleset ||
keyword == eCSSKeyword_character_variant) {
maxElems = MAX_ALLOWED_FEATURES;
}
return ParseFunction(keyword, nullptr, VARIANT_IDENTIFIER,
1, maxElems, aValue);
1, MaxElementsForAlternateType(keyword), aValue);
}
bool
@ -12026,6 +12042,35 @@ CSSParserImpl::ParseFontVariantAlternates(nsCSSValue& aValue)
return true;
}
bool
CSSParserImpl::MergeBitmaskValue(int32_t aNewValue,
const int32_t aMasks[],
int32_t& aMergedValue)
{
// check to make sure value not already set
if (aNewValue & aMergedValue) {
return false;
}
const int32_t *m = aMasks;
int32_t c = 0;
while (*m != MASK_END_VALUE) {
if (*m & aNewValue) {
c = aMergedValue & *m;
break;
}
m++;
}
if (c) {
return false;
}
aMergedValue |= aNewValue;
return true;
}
// aMasks - array of masks for mutually-exclusive property values,
// e.g. proportial-nums, tabular-nums
@ -12045,29 +12090,9 @@ CSSParserImpl::ParseBitmaskValues(nsCSSValue& aValue,
while (ParseEnum(nextValue, aKeywordTable))
{
int32_t nextIntValue = nextValue.GetIntValue();
// check to make sure value not already set
if (nextIntValue & mergedValue) {
if (!MergeBitmaskValue(nextValue.GetIntValue(), aMasks, mergedValue)) {
return false;
}
const int32_t *m = aMasks;
int32_t c = 0;
while (*m != MASK_END_VALUE) {
if (*m & nextIntValue) {
c = mergedValue & *m;
break;
}
m++;
}
if (c) {
return false;
}
mergedValue |= nextIntValue;
}
aValue.SetIntValue(mergedValue, eCSSUnit_Enumerated);
@ -12107,7 +12132,9 @@ static const int32_t maskLigatures[] = {
bool
CSSParserImpl::ParseFontVariantLigatures(nsCSSValue& aValue)
{
if (ParseVariant(aValue, VARIANT_INHERIT | VARIANT_NORMAL, nullptr)) {
if (ParseVariant(aValue,
VARIANT_INHERIT | VARIANT_NORMAL | VARIANT_NONE,
nullptr)) {
return true;
}
@ -12115,20 +12142,8 @@ CSSParserImpl::ParseFontVariantLigatures(nsCSSValue& aValue)
MASK_END_VALUE,
"incorrectly terminated array");
bool parsed =
ParseBitmaskValues(aValue, nsCSSProps::kFontVariantLigaturesKTable,
maskLigatures);
// if none value included, no other values are possible
if (parsed && eCSSUnit_Enumerated == aValue.GetUnit()) {
int32_t val = aValue.GetIntValue();
if ((val & NS_FONT_VARIANT_LIGATURES_NONE) &&
(val & ~int32_t(NS_FONT_VARIANT_LIGATURES_NONE))) {
parsed = false;
}
}
return parsed;
return ParseBitmaskValues(aValue, nsCSSProps::kFontVariantLigaturesKTable,
maskLigatures);
}
static const int32_t maskNumeric[] = {
@ -12153,6 +12168,194 @@ CSSParserImpl::ParseFontVariantNumeric(nsCSSValue& aValue)
maskNumeric);
}
bool
CSSParserImpl::ParseFontVariant()
{
// parse single values - normal/inherit/none
nsCSSValue value;
nsCSSValue normal(eCSSUnit_Normal);
if (ParseVariant(value,
VARIANT_INHERIT | VARIANT_NORMAL | VARIANT_NONE,
nullptr)) {
AppendValue(eCSSProperty_font_variant_ligatures, value);
if (eCSSUnit_None == value.GetUnit()) {
// 'none' applies the value 'normal' to all properties other
// than 'font-variant-ligatures'
value.SetNormalValue();
}
AppendValue(eCSSProperty_font_variant_alternates, value);
AppendValue(eCSSProperty_font_variant_caps, value);
AppendValue(eCSSProperty_font_variant_east_asian, value);
AppendValue(eCSSProperty_font_variant_numeric, value);
AppendValue(eCSSProperty_font_variant_position, value);
return true;
}
// set each of the individual subproperties
int32_t altFeatures = 0, capsFeatures = 0, eastAsianFeatures = 0,
ligFeatures = 0, numericFeatures = 0, posFeatures = 0;
nsCSSValue altListValue;
nsCSSValueList* altList = nullptr;
// if no functional values, this may be a list with a single, unused element
altListValue.SetListValue();
bool foundValid = false; // found at least one proper value
while (GetToken(true)) {
// only an ident or a function at this point
bool isFunction = (mToken.mType == eCSSToken_Function);
if (mToken.mType != eCSSToken_Ident && !isFunction) {
UngetToken();
break;
}
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
if (keyword == eCSSKeyword_UNKNOWN) {
UngetToken();
return false;
}
int32_t feature;
// function? ==> font-variant-alternates
if (isFunction) {
if (!nsCSSProps::FindKeyword(keyword,
nsCSSProps::kFontVariantAlternatesFuncsKTable,
feature) ||
(feature & altFeatures)) {
UngetToken();
return false;
}
altFeatures |= feature;
nsCSSValue funcValue;
if (!ParseFunction(keyword, nullptr, VARIANT_IDENTIFIER, 1,
MaxElementsForAlternateType(keyword), funcValue) ||
funcValue.GetUnit() != eCSSUnit_Function) {
UngetToken();
return false;
}
if (!altList) {
altList = altListValue.GetListValue();
} else {
altList->mNext = new nsCSSValueList;
altList = altList->mNext;
}
altList->mValue = funcValue;
} else if (nsCSSProps::FindKeyword(keyword,
nsCSSProps::kFontVariantCapsKTable,
feature)) {
if (capsFeatures != 0) {
// multiple values for font-variant-caps
UngetToken();
return false;
}
capsFeatures = feature;
} else if (nsCSSProps::FindKeyword(keyword,
nsCSSProps::kFontVariantAlternatesKTable,
feature)) {
if (feature & altFeatures) {
// same value repeated
UngetToken();
return false;
}
altFeatures |= feature;
} else if (nsCSSProps::FindKeyword(keyword,
nsCSSProps::kFontVariantEastAsianKTable,
feature)) {
if (!MergeBitmaskValue(feature, maskEastAsian, eastAsianFeatures)) {
// multiple mutually exclusive values
UngetToken();
return false;
}
} else if (nsCSSProps::FindKeyword(keyword,
nsCSSProps::kFontVariantLigaturesKTable,
feature)) {
if (keyword == eCSSKeyword_none ||
!MergeBitmaskValue(feature, maskLigatures, ligFeatures)) {
// none or multiple mutually exclusive values
UngetToken();
return false;
}
} else if (nsCSSProps::FindKeyword(keyword,
nsCSSProps::kFontVariantNumericKTable,
feature)) {
if (!MergeBitmaskValue(feature, maskNumeric, numericFeatures)) {
// multiple mutually exclusive values
UngetToken();
return false;
}
} else if (nsCSSProps::FindKeyword(keyword,
nsCSSProps::kFontVariantPositionKTable,
feature)) {
if (posFeatures != 0) {
// multiple values for font-variant-caps
UngetToken();
return false;
}
posFeatures = feature;
} else {
// bogus keyword, bail...
UngetToken();
return false;
}
foundValid = true;
}
if (!foundValid) {
return false;
}
if (altFeatures) {
nsCSSValue featureValue;
featureValue.SetIntValue(altFeatures, eCSSUnit_Enumerated);
value.SetPairValue(featureValue, altListValue);
AppendValue(eCSSProperty_font_variant_alternates, value);
} else {
AppendValue(eCSSProperty_font_variant_alternates, normal);
}
if (capsFeatures) {
value.SetIntValue(capsFeatures, eCSSUnit_Enumerated);
AppendValue(eCSSProperty_font_variant_caps, value);
} else {
AppendValue(eCSSProperty_font_variant_caps, normal);
}
if (eastAsianFeatures) {
value.SetIntValue(eastAsianFeatures, eCSSUnit_Enumerated);
AppendValue(eCSSProperty_font_variant_east_asian, value);
} else {
AppendValue(eCSSProperty_font_variant_east_asian, normal);
}
if (ligFeatures) {
value.SetIntValue(ligFeatures, eCSSUnit_Enumerated);
AppendValue(eCSSProperty_font_variant_ligatures, value);
} else {
AppendValue(eCSSProperty_font_variant_ligatures, normal);
}
if (numericFeatures) {
value.SetIntValue(numericFeatures, eCSSUnit_Enumerated);
AppendValue(eCSSProperty_font_variant_numeric, value);
} else {
AppendValue(eCSSProperty_font_variant_numeric, normal);
}
if (posFeatures) {
value.SetIntValue(posFeatures, eCSSUnit_Enumerated);
AppendValue(eCSSProperty_font_variant_position, value);
} else {
AppendValue(eCSSProperty_font_variant_position, normal);
}
return true;
}
bool
CSSParserImpl::ParseFontWeight(nsCSSValue& aValue)
{

View File

@ -1889,18 +1889,12 @@ CSS_PROP_FONT(
kFontSynthesisKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_FONT(
CSS_PROP_SHORTHAND(
font-variant,
font_variant,
FontVariant,
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
"",
VARIANT_HK | VARIANT_SYSFONT,
kFontVariantKTable,
offsetof(nsStyleFont, mFont.variant),
eStyleAnimType_EnumU8)
CSS_PROPERTY_PARSE_FUNCTION,
"")
CSS_PROP_FONT(
font-variant-alternates,
font_variant_alternates,
@ -1910,7 +1904,7 @@ CSS_PROP_FONT(
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
"layout.css.font-features.enabled",
VARIANT_HK,
0,
kFontVariantAlternatesKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)

View File

@ -1246,13 +1246,6 @@ const KTableValue nsCSSProps::kFontSynthesisKTable[] = {
eCSSKeyword_UNKNOWN,-1
};
const KTableValue nsCSSProps::kFontVariantKTable[] = {
eCSSKeyword_normal, NS_STYLE_FONT_VARIANT_NORMAL,
eCSSKeyword_small_caps, NS_STYLE_FONT_VARIANT_SMALL_CAPS,
eCSSKeyword_UNKNOWN,-1
};
const KTableValue nsCSSProps::kFontVariantAlternatesKTable[] = {
eCSSKeyword_historical_forms, NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
eCSSKeyword_UNKNOWN,-1
@ -1292,7 +1285,6 @@ const KTableValue nsCSSProps::kFontVariantEastAsianKTable[] = {
};
const KTableValue nsCSSProps::kFontVariantLigaturesKTable[] = {
eCSSKeyword_none, NS_FONT_VARIANT_LIGATURES_NONE,
eCSSKeyword_common_ligatures, NS_FONT_VARIANT_LIGATURES_COMMON,
eCSSKeyword_no_common_ligatures, NS_FONT_VARIANT_LIGATURES_NO_COMMON,
eCSSKeyword_discretionary_ligatures, NS_FONT_VARIANT_LIGATURES_DISCRETIONARY,
@ -2470,7 +2462,6 @@ static const nsCSSProperty gBorderEndWidthSubpropTable[] = {
static const nsCSSProperty gFontSubpropTable[] = {
eCSSProperty_font_family,
eCSSProperty_font_style,
eCSSProperty_font_variant,
eCSSProperty_font_weight,
eCSSProperty_font_size,
eCSSProperty_line_height,
@ -2490,6 +2481,16 @@ static const nsCSSProperty gFontSubpropTable[] = {
eCSSProperty_UNKNOWN
};
static const nsCSSProperty gFontVariantSubpropTable[] = {
eCSSProperty_font_variant_alternates,
eCSSProperty_font_variant_caps,
eCSSProperty_font_variant_east_asian,
eCSSProperty_font_variant_ligatures,
eCSSProperty_font_variant_numeric,
eCSSProperty_font_variant_position,
eCSSProperty_UNKNOWN
};
static const nsCSSProperty gListStyleSubpropTable[] = {
eCSSProperty_list_style_type,
eCSSProperty_list_style_image,

View File

@ -1469,16 +1469,6 @@ nsComputedDOMStyle::DoGetFontWeight()
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetFontVariant()
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.variant,
nsCSSProps::kFontVariantKTable));
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetFontFeatureSettings()
{
@ -1622,6 +1612,8 @@ nsComputedDOMStyle::DoGetFontVariantLigatures()
if (0 == intValue) {
val->SetIdent(eCSSKeyword_normal);
} else if (NS_FONT_VARIANT_LIGATURES_NONE == intValue) {
val->SetIdent(eCSSKeyword_none);
} else {
nsAutoString valueStr;

View File

@ -253,7 +253,6 @@ private:
mozilla::dom::CSSValue* DoGetFontStretch();
mozilla::dom::CSSValue* DoGetFontStyle();
mozilla::dom::CSSValue* DoGetFontSynthesis();
mozilla::dom::CSSValue* DoGetFontVariant();
mozilla::dom::CSSValue* DoGetFontVariantAlternates();
mozilla::dom::CSSValue* DoGetFontVariantCaps();
mozilla::dom::CSSValue* DoGetFontVariantEastAsian();

View File

@ -123,7 +123,6 @@ COMPUTED_STYLE_PROP(font_size_adjust, FontSizeAdjust)
COMPUTED_STYLE_PROP(font_stretch, FontStretch)
COMPUTED_STYLE_PROP(font_style, FontStyle)
COMPUTED_STYLE_PROP(font_synthesis, FontSynthesis)
COMPUTED_STYLE_PROP(font_variant, FontVariant)
COMPUTED_STYLE_PROP(font_variant_alternates, FontVariantAlternates)
COMPUTED_STYLE_PROP(font_variant_caps, FontVariantCaps)
COMPUTED_STYLE_PROP(font_variant_east_asian, FontVariantEastAsian)

View File

@ -3332,7 +3332,6 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
systemFont.fontlist.SetDefaultFontType(eFamily_none);
systemFont.style = fontStyle.style;
systemFont.systemFont = fontStyle.systemFont;
systemFont.variant = NS_FONT_VARIANT_NORMAL;
systemFont.weight = fontStyle.weight;
systemFont.stretch = fontStyle.stretch;
systemFont.decorations = NS_FONT_DECORATION_NONE;
@ -3456,14 +3455,6 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
0, 0, 0, systemFont.style);
}
// font-variant: enum, inherit, initial, -moz-system-font
SetDiscrete(*aRuleData->ValueForFontVariant(),
aFont->mFont.variant, aCanStoreInRuleTree,
SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT | SETDSC_UNSET_INHERIT,
aParentFont->mFont.variant,
defaultVariableFont->variant,
0, 0, 0, systemFont.variant);
// font-weight: int, enum, inherit, initial, -moz-system-font
// special handling for enum
const nsCSSValue* weightValue = aRuleData->ValueForFontWeight();
@ -3647,15 +3638,15 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
defaultVariableFont->variantEastAsian,
0, 0, 0, systemFont.variantEastAsian);
// font-variant-ligatures: normal, enum (bit field), inherit, initial,
// font-variant-ligatures: normal, none, enum (bit field), inherit, initial,
// -moz-system-font
SetDiscrete(*aRuleData->ValueForFontVariantLigatures(),
aFont->mFont.variantLigatures, aCanStoreInRuleTree,
SETDSC_NORMAL | SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT |
SETDSC_UNSET_INHERIT,
SETDSC_NORMAL | SETDSC_NONE | SETDSC_ENUMERATED |
SETDSC_SYSTEM_FONT | SETDSC_UNSET_INHERIT,
aParentFont->mFont.variantLigatures,
defaultVariableFont->variantLigatures,
0, 0, 0, systemFont.variantLigatures);
0, NS_FONT_VARIANT_LIGATURES_NONE, 0, systemFont.variantLigatures);
// font-variant-numeric: normal, enum (bit field), inherit, initial,
// -moz-system-font

View File

@ -494,11 +494,6 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
#define NS_STYLE_FONT_STYLE_ITALIC NS_FONT_STYLE_ITALIC
#define NS_STYLE_FONT_STYLE_OBLIQUE NS_FONT_STYLE_OBLIQUE
// See nsStyleFont
// We should eventually stop using the NS_STYLE_* variants here.
#define NS_STYLE_FONT_VARIANT_NORMAL NS_FONT_VARIANT_NORMAL
#define NS_STYLE_FONT_VARIANT_SMALL_CAPS NS_FONT_VARIANT_SMALL_CAPS
// See nsStyleFont
// We should eventually stop using the NS_STYLE_* variants here.
#define NS_STYLE_FONT_WEIGHT_NORMAL NS_FONT_WEIGHT_NORMAL

View File

@ -214,7 +214,6 @@ nsChangeHint nsStyleFont::CalcFontDifference(const nsFont& aFont1, const nsFont&
if ((aFont1.size == aFont2.size) &&
(aFont1.sizeAdjust == aFont2.sizeAdjust) &&
(aFont1.style == aFont2.style) &&
(aFont1.variant == aFont2.variant) &&
(aFont1.weight == aFont2.weight) &&
(aFont1.stretch == aFont2.stretch) &&
(aFont1.smoothing == aFont2.smoothing) &&

View File

@ -2522,10 +2522,17 @@ var gCSSProperties = {
"font-variant": {
domProp: "fontVariant",
inherited: true,
type: CSS_TYPE_LONGHAND,
type: CSS_TYPE_TRUE_SHORTHAND,
subproperties: [ "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position" ],
initial_values: [ "normal" ],
other_values: [ "small-caps" ],
invalid_values: [ "small-caps normal" ]
other_values: [ "small-caps", "none", "traditional oldstyle-nums", "all-small-caps", "common-ligatures no-discretionary-ligatures",
"proportional-nums oldstyle-nums", "proportional-nums slashed-zero diagonal-fractions oldstyle-nums ordinal",
"traditional historical-forms styleset(ok-alt-a, ok-alt-b)", "styleset(potato)" ],
invalid_values: [ "small-caps normal", "small-caps small-caps", "none common-ligatures", "common-ligatures none", "small-caps potato",
"small-caps jis83 all-small-caps", "super historical-ligatures sub", "stacked-fractions diagonal-fractions historical-ligatures",
"common-ligatures traditional common-ligatures", "lining-nums traditional slashed-zero ordinal normal",
"traditional historical-forms styleset(ok-alt-a, ok-alt-b) historical-forms",
"historical-forms styleset(ok-alt-a, ok-alt-b) traditional styleset(potato)", "annotation(a,b,c)" ]
},
"font-weight": {
domProp: "fontWeight",

View File

@ -48,10 +48,7 @@ is(e.style.font, "", "font getter returns nothing");
e.setAttribute("style", "font: inherit; font-family: Helvetica;");
var cssTextStr = "font-style: inherit; font-variant: inherit; font-weight: inherit; font-size: inherit; line-height: inherit; font-size-adjust: inherit; font-stretch: inherit; -moz-font-feature-settings: inherit; -moz-font-language-override: inherit;";
if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) {
cssTextStr += " font-kerning: inherit; font-synthesis: inherit; font-variant-alternates: inherit; font-variant-caps: inherit; font-variant-east-asian: inherit; font-variant-ligatures: inherit; font-variant-numeric: inherit; font-variant-position: inherit;"
}
var cssTextStr = "font-style: inherit; font-weight: inherit; font-size: inherit; line-height: inherit; font-size-adjust: inherit; font-stretch: inherit; -moz-font-feature-settings: inherit; -moz-font-language-override: inherit; font-kerning: inherit; font-synthesis: inherit; font-variant: inherit;";
is(e.style.cssText, cssTextStr + " font-family: Helvetica;", "don't serialize system font for font:inherit");
is(e.style.font, "", "font getter returns nothing");