Commit 8b4edde0 authored by Dominik Röttsches's avatar Dominik Röttsches Committed by Commit Bot

Parse ranges for font-style in @font-face

Allow ranges for font-style in @font-face, compare
https://drafts.csswg.org/css-fonts-4/#font-prop-desc and support the
oblique <angle> style property of CSS Fonts Level 4.

Bug: 749091
Change-Id: I7888f2f01f3cda8ec1b8d5c13b884f75b1790e50
Reviewed-on: https://chromium-review.googlesource.com/600228
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Reviewed-by: default avatarBugs Nash <bugsnash@chromium.org>
Reviewed-by: default avatarRune Lillesveen <rune@opera.com>
Cr-Commit-Position: refs/heads/master@{#491978}
parent 943ec8a0
......@@ -21,12 +21,15 @@ var styleValidTests = {
'calc(100 + 300)',
'calc(0.2 + 205.5)',
],
'stretch': ['51%', '199%', 'calc(10% + 20%)']
'stretch': ['51%', '199%', 'calc(10% + 20%)'],
'style' : [ 'normal', 'italic', 'oblique', 'oblique 50deg', 'oblique -90deg', 'oblique 90deg',
'oblique calc(30deg + 20deg)' ]
};
var styleInvalidTests = {
'weight': ['100 400', 'calc(0 - 100)', 'calc(200 + 801)'],
'stretch': ['100% 110%', '0%', '100% 150%', 'calc(1 + 10%)']
'stretch': ['100% 110%', '0%', '100% 150%', 'calc(1 + 10%)'],
'style' : [ 'normal 10deg', 'italic 10deg', 'oblique -91deg', 'oblique 91deg', 'oblique calc(90deg + 20deg)']
};
function testParseStyle() {
......@@ -70,6 +73,13 @@ var faceTests = {
['ultra-condensed', 'ultra-condensed'],
['ultra-expanded', 'ultra-expanded'],
],
'style' : [
[ "normal", "normal" ],
[ "italic", "italic" ],
[ "oblique", "oblique" ],
[ "oblique 10deg", "oblique 10deg" ],
[ "oblique 10deg 20deg", "oblique 10deg 20deg" ]
]
};
var faceInvalidTests = {
......@@ -90,6 +100,8 @@ var faceInvalidTests = {
'-0.5%', '-1%', '0%', 'calc(0% - 10%)', '60% 70% 80%', 'a%', 'a b c', '0.1',
'-60% 80%', 'ultra-expannnned', '50% 0'
],
'style' : [ 'oblique 100deg', 'oblique italic', 'oblique -91deg', 'oblique 0',
'oblique 10', 'iiitalic', '90deg', '11', 'italic 90deg' ]
};
function testParseFace() {
......
......@@ -166,7 +166,7 @@ const CSSValue* ConsumeSingleType(const CSSSyntaxComponent& syntax,
case CSSSyntaxType::kInteger:
return ConsumeInteger(range);
case CSSSyntaxType::kAngle:
return ConsumeAngle(range, *context, WTF::Optional<WebFeature>());
return ConsumeAngle(range, context, WTF::Optional<WebFeature>());
case CSSSyntaxType::kTime:
return ConsumeTime(range, ValueRange::kValueRangeAll);
case CSSSyntaxType::kResolution:
......
......@@ -588,7 +588,8 @@ bool CSSPropertyParser::ParseFontFaceDescriptor(CSSPropertyID prop_id) {
range_, kCSSFontFaceRuleMode);
break;
case CSSPropertyFontStyle:
parsed_value = CSSPropertyFontUtils::ConsumeFontStyle(range_);
parsed_value =
CSSPropertyFontUtils::ConsumeFontStyle(range_, kCSSFontFaceRuleMode);
break;
case CSSPropertyFontVariant:
parsed_value = ConsumeFontVariantList(range_);
......
......@@ -338,8 +338,11 @@ CSSPrimitiveValue* ConsumeGradientLengthOrPercent(
}
CSSPrimitiveValue* ConsumeAngle(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserContext* context,
WTF::Optional<WebFeature> unitlessZeroFeature) {
// Ensure that we have a context for counting the unitlessZeroFeature if it is
// requested.
DCHECK(context || !unitlessZeroFeature);
const CSSParserToken& token = range.Peek();
if (token.GetType() == kDimensionToken) {
switch (token.GetUnitType()) {
......@@ -357,7 +360,7 @@ CSSPrimitiveValue* ConsumeAngle(CSSParserTokenRange& range,
if (token.GetType() == kNumberToken && token.NumericValue() == 0 &&
unitlessZeroFeature) {
range.ConsumeIncludingWhitespace();
context.Count(*unitlessZeroFeature);
context->Count(*unitlessZeroFeature);
return CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kDegrees);
}
CalcParser calc_parser(range, kValueRangeAll);
......@@ -982,7 +985,7 @@ static CSSPrimitiveValue* ConsumeGradientAngleOrPercent(
UnitlessQuirk) {
const CSSParserToken& token = range.Peek();
if (token.GetType() == kDimensionToken || token.GetType() == kNumberToken) {
return ConsumeAngle(range, context, WTF::Optional<WebFeature>());
return ConsumeAngle(range, &context, WTF::Optional<WebFeature>());
}
if (token.GetType() == kPercentageToken)
return ConsumePercent(range, value_range);
......@@ -1185,7 +1188,7 @@ static CSSValue* ConsumeLinearGradient(CSSParserTokenRange& args,
CSSGradientType gradient_type) {
bool expect_comma = true;
const CSSPrimitiveValue* angle =
ConsumeAngle(args, context, WebFeature::kUnitlessZeroAngleGradient);
ConsumeAngle(args, &context, WebFeature::kUnitlessZeroAngleGradient);
const CSSIdentifierValue* end_x = nullptr;
const CSSIdentifierValue* end_y = nullptr;
if (!angle) {
......@@ -1226,7 +1229,7 @@ static CSSValue* ConsumeConicGradient(CSSParserTokenRange& args,
const CSSPrimitiveValue* from_angle = nullptr;
if (ConsumeIdent<CSSValueFrom>(args)) {
if (!(from_angle =
ConsumeAngle(args, context, WTF::Optional<WebFeature>())))
ConsumeAngle(args, &context, WTF::Optional<WebFeature>())))
return nullptr;
}
......
......@@ -59,7 +59,7 @@ CSSPrimitiveValue* ConsumeLengthOrPercent(
UnitlessQuirk = UnitlessQuirk::kForbid);
CSSPrimitiveValue* ConsumeAngle(CSSParserTokenRange&,
const CSSParserContext&,
const CSSParserContext*,
WTF::Optional<WebFeature> unitlessZeroFeature);
CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange&, ValueRange);
CSSPrimitiveValue* ConsumeResolution(CSSParserTokenRange&);
......
......@@ -45,7 +45,7 @@ static CSSFunctionValue* ConsumeFilterFunction(
}
} else if (filter_type == CSSValueHueRotate) {
parsed_value = CSSPropertyParserHelpers::ConsumeAngle(
args, context, WebFeature::kUnitlessZeroAngleFilter);
args, &context, WebFeature::kUnitlessZeroAngleFilter);
} else if (filter_type == CSSValueBlur) {
parsed_value = CSSPropertyParserHelpers::ConsumeLength(
args, kHTMLStandardMode, kValueRangeNonNegative);
......
......@@ -4,15 +4,16 @@
#include "core/css/properties/CSSPropertyAPIFontStyle.h"
#include "core/css/parser/CSSParserContext.h"
#include "core/css/properties/CSSPropertyFontUtils.h"
namespace blink {
const CSSValue* CSSPropertyAPIFontStyle::parseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext&,
const CSSParserContext& context,
const CSSParserLocalContext&) {
return CSSPropertyFontUtils::ConsumeFontStyle(range);
return CSSPropertyFontUtils::ConsumeFontStyle(range, context.Mode());
}
} // namespace blink
......@@ -21,7 +21,7 @@ const CSSValue* CSSPropertyAPIImageOrientation::parseSingleValue(
return CSSPropertyParserHelpers::ConsumeIdent(range);
if (range.Peek().GetType() != kNumberToken) {
CSSPrimitiveValue* angle = CSSPropertyParserHelpers::ConsumeAngle(
range, context, WTF::Optional<WebFeature>());
range, &context, WTF::Optional<WebFeature>());
if (angle && angle->GetDoubleValue() == 0)
return angle;
}
......
......@@ -36,7 +36,7 @@ const CSSValue* CSSPropertyAPIRotate::parseSingleValue(
}
CSSValue* rotation = CSSPropertyParserHelpers::ConsumeAngle(
range, context, WTF::Optional<WebFeature>());
range, &context, WTF::Optional<WebFeature>());
if (!rotation)
return nullptr;
list->Append(*rotation);
......
......@@ -6,6 +6,7 @@
#include "core/css/CSSFontFamilyValue.h"
#include "core/css/CSSFontFeatureValue.h"
#include "core/css/CSSFontStyleRangeValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSValueList.h"
#include "core/css/CSSValuePair.h"
......@@ -95,14 +96,60 @@ String CSSPropertyFontUtils::ConcatenateFamilyName(CSSParserTokenRange& range) {
return builder.ToString();
}
// TODO(drott) crbug.com/739139: In a subsequent stage, make these three methods
// understand ranges.
CSSValue* CSSPropertyFontUtils::ConsumeFontStyle(CSSParserTokenRange& range) {
const CSSParserToken& token = range.Peek();
if (token.Id() == CSSValueNormal || token.Id() == CSSValueItalic ||
token.Id() == CSSValueOblique)
static CSSValueList* CombineToRangeListOrNull(
const CSSPrimitiveValue* range_start,
const CSSPrimitiveValue* range_end) {
DCHECK(range_start);
DCHECK(range_end);
if (range_end->GetFloatValue() < range_start->GetFloatValue())
return nullptr;
CSSValueList* value_list = CSSValueList::CreateSpaceSeparated();
value_list->Append(*range_start);
value_list->Append(*range_end);
return value_list;
}
static bool IsAngleWithinLimits(CSSPrimitiveValue* angle) {
constexpr float kMaxAngle = 90.0f;
return angle->GetFloatValue() >= -kMaxAngle &&
angle->GetFloatValue() <= kMaxAngle;
}
CSSValue* CSSPropertyFontUtils::ConsumeFontStyle(
CSSParserTokenRange& range,
const CSSParserMode& parser_mode) {
if (range.Peek().Id() == CSSValueNormal ||
range.Peek().Id() == CSSValueItalic)
return CSSPropertyParserHelpers::ConsumeIdent(range);
if (range.Peek().Id() != CSSValueOblique)
return nullptr;
CSSIdentifierValue* oblique_identifier =
CSSPropertyParserHelpers::ConsumeIdent<CSSValueOblique>(range);
CSSPrimitiveValue* start_angle =
CSSPropertyParserHelpers::ConsumeAngle(range, nullptr, WTF::nullopt);
if (!start_angle)
return oblique_identifier;
if (!IsAngleWithinLimits(start_angle))
return nullptr;
if (parser_mode != kCSSFontFaceRuleMode || range.AtEnd()) {
CSSValueList* value_list = CSSValueList::CreateSpaceSeparated();
value_list->Append(*start_angle);
return CSSFontStyleRangeValue::Create(*oblique_identifier, *value_list);
}
CSSPrimitiveValue* end_angle =
CSSPropertyParserHelpers::ConsumeAngle(range, nullptr, WTF::nullopt);
if (!end_angle || !IsAngleWithinLimits(end_angle))
return nullptr;
CSSValueList* range_list = CombineToRangeListOrNull(start_angle, end_angle);
if (!range_list)
return nullptr;
return CSSFontStyleRangeValue::Create(*oblique_identifier, *range_list);
}
CSSIdentifierValue* CSSPropertyFontUtils::ConsumeFontStretchKeywordOnly(
......@@ -114,18 +161,6 @@ CSSIdentifierValue* CSSPropertyFontUtils::ConsumeFontStretchKeywordOnly(
return nullptr;
}
static CSSValue* CombineToRangeListOrNull(const CSSPrimitiveValue* range_start,
const CSSPrimitiveValue* range_end) {
DCHECK(range_start);
DCHECK(range_end);
if (range_end->GetFloatValue() < range_start->GetFloatValue())
return nullptr;
CSSValueList* value_list = CSSValueList::CreateSpaceSeparated();
value_list->Append(*range_start);
value_list->Append(*range_end);
return value_list;
}
CSSValue* CSSPropertyFontUtils::ConsumeFontStretch(
CSSParserTokenRange& range,
const CSSParserMode& parser_mode) {
......
......@@ -37,7 +37,7 @@ class CSSPropertyFontUtils {
CSSParserTokenRange&);
static CSSValue* ConsumeFontStretch(CSSParserTokenRange&,
const CSSParserMode&);
static CSSValue* ConsumeFontStyle(CSSParserTokenRange&);
static CSSValue* ConsumeFontStyle(CSSParserTokenRange&, const CSSParserMode&);
static CSSValue* ConsumeFontWeight(CSSParserTokenRange&,
const CSSParserMode&);
......
......@@ -57,7 +57,7 @@ CSSValue* ConsumeRay(CSSParserTokenRange& range,
while (!function_args.AtEnd()) {
if (!angle) {
angle = CSSPropertyParserHelpers::ConsumeAngle(
function_args, context, WTF::Optional<WebFeature>());
function_args, &context, WTF::Optional<WebFeature>());
if (angle)
continue;
}
......
......@@ -12,7 +12,7 @@ CSSValue* CSSPropertyOffsetRotateUtils::ConsumeOffsetRotate(
CSSParserTokenRange& range,
const CSSParserContext& context) {
CSSValue* angle = CSSPropertyParserHelpers::ConsumeAngle(
range, context, Optional<WebFeature>());
range, &context, Optional<WebFeature>());
CSSValue* keyword =
CSSPropertyParserHelpers::ConsumeIdent<CSSValueAuto, CSSValueReverse>(
range);
......@@ -20,7 +20,7 @@ CSSValue* CSSPropertyOffsetRotateUtils::ConsumeOffsetRotate(
return nullptr;
if (!angle) {
angle = CSSPropertyParserHelpers::ConsumeAngle(range, context,
angle = CSSPropertyParserHelpers::ConsumeAngle(range, &context,
Optional<WebFeature>());
}
......
......@@ -96,14 +96,14 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
case CSSValueSkewY:
case CSSValueSkew:
parsed_value = CSSPropertyParserHelpers::ConsumeAngle(
args, context, WebFeature::kUnitlessZeroAngleTransform);
args, &context, WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
if (function_id == CSSValueSkew &&
CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(args)) {
transform_value->Append(*parsed_value);
parsed_value = CSSPropertyParserHelpers::ConsumeAngle(
args, context, WebFeature::kUnitlessZeroAngleTransform);
args, &context, WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
}
......@@ -168,7 +168,7 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
return nullptr;
}
parsed_value = CSSPropertyParserHelpers::ConsumeAngle(
args, context, WebFeature::kUnitlessZeroAngleTransform);
args, &context, WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
break;
......
......@@ -102,7 +102,8 @@ bool ConsumeFont(bool important,
CSSValueID id = range.Peek().Id();
if (!font_style && (id == CSSValueNormal || id == CSSValueItalic ||
id == CSSValueOblique)) {
font_style = CSSPropertyFontUtils::ConsumeFontStyle(range);
font_style =
CSSPropertyFontUtils::ConsumeFontStyle(range, context.Mode());
continue;
}
if (!font_variant_caps &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment