Update font-style's implementation in the font selection algorithm
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 May 2017 07:37:42 +0000 (07:37 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 May 2017 07:37:42 +0000 (07:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169453

Reviewed by Simon Fraser.

Source/WebCore:

Previously, we were treating "font-style: oblique" exactly the same as "font-style: italic".
These values were parsed to the same internal data type. However, variation fonts may have two
distinct axes: 'slnt' and 'ital'. Therefore, we need to keep a bool of state which represents
which of these two axes we should be setting when we apply font variations. We can do this by
making the "font-style" parser a "custom" parser. The implementation of these custom functions
will set both the italic value on the FontDescription as well as this extra bool.

We don't, however, want to treat these values as distinct for the purposese of font selection.
The fact that we treat oblique fonts the same as italic fonts is a feature, not a bug. Therefore,
the font selection algorithm is not made aware of this distinction. This is why we don't want to
package up the bool and FontSelectionValue into a class: font selection only cares about the
FontSelectionValue, so conceptually they shouldn't be joined. (The FontSelectionValue already
exists within a collection of all the things font selection needs to know about.)

Now that there is this extra bit of state on the FontDescription, we can do a little better when
computing the result of getComputedStyle(). Previously, we were always returning "italic" even
when "oblique" was specified. Now, we can return the correct one. However, this extra bit of
state is not kept on the CSSFontFace (because it doesn't need to be), which means we can only
improve the computed style of an element, rather than the cssText of an @font-face rule.

Test: fast/text/font-style-parse.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::fontStyleFromStyleValue):
(WebCore::fontStyleFromStyle):
(WebCore::fontShorthandValueForSelectionProperties):
* css/CSSComputedStyleDeclaration.h:
* css/CSSFontFaceSet.h:
* css/CSSProperties.json:
* css/FontFace.cpp:
(WebCore::FontFace::style):
* css/FontSelectionValueInlines.h:
(WebCore::fontStyleKeyword):
* css/StyleBuilderConverter.h:
(WebCore::StyleBuilderConverter::convertFontStyle): Deleted.
* css/StyleBuilderCustom.h:
(WebCore::StyleBuilderCustom::applyInitialFontStyle):
(WebCore::StyleBuilderCustom::applyInheritFontStyle):
(WebCore::StyleBuilderCustom::applyValueFontStyle):
* platform/graphics/FontCache.h:
(WebCore::FontDescriptionKey::makeFlagsKey):
* platform/graphics/FontDescription.cpp:
(WebCore::FontDescription::FontDescription):
* platform/graphics/FontDescription.h:
(WebCore::FontDescription::shouldUseItalicVariationAxis):
(WebCore::FontDescription::setShouldUseItalicVariationAxis):
(WebCore::FontDescription::operator==):
(WebCore::FontCascadeDescription::initialShouldUseItalicVariationAxis):
* platform/graphics/cocoa/FontCacheCoreText.cpp:
(WebCore::preparePlatformFont):
(WebCore::fontWithFamily):
(WebCore::FontCache::createFontPlatformData):
(WebCore::FontCache::systemFallbackForCharacters):
* platform/graphics/mac/FontCustomPlatformData.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):

LayoutTests:

* fast/text/font-style-parse-expected.txt:
* fast/text/font-style-parse.html:
* platform/mac-elcapitan/fast/text/font-style-parse-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@217272 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/text/font-style-parse-expected.txt
LayoutTests/fast/text/font-style-parse.html
LayoutTests/platform/mac-elcapitan/fast/text/font-style-parse-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSComputedStyleDeclaration.h
Source/WebCore/css/CSSFontFaceSet.h
Source/WebCore/css/CSSProperties.json
Source/WebCore/css/FontFace.cpp
Source/WebCore/css/FontSelectionValueInlines.h
Source/WebCore/css/StyleBuilderConverter.h
Source/WebCore/css/StyleBuilderCustom.h
Source/WebCore/platform/graphics/FontCache.h
Source/WebCore/platform/graphics/FontDescription.cpp
Source/WebCore/platform/graphics/FontDescription.h
Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp
Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
Source/WebCore/platform/text/TextFlags.h

index e59d904..0017f39 100644 (file)
@@ -1,3 +1,14 @@
+2017-05-22  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Update font-style's implementation in the font selection algorithm
+        https://bugs.webkit.org/show_bug.cgi?id=169453
+
+        Reviewed by Simon Fraser.
+
+        * fast/text/font-style-parse-expected.txt:
+        * fast/text/font-style-parse.html:
+        * platform/mac-elcapitan/fast/text/font-style-parse-expected.txt:
+
 2017-05-22  Per Arne Vollan  <pvollan@apple.com>
 
         [Win] Update expectations for layout tests.
index 40908e6..c800e6e 100644 (file)
@@ -6,7 +6,7 @@ PASS window.getComputedStyle(document.getElementById('test5')).fontStyle is "obl
 PASS window.getComputedStyle(document.getElementById('test6')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test7')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test8')).fontStyle is "italic"
-PASS window.getComputedStyle(document.getElementById('test9')).fontStyle is "italic"
+PASS window.getComputedStyle(document.getElementById('test9')).fontStyle is "oblique"
 PASS window.getComputedStyle(document.getElementById('test10')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test11')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test12')).fontStyle is "normal"
@@ -19,6 +19,7 @@ PASS window.getComputedStyle(document.getElementById('test18')).fontStyle is "it
 PASS window.getComputedStyle(document.getElementById('test19')).fontStyle is "italic"
 PASS window.getComputedStyle(document.getElementById('test20')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test21')).fontStyle is "oblique 14deg"
+PASS window.getComputedStyle(document.getElementById('test22')).fontStyle is "oblique"
 PASS window.getComputedStyle(document.getElementById('test1')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test2')).font is "16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test3')).font is "16px/18px Times"
@@ -27,7 +28,7 @@ PASS window.getComputedStyle(document.getElementById('test5')).font is "16px/18p
 PASS window.getComputedStyle(document.getElementById('test6')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test7')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test8')).font is "italic normal normal normal 16px/18px Times"
-PASS window.getComputedStyle(document.getElementById('test9')).font is "italic normal normal normal 16px/18px Times"
+PASS window.getComputedStyle(document.getElementById('test9')).font is "oblique normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test10')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test11')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test12')).font is "normal normal normal normal 16px/18px Times"
@@ -40,6 +41,7 @@ PASS window.getComputedStyle(document.getElementById('test18')).font is "italic
 PASS window.getComputedStyle(document.getElementById('test19')).font is "italic small-caps 100 extra-expanded 48px/49px 'Helvetica Neue'"
 PASS window.getComputedStyle(document.getElementById('test20')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test21')).font is "48px/49px 'Helvetica Neue'"
+PASS window.getComputedStyle(document.getElementById('test22')).font is "oblique normal normal normal 16px/18px Times"
 PASS document.getElementById('test1').style.font is ""
 PASS document.getElementById('test15').style.font is "italic 100 48px/49px 'Helvetica Neue'"
 PASS document.getElementById('test16').style.font is "italic 100 48px/49px 'Helvetica Neue'"
index 4e5c1fa..02cc5fa 100644 (file)
@@ -26,6 +26,7 @@
 <div id="test19" style="font: italic small-caps 100 extra-expanded 48px/49px 'Helvetica Neue';"></div>
 <div id="test20" style="font: 13deg small-caps 123 extra-expanded 48px/49px 'Helvetica Neue';"></div>
 <div id="test21" style="font: oblique 14deg small-caps 123 extra-expanded 48px/49px 'Helvetica Neue';"></div>
+<div id="test22" style="font-style: oblique 20deg;"></div>
 </div>
 <script>
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test1')).fontStyle", "normal");
@@ -36,7 +37,7 @@ shouldBeEqualToString("window.getComputedStyle(document.getElementById('test5'))
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test6')).fontStyle", "normal");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test7')).fontStyle", "normal");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test8')).fontStyle", "italic");
-shouldBeEqualToString("window.getComputedStyle(document.getElementById('test9')).fontStyle", "italic");
+shouldBeEqualToString("window.getComputedStyle(document.getElementById('test9')).fontStyle", "oblique");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test10')).fontStyle", "normal");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test11')).fontStyle", "normal");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test12')).fontStyle", "normal");
@@ -49,6 +50,7 @@ shouldBeEqualToString("window.getComputedStyle(document.getElementById('test18')
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test19')).fontStyle", "italic");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test20')).fontStyle", "normal");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test21')).fontStyle", "oblique 14deg");
+shouldBeEqualToString("window.getComputedStyle(document.getElementById('test22')).fontStyle", "oblique");
 
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test1')).font", "normal normal normal normal 16px/18px Times");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test2')).font", "16px/18px Times");
@@ -58,7 +60,7 @@ shouldBeEqualToString("window.getComputedStyle(document.getElementById('test5'))
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test6')).font", "normal normal normal normal 16px/18px Times");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test7')).font", "normal normal normal normal 16px/18px Times");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test8')).font", "italic normal normal normal 16px/18px Times");
-shouldBeEqualToString("window.getComputedStyle(document.getElementById('test9')).font", "italic normal normal normal 16px/18px Times");
+shouldBeEqualToString("window.getComputedStyle(document.getElementById('test9')).font", "oblique normal normal normal 16px/18px Times");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test10')).font", "normal normal normal normal 16px/18px Times");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test11')).font", "normal normal normal normal 16px/18px Times");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test12')).font", "normal normal normal normal 16px/18px Times");
@@ -71,6 +73,7 @@ shouldBeEqualToString("window.getComputedStyle(document.getElementById('test18')
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test19')).font", "italic small-caps 100 extra-expanded 48px/49px 'Helvetica Neue'");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test20')).font", "normal normal normal normal 16px/18px Times");
 shouldBeEqualToString("window.getComputedStyle(document.getElementById('test21')).font", "48px/49px 'Helvetica Neue'");
+shouldBeEqualToString("window.getComputedStyle(document.getElementById('test22')).font", "oblique normal normal normal 16px/18px Times");
 
 shouldBeEqualToString("document.getElementById('test1').style.font", "");
 shouldBeEqualToString("document.getElementById('test15').style.font", "italic 100 48px/49px 'Helvetica Neue'");
index 382bc14..42be44f 100644 (file)
@@ -6,7 +6,7 @@ FAIL window.getComputedStyle(document.getElementById('test5')).fontStyle should
 PASS window.getComputedStyle(document.getElementById('test6')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test7')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test8')).fontStyle is "italic"
-PASS window.getComputedStyle(document.getElementById('test9')).fontStyle is "italic"
+PASS window.getComputedStyle(document.getElementById('test9')).fontStyle is "oblique"
 PASS window.getComputedStyle(document.getElementById('test10')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test11')).fontStyle is "normal"
 PASS window.getComputedStyle(document.getElementById('test12')).fontStyle is "normal"
@@ -19,6 +19,7 @@ PASS window.getComputedStyle(document.getElementById('test18')).fontStyle is "it
 PASS window.getComputedStyle(document.getElementById('test19')).fontStyle is "italic"
 PASS window.getComputedStyle(document.getElementById('test20')).fontStyle is "normal"
 FAIL window.getComputedStyle(document.getElementById('test21')).fontStyle should be oblique 14deg. Was normal.
+FAIL window.getComputedStyle(document.getElementById('test22')).fontStyle should be oblique. Was normal.
 PASS window.getComputedStyle(document.getElementById('test1')).font is "normal normal normal normal 16px/18px Times"
 FAIL window.getComputedStyle(document.getElementById('test2')).font should be 16px/18px Times. Was normal normal normal normal 16px/18px Times.
 FAIL window.getComputedStyle(document.getElementById('test3')).font should be 16px/18px Times. Was normal normal normal normal 16px/18px Times.
@@ -27,7 +28,7 @@ FAIL window.getComputedStyle(document.getElementById('test5')).font should be 16
 PASS window.getComputedStyle(document.getElementById('test6')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test7')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test8')).font is "italic normal normal normal 16px/18px Times"
-PASS window.getComputedStyle(document.getElementById('test9')).font is "italic normal normal normal 16px/18px Times"
+PASS window.getComputedStyle(document.getElementById('test9')).font is "oblique normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test10')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test11')).font is "normal normal normal normal 16px/18px Times"
 PASS window.getComputedStyle(document.getElementById('test12')).font is "normal normal normal normal 16px/18px Times"
@@ -40,6 +41,7 @@ PASS window.getComputedStyle(document.getElementById('test18')).font is "italic
 PASS window.getComputedStyle(document.getElementById('test19')).font is "italic small-caps 100 extra-expanded 48px/49px 'Helvetica Neue'"
 PASS window.getComputedStyle(document.getElementById('test20')).font is "normal normal normal normal 16px/18px Times"
 FAIL window.getComputedStyle(document.getElementById('test21')).font should be 48px/49px 'Helvetica Neue'. Was normal normal normal normal 16px/18px Times.
+FAIL window.getComputedStyle(document.getElementById('test22')).font should be oblique normal normal normal 16px/18px Times. Was normal normal normal normal 16px/18px Times.
 PASS document.getElementById('test1').style.font is ""
 PASS document.getElementById('test15').style.font is "italic 100 48px/49px 'Helvetica Neue'"
 PASS document.getElementById('test16').style.font is "italic 100 48px/49px 'Helvetica Neue'"
index f03a3d8..747f7a4 100644 (file)
@@ -1,5 +1,68 @@
 2017-05-22  Myles C. Maxfield  <mmaxfield@apple.com>
 
+        Update font-style's implementation in the font selection algorithm
+        https://bugs.webkit.org/show_bug.cgi?id=169453
+
+        Reviewed by Simon Fraser.
+
+        Previously, we were treating "font-style: oblique" exactly the same as "font-style: italic".
+        These values were parsed to the same internal data type. However, variation fonts may have two
+        distinct axes: 'slnt' and 'ital'. Therefore, we need to keep a bool of state which represents
+        which of these two axes we should be setting when we apply font variations. We can do this by
+        making the "font-style" parser a "custom" parser. The implementation of these custom functions
+        will set both the italic value on the FontDescription as well as this extra bool.
+
+        We don't, however, want to treat these values as distinct for the purposese of font selection.
+        The fact that we treat oblique fonts the same as italic fonts is a feature, not a bug. Therefore,
+        the font selection algorithm is not made aware of this distinction. This is why we don't want to
+        package up the bool and FontSelectionValue into a class: font selection only cares about the
+        FontSelectionValue, so conceptually they shouldn't be joined. (The FontSelectionValue already
+        exists within a collection of all the things font selection needs to know about.)
+
+        Now that there is this extra bit of state on the FontDescription, we can do a little better when
+        computing the result of getComputedStyle(). Previously, we were always returning "italic" even
+        when "oblique" was specified. Now, we can return the correct one. However, this extra bit of
+        state is not kept on the CSSFontFace (because it doesn't need to be), which means we can only
+        improve the computed style of an element, rather than the cssText of an @font-face rule.
+
+        Test: fast/text/font-style-parse.html
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::ComputedStyleExtractor::fontStyleFromStyleValue):
+        (WebCore::fontStyleFromStyle):
+        (WebCore::fontShorthandValueForSelectionProperties):
+        * css/CSSComputedStyleDeclaration.h:
+        * css/CSSFontFaceSet.h:
+        * css/CSSProperties.json:
+        * css/FontFace.cpp:
+        (WebCore::FontFace::style):
+        * css/FontSelectionValueInlines.h:
+        (WebCore::fontStyleKeyword):
+        * css/StyleBuilderConverter.h:
+        (WebCore::StyleBuilderConverter::convertFontStyle): Deleted.
+        * css/StyleBuilderCustom.h:
+        (WebCore::StyleBuilderCustom::applyInitialFontStyle):
+        (WebCore::StyleBuilderCustom::applyInheritFontStyle):
+        (WebCore::StyleBuilderCustom::applyValueFontStyle):
+        * platform/graphics/FontCache.h:
+        (WebCore::FontDescriptionKey::makeFlagsKey):
+        * platform/graphics/FontDescription.cpp:
+        (WebCore::FontDescription::FontDescription):
+        * platform/graphics/FontDescription.h:
+        (WebCore::FontDescription::shouldUseItalicVariationAxis):
+        (WebCore::FontDescription::setShouldUseItalicVariationAxis):
+        (WebCore::FontDescription::operator==):
+        (WebCore::FontCascadeDescription::initialShouldUseItalicVariationAxis):
+        * platform/graphics/cocoa/FontCacheCoreText.cpp:
+        (WebCore::preparePlatformFont):
+        (WebCore::fontWithFamily):
+        (WebCore::FontCache::createFontPlatformData):
+        (WebCore::FontCache::systemFallbackForCharacters):
+        * platform/graphics/mac/FontCustomPlatformData.cpp:
+        (WebCore::FontCustomPlatformData::fontPlatformData):
+
+2017-05-22  Myles C. Maxfield  <mmaxfield@apple.com>
+
         Support calc() in font-variation-settings and font-feature-settings
         https://bugs.webkit.org/show_bug.cgi?id=171032
 
index 0460e51..9da202b 100644 (file)
@@ -1967,16 +1967,16 @@ Ref<CSSFontStyleValue> ComputedStyleExtractor::fontNonKeywordStyleFromStyleValue
     return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique), CSSValuePool::singleton().createValue(static_cast<float>(italic), CSSPrimitiveValue::CSS_DEG));
 }
 
-Ref<CSSFontStyleValue> ComputedStyleExtractor::fontStyleFromStyleValue(FontSelectionValue italic)
+Ref<CSSFontStyleValue> ComputedStyleExtractor::fontStyleFromStyleValue(FontSelectionValue italic, FontStyleAxis fontStyleAxis)
 {
-    if (auto keyword = fontStyleKeyword(italic))
+    if (auto keyword = fontStyleKeyword(italic, fontStyleAxis))
         return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(keyword.value()));
     return fontNonKeywordStyleFromStyleValue(italic);
 }
 
 static Ref<CSSFontStyleValue> fontStyleFromStyle(const RenderStyle& style)
 {
-    return ComputedStyleExtractor::fontStyleFromStyleValue(style.fontDescription().italic());
+    return ComputedStyleExtractor::fontStyleFromStyleValue(style.fontDescription().italic(), style.fontDescription().fontStyleAxis());
 }
 
 static Ref<CSSValue> fontVariantFromStyle(const RenderStyle& style)
@@ -2610,7 +2610,7 @@ static Ref<CSSFontValue> fontShorthandValueForSelectionProperties(const FontDesc
     else
         return CSSFontValue::create();
 
-    if (auto italic = fontStyleKeyword(fontDescription.italic()))
+    if (auto italic = fontStyleKeyword(fontDescription.italic(), fontDescription.fontStyleAxis()))
         computedFont->style = CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(italic.value()));
     else
         return CSSFontValue::create();
index 58341bf..d23f7e4 100644 (file)
@@ -21,6 +21,7 @@
 #pragma once
 
 #include "CSSStyleDeclaration.h"
+#include "FontDescription.h"
 #include "RenderStyleConstants.h"
 #include "SVGRenderStyleDefs.h"
 #include <wtf/RefPtr.h>
@@ -71,7 +72,7 @@ public:
     static Ref<CSSPrimitiveValue> fontNonKeywordStretchFromStyleValue(FontSelectionValue);
     static Ref<CSSPrimitiveValue> fontStretchFromStyleValue(FontSelectionValue);
     static Ref<CSSFontStyleValue> fontNonKeywordStyleFromStyleValue(FontSelectionValue);
-    static Ref<CSSFontStyleValue> fontStyleFromStyleValue(FontSelectionValue);
+    static Ref<CSSFontStyleValue> fontStyleFromStyleValue(FontSelectionValue, FontStyleAxis);
 
 private:
     // The styled element is either the element passed into computedPropertyValue, or the
index ad44787..2b7e2eb 100644 (file)
@@ -52,10 +52,6 @@ public:
     }
     ~CSSFontFaceSet();
 
-    static FontSelectionValue convertFontWeightFromValue(const CSSValue&);
-    static FontSelectionValue convertFontStretchFromValue(const CSSValue&);
-    static FontSelectionValue convertFontStyleFromValue(const CSSValue&);
-
     void addClient(CSSFontFaceSetClient&);
     void removeClient(CSSFontFaceSetClient&);
 
index 57c3a3f..011a959 100644 (file)
                 "oblique"
             ],
             "codegen-properties": {
-                "name-for-methods": "Italic",
+                "custom": "All",
                 "font-property": true,
-                "high-priority": true,
-                "converter": "FontStyle"
+                "high-priority": true
             },
             "specification": {
                 "category": "css-fonts",
index 8092aa7..62d7439 100644 (file)
@@ -289,8 +289,8 @@ String FontFace::style() const
     m_backing->updateStyleIfNeeded();
     auto style = m_backing->italic();
 
-    auto minimum = ComputedStyleExtractor::fontStyleFromStyleValue(style.minimum);
-    auto maximum = ComputedStyleExtractor::fontStyleFromStyleValue(style.maximum);
+    auto minimum = ComputedStyleExtractor::fontStyleFromStyleValue(style.minimum, FontStyleAxis::ital);
+    auto maximum = ComputedStyleExtractor::fontStyleFromStyleValue(style.maximum, FontStyleAxis::ital);
 
     if (minimum.get().equals(maximum.get()))
         return minimum->cssText();
index 00fdb4e..0df020b 100644 (file)
@@ -121,12 +121,12 @@ inline std::optional<FontSelectionValue> fontStretchValue(CSSValueID value)
     }
 }
 
-inline std::optional<CSSValueID> fontStyleKeyword(FontSelectionValue style)
+inline std::optional<CSSValueID> fontStyleKeyword(FontSelectionValue style, FontStyleAxis axis)
 {
     if (style == normalItalicValue())
         return CSSValueNormal;
     if (style == italicValue())
-        return CSSValueItalic;
+        return axis == FontStyleAxis::ital ? CSSValueItalic : CSSValueOblique;
     return std::nullopt;
 }
 
index 4c8c442..0052111 100644 (file)
@@ -1238,11 +1238,6 @@ inline FontSelectionValue StyleBuilderConverter::convertFontStretch(StyleResolve
     return convertFontStretchFromValue(value);
 }
 
-inline FontSelectionValue StyleBuilderConverter::convertFontStyle(StyleResolver&, const CSSValue& value)
-{
-    return convertFontStyleFromValue(value);
-}
-
 #if ENABLE(VARIATION_FONTS)
 inline FontVariationSettings StyleBuilderConverter::convertFontVariationSettings(StyleResolver&, const CSSValue& value)
 {
index 802f1fb..0ad263e 100644 (file)
@@ -81,6 +81,7 @@ public:
     DECLARE_PROPERTY_CUSTOM_HANDLERS(Fill);
     DECLARE_PROPERTY_CUSTOM_HANDLERS(FontFamily);
     DECLARE_PROPERTY_CUSTOM_HANDLERS(FontSize);
+    DECLARE_PROPERTY_CUSTOM_HANDLERS(FontStyle);
 #if ENABLE(CSS_IMAGE_RESOLUTION)
     DECLARE_PROPERTY_CUSTOM_HANDLERS(ImageResolution);
 #endif
@@ -1582,6 +1583,31 @@ inline float StyleBuilderCustom::determineRubyTextSizeMultiplier(StyleResolver&
     return 0.25f;
 }
 
+inline void StyleBuilderCustom::applyInitialFontStyle(StyleResolver& styleResolver)
+{
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setItalic(FontCascadeDescription::initialItalic());
+    fontDescription.setFontStyleAxis(FontCascadeDescription::initialFontStyleAxis());
+    styleResolver.setFontDescription(fontDescription);
+}
+
+inline void StyleBuilderCustom::applyInheritFontStyle(StyleResolver& styleResolver)
+{
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setItalic(styleResolver.parentFontDescription().italic());
+    fontDescription.setFontStyleAxis(styleResolver.parentFontDescription().fontStyleAxis());
+    styleResolver.setFontDescription(fontDescription);
+}
+
+inline void StyleBuilderCustom::applyValueFontStyle(StyleResolver& styleResolver, CSSValue& value)
+{
+    auto& fontStyleValue = downcast<CSSFontStyleValue>(value);
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setItalic(StyleBuilderConverter::convertFontStyleFromValue(fontStyleValue));
+    fontDescription.setFontStyleAxis(fontStyleValue.fontStyleValue->valueID() == CSSValueItalic ? FontStyleAxis::ital : FontStyleAxis::slnt);
+    styleResolver.setFontDescription(fontDescription);
+}
+
 inline void StyleBuilderCustom::applyValueFontSize(StyleResolver& styleResolver, CSSValue& value)
 {
     auto fontDescription = styleResolver.style()->fontDescription();
index 79c6ade..228c959 100644 (file)
@@ -122,7 +122,8 @@ private:
     static std::array<unsigned, 2> makeFlagsKey(const FontDescription& description)
     {
         static_assert(USCRIPT_CODE_LIMIT < 0x1000, "Script code must fit in an unsigned along with the other flags");
-        unsigned first = static_cast<unsigned>(description.script()) << 12
+        unsigned first = static_cast<unsigned>(description.script()) << 13
+            | static_cast<unsigned>(description.fontStyleAxis() == FontStyleAxis::slnt) << 12
             | static_cast<unsigned>(description.opticalSizing()) << 11
             | static_cast<unsigned>(description.textRenderingMode()) << 9
             | static_cast<unsigned>(description.fontSynthesis()) << 6
@@ -275,7 +276,7 @@ struct SynthesisPair {
     bool needsSyntheticOblique;
 };
 
-RetainPtr<CTFontRef> preparePlatformFont(CTFontRef, TextRenderingMode, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities, const FontFeatureSettings& features, const FontVariantSettings&, FontSelectionRequest, const FontVariationSettings&, FontOpticalSizing, float size);
+RetainPtr<CTFontRef> preparePlatformFont(CTFontRef, TextRenderingMode, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities, const FontFeatureSettings& features, const FontVariantSettings&, FontSelectionRequest, const FontVariationSettings&, FontOpticalSizing, float size, FontStyleAxis);
 SynthesisPair computeNecessarySynthesis(CTFontRef, const FontDescription&, bool isPlatformFont = false);
 RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& family, FontSelectionRequest, float size);
 RetainPtr<CTFontRef> platformFontWithFamily(const AtomicString& family, FontSelectionRequest, TextRenderingMode, float size);
index e36fb64..2c9eea5 100644 (file)
@@ -78,6 +78,7 @@ FontDescription::FontDescription()
     , m_variantEastAsianWidth(static_cast<unsigned>(FontVariantEastAsianWidth::Normal))
     , m_variantEastAsianRuby(static_cast<unsigned>(FontVariantEastAsianRuby::Normal))
     , m_opticalSizing(static_cast<unsigned>(FontOpticalSizing::Enabled))
+    , m_fontStyleAxis(FontCascadeDescription::initialFontStyleAxis() == FontStyleAxis::ital)
 {
 }
 
index c108dbb..e28cbbc 100644 (file)
@@ -96,6 +96,7 @@ public:
             variantEastAsianRuby() };
     }
     FontOpticalSizing opticalSizing() const { return static_cast<FontOpticalSizing>(m_opticalSizing); }
+    FontStyleAxis fontStyleAxis() const { return m_fontStyleAxis ? FontStyleAxis::ital : FontStyleAxis::slnt; }
 
     void setComputedSize(float s) { m_computedSize = clampToFloat(s); }
     void setItalic(FontSelectionValue italic) { m_fontSelectionRequest.slope = italic; }
@@ -129,6 +130,7 @@ public:
     void setVariantEastAsianWidth(FontVariantEastAsianWidth variant) { m_variantEastAsianWidth = static_cast<unsigned>(variant); }
     void setVariantEastAsianRuby(FontVariantEastAsianRuby variant) { m_variantEastAsianRuby = static_cast<unsigned>(variant); }
     void setOpticalSizing(FontOpticalSizing sizing) { m_opticalSizing = static_cast<unsigned>(sizing); }
+    void setFontStyleAxis(FontStyleAxis axis) { m_fontStyleAxis = axis == FontStyleAxis::ital; }
 
 private:
     // FIXME: Investigate moving these into their own object on the heap (to save memory).
@@ -161,6 +163,7 @@ private:
     unsigned m_variantEastAsianWidth : 2; // FontVariantEastAsianWidth
     unsigned m_variantEastAsianRuby : 1; // FontVariantEastAsianRuby
     unsigned m_opticalSizing : 1; // FontOpticalSizing
+    unsigned m_fontStyleAxis : 1; // Whether "font-style: italic" or "font-style: oblique 20deg" was specified
 };
 
 inline bool FontDescription::operator==(const FontDescription& other) const
@@ -193,7 +196,8 @@ inline bool FontDescription::operator==(const FontDescription& other) const
         && m_variantEastAsianVariant == other.m_variantEastAsianVariant
         && m_variantEastAsianWidth == other.m_variantEastAsianWidth
         && m_variantEastAsianRuby == other.m_variantEastAsianRuby
-        && m_opticalSizing == other.m_opticalSizing;
+        && m_opticalSizing == other.m_opticalSizing
+        && m_fontStyleAxis == other.m_fontStyleAxis;
 }
 
 // FIXME: Move to a file of its own.
@@ -265,6 +269,7 @@ public:
 
     // Initial values for font properties.
     static FontSelectionValue initialItalic() { return normalItalicValue(); }
+    static FontStyleAxis initialFontStyleAxis() { return FontStyleAxis::slnt; }
     static FontSelectionValue initialWeight() { return normalWeightValue(); }
     static FontSelectionValue initialStretch() { return normalStretchValue(); }
     static FontSmallCaps initialSmallCaps() { return FontSmallCapsOff; }
index 34c1fc6..181c033 100644 (file)
@@ -497,7 +497,7 @@ static inline float normalizeWidth(float value)
 }
 #endif
 
-RetainPtr<CTFontRef> preparePlatformFont(CTFontRef originalFont, TextRenderingMode textRenderingMode, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities, const FontFeatureSettings& features, const FontVariantSettings& variantSettings, FontSelectionRequest fontSelectionRequest, const FontVariationSettings& variations, FontOpticalSizing fontOpticalSizing, float size)
+RetainPtr<CTFontRef> preparePlatformFont(CTFontRef originalFont, TextRenderingMode textRenderingMode, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities, const FontFeatureSettings& features, const FontVariantSettings& variantSettings, FontSelectionRequest fontSelectionRequest, const FontVariationSettings& variations, FontOpticalSizing fontOpticalSizing, float size, FontStyleAxis axis)
 {
     bool alwaysAddVariations = false;
 
@@ -510,6 +510,7 @@ RetainPtr<CTFontRef> preparePlatformFont(CTFontRef originalFont, TextRenderingMo
     UNUSED_PARAM(fontOpticalSizing);
     UNUSED_PARAM(fontFaceCapabilities);
     UNUSED_PARAM(size);
+    UNUSED_PARAM(axis);
 #endif
 
     if (!originalFont || (!features.size() && (!alwaysAddVariations && variations.isEmpty()) && (textRenderingMode == AutoTextRendering) && variantSettings.isAllNormal()
@@ -592,7 +593,10 @@ RetainPtr<CTFontRef> preparePlatformFont(CTFontRef originalFont, TextRenderingMo
         }
         applyVariation({{'w', 'g', 'h', 't'}}, weight);
         applyVariation({{'w', 'd', 't', 'h'}}, width);
-        applyVariation({{'s', 'l', 'n', 't'}}, slope);
+        if (axis == FontStyleAxis::ital)
+            applyVariation({{'i', 't', 'a', 'l'}}, 1);
+        else
+            applyVariation({{'s', 'l', 'n', 't'}}, slope);
     }
 
     if (fontOpticalSizing == FontOpticalSizing::Enabled) {
@@ -1162,7 +1166,7 @@ static void invalidateFontCache()
     FontCache::singleton().invalidate();
 }
 
-static RetainPtr<CTFontRef> fontWithFamily(const AtomicString& family, FontSelectionRequest request, const FontFeatureSettings& featureSettings, const FontVariantSettings& variantSettings, const FontVariationSettings& variationSettings, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities, const TextRenderingMode& textRenderingMode, FontSelectionRequest fontSelectionRequest, FontOpticalSizing fontOpticalSizing, float size)
+static RetainPtr<CTFontRef> fontWithFamily(const AtomicString& family, FontSelectionRequest request, const FontFeatureSettings& featureSettings, const FontVariantSettings& variantSettings, const FontVariationSettings& variationSettings, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities, const TextRenderingMode& textRenderingMode, FontSelectionRequest fontSelectionRequest, FontOpticalSizing fontOpticalSizing, float size, FontStyleAxis axis)
 {
     if (family.isEmpty())
         return nullptr;
@@ -1170,7 +1174,7 @@ static RetainPtr<CTFontRef> fontWithFamily(const AtomicString& family, FontSelec
     auto foundFont = platformFontWithFamilySpecialCase(family, request, size);
     if (!foundFont)
         foundFont = platformFontLookupWithFamily(family, request, size);
-    return preparePlatformFont(foundFont.get(), textRenderingMode, fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities, featureSettings, variantSettings, fontSelectionRequest, variationSettings, fontOpticalSizing, size);
+    return preparePlatformFont(foundFont.get(), textRenderingMode, fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities, featureSettings, variantSettings, fontSelectionRequest, variationSettings, fontOpticalSizing, size, axis);
 }
 
 #if PLATFORM(MAC)
@@ -1209,7 +1213,7 @@ std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDe
 {
     float size = fontDescription.computedPixelSize();
 
-    auto font = fontWithFamily(family, fontDescription.fontSelectionRequest(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.variationSettings(), fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities, fontDescription.textRenderingMode(), fontDescription.fontSelectionRequest(), fontDescription.opticalSizing(), size);
+    auto font = fontWithFamily(family, fontDescription.fontSelectionRequest(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.variationSettings(), fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities, fontDescription.textRenderingMode(), fontDescription.fontSelectionRequest(), fontDescription.opticalSizing(), size, fontDescription.fontStyleAxis());
 
 #if PLATFORM(MAC)
     if (!font) {
@@ -1220,7 +1224,7 @@ std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDe
         // Ignore the result because we want to use our own algorithm to actually find the font.
         autoActivateFont(family.string(), size);
 
-        font = fontWithFamily(family, fontDescription.fontSelectionRequest(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.variationSettings(), fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities, fontDescription.textRenderingMode(), fontDescription.fontSelectionRequest(), fontDescription.opticalSizing(), size);
+        font = fontWithFamily(family, fontDescription.fontSelectionRequest(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.variationSettings(), fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities, fontDescription.textRenderingMode(), fontDescription.fontSelectionRequest(), fontDescription.opticalSizing(), size, fontDescription.fontStyleAxis());
     }
 #endif
 
@@ -1308,7 +1312,7 @@ RefPtr<Font> FontCache::systemFallbackForCharacters(const FontDescription& descr
 
     const FontPlatformData& platformData = originalFontData->platformData();
     auto result = lookupFallbackFont(platformData.font(), description.weight(), description.locale(), characters, length);
-    result = preparePlatformFont(result.get(), description.textRenderingMode(), nullptr, nullptr, { }, description.featureSettings(), description.variantSettings(), description.fontSelectionRequest(), description.variationSettings(), description.opticalSizing(), description.computedSize());
+    result = preparePlatformFont(result.get(), description.textRenderingMode(), nullptr, nullptr, { }, description.featureSettings(), description.variantSettings(), description.fontSelectionRequest(), description.variationSettings(), description.opticalSizing(), description.computedSize(), description.fontStyleAxis());
     if (!result)
         return lastResortFallbackFont(description);
 
index 158344e..be1f60e 100644 (file)
@@ -40,7 +40,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription&
     FontOrientation orientation = fontDescription.orientation();
     FontWidthVariant widthVariant = fontDescription.widthVariant();
     RetainPtr<CTFontRef> font = adoptCF(CTFontCreateWithFontDescriptor(m_fontDescriptor.get(), size, nullptr));
-    font = preparePlatformFont(font.get(), fontDescription.textRenderingMode(), &fontFaceFeatures, &fontFaceVariantSettings, fontFaceCapabilities, fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.fontSelectionRequest(), fontDescription.variationSettings(), fontDescription.opticalSizing(), fontDescription.computedSize());
+    font = preparePlatformFont(font.get(), fontDescription.textRenderingMode(), &fontFaceFeatures, &fontFaceVariantSettings, fontFaceCapabilities, fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.fontSelectionRequest(), fontDescription.variationSettings(), fontDescription.opticalSizing(), fontDescription.computedSize(), fontDescription.fontStyleAxis());
     ASSERT(font);
     return FontPlatformData(font.get(), size, bold, italic, orientation, widthVariant, fontDescription.textRenderingMode());
 }
index c7087ff..dfde5bf 100644 (file)
@@ -356,4 +356,10 @@ enum class FontOpticalSizing {
     Disabled
 };
 
+// https://www.microsoft.com/typography/otspec/fvar.htm#VAT
+enum class FontStyleAxis {
+    slnt,
+    ital
+};
+
 }