зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1321022 pt 4 - Implement CSS parsing of the font-variations-setting property, storing the value into nsFont. r=dholbert
This commit is contained in:
Родитель
9edd951825
Коммит
cd6fcd068a
|
@ -1056,6 +1056,7 @@ protected:
|
|||
bool ParseOneFamily(nsAString& aFamily, bool& aOneKeyword, bool& aQuoted);
|
||||
bool ParseFamily(nsCSSValue& aValue);
|
||||
bool ParseFontFeatureSettings(nsCSSValue& aValue);
|
||||
bool ParseFontVariationSettings(nsCSSValue& aValue);
|
||||
bool ParseFontSrc(nsCSSValue& aValue);
|
||||
bool ParseFontSrcFormat(InfallibleTArray<nsCSSValue>& values);
|
||||
bool ParseFontRanges(nsCSSValue& aValue);
|
||||
|
@ -12099,6 +12100,8 @@ CSSParserImpl::ParseSingleValuePropertyByFunction(nsCSSValue& aValue,
|
|||
return ParseFontVariantNumeric(aValue);
|
||||
case eCSSProperty_font_feature_settings:
|
||||
return ParseFontFeatureSettings(aValue);
|
||||
case eCSSProperty_font_variation_settings:
|
||||
return ParseFontVariationSettings(aValue);
|
||||
case eCSSProperty_font_weight:
|
||||
return ParseFontWeight(aValue);
|
||||
case eCSSProperty_image_orientation:
|
||||
|
@ -15354,6 +15357,55 @@ CSSParserImpl::ParseFontFeatureSettings(nsCSSValue& aValue)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontVariationSettings(nsCSSValue& aValue)
|
||||
{
|
||||
if (ParseSingleTokenVariant(aValue, VARIANT_INHERIT | VARIANT_NORMAL,
|
||||
nullptr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto resultHead = MakeUnique<nsCSSValuePairList>();
|
||||
nsCSSValuePairList* cur = resultHead.get();
|
||||
|
||||
for (;;) {
|
||||
// variation tag
|
||||
if (!GetToken(true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// variation tags are subject to the same validation as feature tags
|
||||
if (mToken.mType != eCSSToken_String ||
|
||||
!ValidFontFeatureTag(mToken.mIdent)) {
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
cur->mXValue.SetStringValue(mToken.mIdent, eCSSUnit_String);
|
||||
|
||||
if (!GetToken(true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mToken.mType == eCSSToken_Number) {
|
||||
cur->mYValue.SetFloatValue(mToken.mNumber, eCSSUnit_Number);
|
||||
} else {
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ExpectSymbol(',', true)) {
|
||||
break;
|
||||
}
|
||||
|
||||
cur->mNext = new nsCSSValuePairList;
|
||||
cur = cur->mNext;
|
||||
}
|
||||
|
||||
aValue.AdoptPairListValue(Move(resultHead));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseListStyle()
|
||||
{
|
||||
|
|
|
@ -2036,6 +2036,20 @@ CSS_PROP_FONT(
|
|||
kFontVariantPositionKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_Discrete)
|
||||
CSS_PROP_FONT(
|
||||
font-variation-settings,
|
||||
font_variation_settings,
|
||||
FontVariationSettings,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
|
||||
CSS_PROPERTY_VALUE_LIST_USES_COMMAS |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-variations.enabled",
|
||||
0,
|
||||
nullptr,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_Discrete)
|
||||
CSS_PROP_FONT(
|
||||
font-weight,
|
||||
font_weight,
|
||||
|
|
|
@ -1588,6 +1588,23 @@ nsComputedDOMStyle::DoGetFontFeatureSettings()
|
|||
return val.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetFontVariationSettings()
|
||||
{
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
|
||||
const nsStyleFont* font = StyleFont();
|
||||
if (font->mFont.fontVariationSettings.IsEmpty()) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
} else {
|
||||
nsAutoString result;
|
||||
nsStyleUtil::AppendFontVariationSettings(font->mFont.fontVariationSettings,
|
||||
result);
|
||||
val->SetString(result);
|
||||
}
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetFontKerning()
|
||||
{
|
||||
|
|
|
@ -256,6 +256,7 @@ private:
|
|||
already_AddRefed<CSSValue> DoGetColor();
|
||||
already_AddRefed<CSSValue> DoGetFontFamily();
|
||||
already_AddRefed<CSSValue> DoGetFontFeatureSettings();
|
||||
already_AddRefed<CSSValue> DoGetFontVariationSettings();
|
||||
already_AddRefed<CSSValue> DoGetFontKerning();
|
||||
already_AddRefed<CSSValue> DoGetFontLanguageOverride();
|
||||
already_AddRefed<CSSValue> DoGetFontSize();
|
||||
|
|
|
@ -144,6 +144,7 @@ COMPUTED_STYLE_PROP(font_variant_east_asian, FontVariantEastAsian)
|
|||
COMPUTED_STYLE_PROP(font_variant_ligatures, FontVariantLigatures)
|
||||
COMPUTED_STYLE_PROP(font_variant_numeric, FontVariantNumeric)
|
||||
COMPUTED_STYLE_PROP(font_variant_position, FontVariantPosition)
|
||||
COMPUTED_STYLE_PROP(font_variation_settings, FontVariationSettings)
|
||||
COMPUTED_STYLE_PROP(font_weight, FontWeight)
|
||||
COMPUTED_STYLE_PROP(grid_auto_columns, GridAutoColumns)
|
||||
COMPUTED_STYLE_PROP(grid_auto_flow, GridAutoFlow)
|
||||
|
|
|
@ -3994,6 +3994,41 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
|
|||
break;
|
||||
}
|
||||
|
||||
// font-variation-settings
|
||||
const nsCSSValue* variationSettingsValue =
|
||||
aRuleData->ValueForFontVariationSettings();
|
||||
|
||||
switch (variationSettingsValue->GetUnit()) {
|
||||
case eCSSUnit_Null:
|
||||
break;
|
||||
|
||||
case eCSSUnit_Normal:
|
||||
case eCSSUnit_Initial:
|
||||
aFont->mFont.fontVariationSettings.Clear();
|
||||
break;
|
||||
|
||||
case eCSSUnit_Inherit:
|
||||
case eCSSUnit_Unset:
|
||||
aConditions.SetUncacheable();
|
||||
aFont->mFont.fontVariationSettings =
|
||||
aParentFont->mFont.fontVariationSettings;
|
||||
break;
|
||||
|
||||
case eCSSUnit_System_Font:
|
||||
aFont->mFont.fontVariationSettings = systemFont.fontVariationSettings;
|
||||
break;
|
||||
|
||||
case eCSSUnit_PairList:
|
||||
case eCSSUnit_PairListDep:
|
||||
ComputeFontVariations(variationSettingsValue->GetPairListValue(),
|
||||
aFont->mFont.fontVariationSettings);
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(false, "unexpected value unit");
|
||||
break;
|
||||
}
|
||||
|
||||
// font-language-override
|
||||
const nsCSSValue* languageOverrideValue =
|
||||
aRuleData->ValueForFontLanguageOverride();
|
||||
|
@ -4126,6 +4161,18 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
|
|||
SETFCT_NONE | SETFCT_UNSET_INHERIT);
|
||||
}
|
||||
|
||||
static inline void
|
||||
AssertValidFontTag(const nsString& aString)
|
||||
{
|
||||
// To be valid as a font feature tag, a string MUST be:
|
||||
MOZ_ASSERT(aString.Length() == 4 && // (1) exactly 4 chars long
|
||||
NS_IsAscii(aString.BeginReading()) && // (2) entirely ASCII
|
||||
isprint(aString[0]) && // (3) all printable chars
|
||||
isprint(aString[1]) &&
|
||||
isprint(aString[2]) &&
|
||||
isprint(aString[3]));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsRuleNode::ComputeFontFeatures(const nsCSSValuePairList *aFeaturesList,
|
||||
nsTArray<gfxFontFeature>& aFeatureSettings)
|
||||
|
@ -4156,6 +4203,37 @@ nsRuleNode::ComputeFontFeatures(const nsCSSValuePairList *aFeaturesList,
|
|||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsRuleNode::ComputeFontVariations(const nsCSSValuePairList* aVariationsList,
|
||||
nsTArray<gfxFontVariation>& aVariationSettings)
|
||||
{
|
||||
aVariationSettings.Clear();
|
||||
for (const nsCSSValuePairList* p = aVariationsList; p; p = p->mNext) {
|
||||
gfxFontVariation var;
|
||||
|
||||
MOZ_ASSERT(aVariationsList->mXValue.GetUnit() == eCSSUnit_String,
|
||||
"unexpected value unit");
|
||||
|
||||
// tag is a 4-byte ASCII sequence
|
||||
nsAutoString tag;
|
||||
p->mXValue.GetStringValue(tag);
|
||||
AssertValidFontTag(tag);
|
||||
if (tag.Length() != 4) {
|
||||
continue;
|
||||
}
|
||||
// parsing validates that these are ASCII chars
|
||||
// tags are always big-endian
|
||||
var.mTag = (tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3];
|
||||
|
||||
// value
|
||||
NS_ASSERTION(p->mYValue.GetUnit() == eCSSUnit_Number,
|
||||
"should have found a number unit");
|
||||
var.mValue = p->mYValue.GetFloatValue();
|
||||
|
||||
aVariationSettings.AppendElement(var);
|
||||
}
|
||||
}
|
||||
|
||||
// This should die (bug 380915).
|
||||
//
|
||||
// SetGenericFont:
|
||||
|
|
|
@ -1025,6 +1025,9 @@ public:
|
|||
static void ComputeFontFeatures(const nsCSSValuePairList *aFeaturesList,
|
||||
nsTArray<gfxFontFeature>& aFeatureSettings);
|
||||
|
||||
static void ComputeFontVariations(const nsCSSValuePairList* aVariationsList,
|
||||
nsTArray<gfxFontVariation>& aVariationSettings);
|
||||
|
||||
static nscoord CalcFontPointSize(int32_t aHTMLSize, int32_t aBasePointSize,
|
||||
nsPresContext* aPresContext,
|
||||
nsFontSizeType aFontSizeType = eFontSize_HTML);
|
||||
|
|
|
@ -390,6 +390,45 @@ nsStyleUtil::AppendFontFeatureSettings(const nsCSSValue& aSrc,
|
|||
AppendFontFeatureSettings(featureSettings, aResult);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::AppendFontVariationSettings(const nsTArray<gfxFontVariation>& aVariations,
|
||||
nsAString& aResult)
|
||||
{
|
||||
for (uint32_t i = 0, numVars = aVariations.Length(); i < numVars; i++) {
|
||||
const gfxFontVariation& var = aVariations[i];
|
||||
|
||||
if (i != 0) {
|
||||
aResult.AppendLiteral(", ");
|
||||
}
|
||||
|
||||
// output tag
|
||||
AppendFontTagAsString(var.mTag, aResult);
|
||||
|
||||
// output value
|
||||
aResult.Append(' ');
|
||||
aResult.AppendFloat(var.mValue);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::AppendFontVariationSettings(const nsCSSValue& aSrc,
|
||||
nsAString& aResult)
|
||||
{
|
||||
nsCSSUnit unit = aSrc.GetUnit();
|
||||
|
||||
if (unit == eCSSUnit_Normal) {
|
||||
aResult.AppendLiteral("normal");
|
||||
return;
|
||||
}
|
||||
|
||||
NS_PRECONDITION(unit == eCSSUnit_PairList || unit == eCSSUnit_PairListDep,
|
||||
"improper value unit for font-variation-settings:");
|
||||
|
||||
nsTArray<gfxFontVariation> variationSettings;
|
||||
nsRuleNode::ComputeFontVariations(aSrc.GetPairListValue(), variationSettings);
|
||||
AppendFontVariationSettings(variationSettings, aResult);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::GetFunctionalAlternatesName(int32_t aFeature,
|
||||
nsAString& aFeatureName)
|
||||
|
|
|
@ -71,6 +71,12 @@ public:
|
|||
static void AppendFontFeatureSettings(const nsCSSValue& src,
|
||||
nsAString& aResult);
|
||||
|
||||
static void AppendFontVariationSettings(const nsTArray<gfxFontVariation>& aVariations,
|
||||
nsAString& aResult);
|
||||
|
||||
static void AppendFontVariationSettings(const nsCSSValue& src,
|
||||
nsAString& aResult);
|
||||
|
||||
static void AppendUnicodeRange(const nsCSSValue& aValue, nsAString& aResult);
|
||||
|
||||
static void AppendCSSNumber(float aNumber, nsAString& aResult)
|
||||
|
|
|
@ -5687,6 +5687,31 @@ if (IsCSSPropertyPrefEnabled("layout.css.text-combine-upright.enabled")) {
|
|||
}
|
||||
}
|
||||
|
||||
if (IsCSSPropertyPrefEnabled("layout.css.font-variations.enabled")) {
|
||||
gCSSProperties["font-variation-settings"] = {
|
||||
domProp: "fontVariationSettings",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [
|
||||
"'wdth' 0", "'wdth' -.1", "\"wdth\" 1", "'wdth' 2, 'wght' 3", "\"XXXX\" 0"
|
||||
],
|
||||
invalid_values: [
|
||||
"wdth", "wdth 1", // unquoted tags
|
||||
"'wdth'", "'wdth' 'wght'", "'wdth', 'wght'", // missing values
|
||||
"'' 1", "'wid' 1", "'width' 1", // incorrect tag lengths
|
||||
"'wd\th' 1", // non-graphic character in tag
|
||||
"'wdth' 1 'wght' 2", // missing comma between pairs
|
||||
"'wdth' 1,", // trailing comma
|
||||
"'wdth' 1 , , 'wght' 2", // extra comma
|
||||
"'wdth', 1" // comma within pair
|
||||
],
|
||||
unbalanced_values: [
|
||||
"'wdth\" 1", "\"wdth' 1" // mismatched quotes
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (IsCSSPropertyPrefEnabled("svg.paint-order.enabled")) {
|
||||
gCSSProperties["paint-order"] = {
|
||||
domProp: "paintOrder",
|
||||
|
|
|
@ -2547,6 +2547,9 @@ pref("layout.css.image-orientation.enabled", true);
|
|||
// Is support for the font-display @font-face descriptor enabled?
|
||||
pref("layout.css.font-display.enabled", false);
|
||||
|
||||
// Is support for variation fonts enabled?
|
||||
pref("layout.css.font-variations.enabled", false);
|
||||
|
||||
// Are sets of prefixed properties supported?
|
||||
pref("layout.css.prefixes.border-image", true);
|
||||
pref("layout.css.prefixes.transforms", true);
|
||||
|
|
Загрузка…
Ссылка в новой задаче