LibWeb: Make text-decoration lines entire width of fragment

This fixes an issue where text decorations (e.g. underlines) of text
split across multiple fragments would have unintended 1px gaps.

Gains us 2 WPT passes (imported)
This commit is contained in:
Callum Law 2025-09-12 01:00:59 +12:00 committed by Tim Ledbetter
commit 9aa2d1bd3e
Notes: github-actions[bot] 2025-09-12 06:08:17 +00:00
8 changed files with 154 additions and 4 deletions

View file

@ -841,16 +841,16 @@ void paint_text_decoration(DisplayListRecordingContext& context, TextPaintable c
return;
case CSS::TextDecorationLine::Underline:
line_start_point = context.rounded_device_point(fragment_box.top_left().translated(0, baseline + 2));
line_end_point = context.rounded_device_point(fragment_box.top_right().translated(-1, baseline + 2));
line_end_point = context.rounded_device_point(fragment_box.top_right().translated(0, baseline + 2));
break;
case CSS::TextDecorationLine::Overline:
line_start_point = context.rounded_device_point(fragment_box.top_left().translated(0, baseline - glyph_height));
line_end_point = context.rounded_device_point(fragment_box.top_right().translated(-1, baseline - glyph_height));
line_end_point = context.rounded_device_point(fragment_box.top_right().translated(0, baseline - glyph_height));
break;
case CSS::TextDecorationLine::LineThrough: {
auto x_height = font.x_height();
line_start_point = context.rounded_device_point(fragment_box.top_left().translated(0, baseline - x_height * CSSPixels(0.5f)));
line_end_point = context.rounded_device_point(fragment_box.top_right().translated(-1, baseline - x_height * CSSPixels(0.5f)));
line_end_point = context.rounded_device_point(fragment_box.top_right().translated(0, baseline - x_height * CSSPixels(0.5f)));
break;
}
case CSS::TextDecorationLine::Blink:

View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<meta charset="UTF-8" />
<title>text-decoration-thickness calc() support</title>
<link rel="author" title="ChangSeok Oh" href="mailto:changseok@webkit.org" />
<link rel="stylesheet" type="text/css" href="../../../../../Text/input/wpt-import/fonts/ahem.css" />
<style type="text/css">
div {
display: flex;
font-family: Ahem;
font-size: 8px;
}
.underline {
text-decoration-color: green;
text-decoration-line: underline;
text-decoration-skip-ink: none;
}
.overline {
text-decoration-color: green;
text-decoration-line: overline;
text-decoration-skip-ink: none;
}
.line-through {
text-decoration-color: green;
text-decoration-line: line-through;
text-decoration-skip-ink: none;
}
.ref {
text-decoration-thickness: 8px;
}
</style>
<p>Test passes if black and green bar pairs are the same shape and size.</p>
<div>
<span class="underline ref">XXXXXX</span>
</div>
<br />
<br />
<div>
<span class="overline ref">XXXXXX</span>
</div>
<br />
<div>
<span class="ref">XXXXXX</span>
</div>
<div>
<span class="line-through ref">XXXXXX</span>
</div>

View file

@ -0,0 +1,3 @@
<!doctype html>
<title>CSS Test Reference</title>
<!-- Intentionally blank -->

View file

@ -0,0 +1,79 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>text-decoration-thickness calc() support</title>
<link rel="author" title="ChangSeok Oh" href="mailto:changseok@webkit.org" />
<link rel="help" href="https://www.w3.org/TR/css-text-decor-4/#text-decoration-thickness-property" />
<link rel="match" href="../../../../expected/wpt-import/css/css-text-decor/text-decoration-thickness-calc-ref.html" />
<link rel="stylesheet" type="text/css" href="../../../../../Text/input/wpt-import/fonts/ahem.css">
<meta name="assert" content="Test checks whether text-decoration-thickness supports calc() values.">
<style type="text/css">
div {
display: flex;
font-family: Ahem;
font-size: 8px;
}
.underline {
text-decoration-color: green;
text-decoration-line: underline;
text-decoration-skip-ink: none;
}
.overline {
text-decoration-color: green;
text-decoration-line: overline;
text-decoration-skip-ink: none;
}
.line-through {
text-decoration-color: green;
text-decoration-line: line-through;
text-decoration-skip-ink: none;
}
.ref {
text-decoration-thickness: 8px;
}
.test1 {
text-decoration-thickness: calc(1em);
}
.test2 {
text-decoration-thickness: calc(100%);
}
.test3 {
text-decoration-thickness: calc(50% + 4px);
}
.test4 {
text-decoration-thickness: calc(50% + 0.5em);
}
.test5 {
text-decoration-thickness: calc(0.5em + 4px);
}
</style>
<p>Test passes if black and green bar pairs are the same shape and size.</p>
<div>
<span class="underline ref">X</span>
<span class="underline test1">X</span>
<span class="underline test2">X</span>
<span class="underline test3">X</span>
<span class="underline test4">X</span>
<span class="underline test5">X</span>
</div>
<br>
<br>
<div>
<span class="overline ref">X</span>
<span class="overline test1">X</span>
<span class="overline test2">X</span>
<span class="overline test3">X</span>
<span class="overline test4">X</span>
<span class="overline test5">X</span>
</div>
<br>
<div>
<span class="ref">XXXXXX</span>
</div>
<div>
<span class="line-through ref">X</span>
<span class="line-through test1">X</span>
<span class="line-through test2">X</span>
<span class="line-through test3">X</span>
<span class="line-through test4">X</span>
<span class="line-through test5">X</span>
</div>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>text-decoration-thickness: from-font with zero sized font</title>
<meta name="assert" content="text-decoration-thickness: from-font with a zero size font does not crash">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-text-decor-4/#text-decoration-width-property">
<link rel="match" href="../../../../expected/wpt-import/css/css-text-decor/../reference/blank.html">
<link rel="stylesheet" type="text/css" href="../../fonts/ahem.css">
<style>
span {
font-size: 0px;
text-decoration: line-through;
text-decoration-thickness: from-font;
}
</style>
</head>
<body>
<span>This line has a zero sized font.</span>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

View file

@ -4,7 +4,7 @@ SaveLayer
FillRect rect=[8,8 106x22] color=rgb(212, 208, 200)
FillPath
DrawGlyphRun rect=[13,10 96x18] translation=[13,23.796875] color=rgb(0, 0, 0) scale=1
DrawLine from=[13,26] to=[108,26] color=rgb(0, 0, 0) thickness=2
DrawLine from=[13,26] to=[109,26] color=rgb(0, 0, 0) thickness=2
PopStackingContext
PopStackingContext
Restore