Skip to content

Commit ce3ffc8

Browse files
committed
[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: Canonical link: https://commits.webkit.org/227392@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@264646 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 402caad commit ce3ffc8

4 files changed

Lines changed: 86 additions & 23 deletions

File tree

LayoutTests/ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2020-07-21 Carlos Garcia Campos <[email protected]>
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+
112
2020-07-20 Alex Christensen <[email protected]>
213

314
Revert r262776 for existing apps using UIWebView/WebView

LayoutTests/platform/gtk/TestExpectations

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,9 +1230,6 @@ webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-backgrounds/backgrou
12301230
webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-backgrounds/background-repeat/background-repeat-round.xht [ ImageOnlyFailure ]
12311231
webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-backgrounds/background-repeat/background-repeat-space.xht [ ImageOnlyFailure ]
12321232
webkit.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 ]
12361233
webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-values/ch-unit-002.html [ ImageOnlyFailure ]
12371234
webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-values/ch-unit-011.html [ ImageOnlyFailure ]
12381235
webkit.org/b/214470 imported/w3c/web-platform-tests/css/css-images/image-orientation/image-orientation-border-image.html [ ImageOnlyFailure ]

Source/WebCore/ChangeLog

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2020-07-21 Carlos Garcia Campos <[email protected]>
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+
115
2020-07-21 Carlos Garcia Campos <[email protected]>
216

317
[GTK][WPE] imported blink large gradient tests are crashing on debug builds

Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,37 @@ static RefPtr<cairo_scaled_font_t> scaledFontWithoutMetricsHinting(cairo_scaled_
6666
return adoptRef(cairo_scaled_font_create(cairo_scaled_font_get_font_face(scaledFont), &fontMatrix, &fontCTM, fontOptions.get()));
6767
}
6868

69+
static 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+
89+
static 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+
69100
void Font::platformInit()
70101
{
71102
if (!m_platformData.size())
@@ -84,24 +115,35 @@ void Font::platformInit()
84115
float capHeight = narrowPrecisionToFloat(fontExtents.height);
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());
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);
140+
}
90141

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);
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;
103146
}
104-
xHeight = narrowPrecisionToFloat(yscale * OS2Table->sxHeight);
105147
}
106148
}
107149
}
@@ -118,17 +160,16 @@ void Font::platformInit()
118160
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
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

134175
FcChar8* fontConfigFamilyName;

0 commit comments

Comments
 (0)