mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 549861. Implement CSS parsing of font-variant-alternates. r=dbaron
This commit is contained in:
parent
c18a21b5f6
commit
57964002fe
@ -541,6 +541,8 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
|
||||
*data->ValueFor(eCSSProperty_font_kerning);
|
||||
const nsCSSValue &fontSynthesis =
|
||||
*data->ValueFor(eCSSProperty_font_synthesis);
|
||||
const nsCSSValue &fontVariantAlternates =
|
||||
*data->ValueFor(eCSSProperty_font_variant_alternates);
|
||||
const nsCSSValue &fontVariantCaps =
|
||||
*data->ValueFor(eCSSProperty_font_variant_caps);
|
||||
const nsCSSValue &fontVariantEastAsian =
|
||||
@ -567,6 +569,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
|
||||
languageOverride.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontKerning.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontSynthesis.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantAlternates.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantCaps.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantEastAsian.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantLigatures.GetUnit() != eCSSUnit_System_Font ||
|
||||
@ -590,6 +593,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
|
||||
fontKerning.GetIntValue() != NS_FONT_KERNING_AUTO ||
|
||||
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 ||
|
||||
|
@ -170,6 +170,7 @@ CSS_KEY(alpha, alpha)
|
||||
CSS_KEY(alternate, alternate)
|
||||
CSS_KEY(alternate-reverse, alternate_reverse)
|
||||
CSS_KEY(always, always)
|
||||
CSS_KEY(annotation, annotation)
|
||||
CSS_KEY(appworkspace, appworkspace)
|
||||
CSS_KEY(armenian, armenian)
|
||||
CSS_KEY(auto, auto)
|
||||
@ -202,6 +203,7 @@ CSS_KEY(captiontext, captiontext)
|
||||
CSS_KEY(cell, cell)
|
||||
CSS_KEY(center, center)
|
||||
CSS_KEY(ch, ch)
|
||||
CSS_KEY(character-variant, character_variant)
|
||||
CSS_KEY(circle, circle)
|
||||
CSS_KEY(cjk-ideographic, cjk_ideographic)
|
||||
CSS_KEY(clip, clip)
|
||||
@ -279,6 +281,7 @@ CSS_KEY(highlight, highlight)
|
||||
CSS_KEY(highlighttext, highlighttext)
|
||||
CSS_KEY(hiragana, hiragana)
|
||||
CSS_KEY(hiragana-iroha, hiragana_iroha)
|
||||
CSS_KEY(historical-forms, historical_forms)
|
||||
CSS_KEY(historical-ligatures, historical_ligatures)
|
||||
CSS_KEY(horizontal, horizontal)
|
||||
CSS_KEY(hz, hz)
|
||||
@ -367,6 +370,7 @@ CSS_KEY(oblique, oblique)
|
||||
CSS_KEY(oldstyle-nums, oldstyle_nums)
|
||||
CSS_KEY(open-quote, open_quote)
|
||||
CSS_KEY(ordinal, ordinal)
|
||||
CSS_KEY(ornaments, ornaments)
|
||||
CSS_KEY(outset, outset)
|
||||
CSS_KEY(outside, outside)
|
||||
CSS_KEY(overline, overline)
|
||||
@ -455,9 +459,12 @@ CSS_KEY(stretch, stretch)
|
||||
CSS_KEY(stretch-to-fit, stretch_to_fit)
|
||||
CSS_KEY(stroke, stroke)
|
||||
CSS_KEY(style, style)
|
||||
CSS_KEY(styleset, styleset)
|
||||
CSS_KEY(stylistic, stylistic)
|
||||
CSS_KEY(sub, sub)
|
||||
CSS_KEY(super, super)
|
||||
CSS_KEY(sw-resize, sw_resize)
|
||||
CSS_KEY(swash, swash)
|
||||
CSS_KEY(table, table)
|
||||
CSS_KEY(table-caption, table_caption)
|
||||
CSS_KEY(table-cell, table_cell)
|
||||
|
@ -563,6 +563,8 @@ protected:
|
||||
bool ParseCursor();
|
||||
bool ParseFont();
|
||||
bool ParseFontSynthesis(nsCSSValue& aValue);
|
||||
bool ParseSingleAlternate(int32_t& aWhichFeature, nsCSSValue& aValue);
|
||||
bool ParseFontVariantAlternates(nsCSSValue& aValue);
|
||||
bool ParseBitmaskValues(nsCSSValue& aValue, const int32_t aKeywordTable[],
|
||||
const int32_t aMasks[]);
|
||||
bool ParseFontVariantEastAsian(nsCSSValue& aValue);
|
||||
@ -671,12 +673,13 @@ protected:
|
||||
/* Functions for transform Parsing */
|
||||
bool ParseSingleTransform(bool aIsPrefixed, nsCSSValue& aValue, bool& aIs3D);
|
||||
bool ParseFunction(const nsString &aFunction, const int32_t aAllowedTypes[],
|
||||
uint16_t aMinElems, uint16_t aMaxElems,
|
||||
nsCSSValue &aValue);
|
||||
int32_t aVariantMaskAll, uint16_t aMinElems,
|
||||
uint16_t aMaxElems, nsCSSValue &aValue);
|
||||
bool ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
uint16_t aMinElems,
|
||||
uint16_t aMaxElems,
|
||||
InfallibleTArray<nsCSSValue>& aOutput);
|
||||
int32_t aVariantMaskAll,
|
||||
uint16_t aMinElems,
|
||||
uint16_t aMaxElems,
|
||||
InfallibleTArray<nsCSSValue>& aOutput);
|
||||
|
||||
/* Functions for transform-origin/perspective-origin Parsing */
|
||||
bool ParseTransformOrigin(bool aPerspective);
|
||||
@ -6378,6 +6381,8 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
|
||||
return ParseFamily(aValue);
|
||||
case eCSSProperty_font_synthesis:
|
||||
return ParseFontSynthesis(aValue);
|
||||
case eCSSProperty_font_variant_alternates:
|
||||
return ParseFontVariantAlternates(aValue);
|
||||
case eCSSProperty_font_variant_east_asian:
|
||||
return ParseFontVariantEastAsian(aValue);
|
||||
case eCSSProperty_font_variant_ligatures:
|
||||
@ -8319,6 +8324,7 @@ CSSParserImpl::ParseFont()
|
||||
AppendValue(eCSSProperty_font_language_override, family);
|
||||
AppendValue(eCSSProperty_font_kerning, family);
|
||||
AppendValue(eCSSProperty_font_synthesis, family);
|
||||
AppendValue(eCSSProperty_font_variant_alternates, family);
|
||||
AppendValue(eCSSProperty_font_variant_caps, family);
|
||||
AppendValue(eCSSProperty_font_variant_east_asian, family);
|
||||
AppendValue(eCSSProperty_font_variant_ligatures, family);
|
||||
@ -8340,6 +8346,7 @@ CSSParserImpl::ParseFont()
|
||||
AppendValue(eCSSProperty_font_language_override, systemFont);
|
||||
AppendValue(eCSSProperty_font_kerning, systemFont);
|
||||
AppendValue(eCSSProperty_font_synthesis, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_alternates, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_caps, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_east_asian, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_ligatures, systemFont);
|
||||
@ -8413,6 +8420,8 @@ CSSParserImpl::ParseFont()
|
||||
AppendValue(eCSSProperty_font_synthesis,
|
||||
nsCSSValue(NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE,
|
||||
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));
|
||||
@ -8459,6 +8468,111 @@ CSSParserImpl::ParseFontSynthesis(nsCSSValue& aValue)
|
||||
return true;
|
||||
}
|
||||
|
||||
// font-variant-alternates allows for a multiple number of
|
||||
// both simple enumerated values and functional values with
|
||||
// parameter lists with one or more idents (these are resolved
|
||||
// later based on values defined in @font-feature-value rules).
|
||||
//
|
||||
// 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 bitmap of both simple and functional property values
|
||||
// and another value containing a valuelist with lists of idents
|
||||
// for each functional property value.
|
||||
//
|
||||
// pairValue
|
||||
// o intValue
|
||||
// NS_FONT_VARIANT_ALTERNATES_SWASH |
|
||||
// NS_FONT_VARIANT_ALTERNATES_STYLESET
|
||||
// o valuePairList, each element with
|
||||
// - intValue - indicates which alternate
|
||||
// - string or valueList of strings
|
||||
|
||||
#define MAX_ALLOWED_FEATURES 512
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseSingleAlternate(int32_t& aWhichFeature,
|
||||
nsCSSValue& aValue)
|
||||
{
|
||||
if (!GetToken(true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isIdent = (mToken.mType == eCSSToken_Ident);
|
||||
if (mToken.mType != eCSSToken_Function && !isIdent) {
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
// ident ==> simple enumerated prop val (e.g. historical-forms)
|
||||
// function ==> e.g. swash(flowing) styleset(alt-g, alt-m)
|
||||
|
||||
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
|
||||
if (eCSSKeyword_UNKNOWN < keyword &&
|
||||
nsCSSProps::FindKeyword(keyword,
|
||||
(isIdent ?
|
||||
nsCSSProps::kFontVariantAlternatesKTable :
|
||||
nsCSSProps::kFontVariantAlternatesFuncsKTable),
|
||||
aWhichFeature))
|
||||
{
|
||||
if (isIdent) {
|
||||
aValue.SetIntValue(aWhichFeature, eCSSUnit_Enumerated);
|
||||
return true;
|
||||
} else {
|
||||
uint16_t maxElems = 1;
|
||||
if (keyword == eCSSKeyword_styleset ||
|
||||
keyword == eCSSKeyword_character_variant) {
|
||||
maxElems = MAX_ALLOWED_FEATURES;
|
||||
}
|
||||
return ParseFunction(mToken.mIdent, nullptr, VARIANT_IDENTIFIER,
|
||||
1, maxElems, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
// failed, pop token
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontVariantAlternates(nsCSSValue& aValue)
|
||||
{
|
||||
if (ParseVariant(aValue, VARIANT_INHERIT | VARIANT_NORMAL, nullptr)) {
|
||||
if (!ExpectEndProperty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// iterate through parameters
|
||||
nsCSSValue listValue;
|
||||
int32_t feature, featureFlags = 0;
|
||||
|
||||
nsCSSValueList* cur = listValue.SetListValue();
|
||||
while (ParseSingleAlternate(feature, cur->mValue)) {
|
||||
|
||||
// check to make sure value not normal and not already set
|
||||
if (feature == 0 ||
|
||||
feature & featureFlags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
featureFlags |= feature;
|
||||
|
||||
if (cur->mValue.GetUnit() == eCSSUnit_Function) {
|
||||
cur->mNext = new nsCSSValueList;
|
||||
cur = cur->mNext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nsCSSValue featureValue;
|
||||
featureValue.SetIntValue(featureFlags, eCSSUnit_Enumerated);
|
||||
aValue.SetPairValue(featureValue, listValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define MASK_END_VALUE -1
|
||||
|
||||
// aMasks - array of masks for mutually-exclusive property values,
|
||||
@ -9343,14 +9457,17 @@ CSSParserImpl::ParseTextOverflow(nsCSSValue& aValue)
|
||||
*/
|
||||
bool
|
||||
CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
int32_t aVariantMaskAll,
|
||||
uint16_t aMinElems,
|
||||
uint16_t aMaxElems,
|
||||
InfallibleTArray<nsCSSValue> &aOutput)
|
||||
{
|
||||
for (uint16_t index = 0; index < aMaxElems; ++index) {
|
||||
nsCSSValue newValue;
|
||||
if (!ParseVariant(newValue, aVariantMask[index], nullptr))
|
||||
int32_t m = aVariantMaskAll ? aVariantMaskAll : aVariantMask[index];
|
||||
if (!ParseVariant(newValue, m, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutput.AppendElement(newValue);
|
||||
|
||||
@ -9379,6 +9496,7 @@ CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
* array corresponds to the first function parameter, etc. The length
|
||||
* of this array _must_ be greater than or equal to aMaxElems or the
|
||||
* behavior is undefined.
|
||||
* @param aAllowTypeAll If set, all elements tested for these types
|
||||
* @param aMinElems Minimum number of elements to read. Reading fewer than
|
||||
* this many elements will result in the function failing.
|
||||
* @param aMaxElems Maximum number of elements to read. Reading more than
|
||||
@ -9388,6 +9506,7 @@ CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
bool
|
||||
CSSParserImpl::ParseFunction(const nsString &aFunction,
|
||||
const int32_t aAllowedTypes[],
|
||||
int32_t aAllowedTypesAll,
|
||||
uint16_t aMinElems, uint16_t aMaxElems,
|
||||
nsCSSValue &aValue)
|
||||
{
|
||||
@ -9408,9 +9527,10 @@ CSSParserImpl::ParseFunction(const nsString &aFunction,
|
||||
* it's out of bounds.
|
||||
*/
|
||||
InfallibleTArray<nsCSSValue> foundValues;
|
||||
if (!ParseFunctionInternals(aAllowedTypes, aMinElems, aMaxElems,
|
||||
foundValues))
|
||||
if (!ParseFunctionInternals(aAllowedTypes, aAllowedTypesAll, aMinElems,
|
||||
aMaxElems, foundValues)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Now, convert this array into an nsCSSValue::Array object.
|
||||
* We'll need N + 1 spots, one for the function name and the rest for the
|
||||
@ -9685,7 +9805,8 @@ CSSParserImpl::ParseSingleTransform(bool aIsPrefixed,
|
||||
break;
|
||||
}
|
||||
|
||||
return ParseFunction(mToken.mIdent, variantMask, minElems, maxElems, aValue);
|
||||
return ParseFunction(mToken.mIdent, variantMask, 0, minElems,
|
||||
maxElems, aValue);
|
||||
}
|
||||
|
||||
/* Parses a transform property list by continuously reading in properties
|
||||
|
@ -1811,6 +1811,19 @@ CSS_PROP_FONT(
|
||||
kFontVariantKTable,
|
||||
offsetof(nsStyleFont, mFont.variant),
|
||||
eStyleAnimType_EnumU8)
|
||||
CSS_PROP_FONT(
|
||||
font-variant-alternates,
|
||||
font_variant_alternates,
|
||||
FontVariantAlternates,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
VARIANT_HK,
|
||||
kFontVariantAlternatesKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-variant-caps,
|
||||
font_variant_caps,
|
||||
|
@ -1066,6 +1066,21 @@ const int32_t nsCSSProps::kFontVariantKTable[] = {
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantAlternatesKTable[] = {
|
||||
eCSSKeyword_historical_forms, NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantAlternatesFuncsKTable[] = {
|
||||
eCSSKeyword_stylistic, NS_FONT_VARIANT_ALTERNATES_STYLISTIC,
|
||||
eCSSKeyword_styleset, NS_FONT_VARIANT_ALTERNATES_STYLESET,
|
||||
eCSSKeyword_character_variant, NS_FONT_VARIANT_ALTERNATES_CHARACTER_VARIANT,
|
||||
eCSSKeyword_swash, NS_FONT_VARIANT_ALTERNATES_SWASH,
|
||||
eCSSKeyword_ornaments, NS_FONT_VARIANT_ALTERNATES_ORNAMENTS,
|
||||
eCSSKeyword_annotation, NS_FONT_VARIANT_ALTERNATES_ANNOTATION,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantCapsKTable[] = {
|
||||
eCSSKeyword_small_caps, NS_FONT_VARIANT_CAPS_SMALLCAPS,
|
||||
eCSSKeyword_all_small_caps, NS_FONT_VARIANT_CAPS_ALLSMALL,
|
||||
@ -2146,6 +2161,7 @@ static const nsCSSProperty gFontSubpropTable[] = {
|
||||
eCSSProperty_font_language_override,
|
||||
eCSSProperty_font_kerning,
|
||||
eCSSProperty_font_synthesis,
|
||||
eCSSProperty_font_variant_alternates,
|
||||
eCSSProperty_font_variant_caps,
|
||||
eCSSProperty_font_variant_east_asian,
|
||||
eCSSProperty_font_variant_ligatures,
|
||||
|
@ -404,6 +404,8 @@ public:
|
||||
static const int32_t kFontStyleKTable[];
|
||||
static const int32_t kFontSynthesisKTable[];
|
||||
static const int32_t kFontVariantKTable[];
|
||||
static const int32_t kFontVariantAlternatesKTable[];
|
||||
static const int32_t kFontVariantAlternatesFuncsKTable[];
|
||||
static const int32_t kFontVariantCapsKTable[];
|
||||
static const int32_t kFontVariantEastAsianKTable[];
|
||||
static const int32_t kFontVariantLigaturesKTable[];
|
||||
|
@ -1095,7 +1095,27 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
|
||||
|
||||
aResult.AppendLiteral(")");
|
||||
} else if (eCSSUnit_Pair == unit) {
|
||||
GetPairValue().AppendToString(aProperty, aResult);
|
||||
if (eCSSProperty_font_variant_alternates == aProperty) {
|
||||
int32_t intValue = GetPairValue().mXValue.GetIntValue();
|
||||
nsAutoString out;
|
||||
|
||||
// simple, enumerated values
|
||||
nsStyleUtil::AppendBitmaskCSSValue(aProperty,
|
||||
intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
|
||||
out);
|
||||
|
||||
// functional values
|
||||
const nsCSSValueList *list = GetPairValue().mYValue.GetListValue();
|
||||
nsAutoTArray<gfxAlternateValue,8> altValues;
|
||||
|
||||
nsStyleUtil::AppendAlternateValues(list, altValues);
|
||||
nsStyleUtil::AppendFunctionalAlternates(altValues, out);
|
||||
aResult.Append(out);
|
||||
} else {
|
||||
GetPairValue().AppendToString(aProperty, aResult);
|
||||
}
|
||||
} else if (eCSSUnit_Triplet == unit) {
|
||||
GetTripletValue().AppendToString(aProperty, aResult);
|
||||
} else if (eCSSUnit_Rect == unit) {
|
||||
|
@ -1379,6 +1379,37 @@ nsComputedDOMStyle::DoGetFontSynthesis()
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontVariantAlternates()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
|
||||
int32_t intValue = StyleFont()->mFont.variantAlternates;
|
||||
|
||||
if (0 == intValue) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
return val;
|
||||
}
|
||||
|
||||
// first, include enumerated values
|
||||
nsAutoString valueStr;
|
||||
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_alternates,
|
||||
intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL, valueStr);
|
||||
|
||||
// next, include functional values if present
|
||||
if (intValue & NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK) {
|
||||
nsStyleUtil::AppendFunctionalAlternates(StyleFont()->mFont.alternateValues,
|
||||
valueStr);
|
||||
}
|
||||
|
||||
val->SetString(valueStr);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontVariantCaps()
|
||||
{
|
||||
@ -4898,6 +4929,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(uint32_t* aLength)
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_style, FontStyle),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_synthesis, FontSynthesis),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant, FontVariant),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_alternates, FontVariantAlternates),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_caps, FontVariantCaps),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_east_asian, FontVariantEastAsian),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_ligatures, FontVariantLigatures),
|
||||
|
@ -196,6 +196,7 @@ private:
|
||||
mozilla::dom::CSSValue* DoGetFontStyle();
|
||||
mozilla::dom::CSSValue* DoGetFontSynthesis();
|
||||
mozilla::dom::CSSValue* DoGetFontVariant();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantAlternates();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantCaps();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantEastAsian();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantLigatures();
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "CSSCalc.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
|
||||
@ -3289,6 +3290,49 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
|
||||
defaultVariableFont->synthesis,
|
||||
0, 0, 0, systemFont.synthesis);
|
||||
|
||||
// font-variant-alternates: enum (bit field) + functions, inherit, initial
|
||||
const nsCSSValue* variantAlternatesValue =
|
||||
aRuleData->ValueForFontVariantAlternates();
|
||||
int32_t variantAlternates = 0;
|
||||
|
||||
switch (variantAlternatesValue->GetUnit()) {
|
||||
case eCSSUnit_Initial:
|
||||
aFont->mFont.CopyAlternates(*defaultVariableFont);
|
||||
break;
|
||||
|
||||
case eCSSUnit_Inherit:
|
||||
aFont->mFont.CopyAlternates(aParentFont->mFont);
|
||||
aCanStoreInRuleTree = false;
|
||||
break;
|
||||
|
||||
case eCSSUnit_Normal:
|
||||
aFont->mFont.variantAlternates = 0;
|
||||
aFont->mFont.alternateValues.Clear();
|
||||
aFont->mFont.featureValueLookup = nullptr;
|
||||
break;
|
||||
|
||||
case eCSSUnit_Pair:
|
||||
NS_ASSERTION(variantAlternatesValue->GetPairValue().mXValue.GetUnit() ==
|
||||
eCSSUnit_Enumerated, "strange unit for variantAlternates");
|
||||
variantAlternates =
|
||||
variantAlternatesValue->GetPairValue().mXValue.GetIntValue();
|
||||
aFont->mFont.variantAlternates = variantAlternates;
|
||||
|
||||
if (variantAlternates & NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK) {
|
||||
// fetch the feature lookup object from the styleset
|
||||
aFont->mFont.featureValueLookup =
|
||||
aPresContext->StyleSet()->GetFontFeatureValuesLookup();
|
||||
|
||||
nsStyleUtil::AppendAlternateValues(
|
||||
variantAlternatesValue->GetPairValue().mYValue.GetListValue(),
|
||||
aFont->mFont.alternateValues);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// font-variant-caps: enum, inherit, initial
|
||||
SetDiscrete(*aRuleData->ValueForFontVariantCaps(),
|
||||
aFont->mFont.variantCaps, aCanStoreInRuleTree,
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIStyleRule.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "gfxFontFeatures.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsCSSFontFaceRule;
|
||||
@ -164,6 +164,12 @@ class nsStyleSet
|
||||
bool AppendKeyframesRules(nsPresContext* aPresContext,
|
||||
nsTArray<nsCSSKeyframesRule*>& aArray);
|
||||
|
||||
already_AddRefed<gfxFontFeatureValueSet>
|
||||
GetFontFeatureValuesLookup()
|
||||
{
|
||||
return nullptr; // not implemented yet
|
||||
}
|
||||
|
||||
// Append all the currently-active page rules to aArray. Return
|
||||
// true for success and false for failure.
|
||||
bool AppendPageRules(nsPresContext* aPresContext,
|
||||
|
@ -194,6 +194,9 @@ nsChangeHint nsStyleFont::CalcFontDifference(const nsFont& aFont1, const nsFont&
|
||||
(aFont1.name == aFont2.name) &&
|
||||
(aFont1.kerning == aFont2.kerning) &&
|
||||
(aFont1.synthesis == aFont2.synthesis) &&
|
||||
(aFont1.variantAlternates == aFont2.variantAlternates) &&
|
||||
(aFont1.alternateValues == aFont2.alternateValues) &&
|
||||
(aFont1.featureValueLookup == aFont2.featureValueLookup) &&
|
||||
(aFont1.variantCaps == aFont2.variantCaps) &&
|
||||
(aFont1.variantEastAsian == aFont2.variantEastAsian) &&
|
||||
(aFont1.variantLigatures == aFont2.variantLigatures) &&
|
||||
|
@ -269,6 +269,118 @@ nsStyleUtil::AppendFontFeatureSettings(const nsCSSValue& aSrc,
|
||||
AppendFontFeatureSettings(featureSettings, aResult);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::GetFunctionalAlternatesName(int32_t aFeature,
|
||||
nsAString& aFeatureName)
|
||||
{
|
||||
aFeatureName.Truncate();
|
||||
nsCSSKeyword key =
|
||||
nsCSSProps::ValueToKeywordEnum(aFeature,
|
||||
nsCSSProps::kFontVariantAlternatesFuncsKTable);
|
||||
|
||||
NS_ASSERTION(key != eCSSKeyword_UNKNOWN, "bad alternate feature type");
|
||||
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(key), aFeatureName);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::AppendFunctionalAlternates(
|
||||
const nsTArray<gfxAlternateValue>& aAlternates,
|
||||
nsAString& aResult)
|
||||
{
|
||||
nsAutoString funcName, funcParams;
|
||||
uint32_t numValues = aAlternates.Length();
|
||||
|
||||
uint32_t feature = 0;
|
||||
for (uint32_t i = 0; i < numValues; i++) {
|
||||
const gfxAlternateValue& v = aAlternates.ElementAt(i);
|
||||
if (feature != v.alternate) {
|
||||
feature = v.alternate;
|
||||
if (!funcName.IsEmpty() && !funcParams.IsEmpty()) {
|
||||
if (!aResult.IsEmpty()) {
|
||||
aResult.Append(PRUnichar(' '));
|
||||
}
|
||||
|
||||
// append the previous functional value
|
||||
aResult.Append(funcName);
|
||||
aResult.Append(PRUnichar('('));
|
||||
aResult.Append(funcParams);
|
||||
aResult.Append(PRUnichar(')'));
|
||||
}
|
||||
|
||||
// function name
|
||||
GetFunctionalAlternatesName(v.alternate, funcName);
|
||||
NS_ASSERTION(!funcName.IsEmpty(), "unknown property value name");
|
||||
|
||||
// function params
|
||||
funcParams.Assign(v.value);
|
||||
} else {
|
||||
if (!funcParams.IsEmpty()) {
|
||||
funcParams.Append(NS_LITERAL_STRING(", "));
|
||||
}
|
||||
funcParams.Append(v.value);
|
||||
}
|
||||
}
|
||||
|
||||
// append the previous functional value
|
||||
if (!funcName.IsEmpty() && !funcParams.IsEmpty()) {
|
||||
if (!aResult.IsEmpty()) {
|
||||
aResult.Append(PRUnichar(' '));
|
||||
}
|
||||
|
||||
aResult.Append(funcName);
|
||||
aResult.Append(PRUnichar('('));
|
||||
aResult.Append(funcParams);
|
||||
aResult.Append(PRUnichar(')'));
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::AppendAlternateValues(const nsCSSValueList* aList,
|
||||
nsTArray<gfxAlternateValue>& aAlternateValues)
|
||||
{
|
||||
gfxAlternateValue v;
|
||||
|
||||
aAlternateValues.Clear();
|
||||
for (const nsCSSValueList* curr = aList; curr != nullptr; curr = curr->mNext) {
|
||||
// list contains function units
|
||||
if (curr->mValue.GetUnit() != eCSSUnit_Function) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// element 0 is the propval in ident form
|
||||
const nsCSSValue::Array *func = curr->mValue.GetArrayValue();
|
||||
|
||||
// lookup propval
|
||||
nsAutoString keywordStr;
|
||||
func->Item(0).GetStringValue(keywordStr);
|
||||
nsCSSKeyword key = nsCSSKeywords::LookupKeyword(keywordStr);
|
||||
NS_ASSERTION(key != eCSSKeyword_UNKNOWN, "unknown alternate property value");
|
||||
|
||||
int32_t alternate;
|
||||
if (key == eCSSKeyword_UNKNOWN ||
|
||||
!nsCSSProps::FindKeyword(key,
|
||||
nsCSSProps::kFontVariantAlternatesFuncsKTable,
|
||||
alternate)) {
|
||||
continue;
|
||||
}
|
||||
v.alternate = alternate;
|
||||
|
||||
// other elements are the idents associated with the propval
|
||||
// append one alternate value for each one
|
||||
uint32_t numElems = func->Count();
|
||||
for (uint32_t i = 1; i < numElems; i++) {
|
||||
const nsCSSValue& value = func->Item(i);
|
||||
NS_ASSERTION(value.GetUnit() == eCSSUnit_Ident,
|
||||
"weird unit found in variant alternate");
|
||||
if (value.GetUnit() != eCSSUnit_Ident) {
|
||||
continue;
|
||||
}
|
||||
value.GetStringValue(v.value);
|
||||
aAlternateValues.AppendElement(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ float
|
||||
nsStyleUtil::ColorComponentToFloat(uint8_t aAlpha)
|
||||
{
|
||||
|
@ -7,11 +7,13 @@
|
||||
|
||||
#include "nsCoord.h"
|
||||
#include "nsCSSProperty.h"
|
||||
#include "gfxFontFeatures.h"
|
||||
|
||||
class nsCSSValue;
|
||||
class nsStringComparator;
|
||||
class nsIContent;
|
||||
struct gfxFontFeature;
|
||||
class nsCSSValueList;
|
||||
template <class E> class nsTArray;
|
||||
|
||||
// Style utility functions
|
||||
@ -49,6 +51,20 @@ public:
|
||||
static void AppendFontFeatureSettings(const nsCSSValue& src,
|
||||
nsAString& aResult);
|
||||
|
||||
// convert bitmask value to keyword name for a functional alternate
|
||||
static void GetFunctionalAlternatesName(int32_t aFeature,
|
||||
nsAString& aFeatureName);
|
||||
|
||||
// Append functional font-variant-alternates values to string
|
||||
static void
|
||||
AppendFunctionalAlternates(const nsTArray<gfxAlternateValue>& aAlternates,
|
||||
nsAString& aResult);
|
||||
|
||||
// List of functional font-variant-alternates values to feature/value pairs
|
||||
static void
|
||||
AppendAlternateValues(const nsCSSValueList* aList,
|
||||
nsTArray<gfxAlternateValue>& aAlternateValues);
|
||||
|
||||
/*
|
||||
* Convert an author-provided floating point number to an integer (0
|
||||
* ... 255) appropriate for use in the alpha component of a color.
|
||||
|
@ -4267,6 +4267,16 @@ if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) {
|
||||
other_values: [ "normal", "none" ],
|
||||
invalid_values: [ "on" ]
|
||||
},
|
||||
"font-variant-alternates": {
|
||||
domProp: "fontVariantAlternates",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "historical-forms",
|
||||
"styleset(alt-a, alt-b)", "character-variant(a, b, c)", "annotation(circled)" ],
|
||||
invalid_values: [ "historical-forms normal", "historical-forms historical-forms",
|
||||
"swash", "swash(3)", "annotation(a, b)", "ornaments(a,b)" ]
|
||||
},
|
||||
"font-variant-caps": {
|
||||
domProp: "fontVariantCaps",
|
||||
inherited: true,
|
||||
@ -4332,7 +4342,7 @@ if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) {
|
||||
for (var prop in fontFeatureProperties) {
|
||||
gCSSProperties[prop] = fontFeatureProperties[prop];
|
||||
}
|
||||
var fontAdditions = [ "font-kerning", "font-synthesis", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position" ];
|
||||
var fontAdditions = [ "font-kerning", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position" ];
|
||||
gCSSProperties["font"].subproperties = gCSSProperties["font"].subproperties.concat(fontAdditions);
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@ if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) {
|
||||
var featureDefs = {
|
||||
"font-kerning": "auto", // has to be default value
|
||||
"font-synthesis": "weight style", // has to be default value
|
||||
"font-variant-alternates": "normal", // has to be default value
|
||||
"font-variant-caps": "normal", // has to be default value
|
||||
"font-variant-east-asian": "normal", // has to be default value
|
||||
"font-variant-ligatures": "normal", // has to be default value
|
||||
|
@ -50,7 +50,7 @@ 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-caps: inherit; font-variant-east-asian: inherit; font-variant-ligatures: inherit; font-variant-numeric: inherit; font-variant-position: inherit;"
|
||||
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;"
|
||||
}
|
||||
|
||||
is(e.style.cssText, cssTextStr + " font-family: Helvetica;", "don't serialize system font for font:inherit");
|
||||
|
Loading…
Reference in New Issue
Block a user