Title: [213528] trunk
Revision
213528
Author
mmaxfi...@apple.com
Date
2017-03-07 11:26:21 -0800 (Tue, 07 Mar 2017)

Log Message

Parsing font descriptors inside @font-face needs to accept ranges
https://bugs.webkit.org/show_bug.cgi?id=168893

Reviewed by Dean Jackson.

Source/WebCore:

Parse font-weight, font-stretch, and font-style ranges according to
https://drafts.csswg.org/css-fonts-4/#font-prop-desc. There is one difference, though:
as documented in https://github.com/w3c/csswg-drafts/issues/783, slashes are a better
delimiters than hyphens, so this patch implements that instead. I'll update the spec to
include slashes as soon as possible.

Because this patch is all about creating FontSelectionValues from fonts, it doesn't
actually modify the font selection algorithm, and therefore only tests the creation of
these new values. The font selection algorithm itself is already tested elsewhere.

This new work is behind the ENABLE(VARIATION_FONTS) flag.

Test: fast/text/font-selection-font-face-parse.html

* css/CSSFontFace.cpp:
(WebCore::calculateWeightRange):
(WebCore::calculateStretchRange):
(WebCore::calculateItalicRange):
* css/parser/CSSPropertyParser.cpp:
(WebCore::consumeFontWeightRange):
(WebCore::consumeFontStretchRange):
(WebCore::consumeFontStyleRange):
(WebCore::CSSPropertyParser::parseFontFaceDescriptor):
* platform/graphics/cocoa/FontCacheCoreText.cpp:
(WebCore::extractVariationBounds):
(WebCore::variationCapabilitiesForFontDescriptor):
(WebCore::capabilitiesForFontDescriptor):

LayoutTests:

* fast/text/font-selection-font-face-parse-expected.txt:
* fast/text/font-selection-font-face-parse.html:
* platform/mac-elcapitan/fast/text/font-selection-font-face-parse-expected.txt:
Variations are off on El Capitan, so this platform needs explicit results.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (213527 => 213528)


--- trunk/LayoutTests/ChangeLog	2017-03-07 19:21:02 UTC (rev 213527)
+++ trunk/LayoutTests/ChangeLog	2017-03-07 19:26:21 UTC (rev 213528)
@@ -1,3 +1,15 @@
+2017-03-07  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Parsing font descriptors inside @font-face needs to accept ranges
+        https://bugs.webkit.org/show_bug.cgi?id=168893
+
+        Reviewed by Dean Jackson.
+
+        * fast/text/font-selection-font-face-parse-expected.txt:
+        * fast/text/font-selection-font-face-parse.html:
+        * platform/mac-elcapitan/fast/text/font-selection-font-face-parse-expected.txt:
+        Variations are off on El Capitan, so this platform needs explicit results.
+
 2017-03-07  Carlos Alberto Lopez Perez  <clo...@igalia.com>
 
         Move webrtc/descriptionGetters.html to webrtc/libwebrtc/descriptionGetters.html

Modified: trunk/LayoutTests/fast/text/font-selection-font-face-parse-expected.txt (213527 => 213528)


--- trunk/LayoutTests/fast/text/font-selection-font-face-parse-expected.txt	2017-03-07 19:21:02 UTC (rev 213527)
+++ trunk/LayoutTests/fast/text/font-selection-font-face-parse-expected.txt	2017-03-07 19:26:21 UTC (rev 213528)
@@ -16,6 +16,19 @@
 PASS weightTestSheet.cssRules[15].style.fontWeight is "7"
 PASS weightTestSheet.cssRules[16].style.fontWeight is "300"
 PASS weightTestSheet.cssRules[17].style.fontWeight is "200"
+PASS weightTestSheet.cssRules[18].style.fontWeight is "100 / 200"
+PASS weightTestSheet.cssRules[19].style.fontWeight is "100 / 200"
+PASS weightTestSheet.cssRules[20].style.fontWeight is ""
+PASS weightTestSheet.cssRules[21].style.fontWeight is ""
+PASS weightTestSheet.cssRules[22].style.fontWeight is ""
+PASS weightTestSheet.cssRules[23].style.fontWeight is ""
+PASS weightTestSheet.cssRules[24].style.fontWeight is ""
+PASS weightTestSheet.cssRules[25].style.fontWeight is ""
+PASS weightTestSheet.cssRules[26].style.fontWeight is "1 / 2"
+PASS weightTestSheet.cssRules[27].style.fontWeight is "-2 / -1"
+PASS weightTestSheet.cssRules[28].style.fontWeight is ""
+PASS weightTestSheet.cssRules[29].style.fontWeight is "7 / 8"
+PASS weightTestSheet.cssRules[30].style.fontWeight is "2 / 7"
 PASS stretchTestSheet.cssRules[0].style.fontStretch is "1%"
 PASS stretchTestSheet.cssRules[1].style.fontStretch is "2"
 PASS stretchTestSheet.cssRules[2].style.fontStretch is "ultra-condensed"
@@ -30,6 +43,32 @@
 PASS stretchTestSheet.cssRules[11].style.fontStretch is ""
 PASS stretchTestSheet.cssRules[12].style.fontStretch is ""
 PASS stretchTestSheet.cssRules[13].style.fontStretch is "7"
+PASS stretchTestSheet.cssRules[14].style.fontStretch is "100 / 200"
+PASS stretchTestSheet.cssRules[15].style.fontStretch is "100 / 200"
+PASS stretchTestSheet.cssRules[16].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[17].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[18].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[19].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[20].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[21].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[22].style.fontStretch is "1 / 2"
+PASS stretchTestSheet.cssRules[23].style.fontStretch is "-2 / -1"
+PASS stretchTestSheet.cssRules[24].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[25].style.fontStretch is "100% / 200%"
+PASS stretchTestSheet.cssRules[26].style.fontStretch is "100% / 200%"
+PASS stretchTestSheet.cssRules[27].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[28].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[29].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[30].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[31].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[32].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[33].style.fontStretch is "1% / 2%"
+PASS stretchTestSheet.cssRules[34].style.fontStretch is "-2% / -1%"
+PASS stretchTestSheet.cssRules[35].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[36].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[37].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[38].style.fontStretch is "7 / 8"
+PASS stretchTestSheet.cssRules[39].style.fontStretch is "2 / 7"
 PASS styleTestSheet.cssRules[0].style.fontStyle is "1deg"
 PASS styleTestSheet.cssRules[1].style.fontStyle is "200grad"
 PASS styleTestSheet.cssRules[2].style.fontStyle is "6.28318rad"
@@ -43,6 +82,33 @@
 PASS styleTestSheet.cssRules[10].style.fontStyle is ""
 PASS styleTestSheet.cssRules[11].style.fontStyle is "7"
 PASS styleTestSheet.cssRules[12].style.fontStyle is "calc(1441deg)"
+PASS styleTestSheet.cssRules[13].style.fontStyle is "100 / 200"
+PASS styleTestSheet.cssRules[14].style.fontStyle is "100 / 200"
+PASS styleTestSheet.cssRules[15].style.fontStyle is ""
+PASS styleTestSheet.cssRules[16].style.fontStyle is ""
+PASS styleTestSheet.cssRules[17].style.fontStyle is ""
+PASS styleTestSheet.cssRules[18].style.fontStyle is ""
+PASS styleTestSheet.cssRules[19].style.fontStyle is ""
+PASS styleTestSheet.cssRules[20].style.fontStyle is ""
+PASS styleTestSheet.cssRules[21].style.fontStyle is "1 / 2"
+PASS styleTestSheet.cssRules[22].style.fontStyle is "-2 / -1"
+PASS styleTestSheet.cssRules[23].style.fontStyle is ""
+PASS styleTestSheet.cssRules[24].style.fontStyle is "100deg / 200deg"
+PASS styleTestSheet.cssRules[25].style.fontStyle is "100deg / 200deg"
+PASS styleTestSheet.cssRules[26].style.fontStyle is ""
+PASS styleTestSheet.cssRules[27].style.fontStyle is ""
+PASS styleTestSheet.cssRules[28].style.fontStyle is ""
+PASS styleTestSheet.cssRules[29].style.fontStyle is ""
+PASS styleTestSheet.cssRules[30].style.fontStyle is ""
+PASS styleTestSheet.cssRules[31].style.fontStyle is ""
+PASS styleTestSheet.cssRules[32].style.fontStyle is "1deg / 2deg"
+PASS styleTestSheet.cssRules[33].style.fontStyle is "-2deg / -1deg"
+PASS styleTestSheet.cssRules[34].style.fontStyle is ""
+PASS styleTestSheet.cssRules[35].style.fontStyle is ""
+PASS styleTestSheet.cssRules[36].style.fontStyle is ""
+PASS styleTestSheet.cssRules[37].style.fontStyle is "2deg / 1turn"
+PASS styleTestSheet.cssRules[38].style.fontStyle is "7 / 8"
+PASS styleTestSheet.cssRules[39].style.fontStyle is "2 / 7"
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/text/font-selection-font-face-parse.html (213527 => 213528)


--- trunk/LayoutTests/fast/text/font-selection-font-face-parse.html	2017-03-07 19:21:02 UTC (rev 213527)
+++ trunk/LayoutTests/fast/text/font-selection-font-face-parse.html	2017-03-07 19:26:21 UTC (rev 213528)
@@ -56,6 +56,45 @@
 @font-face {
     font-weight: calc(150 + 50);
 }
+@font-face {
+    font-weight: 100/200;
+}
+@font-face {
+    font-weight: 100 / 200;
+}
+@font-face {
+    font-weight: a 100 / 200;
+}
+@font-face {
+    font-weight: 100 / 200 a;
+}
+@font-face {
+    font-weight: 100 a / 200;
+}
+@font-face {
+    font-weight: 100 a/ 200;
+}
+@font-face {
+    font-weight: 100 /a 200;
+}
+@font-face {
+    font-weight: 100 / a200;
+}
+@font-face {
+    font-weight: 1 / 2;
+}
+@font-face {
+    font-weight: -2 / -1;
+}
+@font-face {
+    font-weight: 2 / 1;
+}
+@font-face {
+    font-weight: calc(3 + 4) / 8;
+}
+@font-face {
+    font-weight: 2 / calc(3 + 4);
+}
 </style>
 
 <style id="stretchTest">
@@ -101,6 +140,84 @@
 @font-face {
     font-stretch: calc(3 + 4);
 }
+@font-face {
+    font-stretch: 100/200;
+}
+@font-face {
+    font-stretch: 100 / 200;
+}
+@font-face {
+    font-stretch: a 100 / 200;
+}
+@font-face {
+    font-stretch: 100 / 200 a;
+}
+@font-face {
+    font-stretch: 100 a / 200;
+}
+@font-face {
+    font-stretch: 100 a/ 200;
+}
+@font-face {
+    font-stretch: 100 /a 200;
+}
+@font-face {
+    font-stretch: 100 / a200;
+}
+@font-face {
+    font-stretch: 1 / 2;
+}
+@font-face {
+    font-stretch: -2 / -1;
+}
+@font-face {
+    font-stretch: 2 / 1;
+}
+@font-face {
+    font-stretch: 100%/200%;
+}
+@font-face {
+    font-stretch: 100% / 200%;
+}
+@font-face {
+    font-stretch: a 100% / 200%;
+}
+@font-face {
+    font-stretch: 100% / 200% a;
+}
+@font-face {
+    font-stretch: 100% a / 200%;
+}
+@font-face {
+    font-stretch: 100% a/ 200%;
+}
+@font-face {
+    font-stretch: 100% /a 200%;
+}
+@font-face {
+    font-stretch: 100% / a200%;
+}
+@font-face {
+    font-stretch: 1% / 2%;
+}
+@font-face {
+    font-stretch: -2% / -1%;
+}
+@font-face {
+    font-stretch: 2% / 1%;
+}
+@font-face {
+    font-stretch: 1 / 2%;
+}
+@font-face {
+    font-stretch: 1% / 2;
+}
+@font-face {
+    font-stretch: calc(3 + 4) / 8;
+}
+@font-face {
+    font-stretch: 2 / calc(3 + 4);
+}
 </style>
 
 <style id="styleTest">
@@ -143,6 +260,87 @@
 @font-face {
     font-style: oblique calc(4turn + 1deg);
 }
+@font-face {
+    font-style: oblique 100/200;
+}
+@font-face {
+    font-style: oblique 100 / 200;
+}
+@font-face {
+    font-style: oblique a 100 / 200;
+}
+@font-face {
+    font-style: oblique 100 / 200 a;
+}
+@font-face {
+    font-style: oblique 100 a / 200;
+}
+@font-face {
+    font-style: oblique 100 a/ 200;
+}
+@font-face {
+    font-style: oblique 100 /a 200;
+}
+@font-face {
+    font-style: oblique 100 / a200;
+}
+@font-face {
+    font-style: oblique 1 / 2;
+}
+@font-face {
+    font-style: oblique -2 / -1;
+}
+@font-face {
+    font-style: oblique 2 / 1;
+}
+@font-face {
+    font-style: oblique 100deg/200deg;
+}
+@font-face {
+    font-style: oblique 100deg / 200deg;
+}
+@font-face {
+    font-style: oblique a 100deg / 200deg;
+}
+@font-face {
+    font-style: oblique 100deg / 200deg a;
+}
+@font-face {
+    font-style: oblique 100deg a / 200deg;
+}
+@font-face {
+    font-style: oblique 100deg a/ 200deg;
+}
+@font-face {
+    font-style: oblique 100deg /a 200deg;
+}
+@font-face {
+    font-style: oblique 100deg / a200deg;
+}
+@font-face {
+    font-style: oblique 1deg / 2deg;
+}
+@font-face {
+    font-style: oblique -2deg / -1deg;
+}
+@font-face {
+    font-style: oblique 2deg / 1deg;
+}
+@font-face {
+    font-style: oblique 1 / 2deg;
+}
+@font-face {
+    font-style: oblique 1deg / 2;
+}
+@font-face {
+    font-style: oblique 2deg / 1turn;
+}
+@font-face {
+    font-style: oblique calc(3 + 4) / 8;
+}
+@font-face {
+    font-style: oblique 2 / calc(3 + 4);
+}
 </style>
 </head>
 <body>
@@ -166,6 +364,19 @@
 shouldBeEqualToString("weightTestSheet.cssRules[15].style.fontWeight", "7");
 shouldBeEqualToString("weightTestSheet.cssRules[16].style.fontWeight", "300");
 shouldBeEqualToString("weightTestSheet.cssRules[17].style.fontWeight", "200");
+shouldBeEqualToString("weightTestSheet.cssRules[18].style.fontWeight", "100 / 200");
+shouldBeEqualToString("weightTestSheet.cssRules[19].style.fontWeight", "100 / 200");
+shouldBeEqualToString("weightTestSheet.cssRules[20].style.fontWeight", "");
+shouldBeEqualToString("weightTestSheet.cssRules[21].style.fontWeight", "");
+shouldBeEqualToString("weightTestSheet.cssRules[22].style.fontWeight", "");
+shouldBeEqualToString("weightTestSheet.cssRules[23].style.fontWeight", "");
+shouldBeEqualToString("weightTestSheet.cssRules[24].style.fontWeight", "");
+shouldBeEqualToString("weightTestSheet.cssRules[25].style.fontWeight", "");
+shouldBeEqualToString("weightTestSheet.cssRules[26].style.fontWeight", "1 / 2");
+shouldBeEqualToString("weightTestSheet.cssRules[27].style.fontWeight", "-2 / -1");
+shouldBeEqualToString("weightTestSheet.cssRules[28].style.fontWeight", "");
+shouldBeEqualToString("weightTestSheet.cssRules[29].style.fontWeight", "7 / 8");
+shouldBeEqualToString("weightTestSheet.cssRules[30].style.fontWeight", "2 / 7");
 
 var stretchTestSheet = document.getElementById("stretchTest").sheet;
 shouldBeEqualToString("stretchTestSheet.cssRules[0].style.fontStretch", "1%");
@@ -182,6 +393,32 @@
 shouldBeEqualToString("stretchTestSheet.cssRules[11].style.fontStretch", "");
 shouldBeEqualToString("stretchTestSheet.cssRules[12].style.fontStretch", "");
 shouldBeEqualToString("stretchTestSheet.cssRules[13].style.fontStretch", "7");
+shouldBeEqualToString("stretchTestSheet.cssRules[14].style.fontStretch", "100 / 200");
+shouldBeEqualToString("stretchTestSheet.cssRules[15].style.fontStretch", "100 / 200");
+shouldBeEqualToString("stretchTestSheet.cssRules[16].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[17].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[18].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[19].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[20].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[21].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[22].style.fontStretch", "1 / 2");
+shouldBeEqualToString("stretchTestSheet.cssRules[23].style.fontStretch", "-2 / -1");
+shouldBeEqualToString("stretchTestSheet.cssRules[24].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[25].style.fontStretch", "100% / 200%");
+shouldBeEqualToString("stretchTestSheet.cssRules[26].style.fontStretch", "100% / 200%");
+shouldBeEqualToString("stretchTestSheet.cssRules[27].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[28].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[29].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[30].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[31].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[32].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[33].style.fontStretch", "1% / 2%");
+shouldBeEqualToString("stretchTestSheet.cssRules[34].style.fontStretch", "-2% / -1%");
+shouldBeEqualToString("stretchTestSheet.cssRules[35].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[36].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[37].style.fontStretch", "");
+shouldBeEqualToString("stretchTestSheet.cssRules[38].style.fontStretch", "7 / 8");
+shouldBeEqualToString("stretchTestSheet.cssRules[39].style.fontStretch", "2 / 7");
 
 var styleTestSheet = document.getElementById("styleTest").sheet;
 shouldBeEqualToString("styleTestSheet.cssRules[0].style.fontStyle", "1deg");
@@ -197,6 +434,34 @@
 shouldBeEqualToString("styleTestSheet.cssRules[10].style.fontStyle", "");
 shouldBeEqualToString("styleTestSheet.cssRules[11].style.fontStyle", "7");
 shouldBeEqualToString("styleTestSheet.cssRules[12].style.fontStyle", "calc(1441deg)");
+
+shouldBeEqualToString("styleTestSheet.cssRules[13].style.fontStyle", "100 / 200");
+shouldBeEqualToString("styleTestSheet.cssRules[14].style.fontStyle", "100 / 200");
+shouldBeEqualToString("styleTestSheet.cssRules[15].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[16].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[17].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[18].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[19].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[20].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[21].style.fontStyle", "1 / 2");
+shouldBeEqualToString("styleTestSheet.cssRules[22].style.fontStyle", "-2 / -1");
+shouldBeEqualToString("styleTestSheet.cssRules[23].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[24].style.fontStyle", "100deg / 200deg");
+shouldBeEqualToString("styleTestSheet.cssRules[25].style.fontStyle", "100deg / 200deg");
+shouldBeEqualToString("styleTestSheet.cssRules[26].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[27].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[28].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[29].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[30].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[31].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[32].style.fontStyle", "1deg / 2deg");
+shouldBeEqualToString("styleTestSheet.cssRules[33].style.fontStyle", "-2deg / -1deg");
+shouldBeEqualToString("styleTestSheet.cssRules[34].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[35].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[36].style.fontStyle", "");
+shouldBeEqualToString("styleTestSheet.cssRules[37].style.fontStyle", "2deg / 1turn");
+shouldBeEqualToString("styleTestSheet.cssRules[38].style.fontStyle", "7 / 8");
+shouldBeEqualToString("styleTestSheet.cssRules[39].style.fontStyle", "2 / 7");
 </script>
 <script src=""
 </body>

Added: trunk/LayoutTests/platform/mac-elcapitan/fast/text/font-selection-font-face-parse-expected.txt (0 => 213528)


--- trunk/LayoutTests/platform/mac-elcapitan/fast/text/font-selection-font-face-parse-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-elcapitan/fast/text/font-selection-font-face-parse-expected.txt	2017-03-07 19:26:21 UTC (rev 213528)
@@ -0,0 +1,115 @@
+PASS weightTestSheet.cssRules[0].style.fontWeight is "1"
+PASS weightTestSheet.cssRules[1].style.fontWeight is "100"
+PASS weightTestSheet.cssRules[2].style.fontWeight is "200"
+PASS weightTestSheet.cssRules[3].style.fontWeight is "300"
+PASS weightTestSheet.cssRules[4].style.fontWeight is "400"
+PASS weightTestSheet.cssRules[5].style.fontWeight is "normal"
+PASS weightTestSheet.cssRules[6].style.fontWeight is "500"
+PASS weightTestSheet.cssRules[7].style.fontWeight is "600"
+PASS weightTestSheet.cssRules[8].style.fontWeight is "700"
+PASS weightTestSheet.cssRules[9].style.fontWeight is "bold"
+PASS weightTestSheet.cssRules[10].style.fontWeight is "800"
+PASS weightTestSheet.cssRules[11].style.fontWeight is "900"
+PASS weightTestSheet.cssRules[12].style.fontWeight is ""
+PASS weightTestSheet.cssRules[13].style.fontWeight is ""
+PASS weightTestSheet.cssRules[14].style.fontWeight is ""
+PASS weightTestSheet.cssRules[15].style.fontWeight is "7"
+PASS weightTestSheet.cssRules[16].style.fontWeight is "300"
+PASS weightTestSheet.cssRules[17].style.fontWeight is "200"
+FAIL weightTestSheet.cssRules[18].style.fontWeight should be 100 / 200. Was .
+FAIL weightTestSheet.cssRules[19].style.fontWeight should be 100 / 200. Was .
+PASS weightTestSheet.cssRules[20].style.fontWeight is ""
+PASS weightTestSheet.cssRules[21].style.fontWeight is ""
+PASS weightTestSheet.cssRules[22].style.fontWeight is ""
+PASS weightTestSheet.cssRules[23].style.fontWeight is ""
+PASS weightTestSheet.cssRules[24].style.fontWeight is ""
+PASS weightTestSheet.cssRules[25].style.fontWeight is ""
+FAIL weightTestSheet.cssRules[26].style.fontWeight should be 1 / 2. Was .
+FAIL weightTestSheet.cssRules[27].style.fontWeight should be -2 / -1. Was .
+PASS weightTestSheet.cssRules[28].style.fontWeight is ""
+FAIL weightTestSheet.cssRules[29].style.fontWeight should be 7 / 8. Was .
+FAIL weightTestSheet.cssRules[30].style.fontWeight should be 2 / 7. Was .
+PASS stretchTestSheet.cssRules[0].style.fontStretch is "1%"
+PASS stretchTestSheet.cssRules[1].style.fontStretch is "2"
+PASS stretchTestSheet.cssRules[2].style.fontStretch is "ultra-condensed"
+PASS stretchTestSheet.cssRules[3].style.fontStretch is "extra-condensed"
+PASS stretchTestSheet.cssRules[4].style.fontStretch is "condensed"
+PASS stretchTestSheet.cssRules[5].style.fontStretch is "semi-condensed"
+PASS stretchTestSheet.cssRules[6].style.fontStretch is "normal"
+PASS stretchTestSheet.cssRules[7].style.fontStretch is "semi-expanded"
+PASS stretchTestSheet.cssRules[8].style.fontStretch is "expanded"
+PASS stretchTestSheet.cssRules[9].style.fontStretch is "extra-expanded"
+PASS stretchTestSheet.cssRules[10].style.fontStretch is "ultra-expanded"
+PASS stretchTestSheet.cssRules[11].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[12].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[13].style.fontStretch is "7"
+FAIL stretchTestSheet.cssRules[14].style.fontStretch should be 100 / 200. Was .
+FAIL stretchTestSheet.cssRules[15].style.fontStretch should be 100 / 200. Was .
+PASS stretchTestSheet.cssRules[16].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[17].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[18].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[19].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[20].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[21].style.fontStretch is ""
+FAIL stretchTestSheet.cssRules[22].style.fontStretch should be 1 / 2. Was .
+FAIL stretchTestSheet.cssRules[23].style.fontStretch should be -2 / -1. Was .
+PASS stretchTestSheet.cssRules[24].style.fontStretch is ""
+FAIL stretchTestSheet.cssRules[25].style.fontStretch should be 100% / 200%. Was .
+FAIL stretchTestSheet.cssRules[26].style.fontStretch should be 100% / 200%. Was .
+PASS stretchTestSheet.cssRules[27].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[28].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[29].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[30].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[31].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[32].style.fontStretch is ""
+FAIL stretchTestSheet.cssRules[33].style.fontStretch should be 1% / 2%. Was .
+FAIL stretchTestSheet.cssRules[34].style.fontStretch should be -2% / -1%. Was .
+PASS stretchTestSheet.cssRules[35].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[36].style.fontStretch is ""
+PASS stretchTestSheet.cssRules[37].style.fontStretch is ""
+FAIL stretchTestSheet.cssRules[38].style.fontStretch should be 7 / 8. Was .
+FAIL stretchTestSheet.cssRules[39].style.fontStretch should be 2 / 7. Was .
+PASS styleTestSheet.cssRules[0].style.fontStyle is "1deg"
+PASS styleTestSheet.cssRules[1].style.fontStyle is "200grad"
+PASS styleTestSheet.cssRules[2].style.fontStyle is "6.28318rad"
+PASS styleTestSheet.cssRules[3].style.fontStyle is "4turn"
+PASS styleTestSheet.cssRules[4].style.fontStyle is "5"
+PASS styleTestSheet.cssRules[5].style.fontStyle is "20"
+PASS styleTestSheet.cssRules[6].style.fontStyle is "italic"
+PASS styleTestSheet.cssRules[7].style.fontStyle is "oblique"
+PASS styleTestSheet.cssRules[8].style.fontStyle is "normal"
+PASS styleTestSheet.cssRules[9].style.fontStyle is ""
+PASS styleTestSheet.cssRules[10].style.fontStyle is ""
+PASS styleTestSheet.cssRules[11].style.fontStyle is "7"
+PASS styleTestSheet.cssRules[12].style.fontStyle is "calc(1441deg)"
+FAIL styleTestSheet.cssRules[13].style.fontStyle should be 100 / 200. Was .
+FAIL styleTestSheet.cssRules[14].style.fontStyle should be 100 / 200. Was .
+PASS styleTestSheet.cssRules[15].style.fontStyle is ""
+PASS styleTestSheet.cssRules[16].style.fontStyle is ""
+PASS styleTestSheet.cssRules[17].style.fontStyle is ""
+PASS styleTestSheet.cssRules[18].style.fontStyle is ""
+PASS styleTestSheet.cssRules[19].style.fontStyle is ""
+PASS styleTestSheet.cssRules[20].style.fontStyle is ""
+FAIL styleTestSheet.cssRules[21].style.fontStyle should be 1 / 2. Was .
+FAIL styleTestSheet.cssRules[22].style.fontStyle should be -2 / -1. Was .
+PASS styleTestSheet.cssRules[23].style.fontStyle is ""
+FAIL styleTestSheet.cssRules[24].style.fontStyle should be 100deg / 200deg. Was .
+FAIL styleTestSheet.cssRules[25].style.fontStyle should be 100deg / 200deg. Was .
+PASS styleTestSheet.cssRules[26].style.fontStyle is ""
+PASS styleTestSheet.cssRules[27].style.fontStyle is ""
+PASS styleTestSheet.cssRules[28].style.fontStyle is ""
+PASS styleTestSheet.cssRules[29].style.fontStyle is ""
+PASS styleTestSheet.cssRules[30].style.fontStyle is ""
+PASS styleTestSheet.cssRules[31].style.fontStyle is ""
+FAIL styleTestSheet.cssRules[32].style.fontStyle should be 1deg / 2deg. Was .
+FAIL styleTestSheet.cssRules[33].style.fontStyle should be -2deg / -1deg. Was .
+PASS styleTestSheet.cssRules[34].style.fontStyle is ""
+PASS styleTestSheet.cssRules[35].style.fontStyle is ""
+PASS styleTestSheet.cssRules[36].style.fontStyle is ""
+FAIL styleTestSheet.cssRules[37].style.fontStyle should be 2deg / 1turn. Was .
+FAIL styleTestSheet.cssRules[38].style.fontStyle should be 7 / 8. Was .
+FAIL styleTestSheet.cssRules[39].style.fontStyle should be 2 / 7. Was .
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/platform/mac-elcapitan/fast/text/font-selection-font-face-parse-expected.txt
___________________________________________________________________

Added: svn:eol-style

+native \ No newline at end of property

Added: svn:keywords

+Author Date Id Rev URL \ No newline at end of property

Modified: trunk/Source/WebCore/ChangeLog (213527 => 213528)


--- trunk/Source/WebCore/ChangeLog	2017-03-07 19:21:02 UTC (rev 213527)
+++ trunk/Source/WebCore/ChangeLog	2017-03-07 19:26:21 UTC (rev 213528)
@@ -1,3 +1,38 @@
+2017-03-07  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Parsing font descriptors inside @font-face needs to accept ranges
+        https://bugs.webkit.org/show_bug.cgi?id=168893
+
+        Reviewed by Dean Jackson.
+
+        Parse font-weight, font-stretch, and font-style ranges according to
+        https://drafts.csswg.org/css-fonts-4/#font-prop-desc. There is one difference, though:
+        as documented in https://github.com/w3c/csswg-drafts/issues/783, slashes are a better
+        delimiters than hyphens, so this patch implements that instead. I'll update the spec to
+        include slashes as soon as possible.
+
+        Because this patch is all about creating FontSelectionValues from fonts, it doesn't
+        actually modify the font selection algorithm, and therefore only tests the creation of
+        these new values. The font selection algorithm itself is already tested elsewhere.
+
+        This new work is behind the ENABLE(VARIATION_FONTS) flag.
+
+        Test: fast/text/font-selection-font-face-parse.html
+
+        * css/CSSFontFace.cpp:
+        (WebCore::calculateWeightRange):
+        (WebCore::calculateStretchRange):
+        (WebCore::calculateItalicRange):
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::consumeFontWeightRange):
+        (WebCore::consumeFontStretchRange):
+        (WebCore::consumeFontStyleRange):
+        (WebCore::CSSPropertyParser::parseFontFaceDescriptor):
+        * platform/graphics/cocoa/FontCacheCoreText.cpp:
+        (WebCore::extractVariationBounds):
+        (WebCore::variationCapabilitiesForFontDescriptor):
+        (WebCore::capabilitiesForFontDescriptor):
+
 2017-03-07  Dave Hyatt  <hy...@apple.com>
 
         Animated GIFs fail to play in multi-column layout

Modified: trunk/Source/WebCore/css/CSSFontFace.cpp (213527 => 213528)


--- trunk/Source/WebCore/css/CSSFontFace.cpp	2017-03-07 19:21:02 UTC (rev 213527)
+++ trunk/Source/WebCore/css/CSSFontFace.cpp	2017-03-07 19:26:21 UTC (rev 213528)
@@ -126,7 +126,20 @@
 
 static FontSelectionRange calculateWeightRange(CSSValue& value)
 {
-    // FIXME: Parse range-based values.
+    if (value.isValueList()) {
+        auto& valueList = downcast<CSSValueList>(value);
+        ASSERT(valueList.length() == 2);
+        if (valueList.length() != 2)
+            return { normalWeightValue(), normalWeightValue() };
+        ASSERT(valueList.item(0)->isPrimitiveValue());
+        ASSERT(valueList.item(1)->isPrimitiveValue());
+        auto& value0 = downcast<CSSPrimitiveValue>(*valueList.item(0));
+        auto& value1 = downcast<CSSPrimitiveValue>(*valueList.item(1));
+        ASSERT(value0.isNumber());
+        ASSERT(value1.isNumber());
+        return { FontSelectionValue::clampFloat(value0.floatValue()), FontSelectionValue::clampFloat(value1.floatValue()) };
+    }
+
     ASSERT(is<CSSPrimitiveValue>(value));
     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
 
@@ -162,7 +175,20 @@
 
 static FontSelectionRange calculateStretchRange(CSSValue& value)
 {
-    // FIXME: Parse range-based values.
+    if (value.isValueList()) {
+        auto& valueList = downcast<CSSValueList>(value);
+        ASSERT(valueList.length() == 2);
+        if (valueList.length() != 2)
+            return { normalStretchValue(), normalStretchValue() };
+        ASSERT(valueList.item(0)->isPrimitiveValue());
+        ASSERT(valueList.item(1)->isPrimitiveValue());
+        auto& value0 = downcast<CSSPrimitiveValue>(*valueList.item(0));
+        auto& value1 = downcast<CSSPrimitiveValue>(*valueList.item(1));
+        ASSERT(value0.isPercentage() || value0.isNumber());
+        ASSERT(value1.isPercentage() || value1.isNumber());
+        return { FontSelectionValue::clampFloat(value0.floatValue()), FontSelectionValue::clampFloat(value1.floatValue()) };
+    }
+
     ASSERT(is<CSSPrimitiveValue>(value));
     const auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
 
@@ -198,7 +224,20 @@
 
 static FontSelectionRange calculateItalicRange(CSSValue& value)
 {
-    // FIXME: Parse range-based values.
+    if (value.isValueList()) {
+        auto& valueList = downcast<CSSValueList>(value);
+        ASSERT(valueList.length() == 2);
+        if (valueList.length() != 2)
+            return { normalItalicValue(), normalItalicValue() };
+        ASSERT(valueList.item(0)->isPrimitiveValue());
+        ASSERT(valueList.item(1)->isPrimitiveValue());
+        auto& value0 = downcast<CSSPrimitiveValue>(*valueList.item(0));
+        auto& value1 = downcast<CSSPrimitiveValue>(*valueList.item(1));
+        ASSERT(value0.isAngle() || value0.isNumber() || value0.isCalculated());
+        ASSERT(value1.isAngle() || value1.isNumber() || value1.isCalculated());
+        return { FontSelectionValue::clampFloat(value0.floatValue(CSSPrimitiveValue::CSS_DEG)), FontSelectionValue::clampFloat(value1.floatValue(CSSPrimitiveValue::CSS_DEG)) };
+    }
+
     ASSERT(is<CSSPrimitiveValue>(value));
     const auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
 

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (213527 => 213528)


--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2017-03-07 19:21:02 UTC (rev 213527)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2017-03-07 19:26:21 UTC (rev 213528)
@@ -888,6 +888,30 @@
     return consumeNumber(range, ValueRangeAll);
 }
 
+#if ENABLE(VARIATION_FONTS)
+static RefPtr<CSSValue> consumeFontWeightRange(CSSParserTokenRange& range)
+{
+    if (auto result = consumeFontWeightKeywordValue(range))
+        return result;
+    auto firstNumber = consumeNumber(range, ValueRangeAll);
+    if (!firstNumber)
+        return nullptr;
+    if (range.atEnd())
+        return firstNumber;
+    if (!consumeSlashIncludingWhitespace(range))
+        return nullptr;
+    auto secondNumber = consumeNumber(range, ValueRangeAll);
+    if (!secondNumber)
+        return nullptr;
+    if (firstNumber->floatValue() > secondNumber->floatValue())
+        return nullptr;
+    auto result = CSSValueList::createSlashSeparated();
+    result->append(firstNumber.releaseNonNull());
+    result->append(secondNumber.releaseNonNull());
+    return RefPtr<CSSValue>(WTFMove(result));
+}
+#endif
+
 static RefPtr<CSSPrimitiveValue> consumeFontStretchKeywordValue(CSSParserTokenRange& range)
 {
     return consumeIdent<CSSValueUltraCondensed, CSSValueExtraCondensed, CSSValueCondensed, CSSValueSemiCondensed, CSSValueNormal, CSSValueSemiExpanded, CSSValueExpanded, CSSValueExtraExpanded, CSSValueUltraExpanded>(range);
@@ -902,6 +926,47 @@
     return consumeNumber(range, ValueRangeAll);
 }
 
+#if ENABLE(VARIATION_FONTS)
+static RefPtr<CSSValue> consumeFontStretchRange(CSSParserTokenRange& range)
+{
+    if (auto result = consumeFontStretchKeywordValue(range))
+        return result;
+    if (auto firstPercent = consumePercent(range, ValueRangeAll)) {
+        if (range.atEnd())
+            return firstPercent;
+        if (!consumeSlashIncludingWhitespace(range))
+            return nullptr;
+        auto secondPercent = consumePercent(range, ValueRangeAll);
+        if (!secondPercent)
+            return nullptr;
+        if (firstPercent->floatValue() > secondPercent->floatValue())
+            return nullptr;
+        auto result = CSSValueList::createSlashSeparated();
+        result->append(firstPercent.releaseNonNull());
+        result->append(secondPercent.releaseNonNull());
+        return RefPtr<CSSValue>(WTFMove(result));
+    }
+
+    if (auto firstNumber = consumeNumber(range, ValueRangeAll)) {
+        if (range.atEnd())
+            return firstNumber;
+        if (!consumeSlashIncludingWhitespace(range))
+            return nullptr;
+        auto secondNumber = consumeNumber(range, ValueRangeAll);
+        if (!secondNumber)
+            return nullptr;
+        if (firstNumber->floatValue() > secondNumber->floatValue())
+            return nullptr;
+        auto result = CSSValueList::createSlashSeparated();
+        result->append(firstNumber.releaseNonNull());
+        result->append(secondNumber.releaseNonNull());
+        return RefPtr<CSSValue>(WTFMove(result));
+    }
+
+    return nullptr;
+}
+#endif
+
 static RefPtr<CSSPrimitiveValue> consumeFontStyleKeywordValue(CSSParserTokenRange& range)
 {
     return consumeIdent<CSSValueNormal, CSSValueItalic, CSSValueOblique>(range);
@@ -924,6 +989,54 @@
     return nullptr;
 }
 
+#if ENABLE(VARIATION_FONTS)
+static RefPtr<CSSValue> consumeFontStyleRange(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    if (auto result = consumeFontStyleKeywordValue(range)) {
+        if (result->valueID() == CSSValueOblique) {
+            if (range.atEnd())
+                return result;
+
+            if (auto firstAngle = consumeAngle(range, cssParserMode)) {
+                if (range.atEnd())
+                    return firstAngle;
+                if (!consumeSlashIncludingWhitespace(range))
+                    return nullptr;
+                auto secondAngle = consumeAngle(range, cssParserMode);
+                if (!secondAngle)
+                    return nullptr;
+                if (firstAngle->floatValue(CSSPrimitiveValue::CSS_DEG) > secondAngle->floatValue(CSSPrimitiveValue::CSS_DEG))
+                    return nullptr;
+                auto result = CSSValueList::createSlashSeparated();
+                result->append(firstAngle.releaseNonNull());
+                result->append(secondAngle.releaseNonNull());
+                return RefPtr<CSSValue>(WTFMove(result));
+            }
+
+            if (auto firstNumber = consumeNumber(range, ValueRangeAll)) {
+                if (range.atEnd())
+                    return firstNumber;
+                if (!consumeSlashIncludingWhitespace(range))
+                    return nullptr;
+                auto secondNumber = consumeNumber(range, ValueRangeAll);
+                if (!secondNumber)
+                    return nullptr;
+                if (firstNumber->floatValue() > secondNumber->floatValue())
+                    return nullptr;
+                auto result = CSSValueList::createSlashSeparated();
+                result->append(firstNumber.releaseNonNull());
+                result->append(secondNumber.releaseNonNull());
+                return RefPtr<CSSValue>(WTFMove(result));
+            }
+
+            return nullptr;
+        }
+        return result;
+    }
+    return nullptr;
+}
+#endif
+
 static String concatenateFamilyName(CSSParserTokenRange& range)
 {
     StringBuilder builder;
@@ -4220,16 +4333,25 @@
         parsedValue = consumeFontFaceUnicodeRange(m_range);
         break;
     case CSSPropertyFontWeight:
-        // FIXME: Parse range-based values.
+#if ENABLE(VARIATION_FONTS)
+        parsedValue = consumeFontWeightRange(m_range);
+#else
         parsedValue = consumeFontWeight(m_range);
+#endif
         break;
     case CSSPropertyFontStretch:
-        // FIXME: Parse range-based values.
+#if ENABLE(VARIATION_FONTS)
+        parsedValue = consumeFontStretchRange(m_range);
+#else
         parsedValue = consumeFontStretch(m_range);
+#endif
         break;
     case CSSPropertyFontStyle:
-        // FIXME: Parse range-based values.
+#if ENABLE(VARIATION_FONTS)
+        parsedValue = consumeFontStyleRange(m_range, m_context.mode);
+#else
         parsedValue = consumeFontStyle(m_range, m_context.mode);
+#endif
         break;
     case CSSPropertyFontVariantCaps:
         parsedValue = consumeFontVariantCaps(m_range);

Modified: trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp (213527 => 213528)


--- trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp	2017-03-07 19:21:02 UTC (rev 213527)
+++ trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp	2017-03-07 19:26:21 UTC (rev 213528)
@@ -828,50 +828,127 @@
     HashMap<String, InstalledFont> m_postScriptNameToFontDescriptors;
 };
 
+struct VariationCapabilities {
+    std::optional<FontSelectionRange> weight;
+    std::optional<FontSelectionRange> width;
+    std::optional<FontSelectionRange> slope;
+};
+
+#if ENABLE(VARIATION_FONTS)
+static std::optional<FontSelectionRange> extractVariationBounds(CFDictionaryRef axis)
+{
+    CFNumberRef minimumValue = static_cast<CFNumberRef>(CFDictionaryGetValue(axis, kCTFontVariationAxisMinimumValueKey));
+    CFNumberRef maximumValue = static_cast<CFNumberRef>(CFDictionaryGetValue(axis, kCTFontVariationAxisMaximumValueKey));
+    float rawMinimumValue = 0;
+    float rawMaximumValue = 0;
+    CFNumberGetValue(minimumValue, kCFNumberFloatType, &rawMinimumValue);
+    CFNumberGetValue(maximumValue, kCFNumberFloatType, &rawMaximumValue);
+    if (rawMinimumValue < rawMaximumValue)
+        return {{ FontSelectionValue(rawMinimumValue), FontSelectionValue(rawMaximumValue) }};
+    return std::nullopt;
+}
+#endif
+
+static VariationCapabilities variationCapabilitiesForFontDescriptor(CTFontDescriptorRef fontDescriptor)
+{
+    VariationCapabilities result;
+
+#if ENABLE(VARIATION_FONTS)
+    if (!adoptCF(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontVariationAttribute)))
+        return result;
+
+    auto variations = adoptCF(CTFontCopyVariationAxes(adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor, 0, nullptr)).get()));
+    if (!variations)
+        return result;
+
+    auto axisCount = CFArrayGetCount(variations.get());
+    if (!axisCount)
+        return result;
+
+    for (CFIndex i = 0; i < axisCount; ++i) {
+        CFDictionaryRef axis = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(variations.get(), i));
+        CFNumberRef axisIdentifier = static_cast<CFNumberRef>(CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey));
+        uint32_t rawAxisIdentifier = 0;
+        Boolean success = CFNumberGetValue(axisIdentifier, kCFNumberSInt32Type, &rawAxisIdentifier);
+        ASSERT_UNUSED(success, success);
+        if (rawAxisIdentifier == 0x77676874) // 'wght'
+            result.weight = extractVariationBounds(axis);
+        else if (rawAxisIdentifier == 0x77647468) // 'wdth'
+            result.width = extractVariationBounds(axis);
+        else if (rawAxisIdentifier == 0x736C6E74) // 'slnt'
+            result.slope = extractVariationBounds(axis);
+    }
+#else
+    UNUSED_PARAM(fontDescriptor);
+#endif
+
+    return result;
+}
+
 FontSelectionCapabilities capabilitiesForFontDescriptor(CTFontDescriptorRef fontDescriptor)
 {
     if (!fontDescriptor)
         return { };
 
-    auto traits = adoptCF(static_cast<CFDictionaryRef>(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontTraitsAttribute)));
-    FontSelectionValue width;
-    FontSelectionValue slant;
-    FontSelectionValue weight;
-    if (traits) {
-        width = stretchFromCoreTextTraits(traits.get());
+    VariationCapabilities variationCapabilities = variationCapabilitiesForFontDescriptor(fontDescriptor);
 
-        auto symbolicTraitsNumber = static_cast<CFNumberRef>(CFDictionaryGetValue(traits.get(), kCTFontSymbolicTrait));
-        if (symbolicTraitsNumber) {
-            int32_t symbolicTraits;
-            auto success = CFNumberGetValue(symbolicTraitsNumber, kCFNumberSInt32Type, &symbolicTraits);
-            ASSERT_UNUSED(success, success);
-            slant = symbolicTraits & kCTFontTraitItalic ? italicValue() : normalItalicValue();
-        }
+#if SHOULD_USE_CORE_TEXT_FONT_LOOKUP
+    bool weightComesFromTraits = !variationCapabilities.weight;
+#else
+    bool weightComesFromTraits = false;
+#endif
 
+    if (!variationCapabilities.slope || !variationCapabilities.width || weightComesFromTraits) {
+        auto traits = adoptCF(static_cast<CFDictionaryRef>(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontTraitsAttribute)));
+        if (traits) {
+            if (!variationCapabilities.width) {
+                auto widthValue = stretchFromCoreTextTraits(traits.get());
+                variationCapabilities.width = {{ widthValue, widthValue }};
+            }
+
+            if (!variationCapabilities.slope) {
+                auto symbolicTraitsNumber = static_cast<CFNumberRef>(CFDictionaryGetValue(traits.get(), kCTFontSymbolicTrait));
+                if (symbolicTraitsNumber) {
+                    int32_t symbolicTraits;
+                    auto success = CFNumberGetValue(symbolicTraitsNumber, kCFNumberSInt32Type, &symbolicTraits);
+                    ASSERT_UNUSED(success, success);
+                    auto slopeValue = symbolicTraits & kCTFontTraitItalic ? italicValue() : normalItalicValue();
+                    variationCapabilities.slope = {{ slopeValue, slopeValue }};
+                } else
+                    variationCapabilities.slope = {{ normalItalicValue(), normalItalicValue() }};
+            }
+
 #if SHOULD_USE_CORE_TEXT_FONT_LOOKUP
-        auto weightNumber = static_cast<CFNumberRef>(CFDictionaryGetValue(traits.get(), kCTFontWeightTrait));
-        if (weightNumber) {
-            CGFloat ctWeight;
-            auto success = CFNumberGetValue(weightNumber, kCFNumberCGFloatType, &ctWeight);
-            ASSERT_UNUSED(success, success);
-            weight = fontWeightFromCoreText(ctWeight);
+            if (!variationCapabilities.weight) {
+                auto weightNumber = static_cast<CFNumberRef>(CFDictionaryGetValue(traits.get(), kCTFontWeightTrait));
+                if (weightNumber) {
+                    CGFloat ctWeight;
+                    auto success = CFNumberGetValue(weightNumber, kCFNumberCGFloatType, &ctWeight);
+                    ASSERT_UNUSED(success, success);
+                    auto weightValue = fontWeightFromCoreText(ctWeight);
+                    variationCapabilities.weight = {{ weightValue, weightValue }};
+                } else
+                    variationCapabilities.weight = {{ normalWeightValue(), normalWeightValue() }};
+            }
+#endif
         }
-#endif
     }
 
 #if !SHOULD_USE_CORE_TEXT_FONT_LOOKUP
-    auto weightNumber = adoptCF(static_cast<CFNumberRef>(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontCSSWeightAttribute)));
-    if (weightNumber) {
-        float cssWeight;
-        auto success = CFNumberGetValue(weightNumber.get(), kCFNumberFloatType, &cssWeight);
-        ASSERT_UNUSED(success, success);
-        weight = FontSelectionValue(cssWeight);
+    if (!variationCapabilities.weight) {
+        auto weightNumber = adoptCF(static_cast<CFNumberRef>(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontCSSWeightAttribute)));
+        if (weightNumber) {
+            float cssWeight;
+            auto success = CFNumberGetValue(weightNumber.get(), kCFNumberFloatType, &cssWeight);
+            ASSERT_UNUSED(success, success);
+            auto weightValue = FontSelectionValue(cssWeight);
+            variationCapabilities.weight = {{ weightValue, weightValue }};
+        } else
+            variationCapabilities.weight = {{ normalWeightValue(), normalWeightValue() }};
     }
 #endif
 
-    // FIXME: Educate this function about font variations.
-
-    return { { weight, weight }, { width, width }, { slant, slant } };
+    return { variationCapabilities.weight.value(), variationCapabilities.width.value(), variationCapabilities.slope.value() };
 }
 
 #if !SHOULD_USE_CORE_TEXT_FONT_LOOKUP
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to