Title: [264646] trunk
Revision
264646
Author
carlo...@webkit.org
Date
2020-07-21 01:06:34 -0700 (Tue, 21 Jul 2020)

Log Message

[FreeType] Add support for text-underline-offset and text-decoration-thickness
https://bugs.webkit.org/show_bug.cgi?id=214550

Reviewed by Adrian Perez de Castro.

Source/WebCore:

Get the underline position and thickness from the font if it's scalable and set them in font metrics.

* platform/graphics/freetype/SimpleFontDataFreeType.cpp:
(WebCore::scaledFontScaleFactor):
(WebCore::fontUnitsPerEm):
(WebCore::Font::platformInit):

LayoutTests:

Remove expectations for tests that are now passing.

* platform/gtk/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (264645 => 264646)


--- trunk/LayoutTests/ChangeLog	2020-07-21 08:03:28 UTC (rev 264645)
+++ trunk/LayoutTests/ChangeLog	2020-07-21 08:06:34 UTC (rev 264646)
@@ -1,3 +1,14 @@
+2020-07-21  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        [FreeType] Add support for text-underline-offset and text-decoration-thickness
+        https://bugs.webkit.org/show_bug.cgi?id=214550
+
+        Reviewed by Adrian Perez de Castro.
+
+        Remove expectations for tests that are now passing.
+
+        * platform/gtk/TestExpectations:
+
 2020-07-20  Alex Christensen  <achristen...@webkit.org>
 
         Revert r262776 for existing apps using UIWebView/WebView

Modified: trunk/LayoutTests/platform/gtk/TestExpectations (264645 => 264646)


--- trunk/LayoutTests/platform/gtk/TestExpectations	2020-07-21 08:03:28 UTC (rev 264645)
+++ trunk/LayoutTests/platform/gtk/TestExpectations	2020-07-21 08:06:34 UTC (rev 264646)
@@ -1230,9 +1230,6 @@
 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-backgrounds/background-repeat/background-repeat-round.xht [ ImageOnlyFailure ]
 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-backgrounds/background-repeat/background-repeat-space.xht [ ImageOnlyFailure ]
 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-backgrounds/background-size/background-size-contain.xht [ ImageOnlyFailure ]
-webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-text-decor/text-decoration-thickness-from-font-variable.html [ ImageOnlyFailure ]
-webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-text-decor/text-underline-offset-variable.html [ ImageOnlyFailure ]
-webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-text-decor/text-underline-position-from-font-variable.html [ ImageOnlyFailure ]
 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-values/ch-unit-002.html [ ImageOnlyFailure ]
 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-values/ch-unit-011.html [ ImageOnlyFailure ]
 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-images/image-orientation/image-orientation-border-image.html [ ImageOnlyFailure ]

Modified: trunk/Source/WebCore/ChangeLog (264645 => 264646)


--- trunk/Source/WebCore/ChangeLog	2020-07-21 08:03:28 UTC (rev 264645)
+++ trunk/Source/WebCore/ChangeLog	2020-07-21 08:06:34 UTC (rev 264646)
@@ -1,5 +1,19 @@
 2020-07-21  Carlos Garcia Campos  <cgar...@igalia.com>
 
+        [FreeType] Add support for text-underline-offset and text-decoration-thickness
+        https://bugs.webkit.org/show_bug.cgi?id=214550
+
+        Reviewed by Adrian Perez de Castro.
+
+        Get the underline position and thickness from the font if it's scalable and set them in font metrics.
+
+        * platform/graphics/freetype/SimpleFontDataFreeType.cpp:
+        (WebCore::scaledFontScaleFactor):
+        (WebCore::fontUnitsPerEm):
+        (WebCore::Font::platformInit):
+
+2020-07-21  Carlos Garcia Campos  <cgar...@igalia.com>
+
         [GTK][WPE] imported blink large gradient tests are crashing on debug builds
         https://bugs.webkit.org/show_bug.cgi?id=214192
 

Modified: trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp (264645 => 264646)


--- trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp	2020-07-21 08:03:28 UTC (rev 264645)
+++ trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp	2020-07-21 08:06:34 UTC (rev 264646)
@@ -66,6 +66,37 @@
     return adoptRef(cairo_scaled_font_create(cairo_scaled_font_get_font_face(scaledFont), &fontMatrix, &fontCTM, fontOptions.get()));
 }
 
+static float scaledFontScaleFactor(cairo_scaled_font_t* scaledFont)
+{
+    cairo_matrix_t fontMatrix;
+    cairo_scaled_font_get_font_matrix(scaledFont, &fontMatrix);
+
+    float determinant = fontMatrix.xx * fontMatrix.yy - fontMatrix.yx * fontMatrix.xy;
+    if (!std::isfinite(determinant))
+        return 1;
+
+    determinant = std::abs(determinant);
+    if (!determinant)
+        return 0;
+
+    double x = 1;
+    double y = 0;
+    cairo_matrix_transform_distance(&fontMatrix, &x, &y);
+    double xScale = std::hypot(x, y);
+    return xScale ? narrowPrecisionToFloat(determinant / xScale) : 0.;
+}
+
+static Optional<unsigned> fontUnitsPerEm(FT_Face freeTypeFace)
+{
+    if (freeTypeFace->units_per_EM)
+        return freeTypeFace->units_per_EM;
+
+    if (auto* ttHeader = static_cast<TT_Header*>(FT_Get_Sfnt_Table(freeTypeFace, ft_sfnt_head)))
+        return ttHeader->Units_Per_EM;
+
+    return WTF::nullopt;
+}
+
 void Font::platformInit()
 {
     if (!m_platformData.size())
@@ -84,24 +115,35 @@
     float capHeight = narrowPrecisionToFloat(fontExtents.height);
     float lineGap = narrowPrecisionToFloat(fontExtents.height - fontExtents.ascent - fontExtents.descent);
     Optional<float> xHeight;
+    Optional<unsigned> unitsPerEm;
+    Optional<float> underlinePosition;
+    Optional<float> underlineThickness;
 
     {
         CairoFtFaceLocker cairoFtFaceLocker(m_platformData.scaledFont());
+        if (FT_Face freeTypeFace = cairoFtFaceLocker.ftFace()) {
+            unitsPerEm = fontUnitsPerEm(freeTypeFace);
 
-        // If the USE_TYPO_METRICS flag is set in the OS/2 table then we use typo metrics instead.
-        FT_Face freeTypeFace = cairoFtFaceLocker.ftFace();
-        if (freeTypeFace && freeTypeFace->face_flags & FT_FACE_FLAG_SCALABLE) {
-            if (auto* OS2Table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(freeTypeFace, ft_sfnt_os2))) {
-                const FT_Short kUseTypoMetricsMask = 1 << 7;
-                // FT_Size_Metrics::y_scale is in 16.16 fixed point format.
-                // Its (fractional) value is a factor that converts vertical metrics from design units to units of 1/64 pixels.
-                double yscale = (freeTypeFace->size->metrics.y_scale / 65536.0) / 64.0;
-                if (OS2Table->fsSelection & kUseTypoMetricsMask) {
-                    ascent = narrowPrecisionToFloat(yscale * OS2Table->sTypoAscender);
-                    descent = -narrowPrecisionToFloat(yscale * OS2Table->sTypoDescender);
-                    lineGap = narrowPrecisionToFloat(yscale * OS2Table->sTypoLineGap);
+            if (freeTypeFace->face_flags & FT_FACE_FLAG_SCALABLE) {
+                // If the USE_TYPO_METRICS flag is set in the OS/2 table then we use typo metrics instead.
+                if (auto* OS2Table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(freeTypeFace, ft_sfnt_os2))) {
+                    const FT_Short kUseTypoMetricsMask = 1 << 7;
+                    // FT_Size_Metrics::y_scale is in 16.16 fixed point format.
+                    // Its (fractional) value is a factor that converts vertical metrics from design units to units of 1/64 pixels.
+                    double yscale = (freeTypeFace->size->metrics.y_scale / 65536.0) / 64.0;
+                    if (OS2Table->fsSelection & kUseTypoMetricsMask) {
+                        ascent = narrowPrecisionToFloat(yscale * OS2Table->sTypoAscender);
+                        descent = -narrowPrecisionToFloat(yscale * OS2Table->sTypoDescender);
+                        lineGap = narrowPrecisionToFloat(yscale * OS2Table->sTypoLineGap);
+                    }
+                    xHeight = narrowPrecisionToFloat(yscale * OS2Table->sxHeight);
                 }
-                xHeight = narrowPrecisionToFloat(yscale * OS2Table->sxHeight);
+
+                if (unitsPerEm) {
+                    float scaleFactor = scaledFontScaleFactor(fontWithoutMetricsHinting.get());
+                    underlinePosition = -((freeTypeFace->underline_position + freeTypeFace->underline_thickness / 2.) / static_cast<float>(unitsPerEm.value())) * scaleFactor;
+                    underlineThickness = (freeTypeFace->underline_thickness / static_cast<float>(unitsPerEm.value())) * scaleFactor;
+                }
             }
         }
     }
@@ -118,17 +160,16 @@
     m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
     m_fontMetrics.setLineGap(lineGap);
     m_fontMetrics.setXHeight(xHeight.value());
+    if (unitsPerEm)
+        m_fontMetrics.setUnitsPerEm(unitsPerEm.value());
+    if (underlinePosition)
+        m_fontMetrics.setUnderlinePosition(underlinePosition.value());
+    if (underlineThickness)
+        m_fontMetrics.setUnderlineThickness(underlineThickness.value());
 
     cairo_text_extents_t textExtents;
     cairo_scaled_font_text_extents(m_platformData.scaledFont(), " ", &textExtents);
     m_spaceWidth = narrowPrecisionToFloat((platformData().orientation() == FontOrientation::Horizontal) ? textExtents.x_advance : -textExtents.y_advance);
-
-    if ((platformData().orientation() == FontOrientation::Vertical) && !isTextOrientationFallback()) {
-        CairoFtFaceLocker cairoFtFaceLocker(m_platformData.scaledFont());
-        FT_Face freeTypeFace = cairoFtFaceLocker.ftFace();
-        m_fontMetrics.setUnitsPerEm(freeTypeFace->units_per_EM);
-    }
-
     m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
 
     FcChar8* fontConfigFamilyName;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to