Title: [269957] trunk
Revision
269957
Author
[email protected]
Date
2020-11-18 08:03:50 -0800 (Wed, 18 Nov 2020)

Log Message

Make CSS font shorthands parsable within a worker (i.e. without CSSValuePool)
https://bugs.webkit.org/show_bug.cgi?id=202794

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

* web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt:

Source/WebCore:

Add functions to make it possible to parse CSS font shorthand
properties without using CSS values, so it can be done safely off of
the main thread. To support and test this, also add functions to make
it possible to resolve those properties into a style without
StyleBuilder and use that within CanvasRenderingContext2D.

No new tests, covered by existing tests.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* css/parser/CSSParser.cpp:
(WebCore::CSSParser::parseFontWorkerSafe):
* css/parser/CSSParser.h:
* css/parser/CSSPropertyParser.cpp:
(WebCore::consumeFontWeight):
(WebCore::consumeFontStretchKeywordValue):
(WebCore::consumeFontStyle):
(WebCore::consumeFamilyName):
* css/parser/CSSPropertyParser.h:
* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::CalcParser::consumePercentRaw):
(WebCore::CSSPropertyParserHelpers::CalcParser::consumeAngleRaw):
(WebCore::CSSPropertyParserHelpers::CalcParser::consumeLengthRaw):
(WebCore::CSSPropertyParserHelpers::CalcParser::consumeLengthOrPercentRaw):
(WebCore::CSSPropertyParserHelpers::consumeNumberRaw):
(WebCore::CSSPropertyParserHelpers::consumeNumber):
(WebCore::CSSPropertyParserHelpers::consumeFontWeightNumberRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontWeightNumber):
(WebCore::CSSPropertyParserHelpers::consumeLengthRaw):
(WebCore::CSSPropertyParserHelpers::consumeLength):
(WebCore::CSSPropertyParserHelpers::consumePercent):
(WebCore::CSSPropertyParserHelpers::consumeLengthOrPercentRaw):
(WebCore::CSSPropertyParserHelpers::consumeLengthOrPercent):
(WebCore::CSSPropertyParserHelpers::consumeAngleRaw):
(WebCore::CSSPropertyParserHelpers::consumeIdentRaw):
(WebCore::CSSPropertyParserHelpers::consumeIdent):
(WebCore::CSSPropertyParserHelpers::consumeIdentRangeRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontVariantCSS21Raw):
(WebCore::CSSPropertyParserHelpers::consumeFontWeightKeywordValueRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontWeightRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontStretchKeywordValueRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontStyleKeywordValueRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontStyleRaw):
(WebCore::CSSPropertyParserHelpers::concatenateFamilyName):
(WebCore::CSSPropertyParserHelpers::consumeFamilyNameRaw):
(WebCore::CSSPropertyParserHelpers::consumeGenericFamilyRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontFamilyRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontSizeRaw):
(WebCore::CSSPropertyParserHelpers::consumeLineHeightRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontWorkerSafe):
(WebCore::CSSPropertyParserHelpers::genericFontFamilyFromValueID):
* css/parser/CSSPropertyParserHelpers.h:
(WebCore::CSSPropertyParserHelpers::consumeIdentRaw):
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::setFont):
* style/StyleBuilderCustom.h:
(WebCore::Style::BuilderCustom::applyValueFontFamily):
* style/StyleResolveForFontRaw.cpp: Added.
(WebCore::Style::resolveForFontRaw):
* style/StyleResolveForFontRaw.h: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (269956 => 269957)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2020-11-18 16:03:50 UTC (rev 269957)
@@ -1,3 +1,12 @@
+2020-11-18  Chris Lord  <[email protected]>
+
+        Make CSS font shorthands parsable within a worker (i.e. without CSSValuePool)
+        https://bugs.webkit.org/show_bug.cgi?id=202794
+
+        Reviewed by Darin Adler.
+
+        * web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt:
+
 2020-11-18  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r269940.

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt (269956 => 269957)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt	2020-11-18 16:03:50 UTC (rev 269957)
@@ -1,5 +1,5 @@
 2d.text.font.parse.invalid
 Actual output:
 
-FAIL Canvas test: 2d.text.font.parse.invalid assert_equals: ctx.font === '20px serif' (got 13px sans-serif[string], expected 20px serif[string]) expected "20px serif" but got "13px sans-serif"
+PASS Canvas test: 2d.text.font.parse.invalid
 

Modified: trunk/Source/WebCore/ChangeLog (269956 => 269957)


--- trunk/Source/WebCore/ChangeLog	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/ChangeLog	2020-11-18 16:03:50 UTC (rev 269957)
@@ -1,3 +1,71 @@
+2020-11-18  Chris Lord  <[email protected]>
+
+        Make CSS font shorthands parsable within a worker (i.e. without CSSValuePool)
+        https://bugs.webkit.org/show_bug.cgi?id=202794
+
+        Reviewed by Darin Adler.
+
+        Add functions to make it possible to parse CSS font shorthand
+        properties without using CSS values, so it can be done safely off of
+        the main thread. To support and test this, also add functions to make
+        it possible to resolve those properties into a style without
+        StyleBuilder and use that within CanvasRenderingContext2D.
+
+        No new tests, covered by existing tests.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/parser/CSSParser.cpp:
+        (WebCore::CSSParser::parseFontWorkerSafe):
+        * css/parser/CSSParser.h:
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::consumeFontWeight):
+        (WebCore::consumeFontStretchKeywordValue):
+        (WebCore::consumeFontStyle):
+        (WebCore::consumeFamilyName):
+        * css/parser/CSSPropertyParser.h:
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::CalcParser::consumePercentRaw):
+        (WebCore::CSSPropertyParserHelpers::CalcParser::consumeAngleRaw):
+        (WebCore::CSSPropertyParserHelpers::CalcParser::consumeLengthRaw):
+        (WebCore::CSSPropertyParserHelpers::CalcParser::consumeLengthOrPercentRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeNumberRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeNumber):
+        (WebCore::CSSPropertyParserHelpers::consumeFontWeightNumberRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontWeightNumber):
+        (WebCore::CSSPropertyParserHelpers::consumeLengthRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeLength):
+        (WebCore::CSSPropertyParserHelpers::consumePercent):
+        (WebCore::CSSPropertyParserHelpers::consumeLengthOrPercentRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeLengthOrPercent):
+        (WebCore::CSSPropertyParserHelpers::consumeAngleRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeIdentRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeIdent):
+        (WebCore::CSSPropertyParserHelpers::consumeIdentRangeRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontVariantCSS21Raw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontWeightKeywordValueRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontWeightRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontStretchKeywordValueRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontStyleKeywordValueRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontStyleRaw):
+        (WebCore::CSSPropertyParserHelpers::concatenateFamilyName):
+        (WebCore::CSSPropertyParserHelpers::consumeFamilyNameRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeGenericFamilyRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontFamilyRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontSizeRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeLineHeightRaw):
+        (WebCore::CSSPropertyParserHelpers::consumeFontWorkerSafe):
+        (WebCore::CSSPropertyParserHelpers::genericFontFamilyFromValueID):
+        * css/parser/CSSPropertyParserHelpers.h:
+        (WebCore::CSSPropertyParserHelpers::consumeIdentRaw):
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::setFont):
+        * style/StyleBuilderCustom.h:
+        (WebCore::Style::BuilderCustom::applyValueFontFamily):
+        * style/StyleResolveForFontRaw.cpp: Added.
+        (WebCore::Style::resolveForFontRaw):
+        * style/StyleResolveForFontRaw.h: Added.
+
 2020-11-18  Michael Catanzaro  <[email protected]>
 
         [WPE][GTK] Update Outlook user agent quirk

Modified: trunk/Source/WebCore/Sources.txt (269956 => 269957)


--- trunk/Source/WebCore/Sources.txt	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/Sources.txt	2020-11-18 16:03:50 UTC (rev 269957)
@@ -2427,6 +2427,7 @@
 style/StylePendingResources.cpp
 style/StyleRelations.cpp
 style/StyleResolveForDocument.cpp
+style/StyleResolveForFontRaw.cpp
 style/StyleResolver.cpp
 style/StyleScope.cpp
 style/StyleScopeRuleSets.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (269956 => 269957)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-11-18 16:03:50 UTC (rev 269957)
@@ -5136,6 +5136,7 @@
 		E4D33F44252C50E200837D05 /* LayoutIntegrationLineIteratorLegacyPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F43252C50E200837D05 /* LayoutIntegrationLineIteratorLegacyPath.h */; };
 		E4D33F46252C50FC00837D05 /* LayoutIntegrationLineIteratorModernPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F45252C50FB00837D05 /* LayoutIntegrationLineIteratorModernPath.h */; };
 		E4D58EB517B4DBDC00CBDCA8 /* StyleResolveForDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */; };
+		E4D68EB517B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D68EB317B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h */; };
 		E4D58EB917B4ED8900CBDCA8 /* StyleFontSizeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */; };
 		E4D58EBB17B8F12800CBDCA8 /* ElementTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4D988B417BFD1F60084FB88 /* TextNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */; };
@@ -16286,6 +16287,8 @@
 		E4D33F45252C50FB00837D05 /* LayoutIntegrationLineIteratorModernPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutIntegrationLineIteratorModernPath.h; sourceTree = "<group>"; };
 		E4D58EB217B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveForDocument.cpp; sourceTree = "<group>"; };
 		E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleResolveForDocument.h; sourceTree = "<group>"; };
+		E4D68EB217B4DBDC00CBDCA8 /* StyleResolveForFontRaw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveForFontRaw.cpp; sourceTree = "<group>"; };
+		E4D68EB317B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleResolveForFontRaw.h; sourceTree = "<group>"; };
 		E4D58EB617B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleFontSizeFunctions.cpp; sourceTree = "<group>"; };
 		E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleFontSizeFunctions.h; sourceTree = "<group>"; };
 		E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementTraversal.h; sourceTree = "<group>"; };
@@ -28867,6 +28870,8 @@
 				E461802C1C8DD2900026C02C /* StyleRelations.h */,
 				E4D58EB217B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp */,
 				E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */,
+				E4D68EB217B4DBDC00CBDCA8 /* StyleResolveForFontRaw.cpp */,
+				E4D68EB317B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h */,
 				E139866115478474001E3F65 /* StyleResolver.cpp */,
 				E139866215478474001E3F65 /* StyleResolver.h */,
 				E461D65C1BB0C7F000CB5645 /* StyleScope.cpp */,
@@ -34518,6 +34523,7 @@
 				BC2272870E82E70700E7F975 /* StyleReflection.h in Headers */,
 				E461802D1C8DD2900026C02C /* StyleRelations.h in Headers */,
 				E4D58EB517B4DBDC00CBDCA8 /* StyleResolveForDocument.h in Headers */,
+				E4D68EB517B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h in Headers */,
 				E139866415478474001E3F65 /* StyleResolver.h in Headers */,
 				E4BBED4D14FCDBA1003F0B98 /* StyleRule.h in Headers */,
 				E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */,

Modified: trunk/Source/WebCore/css/parser/CSSParser.cpp (269956 => 269957)


--- trunk/Source/WebCore/css/parser/CSSParser.cpp	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/css/parser/CSSParser.cpp	2020-11-18 16:03:50 UTC (rev 269957)
@@ -138,6 +138,15 @@
     return CSSParserFastPaths::parseHexColor(string);
 }
 
+Optional<CSSPropertyParserHelpers::FontRaw> CSSParser::parseFontWorkerSafe(const String& string, CSSParserMode cssParserMode)
+{
+    CSSTokenizer tokenizer(string);
+    CSSParserTokenRange range(tokenizer.tokenRange());
+    range.consumeWhitespace();
+
+    return CSSPropertyParserHelpers::consumeFontWorkerSafe(range, cssParserMode);
+}
+
 RefPtr<CSSValue> CSSParser::parseSingleValue(CSSPropertyID propertyID, const String& string, const CSSParserContext& context)
 {
     if (string.isEmpty())

Modified: trunk/Source/WebCore/css/parser/CSSParser.h (269956 => 269957)


--- trunk/Source/WebCore/css/parser/CSSParser.h	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/css/parser/CSSParser.h	2020-11-18 16:03:50 UTC (rev 269957)
@@ -44,6 +44,10 @@
 class RenderStyle;
 template<typename> struct SRGBA;
 
+namespace CSSPropertyParserHelpers {
+struct FontRaw;
+}
+
 namespace Style {
 class BuilderState;
 }
@@ -92,6 +96,8 @@
     static Optional<SRGBA<uint8_t>> parseNamedColor(StringView);
     static Optional<SRGBA<uint8_t>> parseHexColor(StringView);
 
+    static Optional<CSSPropertyParserHelpers::FontRaw> parseFontWorkerSafe(const String&, CSSParserMode = HTMLStandardMode);
+
 private:
     ParseResult parseValue(MutableStyleProperties&, CSSPropertyID, const String&, bool important);
 

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (269956 => 269957)


--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2020-11-18 16:03:50 UTC (rev 269957)
@@ -54,7 +54,6 @@
 #include "CSSParserIdioms.h"
 #include "CSSPendingSubstitutionValue.h"
 #include "CSSPrimitiveValueMappings.h"
-#include "CSSPropertyParserHelpers.h"
 #include "CSSReflectValue.h"
 #include "CSSShadowValue.h"
 #include "CSSTimingFunctionValue.h"
@@ -864,16 +863,16 @@
     return consumeIdent<CSSValueNormal, CSSValueSmallCaps>(range);
 }
 
-static RefPtr<CSSPrimitiveValue> consumeFontWeightKeywordValue(CSSParserTokenRange& range)
-{
-    return consumeIdent<CSSValueNormal, CSSValueBold, CSSValueBolder, CSSValueLighter>(range);
-}
-
 static RefPtr<CSSPrimitiveValue> consumeFontWeight(CSSParserTokenRange& range)
 {
-    if (auto result = consumeFontWeightKeywordValue(range))
-        return result;
-    return consumeFontWeightNumber(range);
+    if (auto result = consumeFontWeightRaw(range)) {
+        return switchOn(*result, [] (CSSValueID valueID) {
+            return CSSValuePool::singleton().createIdentifierValue(valueID);
+        }, [] (double weightNumber) {
+            return CSSValuePool::singleton().createValue(weightNumber, CSSUnitType::CSS_NUMBER);
+        });
+    }
+    return nullptr;
 }
 
 static RefPtr<CSSPrimitiveValue> consumeFontWeightAbsoluteKeywordValue(CSSParserTokenRange& range)
@@ -910,7 +909,9 @@
 
 static RefPtr<CSSPrimitiveValue> consumeFontStretchKeywordValue(CSSParserTokenRange& range)
 {
-    return consumeIdent<CSSValueUltraCondensed, CSSValueExtraCondensed, CSSValueCondensed, CSSValueSemiCondensed, CSSValueNormal, CSSValueSemiExpanded, CSSValueExpanded, CSSValueExtraExpanded, CSSValueUltraExpanded>(range);
+    if (auto valueID = consumeFontStretchKeywordValueRaw(range))
+        return CSSValuePool::singleton().createIdentifierValue(*valueID);
+    return nullptr;
 }
 
 #if ENABLE(VARIATION_FONTS)
@@ -965,26 +966,16 @@
 
 static RefPtr<CSSFontStyleValue> consumeFontStyle(CSSParserTokenRange& range, CSSParserMode cssParserMode)
 {
-    auto result = consumeFontStyleKeywordValue(range);
-    if (!result)
-        return nullptr;
-
-    auto valueID = result->valueID();
-    if (valueID == CSSValueNormal || valueID == CSSValueItalic)
-        return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(valueID));
-    ASSERT(result->valueID() == CSSValueOblique);
+    if (auto result = consumeFontStyleRaw(range, cssParserMode)) {
 #if ENABLE(VARIATION_FONTS)
-    if (!range.atEnd()) {
-        if (auto angle = consumeAngle(range, cssParserMode)) {
-            if (fontStyleIsWithinRange(angle->value<float>(CSSUnitType::CSS_DEG)))
-                return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique), WTFMove(angle));
-            return nullptr;
+        if (result->style == CSSValueOblique && result->angle) {
+            return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique),
+                CSSValuePool::singleton().createValue(result->angle->value, result->angle->type));
         }
+#endif
+        return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(result->style));
     }
-#else
-    UNUSED_PARAM(cssParserMode);
-#endif
-    return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique));
+    return nullptr;
 }
 
 #if ENABLE(VARIATION_FONTS)
@@ -1018,30 +1009,9 @@
 }
 #endif
 
-static String concatenateFamilyName(CSSParserTokenRange& range)
-{
-    StringBuilder builder;
-    bool addedSpace = false;
-    const CSSParserToken& firstToken = range.peek();
-    while (range.peek().type() == IdentToken) {
-        if (!builder.isEmpty()) {
-            builder.append(' ');
-            addedSpace = true;
-        }
-        builder.append(range.consumeIncludingWhitespace().value());
-    }
-    if (!addedSpace && isCSSWideKeyword(firstToken.id()))
-        return String();
-    return builder.toString();
-}
-
 static RefPtr<CSSValue> consumeFamilyName(CSSParserTokenRange& range)
 {
-    if (range.peek().type() == StringToken)
-        return CSSValuePool::singleton().createFontFamilyValue(range.consumeIncludingWhitespace().value().toString());
-    if (range.peek().type() != IdentToken)
-        return nullptr;
-    String familyName = concatenateFamilyName(range);
+    auto familyName = consumeFamilyNameRaw(range);
     if (familyName.isNull())
         return nullptr;
     return CSSValuePool::singleton().createFontFamilyValue(familyName);

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.h (269956 => 269957)


--- trunk/Source/WebCore/css/parser/CSSPropertyParser.h	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.h	2020-11-18 16:03:50 UTC (rev 269957)
@@ -23,6 +23,7 @@
 #pragma once
 
 #include "CSSParserTokenRange.h"
+#include "CSSPropertyParserHelpers.h"
 #include "StyleRule.h"
 #include <wtf/text/StringView.h>
 

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (269956 => 269957)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2020-11-18 16:03:50 UTC (rev 269957)
@@ -130,13 +130,16 @@
 
     Optional<double> consumePercentRaw()
     {
-        if (!m_calcValue || m_calcValue->category() != CalculationCategory::Percent)
+        if (!m_calcValue)
             return WTF::nullopt;
+        auto category = m_calcValue->category();
+        if (category != CalculationCategory::Percent)
+            return WTF::nullopt;
         m_sourceRange = m_range;
         return m_calcValue->doubleValue();
     }
 
-    Optional<Angle> consumeAngleRaw()
+    Optional<AngleRaw> consumeAngleRaw()
     {
         if (!m_calcValue || m_calcValue->category() != CalculationCategory::Angle)
             return WTF::nullopt;
@@ -144,6 +147,33 @@
         return { { m_calcValue->primitiveType(), m_calcValue->doubleValue() } };
     }
 
+    Optional<LengthRaw> consumeLengthRaw()
+    {
+        if (!m_calcValue || m_calcValue->category() != CalculationCategory::Length)
+            return WTF::nullopt;
+        m_sourceRange = m_range;
+        return { { m_calcValue->primitiveType(), m_calcValue->doubleValue() } };
+    }
+
+    Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw()
+    {
+        if (!m_calcValue)
+            return WTF::nullopt;
+
+        switch (m_calcValue->category()) {
+        case CalculationCategory::Length:
+            m_sourceRange = m_range;
+            return { LengthRaw({ m_calcValue->primitiveType(), m_calcValue->doubleValue() }) };
+        case CalculationCategory::Percent:
+        case CalculationCategory::PercentLength:
+        case CalculationCategory::PercentNumber:
+            m_sourceRange = m_range;
+            return { { m_calcValue->doubleValue() } };
+        default:
+            return WTF::nullopt;
+        }
+    }
+
 private:
     CSSParserTokenRange& m_sourceRange;
     CSSParserTokenRange m_range;
@@ -177,10 +207,12 @@
     return consumeInteger(range, 1);
 }
 
-bool consumeNumberRaw(CSSParserTokenRange& range, double& result)
+bool consumeNumberRaw(CSSParserTokenRange& range, double& result, ValueRange valueRange)
 {
     const CSSParserToken& token = range.peek();
     if (token.type() == NumberToken) {
+        if (valueRange == ValueRangeNonNegative && token.numericValue() < 0)
+            return false;
         result = range.consumeIncludingWhitespace().numericValue();
         return true;
     }
@@ -188,7 +220,7 @@
     if (token.type() != FunctionToken)
         return false;
 
-    CalcParser calcParser(range, CalculationCategory::Number, ValueRangeAll);
+    CalcParser calcParser(range, CalculationCategory::Number, valueRange);
     return calcParser.consumeNumberRaw(result);
 }
 
@@ -196,22 +228,19 @@
 RefPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange& range, ValueRange valueRange)
 {
     const CSSParserToken& token = range.peek();
-    if (token.type() == NumberToken) {
-        if (valueRange == ValueRangeNonNegative && token.numericValue() < 0)
-            return nullptr;
-        return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), token.unitType());
+    if (token.type() == FunctionToken) {
+        CalcParser calcParser(range, CalculationCategory::Number, valueRange);
+        if (const auto* calcValue = calcParser.value()) {
+            if (calcValue->category() == CalculationCategory::Number)
+                return calcParser.consumeValue();
+        }
+        return nullptr;
     }
 
-    if (token.type() != FunctionToken)
-        return nullptr;
+    double number;
+    if (consumeNumberRaw(range, number, valueRange))
+        return CSSValuePool::singleton().createValue(number, token.unitType());
 
-    CalcParser calcParser(range, CalculationCategory::Number, valueRange);
-    if (const CSSCalcValue* calcValue = calcParser.value()) {
-        if (calcValue->category() != CalculationCategory::Number)
-            return nullptr;
-        return calcParser.consumeValue();
-    }
-
     return nullptr;
 }
 
@@ -222,7 +251,7 @@
 }
 #endif
 
-RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange& range)
+Optional<double> consumeFontWeightNumberRaw(CSSParserTokenRange& range)
 {
     // Values less than or equal to 0 or greater than or equal to 1000 are parse errors.
     auto& token = range.peek();
@@ -230,11 +259,15 @@
 #if !ENABLE(VARIATION_FONTS)
         && token.numericValueType() == IntegerValueType && divisibleBy100(token.numericValue())
 #endif
-    )
-        return consumeNumber(range, ValueRangeAll);
+    ) {
+        double result;
+        if (consumeNumberRaw(range, result))
+            return result;
+        return WTF::nullopt;
+    }
 
     if (token.type() != FunctionToken)
-        return nullptr;
+        return WTF::nullopt;
 
     // "[For calc()], the used value resulting from an _expression_ must be clamped to the range allowed in the target context."
     CalcParser calcParser(range, CalculationCategory::Number, ValueRangeAll);
@@ -245,9 +278,16 @@
 #endif
     ) {
         result = std::min(std::max(result, std::nextafter(0., 1.)), std::nextafter(1000., 0.));
-        return CSSValuePool::singleton().createValue(result, CSSUnitType::CSS_NUMBER);
+        return result;
     }
 
+    return WTF::nullopt;
+}
+
+RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange& range)
+{
+    if (auto result = consumeFontWeightNumberRaw(range))
+        return CSSValuePool::singleton().createValue(*result, CSSUnitType::CSS_NUMBER);
     return nullptr;
 }
 
@@ -259,7 +299,7 @@
         || (cssParserMode == HTMLQuirksMode && unitless == UnitlessQuirk::Allow);
 }
 
-RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
+Optional<LengthRaw> consumeLengthRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
 {
     const CSSParserToken& token = range.peek();
     if (token.type() == DimensionToken) {
@@ -266,7 +306,7 @@
         switch (token.unitType()) {
         case CSSUnitType::CSS_QUIRKY_EMS:
             if (cssParserMode != UASheetMode)
-                return nullptr;
+                return WTF::nullopt;
             FALLTHROUGH;
         case CSSUnitType::CSS_EMS:
         case CSSUnitType::CSS_REMS:
@@ -287,29 +327,40 @@
         case CSSUnitType::CSS_Q:
             break;
         default:
-            return nullptr;
+            return WTF::nullopt;
         }
         if ((valueRange == ValueRangeNonNegative && token.numericValue() < 0) || std::isinf(token.numericValue()))
-            return nullptr;
-        return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), token.unitType());
+            return WTF::nullopt;
+        return { { token.unitType(), range.consumeIncludingWhitespace().numericValue() } };
     }
     if (token.type() == NumberToken) {
         if (!shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless)
             || (valueRange == ValueRangeNonNegative && token.numericValue() < 0))
-            return nullptr;
+            return WTF::nullopt;
         if (std::isinf(token.numericValue()))
-            return nullptr;
-        CSSUnitType unitType = CSSUnitType::CSS_PX;
-        return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), unitType);
+            return WTF::nullopt;
+        return { { CSSUnitType::CSS_PX, range.consumeIncludingWhitespace().numericValue() } };
     }
 
     if (token.type() != FunctionToken)
-        return nullptr;
+        return WTF::nullopt;
 
     CalcParser calcParser(range, CalculationCategory::Length, valueRange);
-    if (calcParser.value() && calcParser.value()->category() == CalculationCategory::Length)
-        return calcParser.consumeValue();
+    return calcParser.consumeLengthRaw();
+}
 
+RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
+{
+    const CSSParserToken& token = range.peek();
+    if (token.type() == FunctionToken) {
+        CalcParser calcParser(range, CalculationCategory::Length, valueRange);
+        if (calcParser.value() && calcParser.value()->category() == CalculationCategory::Length)
+            return calcParser.consumeValue();
+    }
+
+    if (auto result = consumeLengthRaw(range, cssParserMode, valueRange, unitless))
+        return CSSValuePool::singleton().createValue(result->value, result->type);
+
     return nullptr;
 }
 
@@ -333,7 +384,7 @@
 {
     const CSSParserToken& token = range.peek();
     if (token.type() == FunctionToken) {
-        CalcParser calcParser(range, CalculationCategory::Angle, valueRange);
+        CalcParser calcParser(range, CalculationCategory::Percent, valueRange);
         if (const CSSCalcValue* calculation = calcParser.value()) {
             if (calculation->category() == CalculationCategory::Percent)
                 return calcParser.consumeValue();
@@ -361,26 +412,54 @@
     return false;
 }
 
-RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
+Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
 {
     const CSSParserToken& token = range.peek();
-    if (token.type() == DimensionToken || token.type() == NumberToken)
-        return consumeLength(range, cssParserMode, valueRange, unitless);
-    if (token.type() == PercentageToken)
-        return consumePercent(range, valueRange);
+    if (token.type() == DimensionToken || token.type() == NumberToken) {
+        if (auto result = consumeLengthRaw(range, cssParserMode, valueRange, unitless))
+            return { *result };
+        return WTF::nullopt;
+    }
+    if (token.type() == PercentageToken) {
+        if (auto result = consumePercentRaw(range, valueRange))
+            return { *result };
+        return WTF::nullopt;
+    }
 
     if (token.type() != FunctionToken)
-        return nullptr;
+        return WTF::nullopt;
 
     CalcParser calcParser(range, CalculationCategory::Length, valueRange);
     if (const CSSCalcValue* calculation = calcParser.value()) {
         if (canConsumeCalcValue(calculation->category(), cssParserMode))
-            return calcParser.consumeValue();
+            return calcParser.consumeLengthOrPercentRaw();
     }
+    return WTF::nullopt;
+}
+
+RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
+{
+    const CSSParserToken& token = range.peek();
+    if (token.type() == FunctionToken) {
+        CalcParser calcParser(range, CalculationCategory::Length, valueRange);
+        if (const CSSCalcValue* calculation = calcParser.value()) {
+            if (canConsumeCalcValue(calculation->category(), cssParserMode))
+                return calcParser.consumeValue();
+        }
+        return nullptr;
+    }
+
+    if (auto result = consumeLengthOrPercentRaw(range, cssParserMode, valueRange, unitless)) {
+        return switchOn(*result, [] (LengthRaw length) {
+            return CSSValuePool::singleton().createValue(length.value, length.type);
+        }, [] (double percentage) {
+            return CSSValuePool::singleton().createValue(percentage, CSSUnitType::CSS_PERCENTAGE);
+        });
+    }
     return nullptr;
 }
 
-Optional<Angle> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
+Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
 {
     const CSSParserToken& token = range.peek();
     if (token.type() == DimensionToken) {
@@ -502,13 +581,27 @@
     return nullptr;
 }
 
-RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range)
+Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange& range)
 {
     if (range.peek().type() != IdentToken)
-        return nullptr;
-    return CSSValuePool::singleton().createIdentifierValue(range.consumeIncludingWhitespace().id());
+        return WTF::nullopt;
+    return range.consumeIncludingWhitespace().id();
 }
 
+RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range)
+{
+    if (auto result = consumeIdentRaw(range))
+        return CSSValuePool::singleton().createIdentifierValue(*result);
+    return nullptr;
+}
+
+Optional<CSSValueID> consumeIdentRangeRaw(CSSParserTokenRange& range, CSSValueID lower, CSSValueID upper)
+{
+    if (range.peek().id() < lower || range.peek().id() > upper)
+        return WTF::nullopt;
+    return consumeIdentRaw(range);
+}
+
 RefPtr<CSSPrimitiveValue> consumeIdentRange(CSSParserTokenRange& range, CSSValueID lower, CSSValueID upper)
 {
     if (range.peek().id() < lower || range.peek().id() > upper)
@@ -1818,6 +1911,225 @@
     return nullptr;
 }
 
+Optional<CSSValueID> consumeFontVariantCSS21Raw(CSSParserTokenRange& range)
+{
+    return consumeIdentRaw<CSSValueNormal, CSSValueSmallCaps>(range);
+}
+
+Optional<CSSValueID> consumeFontWeightKeywordValueRaw(CSSParserTokenRange& range)
+{
+    return consumeIdentRaw<CSSValueNormal, CSSValueBold, CSSValueBolder, CSSValueLighter>(range);
+}
+
+Optional<FontWeightRaw> consumeFontWeightRaw(CSSParserTokenRange& range)
+{
+    if (auto result = consumeFontWeightKeywordValueRaw(range))
+        return { *result };
+    if (auto result = consumeFontWeightNumberRaw(range))
+        return { *result };
+    return WTF::nullopt;
+}
+
+Optional<CSSValueID> consumeFontStretchKeywordValueRaw(CSSParserTokenRange& range)
+{
+    return consumeIdentRaw<CSSValueUltraCondensed, CSSValueExtraCondensed, CSSValueCondensed, CSSValueSemiCondensed, CSSValueNormal, CSSValueSemiExpanded, CSSValueExpanded, CSSValueExtraExpanded, CSSValueUltraExpanded>(range);
+}
+
+Optional<CSSValueID> consumeFontStyleKeywordValueRaw(CSSParserTokenRange& range)
+{
+    return consumeIdentRaw<CSSValueNormal, CSSValueItalic, CSSValueOblique>(range);
+}
+
+Optional<FontStyleRaw> consumeFontStyleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    auto result = consumeFontStyleKeywordValueRaw(range);
+    if (!result)
+        return WTF::nullopt;
+
+    auto ident = *result;
+    if (ident == CSSValueNormal || ident == CSSValueItalic)
+        return { { ident, WTF::nullopt } };
+    ASSERT(ident == CSSValueOblique);
+#if ENABLE(VARIATION_FONTS)
+    if (!range.atEnd()) {
+        if (auto angle = consumeAngleRaw(range, cssParserMode)) {
+            auto angleInDegrees = CSSPrimitiveValue::computeDegrees(angle->type, angle->value);
+            if (fontStyleIsWithinRange(angleInDegrees))
+                return { { CSSValueOblique, WTFMove(angle) } };
+            return WTF::nullopt;
+        }
+    }
+#else
+    UNUSED_PARAM(cssParserMode);
+#endif
+    return { { CSSValueOblique, WTF::nullopt } };
+}
+
+String concatenateFamilyName(CSSParserTokenRange& range)
+{
+    StringBuilder builder;
+    bool addedSpace = false;
+    const CSSParserToken& firstToken = range.peek();
+    while (range.peek().type() == IdentToken) {
+        if (!builder.isEmpty()) {
+            builder.append(' ');
+            addedSpace = true;
+        }
+        builder.append(range.consumeIncludingWhitespace().value());
+    }
+    if (!addedSpace && isCSSWideKeyword(firstToken.id()))
+        return String();
+    return builder.toString();
+}
+
+String consumeFamilyNameRaw(CSSParserTokenRange& range)
+{
+    if (range.peek().type() == StringToken)
+        return range.consumeIncludingWhitespace().value().toString();
+    if (range.peek().type() != IdentToken)
+        return String();
+    return concatenateFamilyName(range);
+}
+
+Optional<CSSValueID> consumeGenericFamilyRaw(CSSParserTokenRange& range)
+{
+    return consumeIdentRangeRaw(range, CSSValueSerif, CSSValueWebkitBody);
+}
+
+Optional<WTF::Vector<FontFamilyRaw>> consumeFontFamilyRaw(CSSParserTokenRange& range)
+{
+    WTF::Vector<FontFamilyRaw> list;
+    do {
+        if (auto ident = consumeGenericFamilyRaw(range))
+            list.append({ *ident });
+        else {
+            auto familyName = consumeFamilyNameRaw(range);
+            if (familyName.isNull())
+                return WTF::nullopt;
+            list.append({ familyName });
+        }
+    } while (consumeCommaIncludingWhitespace(range));
+    return list;
+}
+
+Optional<FontSizeRaw> consumeFontSizeRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
+{
+    if (range.peek().id() >= CSSValueXxSmall && range.peek().id() <= CSSValueLarger) {
+        if (auto ident = consumeIdentRaw(range))
+            return { *ident };
+        return WTF::nullopt;
+    }
+
+    if (auto result = consumeLengthOrPercentRaw(range, cssParserMode, ValueRangeNonNegative, unitless))
+        return { *result };
+
+    return WTF::nullopt;
+}
+
+Optional<LineHeightRaw> consumeLineHeightRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    if (range.peek().id() == CSSValueNormal) {
+        if (auto ident = consumeIdentRaw(range))
+            return { *ident };
+        return WTF::nullopt;
+    }
+
+    double number;
+    if (consumeNumberRaw(range, number, ValueRangeNonNegative))
+        return { number };
+
+    if (auto lengthOrPercent = consumeLengthOrPercentRaw(range, cssParserMode, ValueRangeNonNegative))
+        return { *lengthOrPercent };
+
+    return WTF::nullopt;
+}
+
+Optional<FontRaw> consumeFontWorkerSafe(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    // Let's check if there is an inherit or initial somewhere in the shorthand.
+    CSSParserTokenRange rangeCopy = range;
+    while (!rangeCopy.atEnd()) {
+        CSSValueID id = rangeCopy.consumeIncludingWhitespace().id();
+        if (id == CSSValueInherit || id == CSSValueInitial)
+            return WTF::nullopt;
+    }
+
+    FontRaw result;
+
+    while (!range.atEnd()) {
+        CSSValueID id = range.peek().id();
+        if (!result.style) {
+            if ((result.style = consumeFontStyleRaw(range, cssParserMode)))
+                continue;
+        }
+        if (!result.variantCaps && (id == CSSValueNormal || id == CSSValueSmallCaps)) {
+            // Font variant in the shorthand is particular, it only accepts normal or small-caps.
+            // See https://drafts.csswg.org/css-fonts/#propdef-font
+            if ((result.variantCaps = consumeFontVariantCSS21Raw(range)))
+                continue;
+        }
+        if (!result.weight) {
+            if ((result.weight = consumeFontWeightRaw(range)))
+                continue;
+        }
+        if (!result.stretch) {
+            if ((result.stretch = consumeFontStretchKeywordValueRaw(range)))
+                continue;
+        }
+        break;
+    }
+
+    if (range.atEnd())
+        return WTF::nullopt;
+
+    // Now a font size _must_ come.
+    if (auto size = consumeFontSizeRaw(range, cssParserMode))
+        result.size = *size;
+    else
+        return WTF::nullopt;
+
+    if (range.atEnd())
+        return WTF::nullopt;
+
+    if (consumeSlashIncludingWhitespace(range)) {
+        if (!(result.lineHeight = consumeLineHeightRaw(range, cssParserMode)))
+            return WTF::nullopt;
+    }
+
+    // Font family must come now.
+    if (auto family = consumeFontFamilyRaw(range))
+        result.family = *family;
+    else
+        return WTF::nullopt;
+
+    if (!range.atEnd())
+        return WTF::nullopt;
+
+    return result;
+}
+
+const AtomString& genericFontFamilyFromValueID(CSSValueID ident)
+{
+    switch (ident) {
+    case CSSValueSerif:
+        return serifFamily.get();
+    case CSSValueSansSerif:
+        return sansSerifFamily.get();
+    case CSSValueCursive:
+        return cursiveFamily.get();
+    case CSSValueFantasy:
+        return fantasyFamily.get();
+    case CSSValueMonospace:
+        return monospaceFamily.get();
+    case CSSValueWebkitPictograph:
+        return pictographFamily.get();
+    case CSSValueSystemUi:
+        return systemUiFamily.get();
+    default:
+        return emptyAtom();
+    }
+}
+
 } // namespace CSSPropertyParserHelpers
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h (269956 => 269957)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h	2020-11-18 16:03:50 UTC (rev 269957)
@@ -37,6 +37,8 @@
 #include "CSSValuePool.h"
 #include "Length.h" // For ValueRange
 #include <wtf/OptionSet.h>
+#include <wtf/Variant.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
@@ -55,28 +57,41 @@
 enum class UnitlessQuirk { Allow, Forbid };
 enum class AllowXResolutionUnit { Allow, Forbid };
 
-struct Angle {
+struct AngleRaw {
     CSSUnitType type;
     double value;
 };
 
+struct LengthRaw {
+    CSSUnitType type;
+    double value;
+};
+
+using LengthOrPercentRaw = WTF::Variant<LengthRaw, double>;
+
 RefPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRange&, double minimumValue = -std::numeric_limits<double>::max());
 RefPtr<CSSPrimitiveValue> consumePositiveInteger(CSSParserTokenRange&);
-bool consumeNumberRaw(CSSParserTokenRange&, double& result);
+bool consumeNumberRaw(CSSParserTokenRange&, double& result, ValueRange = ValueRangeAll);
 RefPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange&, ValueRange);
+Optional<double> consumeFontWeightNumberRaw(CSSParserTokenRange&);
 RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange&);
+Optional<LengthRaw> consumeLengthRaw(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
 RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
 Optional<double> consumePercentRaw(CSSParserTokenRange&, ValueRange = ValueRangeAll);
 RefPtr<CSSPrimitiveValue> consumePercent(CSSParserTokenRange&, ValueRange);
+Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
 RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
-Optional<Angle> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk);
+Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
 RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
 RefPtr<CSSPrimitiveValue> consumeTime(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
 RefPtr<CSSPrimitiveValue> consumeResolution(CSSParserTokenRange&, AllowXResolutionUnit = AllowXResolutionUnit::Forbid);
 
+Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange&);
 RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange&);
+Optional<CSSValueID> consumeIdentRangeRaw(CSSParserTokenRange&, CSSValueID lower, CSSValueID upper);
 RefPtr<CSSPrimitiveValue> consumeIdentRange(CSSParserTokenRange&, CSSValueID lower, CSSValueID upper);
 template<CSSValueID, CSSValueID...> inline bool identMatches(CSSValueID id);
+template<CSSValueID... allowedIdents> Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange&);
 template<CSSValueID... allowedIdents> RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange&);
 
 RefPtr<CSSPrimitiveValue> consumeCustomIdent(CSSParserTokenRange&);
@@ -115,6 +130,40 @@
 RefPtr<CSSValue> consumeFilter(CSSParserTokenRange&, const CSSParserContext&, AllowedFilterFunctions);
 RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange&, CSSParserMode, bool allowInset, bool allowSpread);
 
+struct FontStyleRaw {
+    CSSValueID style;
+    Optional<AngleRaw> angle;
+};
+using FontWeightRaw = WTF::Variant<CSSValueID, double>;
+using FontSizeRaw = WTF::Variant<CSSValueID, CSSPropertyParserHelpers::LengthOrPercentRaw>;
+using LineHeightRaw = WTF::Variant<CSSValueID, double, CSSPropertyParserHelpers::LengthOrPercentRaw>;
+using FontFamilyRaw = WTF::Variant<CSSValueID, String>;
+
+struct FontRaw {
+    Optional<FontStyleRaw> style;
+    Optional<CSSValueID> variantCaps;
+    Optional<FontWeightRaw> weight;
+    Optional<CSSValueID> stretch;
+    FontSizeRaw size;
+    Optional<LineHeightRaw> lineHeight;
+    WTF::Vector<FontFamilyRaw> family;
+};
+
+Optional<CSSValueID> consumeFontVariantCSS21Raw(CSSParserTokenRange&);
+Optional<CSSValueID> consumeFontWeightKeywordValueRaw(CSSParserTokenRange&);
+Optional<FontWeightRaw> consumeFontWeightRaw(CSSParserTokenRange&);
+Optional<CSSValueID> consumeFontStretchKeywordValueRaw(CSSParserTokenRange&);
+Optional<CSSValueID> consumeFontStyleKeywordValueRaw(CSSParserTokenRange&);
+Optional<FontStyleRaw> consumeFontStyleRaw(CSSParserTokenRange&, CSSParserMode);
+String concatenateFamilyName(CSSParserTokenRange&);
+String consumeFamilyNameRaw(CSSParserTokenRange&);
+Optional<CSSValueID> consumeGenericFamilyRaw(CSSParserTokenRange&);
+Optional<WTF::Vector<FontFamilyRaw>> consumeFontFamilyRaw(CSSParserTokenRange&);
+Optional<FontSizeRaw> consumeFontSizeRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
+Optional<LineHeightRaw> consumeLineHeightRaw(CSSParserTokenRange&, CSSParserMode);
+Optional<FontRaw> consumeFontWorkerSafe(CSSParserTokenRange&, CSSParserMode);
+const AtomString& genericFontFamilyFromValueID(CSSValueID);
+
 // Template implementations are at the bottom of the file for readability.
 
 template<typename... emptyBaseCase> inline bool identMatches(CSSValueID) { return false; }
@@ -123,6 +172,13 @@
     return id == head || identMatches<tail...>(id);
 }
 
+template<CSSValueID... names> Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange& range)
+{
+    if (range.peek().type() != IdentToken || !identMatches<names...>(range.peek().id()))
+        return WTF::nullopt;
+    return range.consumeIncludingWhitespace().id();
+}
+
 template<CSSValueID... names> RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range)
 {
     if (range.peek().type() != IdentToken || !identMatches<names...>(range.peek().id()))

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (269956 => 269957)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2020-11-18 16:03:50 UTC (rev 269957)
@@ -36,16 +36,21 @@
 #include "CSSFontSelector.h"
 #include "CSSParser.h"
 #include "CSSPropertyNames.h"
+#include "CSSPropertyParserHelpers.h"
 #include "Gradient.h"
 #include "ImageBuffer.h"
 #include "ImageData.h"
 #include "InspectorInstrumentation.h"
+#include "NodeRenderStyle.h"
 #include "Path2D.h"
 #include "RenderTheme.h"
 #include "ResourceLoadObserver.h"
 #include "RuntimeEnabledFeatures.h"
+#include "Settings.h"
 #include "StyleBuilder.h"
+#include "StyleFontSizeFunctions.h"
 #include "StyleProperties.h"
+#include "StyleResolveForFontRaw.h"
 #include "TextMetrics.h"
 #include "TextRun.h"
 #include <wtf/CheckedArithmetic.h>
@@ -134,16 +139,10 @@
     if (newFont == state().unparsedFont && state().font.realized())
         return;
 
-    auto parsedStyle = MutableStyleProperties::create();
-    CSSParser::parseValue(parsedStyle, CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode));
-    if (parsedStyle->isEmpty())
-        return;
-
-    String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
-
     // According to http://lists.w3.org/Archives/Public/public-html/2009Jul/0947.html,
-    // the "inherit" and "initial" values must be ignored.
-    if (fontValue == "inherit" || fontValue == "initial")
+    // the "inherit" and "initial" values must be ignored. parseFontWorkerSafe() ignores these.
+    auto fontRaw = CSSParser::parseFontWorkerSafe(newFont, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode));
+    if (!fontRaw)
         return;
 
     // The parse succeeded.
@@ -153,38 +152,20 @@
 
     // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
     // relative to the canvas.
-    auto newStyle = RenderStyle::createPtr();
-
     Document& document = canvas().document();
     document.updateStyleIfNeeded();
 
+    FontCascadeDescription fontDescription;
     if (auto* computedStyle = canvas().computedStyle())
-        newStyle->setFontDescription(FontCascadeDescription { computedStyle->fontDescription() });
+        fontDescription = FontCascadeDescription { computedStyle->fontDescription() };
     else {
-        FontCascadeDescription defaultFontDescription;
-        defaultFontDescription.setOneFamily(DefaultFontFamily);
-        defaultFontDescription.setSpecifiedSize(DefaultFontSize);
-        defaultFontDescription.setComputedSize(DefaultFontSize);
-
-        newStyle->setFontDescription(WTFMove(defaultFontDescription));
+        fontDescription.setOneFamily(DefaultFontFamily);
+        fontDescription.setSpecifiedSize(DefaultFontSize);
+        fontDescription.setComputedSize(DefaultFontSize);
     }
 
-    newStyle->fontCascade().update(&document.fontSelector());
-
-    // Now map the font property longhands into the style.
-
-    Style::MatchResult matchResult;
-    auto parentStyle = RenderStyle::clone(*newStyle);
-    Style::Builder styleBuilder(*newStyle, { document, parentStyle }, matchResult, { });
-
-    styleBuilder.applyPropertyValue(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get());
-    styleBuilder.applyPropertyValue(CSSPropertyFontStyle, parsedStyle->getPropertyCSSValue(CSSPropertyFontStyle).get());
-    styleBuilder.applyPropertyValue(CSSPropertyFontVariantCaps, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariantCaps).get());
-    styleBuilder.applyPropertyValue(CSSPropertyFontWeight, parsedStyle->getPropertyCSSValue(CSSPropertyFontWeight).get());
-    styleBuilder.applyPropertyValue(CSSPropertyFontSize, parsedStyle->getPropertyCSSValue(CSSPropertyFontSize).get());
-    styleBuilder.applyPropertyValue(CSSPropertyLineHeight, parsedStyle->getPropertyCSSValue(CSSPropertyLineHeight).get());
-
-    modifiableState().font.initialize(document.fontSelector(), *newStyle);
+    if (auto fontStyle = Style::resolveForFontRaw(*fontRaw, WTFMove(fontDescription), document))
+        modifiableState().font.initialize(document.fontSelector(), *fontStyle);
 }
 
 static CanvasTextAlign toCanvasTextAlign(TextAlign textAlign)

Modified: trunk/Source/WebCore/style/StyleBuilderCustom.h (269956 => 269957)


--- trunk/Source/WebCore/style/StyleBuilderCustom.h	2020-11-18 15:36:33 UTC (rev 269956)
+++ trunk/Source/WebCore/style/StyleBuilderCustom.h	2020-11-18 16:03:50 UTC (rev 269957)
@@ -31,6 +31,7 @@
 #include "CSSFontValue.h"
 #include "CSSGradientValue.h"
 #include "CSSGridTemplateAreasValue.h"
+#include "CSSPropertyParserHelpers.h"
 #include "CSSRegisteredCustomProperty.h"
 #include "CSSShadowValue.h"
 #include "Counter.h"
@@ -1012,40 +1013,11 @@
             // If the family name was resolved by the CSS parser from a system font ID, then it is generic.
             isGenericFamily = fontFamily.fromSystemFontID;
         } else {
-            switch (contentValue.valueID()) {
-            case CSSValueWebkitBody:
+            if (contentValue.valueID() == CSSValueWebkitBody)
                 family = builderState.document().settings().standardFontFamily();
-                break;
-            case CSSValueSerif:
-                family = serifFamily;
+            else {
                 isGenericFamily = true;
-                break;
-            case CSSValueSansSerif:
-                family = sansSerifFamily;
-                isGenericFamily = true;
-                break;
-            case CSSValueCursive:
-                family = cursiveFamily;
-                isGenericFamily = true;
-                break;
-            case CSSValueFantasy:
-                family = fantasyFamily;
-                isGenericFamily = true;
-                break;
-            case CSSValueMonospace:
-                family = monospaceFamily;
-                isGenericFamily = true;
-                break;
-            case CSSValueWebkitPictograph:
-                family = pictographFamily;
-                isGenericFamily = true;
-                break;
-            case CSSValueSystemUi:
-                family = systemUiFamily;
-                isGenericFamily = true;
-                break;
-            default:
-                break;
+                family = CSSPropertyParserHelpers::genericFontFamilyFromValueID(contentValue.valueID());
             }
         }
 

Added: trunk/Source/WebCore/style/StyleResolveForFontRaw.cpp (0 => 269957)


--- trunk/Source/WebCore/style/StyleResolveForFontRaw.cpp	                        (rev 0)
+++ trunk/Source/WebCore/style/StyleResolveForFontRaw.cpp	2020-11-18 16:03:50 UTC (rev 269957)
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Metrological Group B.V.
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StyleResolveForFontRaw.h"
+
+#include "CSSFontSelector.h"
+#include "CSSPropertyParserHelpers.h"
+#include "Document.h"
+#include "FontCascadeDescription.h"
+#include "RenderStyle.h"
+#include "StyleFontSizeFunctions.h"
+
+namespace WebCore {
+
+namespace Style {
+
+using namespace CSSPropertyParserHelpers;
+
+Optional<RenderStyle> resolveForFontRaw(const FontRaw& fontRaw, FontCascadeDescription&& fontDescription, Document& document)
+{
+    auto fontStyle = RenderStyle::create();
+
+    auto getParentStyle = [&] () -> std::unique_ptr<RenderStyle> {
+        auto parentStyle = RenderStyle::clonePtr(fontStyle);
+        parentStyle->setFontDescription(FontCascadeDescription(fontDescription));
+        parentStyle->fontCascade().update(&document.fontSelector());
+        return parentStyle;
+    };
+
+    // Map the font property longhands into the style.
+    float parentSize = fontDescription.specifiedSize();
+
+    // Font family applied in the same way as StyleBuilderCustom::applyValueFontFamily
+    // Before mapping in a new font-family property, we should reset the generic family.
+    bool oldFamilyUsedFixedDefaultSize = fontDescription.useFixedDefaultSize();
+
+    Vector<AtomString> families;
+    families.reserveInitialCapacity(fontRaw.family.size());
+
+    for (auto& item : fontRaw.family) {
+        AtomString family;
+        bool isGenericFamily = false;
+        switchOn(item, [&] (CSSValueID ident) {
+            isGenericFamily = ident != CSSValueWebkitBody;
+            family = isGenericFamily ? CSSPropertyParserHelpers::genericFontFamilyFromValueID(ident)
+                : document.settings().standardFontFamily();
+        }, [&] (const String& familyString) {
+            family = familyString;
+        });
+
+        if (family.isEmpty())
+            continue;
+        if (families.isEmpty())
+            fontDescription.setIsSpecifiedFont(!isGenericFamily);
+        families.uncheckedAppend(family);
+    }
+
+    if (families.isEmpty())
+        return WTF::nullopt;
+    fontDescription.setFamilies(families);
+
+    if (fontDescription.useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize) {
+        if (CSSValueID sizeIdentifier = fontDescription.keywordSizeAsIdentifier()) {
+            auto size = Style::fontSizeForKeyword(sizeIdentifier, !oldFamilyUsedFixedDefaultSize, document);
+            fontDescription.setSpecifiedSize(size);
+            fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSize(size, fontDescription.isAbsoluteSize(), false, &fontStyle, document));
+        }
+    }
+
+    // Font style applied in the same way as BuilderConverter::convertFontStyleFromValue
+    if (fontRaw.style) {
+        switch (fontRaw.style->style) {
+        case CSSValueNormal:
+            break;
+
+        case CSSValueItalic:
+            fontDescription.setItalic(italicValue());
+            break;
+
+        case CSSValueOblique: {
+            float degrees;
+            if (fontRaw.style->angle)
+                degrees = static_cast<float>(CSSPrimitiveValue::computeDegrees(fontRaw.style->angle->type, fontRaw.style->angle->value));
+            else
+                degrees = 0;
+            fontDescription.setItalic(FontSelectionValue(degrees));
+            break;
+        }
+
+        default:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+    }
+    fontDescription.setFontStyleAxis((fontRaw.style && fontRaw.style->style == CSSValueItalic) ? FontStyleAxis::ital : FontStyleAxis::slnt);
+
+    if (fontRaw.variantCaps) {
+        switch (*fontRaw.variantCaps) {
+        case CSSValueNormal:
+            fontDescription.setVariantCaps(FontVariantCaps::Normal);
+            break;
+        case CSSValueSmallCaps:
+            fontDescription.setVariantCaps(FontVariantCaps::Small);
+            break;
+        case CSSValueAllSmallCaps:
+            fontDescription.setVariantCaps(FontVariantCaps::AllSmall);
+            break;
+        case CSSValuePetiteCaps:
+            fontDescription.setVariantCaps(FontVariantCaps::Petite);
+            break;
+        case CSSValueAllPetiteCaps:
+            fontDescription.setVariantCaps(FontVariantCaps::AllPetite);
+            break;
+        case CSSValueUnicase:
+            fontDescription.setVariantCaps(FontVariantCaps::Unicase);
+            break;
+        case CSSValueTitlingCaps:
+            fontDescription.setVariantCaps(FontVariantCaps::Titling);
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+    }
+
+    if (fontRaw.weight) {
+        auto weight = switchOn(*fontRaw.weight, [&] (CSSValueID ident) {
+            switch (ident) {
+            case CSSValueNormal:
+                return normalWeightValue();
+            case CSSValueBold:
+                return boldWeightValue();
+            case CSSValueBolder:
+                return FontCascadeDescription::bolderWeight(fontDescription.weight());
+            case CSSValueLighter:
+                return FontCascadeDescription::lighterWeight(fontDescription.weight());
+            default:
+                ASSERT_NOT_REACHED();
+                return normalWeightValue();
+            }
+        }, [&] (double weight) {
+            return FontSelectionValue::clampFloat(weight);
+        });
+        fontDescription.setWeight(weight);
+    }
+
+    fontDescription.setKeywordSizeFromIdentifier(CSSValueInvalid);
+    float size = switchOn(fontRaw.size, [&] (CSSValueID ident) {
+        switch (ident) {
+        case CSSValueXxSmall:
+        case CSSValueXSmall:
+        case CSSValueSmall:
+        case CSSValueMedium:
+        case CSSValueLarge:
+        case CSSValueXLarge:
+        case CSSValueXxLarge:
+        case CSSValueWebkitXxxLarge:
+            fontDescription.setKeywordSizeFromIdentifier(ident);
+            return Style::fontSizeForKeyword(ident, fontDescription.useFixedDefaultSize(), document);
+        case CSSValueLarger:
+            return parentSize * 1.2f;
+        case CSSValueSmaller:
+            return parentSize / 1.2f;
+        default:
+            return 0.f;
+        }
+    }, [&] (const CSSPropertyParserHelpers::LengthOrPercentRaw& lengthOrPercent) {
+        return switchOn(lengthOrPercent, [&] (const CSSPropertyParserHelpers::LengthRaw& length) {
+            auto parentStyle = getParentStyle();
+            CSSToLengthConversionData conversionData { parentStyle.get(), nullptr, parentStyle.get(), document.renderView(), 1.0f, CSSPropertyFontSize };
+            return static_cast<float>(CSSPrimitiveValue::computeNonCalcLengthDouble(conversionData, length.type, length.value));
+        }, [&] (double percentage) {
+            return static_cast<float>((parentSize * percentage) / 100.0);
+        });
+    });
+
+    if (size > 0) {
+        fontDescription.setSpecifiedSize(size);
+        fontDescription.setComputedSize(size);
+    }
+
+    if (fontRaw.lineHeight) {
+        Optional<Length> lineHeight = switchOn(*fontRaw.lineHeight, [&] (CSSValueID ident) {
+            if (ident == CSSValueNormal)
+                return Optional<Length>(RenderStyle::initialLineHeight());
+            return Optional<Length>(WTF::nullopt);
+        }, [&] (double number) {
+            return Optional<Length>(Length(number * 100.0, Percent));
+        }, [&] (const CSSPropertyParserHelpers::LengthOrPercentRaw& lengthOrPercent) {
+            return switchOn(lengthOrPercent, [&] (const CSSPropertyParserHelpers::LengthRaw& length) {
+                auto parentStyle = getParentStyle();
+                CSSToLengthConversionData conversionData { parentStyle.get(), nullptr, parentStyle.get(), document.renderView(), 1.0f, CSSPropertyLineHeight };
+                return Optional<Length>(Length(clampTo<float>(CSSPrimitiveValue::computeNonCalcLengthDouble(conversionData, length.type, length.value), minValueForCssLength, maxValueForCssLength), Fixed));
+            }, [&] (double percentage) {
+                return Optional<Length>(Length((fontDescription.computedSize() * static_cast<int>(percentage)) / 100, Fixed));
+            });
+        });
+
+        if (lineHeight)
+            fontStyle.setLineHeight(WTFMove(lineHeight.value()));
+    }
+
+    fontStyle.setFontDescription(WTFMove(fontDescription));
+    fontStyle.fontCascade().update(&document.fontSelector());
+
+    return fontStyle;
+}
+
+}
+}

Added: trunk/Source/WebCore/style/StyleResolveForFontRaw.h (0 => 269957)


--- trunk/Source/WebCore/style/StyleResolveForFontRaw.h	                        (rev 0)
+++ trunk/Source/WebCore/style/StyleResolveForFontRaw.h	2020-11-18 16:03:50 UTC (rev 269957)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 Metrological Group B.V.
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/OptionSet.h>
+
+namespace WebCore {
+
+class Document;
+class RenderStyle;
+
+namespace CSSPropertyParserHelpers {
+struct FontRaw;
+}
+
+namespace Style {
+
+Optional<RenderStyle> resolveForFontRaw(const CSSPropertyParserHelpers::FontRaw&, FontCascadeDescription&&, Document&);
+
+}
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to