<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[269957] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/269957">269957</a></dd>
<dt>Author</dt> <dd>clord@igalia.com</dd>
<dt>Date</dt> <dd>2020-11-18 08:03:50 -0800 (Wed, 18 Nov 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestshtmlcanvaselementtextstyles2dtextfontparseinvalidexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParsercpp">trunk/Source/WebCore/css/parser/CSSParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParserh">trunk/Source/WebCore/css/parser/CSSParser.h</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSPropertyParsercpp">trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSPropertyParserh">trunk/Source/WebCore/css/parser/CSSPropertyParser.h</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSPropertyParserHelperscpp">trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSPropertyParserHelpersh">trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasCanvasRenderingContext2Dcpp">trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleStyleBuilderCustomh">trunk/Source/WebCore/style/StyleBuilderCustom.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorestyleStyleResolveForFontRawcpp">trunk/Source/WebCore/style/StyleResolveForFontRaw.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleStyleResolveForFontRawh">trunk/Source/WebCore/style/StyleResolveForFontRaw.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2020-11-18  Chris Lord  <clord@igalia.com>
+
+        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:
+
</ins><span class="cx"> 2020-11-18  Commit Queue  <commit-queue@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, reverting r269940.
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestshtmlcanvaselementtextstyles2dtextfontparseinvalidexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> 2d.text.font.parse.invalid
</span><span class="cx"> Actual output:
</span><span class="cx"> 
</span><del>-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"
</del><ins>+PASS Canvas test: 2d.text.font.parse.invalid
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,71 @@
</span><ins>+2020-11-18  Chris Lord  <clord@igalia.com>
+
+        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.
+
</ins><span class="cx"> 2020-11-18  Michael Catanzaro  <mcatanzaro@gnome.org>
</span><span class="cx"> 
</span><span class="cx">         [WPE][GTK] Update Outlook user agent quirk
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -2427,6 +2427,7 @@
</span><span class="cx"> style/StylePendingResources.cpp
</span><span class="cx"> style/StyleRelations.cpp
</span><span class="cx"> style/StyleResolveForDocument.cpp
</span><ins>+style/StyleResolveForFontRaw.cpp
</ins><span class="cx"> style/StyleResolver.cpp
</span><span class="cx"> style/StyleScope.cpp
</span><span class="cx"> style/StyleScopeRuleSets.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -5136,6 +5136,7 @@
</span><span class="cx">          E4D33F44252C50E200837D05 /* LayoutIntegrationLineIteratorLegacyPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F43252C50E200837D05 /* LayoutIntegrationLineIteratorLegacyPath.h */; };
</span><span class="cx">          E4D33F46252C50FC00837D05 /* LayoutIntegrationLineIteratorModernPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F45252C50FB00837D05 /* LayoutIntegrationLineIteratorModernPath.h */; };
</span><span class="cx">          E4D58EB517B4DBDC00CBDCA8 /* StyleResolveForDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */; };
</span><ins>+               E4D68EB517B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D68EB317B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h */; };
</ins><span class="cx">           E4D58EB917B4ED8900CBDCA8 /* StyleFontSizeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */; };
</span><span class="cx">          E4D58EBB17B8F12800CBDCA8 /* ElementTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          E4D988B417BFD1F60084FB88 /* TextNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */; };
</span><span class="lines">@@ -16286,6 +16287,8 @@
</span><span class="cx">          E4D33F45252C50FB00837D05 /* LayoutIntegrationLineIteratorModernPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutIntegrationLineIteratorModernPath.h; sourceTree = "<group>"; };
</span><span class="cx">          E4D58EB217B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveForDocument.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleResolveForDocument.h; sourceTree = "<group>"; };
</span><ins>+               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>"; };
</ins><span class="cx">           E4D58EB617B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleFontSizeFunctions.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleFontSizeFunctions.h; sourceTree = "<group>"; };
</span><span class="cx">          E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementTraversal.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -28867,6 +28870,8 @@
</span><span class="cx">                          E461802C1C8DD2900026C02C /* StyleRelations.h */,
</span><span class="cx">                          E4D58EB217B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp */,
</span><span class="cx">                          E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */,
</span><ins>+                               E4D68EB217B4DBDC00CBDCA8 /* StyleResolveForFontRaw.cpp */,
+                               E4D68EB317B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h */,
</ins><span class="cx">                           E139866115478474001E3F65 /* StyleResolver.cpp */,
</span><span class="cx">                          E139866215478474001E3F65 /* StyleResolver.h */,
</span><span class="cx">                          E461D65C1BB0C7F000CB5645 /* StyleScope.cpp */,
</span><span class="lines">@@ -34518,6 +34523,7 @@
</span><span class="cx">                          BC2272870E82E70700E7F975 /* StyleReflection.h in Headers */,
</span><span class="cx">                          E461802D1C8DD2900026C02C /* StyleRelations.h in Headers */,
</span><span class="cx">                          E4D58EB517B4DBDC00CBDCA8 /* StyleResolveForDocument.h in Headers */,
</span><ins>+                               E4D68EB517B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h in Headers */,
</ins><span class="cx">                           E139866415478474001E3F65 /* StyleResolver.h in Headers */,
</span><span class="cx">                          E4BBED4D14FCDBA1003F0B98 /* StyleRule.h in Headers */,
</span><span class="cx">                          E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParser.cpp (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -138,6 +138,15 @@
</span><span class="cx">     return CSSParserFastPaths::parseHexColor(string);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Optional<CSSPropertyParserHelpers::FontRaw> CSSParser::parseFontWorkerSafe(const String& string, CSSParserMode cssParserMode)
+{
+    CSSTokenizer tokenizer(string);
+    CSSParserTokenRange range(tokenizer.tokenRange());
+    range.consumeWhitespace();
+
+    return CSSPropertyParserHelpers::consumeFontWorkerSafe(range, cssParserMode);
+}
+
</ins><span class="cx"> RefPtr<CSSValue> CSSParser::parseSingleValue(CSSPropertyID propertyID, const String& string, const CSSParserContext& context)
</span><span class="cx"> {
</span><span class="cx">     if (string.isEmpty())
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParser.h (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -44,6 +44,10 @@
</span><span class="cx"> class RenderStyle;
</span><span class="cx"> template<typename> struct SRGBA;
</span><span class="cx"> 
</span><ins>+namespace CSSPropertyParserHelpers {
+struct FontRaw;
+}
+
</ins><span class="cx"> namespace Style {
</span><span class="cx"> class BuilderState;
</span><span class="cx"> }
</span><span class="lines">@@ -92,6 +96,8 @@
</span><span class="cx">     static Optional<SRGBA<uint8_t>> parseNamedColor(StringView);
</span><span class="cx">     static Optional<SRGBA<uint8_t>> parseHexColor(StringView);
</span><span class="cx"> 
</span><ins>+    static Optional<CSSPropertyParserHelpers::FontRaw> parseFontWorkerSafe(const String&, CSSParserMode = HTMLStandardMode);
+
</ins><span class="cx"> private:
</span><span class="cx">     ParseResult parseValue(MutableStyleProperties&, CSSPropertyID, const String&, bool important);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSPropertyParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -54,7 +54,6 @@
</span><span class="cx"> #include "CSSParserIdioms.h"
</span><span class="cx"> #include "CSSPendingSubstitutionValue.h"
</span><span class="cx"> #include "CSSPrimitiveValueMappings.h"
</span><del>-#include "CSSPropertyParserHelpers.h"
</del><span class="cx"> #include "CSSReflectValue.h"
</span><span class="cx"> #include "CSSShadowValue.h"
</span><span class="cx"> #include "CSSTimingFunctionValue.h"
</span><span class="lines">@@ -864,16 +863,16 @@
</span><span class="cx">     return consumeIdent<CSSValueNormal, CSSValueSmallCaps>(range);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static RefPtr<CSSPrimitiveValue> consumeFontWeightKeywordValue(CSSParserTokenRange& range)
-{
-    return consumeIdent<CSSValueNormal, CSSValueBold, CSSValueBolder, CSSValueLighter>(range);
-}
-
</del><span class="cx"> static RefPtr<CSSPrimitiveValue> consumeFontWeight(CSSParserTokenRange& range)
</span><span class="cx"> {
</span><del>-    if (auto result = consumeFontWeightKeywordValue(range))
-        return result;
-    return consumeFontWeightNumber(range);
</del><ins>+    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;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static RefPtr<CSSPrimitiveValue> consumeFontWeightAbsoluteKeywordValue(CSSParserTokenRange& range)
</span><span class="lines">@@ -910,7 +909,9 @@
</span><span class="cx"> 
</span><span class="cx"> static RefPtr<CSSPrimitiveValue> consumeFontStretchKeywordValue(CSSParserTokenRange& range)
</span><span class="cx"> {
</span><del>-    return consumeIdent<CSSValueUltraCondensed, CSSValueExtraCondensed, CSSValueCondensed, CSSValueSemiCondensed, CSSValueNormal, CSSValueSemiExpanded, CSSValueExpanded, CSSValueExtraExpanded, CSSValueUltraExpanded>(range);
</del><ins>+    if (auto valueID = consumeFontStretchKeywordValueRaw(range))
+        return CSSValuePool::singleton().createIdentifierValue(*valueID);
+    return nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VARIATION_FONTS)
</span><span class="lines">@@ -965,26 +966,16 @@
</span><span class="cx"> 
</span><span class="cx"> static RefPtr<CSSFontStyleValue> consumeFontStyle(CSSParserTokenRange& range, CSSParserMode cssParserMode)
</span><span class="cx"> {
</span><del>-    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);
</del><ins>+    if (auto result = consumeFontStyleRaw(range, cssParserMode)) {
</ins><span class="cx"> #if ENABLE(VARIATION_FONTS)
</span><del>-    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;
</del><ins>+        if (result->style == CSSValueOblique && result->angle) {
+            return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique),
+                CSSValuePool::singleton().createValue(result->angle->value, result->angle->type));
</ins><span class="cx">         }
</span><ins>+#endif
+        return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(result->style));
</ins><span class="cx">     }
</span><del>-#else
-    UNUSED_PARAM(cssParserMode);
-#endif
-    return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique));
</del><ins>+    return nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VARIATION_FONTS)
</span><span class="lines">@@ -1018,30 +1009,9 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-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();
-}
-
</del><span class="cx"> static RefPtr<CSSValue> consumeFamilyName(CSSParserTokenRange& range)
</span><span class="cx"> {
</span><del>-    if (range.peek().type() == StringToken)
-        return CSSValuePool::singleton().createFontFamilyValue(range.consumeIncludingWhitespace().value().toString());
-    if (range.peek().type() != IdentToken)
-        return nullptr;
-    String familyName = concatenateFamilyName(range);
</del><ins>+    auto familyName = consumeFamilyNameRaw(range);
</ins><span class="cx">     if (familyName.isNull())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return CSSValuePool::singleton().createFontFamilyValue(familyName);
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSPropertyParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.h (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include "CSSParserTokenRange.h"
</span><ins>+#include "CSSPropertyParserHelpers.h"
</ins><span class="cx"> #include "StyleRule.h"
</span><span class="cx"> #include <wtf/text/StringView.h>
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSPropertyParserHelperscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -130,13 +130,16 @@
</span><span class="cx"> 
</span><span class="cx">     Optional<double> consumePercentRaw()
</span><span class="cx">     {
</span><del>-        if (!m_calcValue || m_calcValue->category() != CalculationCategory::Percent)
</del><ins>+        if (!m_calcValue)
</ins><span class="cx">             return WTF::nullopt;
</span><ins>+        auto category = m_calcValue->category();
+        if (category != CalculationCategory::Percent)
+            return WTF::nullopt;
</ins><span class="cx">         m_sourceRange = m_range;
</span><span class="cx">         return m_calcValue->doubleValue();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Optional<Angle> consumeAngleRaw()
</del><ins>+    Optional<AngleRaw> consumeAngleRaw()
</ins><span class="cx">     {
</span><span class="cx">         if (!m_calcValue || m_calcValue->category() != CalculationCategory::Angle)
</span><span class="cx">             return WTF::nullopt;
</span><span class="lines">@@ -144,6 +147,33 @@
</span><span class="cx">         return { { m_calcValue->primitiveType(), m_calcValue->doubleValue() } };
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    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;
+        }
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     CSSParserTokenRange& m_sourceRange;
</span><span class="cx">     CSSParserTokenRange m_range;
</span><span class="lines">@@ -177,10 +207,12 @@
</span><span class="cx">     return consumeInteger(range, 1);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool consumeNumberRaw(CSSParserTokenRange& range, double& result)
</del><ins>+bool consumeNumberRaw(CSSParserTokenRange& range, double& result, ValueRange valueRange)
</ins><span class="cx"> {
</span><span class="cx">     const CSSParserToken& token = range.peek();
</span><span class="cx">     if (token.type() == NumberToken) {
</span><ins>+        if (valueRange == ValueRangeNonNegative && token.numericValue() < 0)
+            return false;
</ins><span class="cx">         result = range.consumeIncludingWhitespace().numericValue();
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="lines">@@ -188,7 +220,7 @@
</span><span class="cx">     if (token.type() != FunctionToken)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    CalcParser calcParser(range, CalculationCategory::Number, ValueRangeAll);
</del><ins>+    CalcParser calcParser(range, CalculationCategory::Number, valueRange);
</ins><span class="cx">     return calcParser.consumeNumberRaw(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -196,22 +228,19 @@
</span><span class="cx"> RefPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange& range, ValueRange valueRange)
</span><span class="cx"> {
</span><span class="cx">     const CSSParserToken& token = range.peek();
</span><del>-    if (token.type() == NumberToken) {
-        if (valueRange == ValueRangeNonNegative && token.numericValue() < 0)
-            return nullptr;
-        return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), token.unitType());
</del><ins>+    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;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (token.type() != FunctionToken)
-        return nullptr;
</del><ins>+    double number;
+    if (consumeNumberRaw(range, number, valueRange))
+        return CSSValuePool::singleton().createValue(number, token.unitType());
</ins><span class="cx"> 
</span><del>-    CalcParser calcParser(range, CalculationCategory::Number, valueRange);
-    if (const CSSCalcValue* calcValue = calcParser.value()) {
-        if (calcValue->category() != CalculationCategory::Number)
-            return nullptr;
-        return calcParser.consumeValue();
-    }
-
</del><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -222,7 +251,7 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange& range)
</del><ins>+Optional<double> consumeFontWeightNumberRaw(CSSParserTokenRange& range)
</ins><span class="cx"> {
</span><span class="cx">     // Values less than or equal to 0 or greater than or equal to 1000 are parse errors.
</span><span class="cx">     auto& token = range.peek();
</span><span class="lines">@@ -230,11 +259,15 @@
</span><span class="cx"> #if !ENABLE(VARIATION_FONTS)
</span><span class="cx">         && token.numericValueType() == IntegerValueType && divisibleBy100(token.numericValue())
</span><span class="cx"> #endif
</span><del>-    )
-        return consumeNumber(range, ValueRangeAll);
</del><ins>+    ) {
+        double result;
+        if (consumeNumberRaw(range, result))
+            return result;
+        return WTF::nullopt;
+    }
</ins><span class="cx"> 
</span><span class="cx">     if (token.type() != FunctionToken)
</span><del>-        return nullptr;
</del><ins>+        return WTF::nullopt;
</ins><span class="cx"> 
</span><span class="cx">     // "[For calc()], the used value resulting from an expression must be clamped to the range allowed in the target context."
</span><span class="cx">     CalcParser calcParser(range, CalculationCategory::Number, ValueRangeAll);
</span><span class="lines">@@ -245,9 +278,16 @@
</span><span class="cx"> #endif
</span><span class="cx">     ) {
</span><span class="cx">         result = std::min(std::max(result, std::nextafter(0., 1.)), std::nextafter(1000., 0.));
</span><del>-        return CSSValuePool::singleton().createValue(result, CSSUnitType::CSS_NUMBER);
</del><ins>+        return result;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    return WTF::nullopt;
+}
+
+RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange& range)
+{
+    if (auto result = consumeFontWeightNumberRaw(range))
+        return CSSValuePool::singleton().createValue(*result, CSSUnitType::CSS_NUMBER);
</ins><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -259,7 +299,7 @@
</span><span class="cx">         || (cssParserMode == HTMLQuirksMode && unitless == UnitlessQuirk::Allow);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
</del><ins>+Optional<LengthRaw> consumeLengthRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
</ins><span class="cx"> {
</span><span class="cx">     const CSSParserToken& token = range.peek();
</span><span class="cx">     if (token.type() == DimensionToken) {
</span><span class="lines">@@ -266,7 +306,7 @@
</span><span class="cx">         switch (token.unitType()) {
</span><span class="cx">         case CSSUnitType::CSS_QUIRKY_EMS:
</span><span class="cx">             if (cssParserMode != UASheetMode)
</span><del>-                return nullptr;
</del><ins>+                return WTF::nullopt;
</ins><span class="cx">             FALLTHROUGH;
</span><span class="cx">         case CSSUnitType::CSS_EMS:
</span><span class="cx">         case CSSUnitType::CSS_REMS:
</span><span class="lines">@@ -287,29 +327,40 @@
</span><span class="cx">         case CSSUnitType::CSS_Q:
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            return nullptr;
</del><ins>+            return WTF::nullopt;
</ins><span class="cx">         }
</span><span class="cx">         if ((valueRange == ValueRangeNonNegative && token.numericValue() < 0) || std::isinf(token.numericValue()))
</span><del>-            return nullptr;
-        return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), token.unitType());
</del><ins>+            return WTF::nullopt;
+        return { { token.unitType(), range.consumeIncludingWhitespace().numericValue() } };
</ins><span class="cx">     }
</span><span class="cx">     if (token.type() == NumberToken) {
</span><span class="cx">         if (!shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless)
</span><span class="cx">             || (valueRange == ValueRangeNonNegative && token.numericValue() < 0))
</span><del>-            return nullptr;
</del><ins>+            return WTF::nullopt;
</ins><span class="cx">         if (std::isinf(token.numericValue()))
</span><del>-            return nullptr;
-        CSSUnitType unitType = CSSUnitType::CSS_PX;
-        return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), unitType);
</del><ins>+            return WTF::nullopt;
+        return { { CSSUnitType::CSS_PX, range.consumeIncludingWhitespace().numericValue() } };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (token.type() != FunctionToken)
</span><del>-        return nullptr;
</del><ins>+        return WTF::nullopt;
</ins><span class="cx"> 
</span><span class="cx">     CalcParser calcParser(range, CalculationCategory::Length, valueRange);
</span><del>-    if (calcParser.value() && calcParser.value()->category() == CalculationCategory::Length)
-        return calcParser.consumeValue();
</del><ins>+    return calcParser.consumeLengthRaw();
+}
</ins><span class="cx"> 
</span><ins>+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);
+
</ins><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -333,7 +384,7 @@
</span><span class="cx"> {
</span><span class="cx">     const CSSParserToken& token = range.peek();
</span><span class="cx">     if (token.type() == FunctionToken) {
</span><del>-        CalcParser calcParser(range, CalculationCategory::Angle, valueRange);
</del><ins>+        CalcParser calcParser(range, CalculationCategory::Percent, valueRange);
</ins><span class="cx">         if (const CSSCalcValue* calculation = calcParser.value()) {
</span><span class="cx">             if (calculation->category() == CalculationCategory::Percent)
</span><span class="cx">                 return calcParser.consumeValue();
</span><span class="lines">@@ -361,26 +412,54 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
</del><ins>+Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
</ins><span class="cx"> {
</span><span class="cx">     const CSSParserToken& token = range.peek();
</span><del>-    if (token.type() == DimensionToken || token.type() == NumberToken)
-        return consumeLength(range, cssParserMode, valueRange, unitless);
-    if (token.type() == PercentageToken)
-        return consumePercent(range, valueRange);
</del><ins>+    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;
+    }
</ins><span class="cx"> 
</span><span class="cx">     if (token.type() != FunctionToken)
</span><del>-        return nullptr;
</del><ins>+        return WTF::nullopt;
</ins><span class="cx"> 
</span><span class="cx">     CalcParser calcParser(range, CalculationCategory::Length, valueRange);
</span><span class="cx">     if (const CSSCalcValue* calculation = calcParser.value()) {
</span><span class="cx">         if (canConsumeCalcValue(calculation->category(), cssParserMode))
</span><del>-            return calcParser.consumeValue();
</del><ins>+            return calcParser.consumeLengthOrPercentRaw();
</ins><span class="cx">     }
</span><ins>+    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);
+        });
+    }
</ins><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Optional<Angle> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
</del><ins>+Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
</ins><span class="cx"> {
</span><span class="cx">     const CSSParserToken& token = range.peek();
</span><span class="cx">     if (token.type() == DimensionToken) {
</span><span class="lines">@@ -502,13 +581,27 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range)
</del><ins>+Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange& range)
</ins><span class="cx"> {
</span><span class="cx">     if (range.peek().type() != IdentToken)
</span><del>-        return nullptr;
-    return CSSValuePool::singleton().createIdentifierValue(range.consumeIncludingWhitespace().id());
</del><ins>+        return WTF::nullopt;
+    return range.consumeIncludingWhitespace().id();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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);
+}
+
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeIdentRange(CSSParserTokenRange& range, CSSValueID lower, CSSValueID upper)
</span><span class="cx"> {
</span><span class="cx">     if (range.peek().id() < lower || range.peek().id() > upper)
</span><span class="lines">@@ -1818,6 +1911,225 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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();
+    }
+}
+
</ins><span class="cx"> } // namespace CSSPropertyParserHelpers
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSPropertyParserHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -37,6 +37,8 @@
</span><span class="cx"> #include "CSSValuePool.h"
</span><span class="cx"> #include "Length.h" // For ValueRange
</span><span class="cx"> #include <wtf/OptionSet.h>
</span><ins>+#include <wtf/Variant.h>
+#include <wtf/Vector.h>
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -55,28 +57,41 @@
</span><span class="cx"> enum class UnitlessQuirk { Allow, Forbid };
</span><span class="cx"> enum class AllowXResolutionUnit { Allow, Forbid };
</span><span class="cx"> 
</span><del>-struct Angle {
</del><ins>+struct AngleRaw {
</ins><span class="cx">     CSSUnitType type;
</span><span class="cx">     double value;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct LengthRaw {
+    CSSUnitType type;
+    double value;
+};
+
+using LengthOrPercentRaw = WTF::Variant<LengthRaw, double>;
+
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRange&, double minimumValue = -std::numeric_limits<double>::max());
</span><span class="cx"> RefPtr<CSSPrimitiveValue> consumePositiveInteger(CSSParserTokenRange&);
</span><del>-bool consumeNumberRaw(CSSParserTokenRange&, double& result);
</del><ins>+bool consumeNumberRaw(CSSParserTokenRange&, double& result, ValueRange = ValueRangeAll);
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange&, ValueRange);
</span><ins>+Optional<double> consumeFontWeightNumberRaw(CSSParserTokenRange&);
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange&);
</span><ins>+Optional<LengthRaw> consumeLengthRaw(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
</span><span class="cx"> Optional<double> consumePercentRaw(CSSParserTokenRange&, ValueRange = ValueRangeAll);
</span><span class="cx"> RefPtr<CSSPrimitiveValue> consumePercent(CSSParserTokenRange&, ValueRange);
</span><ins>+Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
</span><del>-Optional<Angle> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk);
</del><ins>+Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
</span><span class="cx"> RefPtr<CSSPrimitiveValue> consumeTime(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
</span><span class="cx"> RefPtr<CSSPrimitiveValue> consumeResolution(CSSParserTokenRange&, AllowXResolutionUnit = AllowXResolutionUnit::Forbid);
</span><span class="cx"> 
</span><ins>+Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange&);
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange&);
</span><ins>+Optional<CSSValueID> consumeIdentRangeRaw(CSSParserTokenRange&, CSSValueID lower, CSSValueID upper);
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> consumeIdentRange(CSSParserTokenRange&, CSSValueID lower, CSSValueID upper);
</span><span class="cx"> template<CSSValueID, CSSValueID...> inline bool identMatches(CSSValueID id);
</span><ins>+template<CSSValueID... allowedIdents> Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange&);
</ins><span class="cx"> template<CSSValueID... allowedIdents> RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange&);
</span><span class="cx"> 
</span><span class="cx"> RefPtr<CSSPrimitiveValue> consumeCustomIdent(CSSParserTokenRange&);
</span><span class="lines">@@ -115,6 +130,40 @@
</span><span class="cx"> RefPtr<CSSValue> consumeFilter(CSSParserTokenRange&, const CSSParserContext&, AllowedFilterFunctions);
</span><span class="cx"> RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange&, CSSParserMode, bool allowInset, bool allowSpread);
</span><span class="cx"> 
</span><ins>+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);
+
</ins><span class="cx"> // Template implementations are at the bottom of the file for readability.
</span><span class="cx"> 
</span><span class="cx"> template<typename... emptyBaseCase> inline bool identMatches(CSSValueID) { return false; }
</span><span class="lines">@@ -123,6 +172,13 @@
</span><span class="cx">     return id == head || identMatches<tail...>(id);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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();
+}
+
</ins><span class="cx"> template<CSSValueID... names> RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range)
</span><span class="cx"> {
</span><span class="cx">     if (range.peek().type() != IdentToken || !identMatches<names...>(range.peek().id()))
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasCanvasRenderingContext2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -36,16 +36,21 @@
</span><span class="cx"> #include "CSSFontSelector.h"
</span><span class="cx"> #include "CSSParser.h"
</span><span class="cx"> #include "CSSPropertyNames.h"
</span><ins>+#include "CSSPropertyParserHelpers.h"
</ins><span class="cx"> #include "Gradient.h"
</span><span class="cx"> #include "ImageBuffer.h"
</span><span class="cx"> #include "ImageData.h"
</span><span class="cx"> #include "InspectorInstrumentation.h"
</span><ins>+#include "NodeRenderStyle.h"
</ins><span class="cx"> #include "Path2D.h"
</span><span class="cx"> #include "RenderTheme.h"
</span><span class="cx"> #include "ResourceLoadObserver.h"
</span><span class="cx"> #include "RuntimeEnabledFeatures.h"
</span><ins>+#include "Settings.h"
</ins><span class="cx"> #include "StyleBuilder.h"
</span><ins>+#include "StyleFontSizeFunctions.h"
</ins><span class="cx"> #include "StyleProperties.h"
</span><ins>+#include "StyleResolveForFontRaw.h"
</ins><span class="cx"> #include "TextMetrics.h"
</span><span class="cx"> #include "TextRun.h"
</span><span class="cx"> #include <wtf/CheckedArithmetic.h>
</span><span class="lines">@@ -134,16 +139,10 @@
</span><span class="cx">     if (newFont == state().unparsedFont && state().font.realized())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    auto parsedStyle = MutableStyleProperties::create();
-    CSSParser::parseValue(parsedStyle, CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode));
-    if (parsedStyle->isEmpty())
-        return;
-
-    String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
-
</del><span class="cx">     // According to http://lists.w3.org/Archives/Public/public-html/2009Jul/0947.html,
</span><del>-    // the "inherit" and "initial" values must be ignored.
-    if (fontValue == "inherit" || fontValue == "initial")
</del><ins>+    // the "inherit" and "initial" values must be ignored. parseFontWorkerSafe() ignores these.
+    auto fontRaw = CSSParser::parseFontWorkerSafe(newFont, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode));
+    if (!fontRaw)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // The parse succeeded.
</span><span class="lines">@@ -153,38 +152,20 @@
</span><span class="cx"> 
</span><span class="cx">     // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
</span><span class="cx">     // relative to the canvas.
</span><del>-    auto newStyle = RenderStyle::createPtr();
-
</del><span class="cx">     Document& document = canvas().document();
</span><span class="cx">     document.updateStyleIfNeeded();
</span><span class="cx"> 
</span><ins>+    FontCascadeDescription fontDescription;
</ins><span class="cx">     if (auto* computedStyle = canvas().computedStyle())
</span><del>-        newStyle->setFontDescription(FontCascadeDescription { computedStyle->fontDescription() });
</del><ins>+        fontDescription = FontCascadeDescription { computedStyle->fontDescription() };
</ins><span class="cx">     else {
</span><del>-        FontCascadeDescription defaultFontDescription;
-        defaultFontDescription.setOneFamily(DefaultFontFamily);
-        defaultFontDescription.setSpecifiedSize(DefaultFontSize);
-        defaultFontDescription.setComputedSize(DefaultFontSize);
-
-        newStyle->setFontDescription(WTFMove(defaultFontDescription));
</del><ins>+        fontDescription.setOneFamily(DefaultFontFamily);
+        fontDescription.setSpecifiedSize(DefaultFontSize);
+        fontDescription.setComputedSize(DefaultFontSize);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    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);
</del><ins>+    if (auto fontStyle = Style::resolveForFontRaw(*fontRaw, WTFMove(fontDescription), document))
+        modifiableState().font.initialize(document.fontSelector(), *fontStyle);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static CanvasTextAlign toCanvasTextAlign(TextAlign textAlign)
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleBuilderCustomh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleBuilderCustom.h (269956 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include "CSSFontValue.h"
</span><span class="cx"> #include "CSSGradientValue.h"
</span><span class="cx"> #include "CSSGridTemplateAreasValue.h"
</span><ins>+#include "CSSPropertyParserHelpers.h"
</ins><span class="cx"> #include "CSSRegisteredCustomProperty.h"
</span><span class="cx"> #include "CSSShadowValue.h"
</span><span class="cx"> #include "Counter.h"
</span><span class="lines">@@ -1012,40 +1013,11 @@
</span><span class="cx">             // If the family name was resolved by the CSS parser from a system font ID, then it is generic.
</span><span class="cx">             isGenericFamily = fontFamily.fromSystemFontID;
</span><span class="cx">         } else {
</span><del>-            switch (contentValue.valueID()) {
-            case CSSValueWebkitBody:
</del><ins>+            if (contentValue.valueID() == CSSValueWebkitBody)
</ins><span class="cx">                 family = builderState.document().settings().standardFontFamily();
</span><del>-                break;
-            case CSSValueSerif:
-                family = serifFamily;
</del><ins>+            else {
</ins><span class="cx">                 isGenericFamily = true;
</span><del>-                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;
</del><ins>+                family = CSSPropertyParserHelpers::genericFontFamilyFromValueID(contentValue.valueID());
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveForFontRawcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/style/StyleResolveForFontRaw.cpp (0 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveForFontRaw.cpp                            (rev 0)
+++ trunk/Source/WebCore/style/StyleResolveForFontRaw.cpp       2020-11-18 16:03:50 UTC (rev 269957)
</span><span class="lines">@@ -0,0 +1,238 @@
</span><ins>+/*
+ * 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;
+}
+
+}
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveForFontRawh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/style/StyleResolveForFontRaw.h (0 => 269957)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveForFontRaw.h                              (rev 0)
+++ trunk/Source/WebCore/style/StyleResolveForFontRaw.h 2020-11-18 16:03:50 UTC (rev 269957)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+/*
+ * 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&);
+
+}
+}
</ins></span></pre>
</div>
</div>

</body>
</html>