mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-01 13:49:16 +00:00
LibWeb/Painting: Paint triangle waves using Skia
This has been left unimplemented since we switched to the Skia renderer. Now `text-decoration-style: wavy` actually paints a wavy line. :^) We had a text-decoration test, but it only checked `solid` lines, so I've replaced it with a modified version of the old test page from Serenity, without the blink option, and with some thickness parameters. I did experiment with using a `SkPath1DPathEffect` to make it repeat the pattern for us, but I couldn't make it look good at all.
This commit is contained in:
parent
08246bfa8c
commit
d8a73a8165
Notes:
github-actions[bot]
2025-02-28 16:35:17 +00:00
Author: https://github.com/AtkinsSJ
Commit: d8a73a8165
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3724
3 changed files with 81 additions and 30 deletions
|
@ -816,8 +816,77 @@ void DisplayListPlayerSkia::paint_conic_gradient(PaintConicGradient const& comma
|
||||||
surface().canvas().drawRect(to_skia_rect(rect), paint);
|
surface().canvas().drawRect(to_skia_rect(rect), paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListPlayerSkia::draw_triangle_wave(DrawTriangleWave const&)
|
void DisplayListPlayerSkia::draw_triangle_wave(DrawTriangleWave const& command)
|
||||||
{
|
{
|
||||||
|
// Skia treats zero thickness as a special case and will draw a hairline, while we want to draw nothing.
|
||||||
|
if (!command.thickness)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// FIXME: Support more than horizontal waves
|
||||||
|
if (command.p1.y() != command.p2.y()) {
|
||||||
|
dbgln("FIXME: Support more than horizontal waves");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& canvas = surface().canvas();
|
||||||
|
auto from = to_skia_point(command.p1);
|
||||||
|
auto to = to_skia_point(command.p2);
|
||||||
|
|
||||||
|
SkPaint paint;
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
paint.setStyle(SkPaint::kStroke_Style);
|
||||||
|
paint.setStrokeWidth(command.thickness);
|
||||||
|
paint.setStrokeJoin(SkPaint::kRound_Join);
|
||||||
|
paint.setStrokeCap(SkPaint::kRound_Cap);
|
||||||
|
paint.setColor(to_skia_color(command.color));
|
||||||
|
|
||||||
|
SkPath path;
|
||||||
|
path.moveTo(from);
|
||||||
|
|
||||||
|
float const wavelength = command.amplitude * 2.0f;
|
||||||
|
float const half_wavelength = command.amplitude;
|
||||||
|
float const quarter_wavelength = command.amplitude / 2.0f;
|
||||||
|
|
||||||
|
auto position = from;
|
||||||
|
auto remaining = abs(to.x() - position.x());
|
||||||
|
while (remaining > wavelength) {
|
||||||
|
// Draw a whole wave
|
||||||
|
path.lineTo(position.x() + quarter_wavelength, position.y() - quarter_wavelength);
|
||||||
|
path.lineTo(position.x() + quarter_wavelength + half_wavelength, position.y() + quarter_wavelength);
|
||||||
|
path.lineTo(position.x() + wavelength, position.y());
|
||||||
|
position.offset(wavelength, 0);
|
||||||
|
remaining = abs(to.x() - position.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Up
|
||||||
|
if (remaining > quarter_wavelength) {
|
||||||
|
path.lineTo(position.x() + quarter_wavelength, position.y() - quarter_wavelength);
|
||||||
|
position.offset(quarter_wavelength, 0);
|
||||||
|
remaining = abs(to.x() - position.x());
|
||||||
|
} else if (remaining >= 1) {
|
||||||
|
auto fraction = remaining / quarter_wavelength;
|
||||||
|
path.lineTo(position.x() + (fraction * quarter_wavelength), position.y() - (fraction * quarter_wavelength));
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Down
|
||||||
|
if (remaining > half_wavelength) {
|
||||||
|
path.lineTo(position.x() + half_wavelength, position.y() + quarter_wavelength);
|
||||||
|
position.offset(half_wavelength, 0);
|
||||||
|
remaining = abs(to.x() - position.x());
|
||||||
|
} else if (remaining >= 1) {
|
||||||
|
auto fraction = remaining / half_wavelength;
|
||||||
|
path.lineTo(position.x() + (fraction * half_wavelength), position.y() - quarter_wavelength + (fraction * half_wavelength));
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Back to middle
|
||||||
|
if (remaining >= 1) {
|
||||||
|
auto fraction = remaining / quarter_wavelength;
|
||||||
|
path.lineTo(position.x() + (fraction * quarter_wavelength), position.y() + ((1 - fraction) * quarter_wavelength));
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListPlayerSkia::add_rounded_rect_clip(AddRoundedRectClip const& command)
|
void DisplayListPlayerSkia::add_rounded_rect_clip(AddRoundedRectClip const& command)
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 15 KiB |
|
@ -3,37 +3,19 @@
|
||||||
<head>
|
<head>
|
||||||
<link rel="match" href="../expected/text-decorations-ref.html" />
|
<link rel="match" href="../expected/text-decorations-ref.html" />
|
||||||
<style>
|
<style>
|
||||||
.underline {
|
.overline { text-decoration: wavy blue overline 2px; }
|
||||||
text-decoration: underline;
|
.underline { text-decoration: red underline double; }
|
||||||
text-decoration-thickness: 2px;
|
.strikethrough { text-decoration: line-through dotted green 5px; }
|
||||||
}
|
.current-color { color: #8B4513; text-decoration: underline; }
|
||||||
|
.overboard { text-decoration: double overline underline line-through magenta; }
|
||||||
.overline {
|
|
||||||
text-decoration: overline;
|
|
||||||
text-decoration-thickness: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-through {
|
|
||||||
text-decoration: line-through;
|
|
||||||
text-decoration-thickness: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.underline-overline {
|
|
||||||
text-decoration: underline overline;
|
|
||||||
text-decoration-thickness: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.underline-line-through {
|
|
||||||
text-decoration: underline line-through;
|
|
||||||
text-decoration-thickness: 2px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p class="underline">Hello</p>
|
<p class="overline">Overline</p>
|
||||||
<p class="overline">Hello</p>
|
<p class="underline">Underline</p>
|
||||||
<p class="line-through">Hello</p>
|
<p class="strikethrough">Wombling</p>
|
||||||
<p class="underline-overline">Hello</p>
|
<p class="blink">FREE!</p>
|
||||||
<p class="underline-line-through">Hello</p>
|
<p class="current-color">This underline should match the text color</p>
|
||||||
|
<p class="overboard">This should have an underline, overline and line-through, all in glorious magenta.</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue