⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 264646 in webkit


Ignore:
Timestamp:
Jul 21, 2020, 1:06:34 AM (6 years ago)
Author:
Carlos Garcia Campos
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:
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r264642 r264646  
     12020-07-21  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [FreeType] Add support for text-underline-offset and text-decoration-thickness
     4        https://bugs.webkit.org/show_bug.cgi?id=214550
     5
     6        Reviewed by Adrian Perez de Castro.
     7
     8        Remove expectations for tests that are now passing.
     9
     10        * platform/gtk/TestExpectations:
     11
    1122020-07-20  Alex Christensen  <achristensen@webkit.org>
    213
  • trunk/LayoutTests/platform/gtk/TestExpectations

    r264607 r264646  
    12311231webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-backgrounds/background-repeat/background-repeat-space.xht [ ImageOnlyFailure ]
    12321232webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-backgrounds/background-size/background-size-contain.xht [ ImageOnlyFailure ]
    1233 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-text-decor/text-decoration-thickness-from-font-variable.html [ ImageOnlyFailure ]
    1234 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-text-decor/text-underline-offset-variable.html [ ImageOnlyFailure ]
    1235 webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-text-decor/text-underline-position-from-font-variable.html [ ImageOnlyFailure ]
    12361233webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-values/ch-unit-002.html [ ImageOnlyFailure ]
    12371234webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-values/ch-unit-011.html [ ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r264645 r264646  
     12020-07-21  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [FreeType] Add support for text-underline-offset and text-decoration-thickness
     4        https://bugs.webkit.org/show_bug.cgi?id=214550
     5
     6        Reviewed by Adrian Perez de Castro.
     7
     8        Get the underline position and thickness from the font if it's scalable and set them in font metrics.
     9
     10        * platform/graphics/freetype/SimpleFontDataFreeType.cpp:
     11        (WebCore::scaledFontScaleFactor):
     12        (WebCore::fontUnitsPerEm):
     13        (WebCore::Font::platformInit):
     14
    1152020-07-21  Carlos Garcia Campos  <cgarcia@igalia.com>
    216
  • trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp

    r254567 r264646  
    6767}
    6868
     69static float scaledFontScaleFactor(cairo_scaled_font_t* scaledFont)
     70{
     71    cairo_matrix_t fontMatrix;
     72    cairo_scaled_font_get_font_matrix(scaledFont, &fontMatrix);
     73
     74    float determinant = fontMatrix.xx * fontMatrix.yy - fontMatrix.yx * fontMatrix.xy;
     75    if (!std::isfinite(determinant))
     76        return 1;
     77
     78    determinant = std::abs(determinant);
     79    if (!determinant)
     80        return 0;
     81
     82    double x = 1;
     83    double y = 0;
     84    cairo_matrix_transform_distance(&fontMatrix, &x, &y);
     85    double xScale = std::hypot(x, y);
     86    return xScale ? narrowPrecisionToFloat(determinant / xScale) : 0.;
     87}
     88
     89static Optional<unsigned> fontUnitsPerEm(FT_Face freeTypeFace)
     90{
     91    if (freeTypeFace->units_per_EM)
     92        return freeTypeFace->units_per_EM;
     93
     94    if (auto* ttHeader = static_cast<TT_Header*>(FT_Get_Sfnt_Table(freeTypeFace, ft_sfnt_head)))
     95        return ttHeader->Units_Per_EM;
     96
     97    return WTF::nullopt;
     98}
     99
    69100void Font::platformInit()
    70101{
     
    85116    float lineGap = narrowPrecisionToFloat(fontExtents.height - fontExtents.ascent - fontExtents.descent);
    86117    Optional<float> xHeight;
     118    Optional<unsigned> unitsPerEm;
     119    Optional<float> underlinePosition;
     120    Optional<float> underlineThickness;
    87121
    88122    {
    89123        CairoFtFaceLocker cairoFtFaceLocker(m_platformData.scaledFont());
    90 
    91         // If the USE_TYPO_METRICS flag is set in the OS/2 table then we use typo metrics instead.
    92         FT_Face freeTypeFace = cairoFtFaceLocker.ftFace();
    93         if (freeTypeFace && freeTypeFace->face_flags & FT_FACE_FLAG_SCALABLE) {
    94             if (auto* OS2Table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(freeTypeFace, ft_sfnt_os2))) {
    95                 const FT_Short kUseTypoMetricsMask = 1 << 7;
    96                 // FT_Size_Metrics::y_scale is in 16.16 fixed point format.
    97                 // Its (fractional) value is a factor that converts vertical metrics from design units to units of 1/64 pixels.
    98                 double yscale = (freeTypeFace->size->metrics.y_scale / 65536.0) / 64.0;
    99                 if (OS2Table->fsSelection & kUseTypoMetricsMask) {
    100                     ascent = narrowPrecisionToFloat(yscale * OS2Table->sTypoAscender);
    101                     descent = -narrowPrecisionToFloat(yscale * OS2Table->sTypoDescender);
    102                     lineGap = narrowPrecisionToFloat(yscale * OS2Table->sTypoLineGap);
     124        if (FT_Face freeTypeFace = cairoFtFaceLocker.ftFace()) {
     125            unitsPerEm = fontUnitsPerEm(freeTypeFace);
     126
     127            if (freeTypeFace->face_flags & FT_FACE_FLAG_SCALABLE) {
     128                // If the USE_TYPO_METRICS flag is set in the OS/2 table then we use typo metrics instead.
     129                if (auto* OS2Table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(freeTypeFace, ft_sfnt_os2))) {
     130                    const FT_Short kUseTypoMetricsMask = 1 << 7;
     131                    // FT_Size_Metrics::y_scale is in 16.16 fixed point format.
     132                    // Its (fractional) value is a factor that converts vertical metrics from design units to units of 1/64 pixels.
     133                    double yscale = (freeTypeFace->size->metrics.y_scale / 65536.0) / 64.0;
     134                    if (OS2Table->fsSelection & kUseTypoMetricsMask) {
     135                        ascent = narrowPrecisionToFloat(yscale * OS2Table->sTypoAscender);
     136                        descent = -narrowPrecisionToFloat(yscale * OS2Table->sTypoDescender);
     137                        lineGap = narrowPrecisionToFloat(yscale * OS2Table->sTypoLineGap);
     138                    }
     139                    xHeight = narrowPrecisionToFloat(yscale * OS2Table->sxHeight);
    103140                }
    104                 xHeight = narrowPrecisionToFloat(yscale * OS2Table->sxHeight);
     141
     142                if (unitsPerEm) {
     143                    float scaleFactor = scaledFontScaleFactor(fontWithoutMetricsHinting.get());
     144                    underlinePosition = -((freeTypeFace->underline_position + freeTypeFace->underline_thickness / 2.) / static_cast<float>(unitsPerEm.value())) * scaleFactor;
     145                    underlineThickness = (freeTypeFace->underline_thickness / static_cast<float>(unitsPerEm.value())) * scaleFactor;
     146                }
    105147            }
    106148        }
     
    119161    m_fontMetrics.setLineGap(lineGap);
    120162    m_fontMetrics.setXHeight(xHeight.value());
     163    if (unitsPerEm)
     164        m_fontMetrics.setUnitsPerEm(unitsPerEm.value());
     165    if (underlinePosition)
     166        m_fontMetrics.setUnderlinePosition(underlinePosition.value());
     167    if (underlineThickness)
     168        m_fontMetrics.setUnderlineThickness(underlineThickness.value());
    121169
    122170    cairo_text_extents_t textExtents;
    123171    cairo_scaled_font_text_extents(m_platformData.scaledFont(), " ", &textExtents);
    124172    m_spaceWidth = narrowPrecisionToFloat((platformData().orientation() == FontOrientation::Horizontal) ? textExtents.x_advance : -textExtents.y_advance);
    125 
    126     if ((platformData().orientation() == FontOrientation::Vertical) && !isTextOrientationFallback()) {
    127         CairoFtFaceLocker cairoFtFaceLocker(m_platformData.scaledFont());
    128         FT_Face freeTypeFace = cairoFtFaceLocker.ftFace();
    129         m_fontMetrics.setUnitsPerEm(freeTypeFace->units_per_EM);
    130     }
    131 
    132173    m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
    133174
Note: See TracChangeset for help on using the changeset viewer.