Title: [259188] trunk
Revision
259188
Author
[email protected]
Date
2020-03-30 02:11:15 -0700 (Mon, 30 Mar 2020)

Log Message

[HarfBuzz] Not all CSS font features are applied
https://bugs.webkit.org/show_bug.cgi?id=209591

Reviewed by Adrian Perez de Castro.

Source/WebCore:

Implement font feature precedence algorithm for HarfBuzz, including features specified in font-face rule and
font-variant settings that we were ignoring.

7.2. Feature precedence
https://www.w3.org/TR/css-fonts-3/#feature-precedence

* platform/graphics/freetype/FontCacheFreeType.cpp:
(WebCore::FontCache::createFontPlatformData): Add font features to be enanled to the font config pattern.
* platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData): Ditto.
* platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp:
(WebCore::setFeatureSettingsFromVariants): Helper to add font-variant settings.
(WebCore::fontFeatures): Implement font feature precedence algorithm.
(WebCore::findScriptForVerticalGlyphSubstitution): Use HB_TAG direftly.
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters): Pass FontPlatformData to fontFeatures().

LayoutTests:

Remove expectations for tests that are now passing.

* platform/gtk/TestExpectations:
* platform/wpe/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (259187 => 259188)


--- trunk/LayoutTests/ChangeLog	2020-03-30 07:33:06 UTC (rev 259187)
+++ trunk/LayoutTests/ChangeLog	2020-03-30 09:11:15 UTC (rev 259188)
@@ -1,3 +1,15 @@
+2020-03-30  Carlos Garcia Campos  <[email protected]>
+
+        [HarfBuzz] Not all CSS font features are applied
+        https://bugs.webkit.org/show_bug.cgi?id=209591
+
+        Reviewed by Adrian Perez de Castro.
+
+        Remove expectations for tests that are now passing.
+
+        * platform/gtk/TestExpectations:
+        * platform/wpe/TestExpectations:
+
 2020-03-29  Antoine Quint  <[email protected]>
 
         [AutoSizing] Bring back the old auto-sizing code as a deprecated codepath for compatibility reasons

Modified: trunk/LayoutTests/platform/gtk/TestExpectations (259187 => 259188)


--- trunk/LayoutTests/platform/gtk/TestExpectations	2020-03-30 07:33:06 UTC (rev 259187)
+++ trunk/LayoutTests/platform/gtk/TestExpectations	2020-03-30 09:11:15 UTC (rev 259188)
@@ -864,7 +864,6 @@
 
 # This port doesn't support small-caps synthesis.
 webkit.org/b/152620 css3/font-variant-all.html [ ImageOnlyFailure ]
-webkit.org/b/152620 css3/font-variant-font-face-override.html [ ImageOnlyFailure ]
 webkit.org/b/152620 css3/font-variant-petite-caps-synthesis-coverage.html [ ImageOnlyFailure ]
 webkit.org/b/152620 css3/font-variant-petite-caps-synthesis.html [ ImageOnlyFailure ]
 webkit.org/b/152620 css3/font-variant-small-caps-synthesis-coverage.html [ ImageOnlyFailure ]
@@ -3877,7 +3876,6 @@
 
 webkit.org/b/168191 fast/text/system-font-weight.html [ Failure ]
 webkit.org/b/168191 fast/text/trak-optimizeLegibility.html [ Failure ]
-webkit.org/b/168191 css3/font-synthesis-small-caps.html [ ImageOnlyFailure ]
 
 webkit.org/b/168192 http/tests/media/hls/video-duration-accessibility.html [ Timeout Failure Crash ]
 
@@ -4510,37 +4508,6 @@
 webkit.org/b/206692 fast/canvas/canvas-fillPath-shadow.html [ Failure ]
 
 webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/generic-family-keywords-001.html [ Failure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-feature-settings-descriptor-01.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-alternates-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-caps-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-caps-04.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-caps-06.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-caps-07.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-03.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-04.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-05.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-06.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-07.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-08.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-09.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-10.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-04.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-05.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-07.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-10.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-03.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-04.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-05.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-06.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-07.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-08.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-09.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-position.html [ ImageOnlyFailure ]
 webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/quoted-generic-ignored.html [ ImageOnlyFailure ]
 
 webkit.org/b/194933 http/tests/cookies/same-site/user-load-cross-site-redirect.php [ Failure ]

Modified: trunk/LayoutTests/platform/wpe/TestExpectations (259187 => 259188)


--- trunk/LayoutTests/platform/wpe/TestExpectations	2020-03-30 07:33:06 UTC (rev 259187)
+++ trunk/LayoutTests/platform/wpe/TestExpectations	2020-03-30 09:11:15 UTC (rev 259188)
@@ -601,37 +601,6 @@
 webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/standard-font-family-7.html [ Pass ]
 webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/standard-font-family.html [ Pass ]
 webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/generic-family-keywords-001.html [ Failure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-feature-settings-descriptor-01.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-alternates-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-caps-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-caps-04.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-caps-06.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-caps-07.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-03.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-04.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-05.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-06.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-07.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-08.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-09.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-east-asian-10.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-04.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-05.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-07.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures-10.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-ligatures.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-02.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-03.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-04.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-05.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-06.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-07.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-08.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric-09.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-numeric.html [ ImageOnlyFailure ]
-webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/font-variant-position.html [ ImageOnlyFailure ]
 webkit.org/b/206885 imported/w3c/web-platform-tests/css/css-fonts/quoted-generic-ignored.html [ ImageOnlyFailure ]
 
 # WPT css-fonts failures/passes unique to WPE
@@ -1923,9 +1892,7 @@
 
 Bug(WPE) css3/font-feature-settings-font-face-rendering.html [ ImageOnlyFailure ]
 Bug(WPE) css3/font-feature-settings-rendering.html [ ImageOnlyFailure ]
-Bug(WPE) css3/font-synthesis-small-caps.html [ ImageOnlyFailure ]
 Bug(WPE) css3/font-variant-all.html [ ImageOnlyFailure ]
-Bug(WPE) css3/font-variant-font-face-override.html [ ImageOnlyFailure ]
 Bug(WPE) css3/font-variant-petite-caps-synthesis-coverage.html [ ImageOnlyFailure ]
 Bug(WPE) css3/font-variant-petite-caps-synthesis.html [ ImageOnlyFailure ]
 Bug(WPE) css3/font-variant-small-caps-synthesis-coverage.html [ ImageOnlyFailure ]

Modified: trunk/Source/WebCore/ChangeLog (259187 => 259188)


--- trunk/Source/WebCore/ChangeLog	2020-03-30 07:33:06 UTC (rev 259187)
+++ trunk/Source/WebCore/ChangeLog	2020-03-30 09:11:15 UTC (rev 259188)
@@ -1,3 +1,26 @@
+2020-03-30  Carlos Garcia Campos  <[email protected]>
+
+        [HarfBuzz] Not all CSS font features are applied
+        https://bugs.webkit.org/show_bug.cgi?id=209591
+
+        Reviewed by Adrian Perez de Castro.
+
+        Implement font feature precedence algorithm for HarfBuzz, including features specified in font-face rule and
+        font-variant settings that we were ignoring.
+
+        7.2. Feature precedence
+        https://www.w3.org/TR/css-fonts-3/#feature-precedence
+
+        * platform/graphics/freetype/FontCacheFreeType.cpp:
+        (WebCore::FontCache::createFontPlatformData): Add font features to be enanled to the font config pattern.
+        * platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp:
+        (WebCore::FontCustomPlatformData::fontPlatformData): Ditto.
+        * platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp:
+        (WebCore::setFeatureSettingsFromVariants): Helper to add font-variant settings.
+        (WebCore::fontFeatures): Implement font feature precedence algorithm.
+        (WebCore::findScriptForVerticalGlyphSubstitution): Use HB_TAG direftly.
+        (WebCore::ComplexTextController::collectComplexTextRunsForCharacters): Pass FontPlatformData to fontFeatures().
+
 2020-03-29  Antoine Quint  <[email protected]>
 
         [AutoSizing] Bring back the old auto-sizing code as a deprecated codepath for compatibility reasons

Modified: trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp (259187 => 259188)


--- trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp	2020-03-30 07:33:06 UTC (rev 259187)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp	2020-03-30 09:11:15 UTC (rev 259188)
@@ -500,7 +500,7 @@
         || equalLettersIgnoringASCIICase(familyNameString, "cursive");
 }
 
-std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomString& family, const FontFeatureSettings*, FontSelectionSpecifiedCapabilities)
+std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomString& family, const FontFeatureSettings* fontFaceFeatures, FontSelectionSpecifiedCapabilities)
 {
     // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
     // says that we must find an exact match for font family, slant (italic or oblique can be used)
@@ -564,6 +564,16 @@
     bool fixedWidth, syntheticBold, syntheticOblique;
     getFontPropertiesFromPattern(resultPattern.get(), fontDescription, fixedWidth, syntheticBold, syntheticOblique);
 
+    if (fontFaceFeatures) {
+        for (auto& fontFaceFeature : *fontFaceFeatures) {
+            if (fontFaceFeature.enabled()) {
+                const auto& tag = fontFaceFeature.tag();
+                const char buffer[] = { tag[0], tag[1], tag[2], tag[3], '\0' };
+                FcPatternAddString(resultPattern.get(), FC_FONT_FEATURES, reinterpret_cast<const FcChar8*>(buffer));
+            }
+        }
+    }
+
     RefPtr<cairo_font_face_t> fontFace = adoptRef(cairo_ft_font_face_create_for_pattern(resultPattern.get()));
 #if ENABLE(VARIATION_FONTS)
     // Cairo doesn't have API to get the FT_Face of an unscaled font, so we need to

Modified: trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp (259187 => 259188)


--- trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp	2020-03-30 07:33:06 UTC (rev 259187)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp	2020-03-30 09:11:15 UTC (rev 259188)
@@ -75,12 +75,21 @@
     return adoptRef(FcPatternDuplicate(pattern));
 }
 
-FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& description, bool bold, bool italic, const FontFeatureSettings&, FontSelectionSpecifiedCapabilities)
+FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& description, bool bold, bool italic, const FontFeatureSettings& fontFaceFeatures, FontSelectionSpecifiedCapabilities)
 {
     auto* freeTypeFace = static_cast<FT_Face>(cairo_font_face_get_user_data(m_fontFace.get(), &freeTypeFaceKey));
     ASSERT(freeTypeFace);
     RefPtr<FcPattern> pattern = defaultFontconfigOptions();
     FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(freeTypeFace->family_name));
+
+    for (auto& fontFaceFeature : fontFaceFeatures) {
+        if (fontFaceFeature.enabled()) {
+            const auto& tag = fontFaceFeature.tag();
+            const char buffer[] = { tag[0], tag[1], tag[2], tag[3], '\0' };
+            FcPatternAddString(pattern.get(), FC_FONT_FEATURES, reinterpret_cast<const FcChar8*>(buffer));
+        }
+    }
+
 #if ENABLE(VARIATION_FONTS)
     auto variants = buildVariationSettings(freeTypeFace, description);
     if (!variants.isEmpty()) {

Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp (259187 => 259188)


--- trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp	2020-03-30 07:33:06 UTC (rev 259187)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp	2020-03-30 09:11:15 UTC (rev 259188)
@@ -28,6 +28,7 @@
 
 #include "CairoUtilities.h"
 #include "FontCascade.h"
+#include "FontTaggedSettings.h"
 #include "HbUniquePtr.h"
 #include "SurrogatePairAwareTextIterator.h"
 #include <hb-ft.h>
@@ -175,30 +176,228 @@
     m_initialAdvance = toFloatSize(m_glyphOrigins[0]);
 }
 
-static const hb_tag_t s_vertTag = HB_TAG('v', 'e', 'r', 't');
-static const hb_tag_t s_vrt2Tag = HB_TAG('v', 'r', 't', '2');
-static const hb_tag_t s_kernTag = HB_TAG('k', 'e', 'r', 'n');
-static const unsigned s_hbEnd = static_cast<unsigned>(-1);
+using FeaturesMap = HashMap<FontTag, int, FourCharacterTagHash, FourCharacterTagHashTraits>;
 
-static Vector<hb_feature_t, 4> fontFeatures(const FontCascade& font, FontOrientation orientation)
+static void setFeatureSettingsFromVariants(const FontVariantSettings& variantSettings, FeaturesMap& features)
 {
-    Vector<hb_feature_t, 4> features;
+    switch (variantSettings.commonLigatures) {
+    case FontVariantLigatures::Normal:
+        break;
+    case FontVariantLigatures::Yes:
+        features.set(fontFeatureTag("liga"), 1);
+        features.set(fontFeatureTag("clig"), 1);
+        break;
+    case FontVariantLigatures::No:
+        features.set(fontFeatureTag("liga"), 0);
+        features.set(fontFeatureTag("clig"), 0);
+        break;
+    }
 
-    if (orientation == FontOrientation::Vertical) {
-        features.append({ s_vertTag, 1, 0, s_hbEnd });
-        features.append({ s_vrt2Tag, 1, 0, s_hbEnd });
+    switch (variantSettings.discretionaryLigatures) {
+    case FontVariantLigatures::Normal:
+        break;
+    case FontVariantLigatures::Yes:
+        features.set(fontFeatureTag("dlig"), 1);
+        break;
+    case FontVariantLigatures::No:
+        features.set(fontFeatureTag("dlig"), 0);
+        break;
     }
 
-    hb_feature_t kerning = { s_kernTag, 0, 0, s_hbEnd };
-    if (font.enableKerning())
-        kerning.value = 1;
-    features.append(WTFMove(kerning));
+    switch (variantSettings.historicalLigatures) {
+    case FontVariantLigatures::Normal:
+        break;
+    case FontVariantLigatures::Yes:
+        features.set(fontFeatureTag("hlig"), 1);
+        break;
+    case FontVariantLigatures::No:
+        features.set(fontFeatureTag("hlig"), 0);
+        break;
+    }
 
-    for (auto& feature : font.fontDescription().featureSettings()) {
-        auto& tag = feature.tag();
-        features.append({ HB_TAG(tag[0], tag[1], tag[2], tag[3]), static_cast<uint32_t>(feature.value()), 0, s_hbEnd });
+    switch (variantSettings.contextualAlternates) {
+    case FontVariantLigatures::Normal:
+        break;
+    case FontVariantLigatures::Yes:
+        features.set(fontFeatureTag("calt"), 1);
+        break;
+    case FontVariantLigatures::No:
+        features.set(fontFeatureTag("calt"), 0);
+        break;
     }
 
+    switch (variantSettings.position) {
+    case FontVariantPosition::Normal:
+        break;
+    case FontVariantPosition::Subscript:
+        features.set(fontFeatureTag("subs"), 1);
+        break;
+    case FontVariantPosition::Superscript:
+        features.set(fontFeatureTag("sups"), 1);
+        break;
+    }
+
+    switch (variantSettings.caps) {
+    case FontVariantCaps::Normal:
+        break;
+    case FontVariantCaps::AllSmall:
+        features.set(fontFeatureTag("c2sc"), 1);
+        FALLTHROUGH;
+    case FontVariantCaps::Small:
+        features.set(fontFeatureTag("smcp"), 1);
+        break;
+    case FontVariantCaps::AllPetite:
+        features.set(fontFeatureTag("c2pc"), 1);
+        FALLTHROUGH;
+    case FontVariantCaps::Petite:
+        features.set(fontFeatureTag("pcap"), 1);
+        break;
+    case FontVariantCaps::Unicase:
+        features.set(fontFeatureTag("unic"), 1);
+        break;
+    case FontVariantCaps::Titling:
+        features.set(fontFeatureTag("titl"), 1);
+        break;
+    }
+
+    switch (variantSettings.numericFigure) {
+    case FontVariantNumericFigure::Normal:
+        break;
+    case FontVariantNumericFigure::LiningNumbers:
+        features.set(fontFeatureTag("lnum"), 1);
+        break;
+    case FontVariantNumericFigure::OldStyleNumbers:
+        features.set(fontFeatureTag("onum"), 1);
+        break;
+    }
+
+    switch (variantSettings.numericSpacing) {
+    case FontVariantNumericSpacing::Normal:
+        break;
+    case FontVariantNumericSpacing::ProportionalNumbers:
+        features.set(fontFeatureTag("pnum"), 1);
+        break;
+    case FontVariantNumericSpacing::TabularNumbers:
+        features.set(fontFeatureTag("tnum"), 1);
+        break;
+    }
+
+    switch (variantSettings.numericFraction) {
+    case FontVariantNumericFraction::Normal:
+        break;
+    case FontVariantNumericFraction::DiagonalFractions:
+        features.set(fontFeatureTag("frac"), 1);
+        break;
+    case FontVariantNumericFraction::StackedFractions:
+        features.set(fontFeatureTag("afrc"), 1);
+        break;
+    }
+
+    switch (variantSettings.numericOrdinal) {
+    case FontVariantNumericOrdinal::Normal:
+        break;
+    case FontVariantNumericOrdinal::Yes:
+        features.set(fontFeatureTag("ordn"), 1);
+        break;
+    }
+
+    switch (variantSettings.numericSlashedZero) {
+    case FontVariantNumericSlashedZero::Normal:
+        break;
+    case FontVariantNumericSlashedZero::Yes:
+        features.set(fontFeatureTag("zero"), 1);
+        break;
+    }
+
+    switch (variantSettings.alternates) {
+    case FontVariantAlternates::Normal:
+        break;
+    case FontVariantAlternates::HistoricalForms:
+        features.set(fontFeatureTag("hist"), 1);
+        break;
+    }
+
+    switch (variantSettings.eastAsianVariant) {
+    case FontVariantEastAsianVariant::Normal:
+        break;
+    case FontVariantEastAsianVariant::Jis78:
+        features.set(fontFeatureTag("jp78"), 1);
+        break;
+    case FontVariantEastAsianVariant::Jis83:
+        features.set(fontFeatureTag("jp83"), 1);
+        break;
+    case FontVariantEastAsianVariant::Jis90:
+        features.set(fontFeatureTag("jp90"), 1);
+        break;
+    case FontVariantEastAsianVariant::Jis04:
+        features.set(fontFeatureTag("jp04"), 1);
+        break;
+    case FontVariantEastAsianVariant::Simplified:
+        features.set(fontFeatureTag("smpl"), 1);
+        break;
+    case FontVariantEastAsianVariant::Traditional:
+        features.set(fontFeatureTag("trad"), 1);
+        break;
+    }
+
+    switch (variantSettings.eastAsianWidth) {
+    case FontVariantEastAsianWidth::Normal:
+        break;
+    case FontVariantEastAsianWidth::Full:
+        features.set(fontFeatureTag("fwid"), 1);
+        break;
+    case FontVariantEastAsianWidth::Proportional:
+        features.set(fontFeatureTag("pwid"), 1);
+        break;
+    }
+
+    switch (variantSettings.eastAsianRuby) {
+    case FontVariantEastAsianRuby::Normal:
+        break;
+    case FontVariantEastAsianRuby::Yes:
+        features.set(fontFeatureTag("ruby"), 1);
+        break;
+    }
+}
+
+static Vector<hb_feature_t, 4> fontFeatures(const FontCascade& font, const FontPlatformData& fontPlatformData)
+{
+    FeaturesMap featuresToBeApplied;
+
+    // 7.2. Feature precedence
+    // https://www.w3.org/TR/css-fonts-3/#feature-precedence
+
+    // 1. Font features enabled by default, including features required for a given script.
+
+    // 2. If the font is defined via an @font-face rule, the font features implied by the
+    //    font-feature-settings descriptor in the @font-face rule.
+    auto* fcPattern = fontPlatformData.fcPattern();
+    FcChar8* fcFontFeature;
+    for (int i = 0; FcPatternGetString(fcPattern, FC_FONT_FEATURES, i, &fcFontFeature) == FcResultMatch; ++i)
+        featuresToBeApplied.set(fontFeatureTag(reinterpret_cast<char*>(fcFontFeature)), 1);
+
+    // 3. Font features implied by the value of the ‘font-variant’ property, the related ‘font-variant’
+    //    subproperties and any other CSS property that uses OpenType features.
+    setFeatureSettingsFromVariants(font.fontDescription().variantSettings(), featuresToBeApplied);
+    featuresToBeApplied.set(fontFeatureTag("kern"), font.enableKerning() ? 1 : 0);
+
+    // 4. Feature settings determined by properties other than ‘font-variant’ or ‘font-feature-settings’.
+    if (fontPlatformData.orientation() == FontOrientation::Vertical) {
+        featuresToBeApplied.set(fontFeatureTag("vert"), 1);
+        featuresToBeApplied.set(fontFeatureTag("vrt2"), 1);
+    }
+
+    // 5. Font features implied by the value of ‘font-feature-settings’ property.
+    for (auto& feature : font.fontDescription().featureSettings())
+        featuresToBeApplied.set(feature.tag(), feature.value());
+
+    Vector<hb_feature_t, 4> features;
+    features.reserveInitialCapacity(featuresToBeApplied.size());
+    for (auto& iter : featuresToBeApplied) {
+        auto& tag = iter.key;
+        features.append({ HB_TAG(tag[0], tag[1], tag[2], tag[3]), static_cast<uint32_t>(iter.value), 0, static_cast<unsigned>(-1) });
+    }
+
     return features;
 }
 
@@ -276,8 +475,8 @@
         hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, scriptIndex, 0, &languageCount, languageTags);
         for (unsigned languageIndex = 0; languageIndex < languageCount; ++languageIndex) {
             unsigned featureIndex;
-            if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, s_vertTag, &featureIndex)
-                || hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, s_vrt2Tag, &featureIndex))
+            if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HB_TAG('v', 'e', 'r', 't'), &featureIndex)
+                || hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HB_TAG('v', 'r', 't', '2'), &featureIndex))
                 return hb_ot_tag_to_script(scriptTags[scriptIndex]);
         }
     }
@@ -341,7 +540,7 @@
 
     hb_font_make_immutable(harfBuzzFont.get());
 
-    auto features = fontFeatures(m_font, fontPlatformData.orientation());
+    auto features = fontFeatures(m_font, fontPlatformData);
     HbUniquePtr<hb_buffer_t> buffer(hb_buffer_create());
     if (fontPlatformData.orientation() == FontOrientation::Vertical)
         hb_buffer_set_script(buffer.get(), findScriptForVerticalGlyphSubstitution(face.get()));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to