Commit Graph

78 Commits

Author SHA1 Message Date
Aliaksandr Kalenik
d2528dd5ce LibWeb: Compare Screenshot tests directly against expected PNGs
Instead of rendering a reference HTML page that wraps an <img> tag
pointing to a PNG, Screenshot tests now load the expected PNG directly
from disk and compare it against the rendered screenshot. This
eliminates the indirection of loading and rendering a second page just
to display a static image.

This also means --rebaseline now works for Screenshot tests, generating
the expected PNG automatically instead of requiring manual screenshot
capture and placement.

Changes:
- Add TestMode::Screenshot with its own collector and runner
- Move PNGs from Screenshot/images/ to Screenshot/expected/ with
  normalized names matching input filenames
- Remove all 92 reference HTML wrapper files and the images/
  directory
- Remove <link rel="match"> from all 94 Screenshot input HTML
  files
- Update add_libweb_test.py Screenshot boilerplate accordingly
- Add Screenshot mode to results viewer image comparison tabs
2026-02-24 09:55:14 +01:00
Aliaksandr Kalenik
86bc379119 Tests: Move true ref tests from Screenshot/ to Ref/
Move them to Ref/ where they belong, before converting the remaining
Screenshot tests to direct PNG comparison.
2026-02-24 09:55:14 +01:00
Aliaksandr Kalenik
5ef132ba1a LibWeb: Replace AddMask/clipShader with saveLayer+DstIn compositing
This applies the same pattern used for background-clip: text (commit
f2e6f70fbb).

Results in visible performance improvement in Discord app where
previously, according to profiles, we spent lots of time allocating
surfaces for masks.
2026-02-24 07:14:16 +01:00
Jelle Raaijmakers
f2e6f70fbb LibWeb: Use saveLayer compositing for background-clip: text
Instead of rendering text glyphs into a separate mask surface and using
clipShader, paint the backgrounds first and then composite the text
glyphs via saveLayer with SkBlendMode::kDstIn. Skia's saveLayer
automatically sizes its backing at device resolution including CSS
transforms, so no manual scale computation is needed.

Fixes pixelation when zooming in on clipped backgrounds on e.g. the
title of https://modern-css.com/.
2026-02-17 18:59:33 +01:00
Callum Law
87eef9e21a LibWeb: Always apply stroke-dasharray
Previously we didn't apply the value of `stroke-dasharray` if it was
`none`.

We also move resolution of this property into `ComputedProperties` in
line with other properties.
2026-02-12 10:26:43 +00:00
Luke Wilde
e9f5df2131 LibWeb/SVG: Implement the feTurbulence filter 2026-02-11 09:39:39 +01:00
Jelle Raaijmakers
b048dbd23a LibWeb: Apply selection highlight to selected images 2026-02-06 10:47:50 +00:00
Jelle Raaijmakers
69fa144539 LibWeb: Keep track of trailing whitespace for wrapped lines
When rendering selections, we want to extend the selection rect for
wrapped lines to show that there is whitespace present. We don't
actually store this whitespace in the fragments; it's purely a visual
clue.

This reflects how both Chrome and Firefox deal with selection ranges
over wrapped lines.
2026-02-06 10:47:50 +00:00
Jelle Raaijmakers
b85fd9e5c7 LibWeb: Make the highlight color semi-transparent
This looks a bit more fancy.
2026-02-06 10:47:50 +00:00
Callum Law
2f7848913b LibWeb: Always respect font-variation-settings
Previously we wouldn't respect font-variation-settings for fonts matched
through `font_matching_algorithm` (i.e. any fonts which didn't have an
exact loaded match).
2026-01-21 23:49:25 +01:00
Tim Ledbetter
81973cafa4 LibWeb: Size root element backgrounds relative to its border box 2026-01-18 00:31:03 +01:00
Luke Wilde
61a344a718 LibWeb: Remove "can run script" checks from MainThreadVM hooks
This allows Promises (including internal ones, like in Streams) and
FinalizationRegistry to work while scripting is disabled.

These were removed in the spec in support of WebDriver BiDi being able
to enable and disable scripting.

https://github.com/whatwg/html/commit/905b7218

This allows Fetch to work while scripting is disabled, due to its use
of Streams. This was noticeable if you disabled scripting in the UI,
or had a sandboxed iframe with scripting disabled.

There is more work to use job settings instead of realm inside these
hooks, but that's a separate issue.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/7409
Fixes https://github.com/LadybirdBrowser/ladybird/issues/3729
2026-01-16 20:48:47 +01:00
ayeteadoe
ee3aa865af Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port
Skia deprecated some non-span versions of their API, but they provided
SK_SUPPORT_UNSPANNED_APIS to expose the legacy versions.

SkFontMgr_New_FontConfig now requires a font scanner to be passed in.

There were a few screenshot tests that visibily looked the same but skia
must've changed some rendering infrastructure as the PNGs were not
matching anymore so I rebaselined those and adjusted the fuzzy matching
config to allow them to pass on both macOS and Linux.

The empty-radial-gradient-crash Ref test started to fail as we were
setting the horizontal scale factor to inf in when the height = 0. It
looks like something changed to make doing that not valid anymore.

The overlay port is removed as the issues, mainly skcms symbol import
and export were resolved upstream in skia and utilized in the new port
version.
2025-12-17 12:00:33 +01:00
Jelle Raaijmakers
34e99c2611 Tests: Increase fuzzy range for canvas-pattern-transform.html on arm64
We don't actually have the ability to differentiate between
architectures in the fuzzy config, so increase the upper range of the
total number of error pixels for this specific tests.

Visually the results are still the same between platforms/architectures.
2025-12-16 06:49:39 -05:00
Andreas Kling
2577c5ce67 Revert "Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port"
This reverts commit ac9688ea1e.

Broke the build on arm64 Linux.
2025-12-15 14:12:34 -06:00
ayeteadoe
ac9688ea1e Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port
Skia deprecated some non-span versions of their API, but they provided
SK_SUPPORT_UNSPANNED_APIS to expose the legacy versions.

SkFontMgr_New_FontConfig now requires a font scanner to be passed in.

There were a few screenshot tests that visibily looked the same but skia
must've changed some rendering infrastructure as the PNGs were not
matching anymore so I rebaselined those and adjusted the fuzzy matching
config to allow them to pass on both macOS and Linux.

The empty-radial-gradient-crash Ref test started to fail as we were
setting the horizontal scale factor to inf in when the height = 0. It
looks like something changed to make doing that not valid anymore.

The overlay port is removed as the issues, mainly skcms symbol import
and export were resolved upstream in skia and utilized in the new port
version.
2025-12-15 10:56:27 +01:00
Callum Law
daf464844b LibWeb: Support all <radial-extent> values in ellipse()
To do this we use the generic `RadialSizeStyleValue` which allows us to
remove the remaining logic around `<shape-radius>`
2025-12-12 12:20:16 +00:00
Callum Law
8501d6995d LibWeb: Support all <radial-extent> values in circle() 2025-12-12 12:20:16 +00:00
Callum Law
4909e19aca LibWeb: Make <radal-size> parsing generic
Previously this was implemented inline within the parsing of
`{repeating}-radial-gradient()` functions but it will also be useful for
`circle()` and `ellipse()`.

We now support the CSS Images Module Level 4 additions to the
`<radial-size>` syntax, namely:
 - `<length-percentage>` rather than just `<length>` for circles.
 - Distinct `<radial-extent>` values for horizontal and vertical for
   ellipses.
 - Mixing of `<radial-extent>` and `<length-percentage>` values for
   ellipses.

The regressions are due to WPT not being updated to expect the first of
these additions.
2025-12-12 12:20:16 +00:00
Callum Law
46da13636e LibWeb: Reduce overlapping inset() dimensions 2025-12-09 11:23:59 +00:00
Sam Atkins
d327f677c5 LibWeb/CSS: Store linear-gradient() angle as a StyleValue
This means we now support calc() there too.
2025-12-01 11:01:06 +00:00
Sam Atkins
73fbaaba77 LibWeb: Store GradientStyleValue color-stop positions as StyleValues
A few things fall out of this:
- We no longer need to templatize our color-stop list types.
- A bit more code is required to resolve gradient data.

This results in a slightly different rendering for a couple of the test
gradients, with a larger difference between macOS and Linux. I've
expanded the fuzziness factor to cover for it.
2025-12-01 11:01:06 +00:00
Psychpsyo
2db3796fd3 LibWeb: Implement CSS perspective-origin 2025-11-21 11:14:28 +00:00
Aliaksandr Kalenik
597fe8288c LibWeb: Apply own clip rect for background phase only when clip used
Fixes a bug where we would clip `box-shadow` when `overflow: hidden`
was set, which is not supposed to happen since `overflow` only affects
clipping of an element's content.
2025-11-19 18:17:42 +01:00
Jelle Raaijmakers
2811c75031 LibWeb: Use anti-aliasing to draw images and painting surfaces
Fixes the jagged edges on the transformed badge on
https://aaronfrancis.com/backstage.
2025-11-12 17:43:02 +01:00
Jelle Raaijmakers
489dea58ba LibWeb: Make all clip rects anti-aliased
This fixes aliased edges when e.g. applying rotation transforms to
certain shapes or SVGs. Although the clip rects themselves are
rectangular, a non-identity matrix transform can be active for the
canvas.

Fixes #5909.
2025-11-12 17:43:02 +01:00
Jelle Raaijmakers
3f6cbeb87e LibGfx+LibWeb: Use mipmaps for downscaling images
This changes Gfx::ScalingMode to reflect the three modes of scaling we
support using Skia, which makes it a bit easier to reason about the mode
to select. New is ::BilinearMipmap, which uses linear interpolation
between mipmap levels to produce higher quality downscaled images.

The cubic resampling options Mitchell and its sibling CatmullRom both
produced weird artifacts or resulted in a worse quality than
BilinearMipmap when downscaling. We might not have been using these
correctly, but the new ::BilinearMipmap method seems to mirror what
Chrome uses for downscaled images.
2025-11-12 15:59:01 +01:00
Jelle Raaijmakers
b4810f47a3 LibWeb: Hook up SVG component transfer filter to Skia 2025-11-09 01:22:48 +01:00
norbiros
3829a85fde LibWeb: Add basic variable font support
Integrates the new `FontVariationSettings` from LibGfx into LibWeb to
enable initial variable font functionality. Currently, only the `wght`
(weight) axis is fully supported and tested. This update also introduces
support for the CSS `font-variation-settings` property.
2025-11-04 21:44:32 +01:00
Jelle Raaijmakers
4dbae64dce LibWeb: Unify objectBoundingBox and userSpaceOnUse coord transformations
There's a fairly complicated interaction between an SVG gradient's paint
transformation and the gradient coordinate transformation required to
correctly draw gradient fills. This was especially noticeable when
scaling down an SVG, resulting in broken gradient coordinates and
graphical glitches.

This changes the objectBoundingBox units to immediately map to the
bounding box's coordinate system, so we can unify the gradient paint
transformation logic and make it a lot simpler. We only need to undo the
bounding box offset and apply the paint transformation to fix a lot of
gradient fill bugs.
2025-10-27 16:42:27 -07:00
Tim Ledbetter
e1ff1e2095 LibWeb: Implement CanvasPattern.setTransform()
This method applies the given transformation matrix to a pattern.
2025-10-27 16:41:02 -07:00
Jelle Raaijmakers
62ae4e878f LibWeb: Implement support for drawing with CanvasPattern
We already had the API, but drawing to the canvas was not affected by
any created CanvasPattern. This moves CanvasPatternPaintStyle to LibGfx
so we don't have to reach into LibWeb, and implements the plumbing to
let Skia use images as a fill pattern.
2025-10-23 13:20:03 +01:00
Jelle Raaijmakers
f8c4043460 LibWeb: Repeat shader for repeating linear gradient
We implemented repeating linear gradients by expanding a vector of color
stops until the entire range was covered. This is both a bit wasteful
and caused Skia to draw corrupted gradients to screen whenever the total
amount of color stops and positions exceeded 127.

Instead of doing that, use the original color stops for the shader and
repeat it instead of clamping it. We need to do a bit of math to project
positions correctly, but after that the shader repeats itself nicely.

While we're here, calculate the gradient's length and the center point
as floats instead of ints, yielding a slight but noticeable improvement
in gradient rendering (see the diff on the zig zag pattern in
css-gradients.html for an example of this).
2025-10-22 10:45:18 +02:00
Jelle Raaijmakers
8af6da64a6 Tests: Rework CSS gradients test layout
Put the CSS gradients in a grid instead of a single long column. This
makes it much easier to detect changes / view diffs.
2025-10-22 10:45:18 +02:00
Psychpsyo
80b629578e LibWeb: Fix partially selecting non-text nodes
Steps 4 and 5 were swapped since marking all the nodes between the start
and end of the selection now also marks the end node as full, even if it
should be marked as End.
There could be extra logic to avoid marking it if it is a text node, but
this seems easier.

As a whole, this fixes partially selected non-text nodes. In such cases,
where the selection starts or ends inside a node with descendants, it is
impossible to just select from the start node to the end node since that
would select all descendants of the start node and none of the end node.
Previously, this was only half considered and only if the start node was
a descendant of the end node.
2025-10-21 10:23:10 +01:00
Tim Ledbetter
34857ba554 LibWeb: Apply dithering when painting gradients 2025-10-19 16:53:00 +02:00
Andreas Kling
d36e5098f8 LibWeb: Support percentage attributes on SVG rect element
This makes the IMDb logo have a yellow background as expected.
2025-09-28 19:25:18 +02:00
Andreas Kling
321809320b LibWeb+LibGfx: Remove Path::close_all_subpaths()
As it turns out, SkPath already behaves the way we need for SVG and HTML
canvas elements. Less work for us, yay! This removes a 5% item from the
profile when scrolling on https://imdb.com/

Note that there's a tiny screenshot test expectation change due to
minor antialiasing differences when we no longer do our redundant
subpath modifications.
2025-09-25 21:42:52 +02:00
Sam Atkins
d9ed784f92 Tests: Add the hidden-img hack to a couple of flaky tests
Editing a WPT import feels wrong because fixing the bug would be better,
but flaky CI helps nobody.
2025-09-25 10:35:28 +01:00
mikiubo
43978ba459 LibWeb: Enable anti-aliasing in DisplayListPlayerSkia::fill_rect
Set SkPaint anti-aliasing to true when filling rectangles
This improves rendering quality by smoothing jagged edges

update clip-path-transformed.html and ref image with anti-aliasing

Partially fixes #5909
2025-09-22 16:22:48 +02:00
Callum Law
1ac7b47764 LibWeb: Disallow spread distance value when parsing text-shadow
`text-shadow` does not support setting a value for spread distance
unlike `box-shadow`.
2025-09-18 15:21:22 +01:00
Jelle Raaijmakers
1a52fcd6ad LibWeb: Draw selected text with its own color
Other browsers such as Chrome and Firefox retain the text's color when
the text is part of a selection, so let's mimic them.
2025-08-20 14:30:16 +02:00
Jelle Raaijmakers
0cf6bd0324 LibWeb: Maintain rect positioning when rounding to device pixel rects
When rounding a CSSPixelRect to a DevicePixelRect, we simply pulled its
width and height through round() and called it a day. Unfortunately this
could negatively affect the rect's perceived positioning.

A rect at { 0.5, 0.0 } with size { 19.5 x 20.0 } should have its right
edge at position 20, but after rounding it would end up at { 1, 0 } with
size { 20 x 20 }, causing its right edge to be at position 21 instead.

Fix this by first rounding the right and bottom edges of the input rect,
and then determining the dimensions by subtracting its rounded position.

Fixes #245.
2025-08-19 21:53:46 +02:00
Sam Atkins
5f986b2c33 LibWeb/Painting: Paint ridge and groove border styles 2025-08-11 11:07:15 +01:00
Sam Atkins
5d4a4e44fe LibWeb/Painting: Paint border-style: double using two solid borders
Call paint_border() recursively, once for the outer line, and once for
the inner one. This is done in a lambda so that we can reuse it for a
couple of other line styles.

Border-radius behaviour doesn't match other browsers, and goes a bit
haywire in some cases. I've left some FIXMEs for someone who
understands the maths here better than I do. 😅

The LineStyle handling is moved to the start of the function, to avoid
unnecessary work.
2025-08-11 11:07:15 +01:00
Timothy Flynn
4a8c70b3a5 LibWeb: Parse CSS/image URLs using DOMURL::parse
DOMURL::parse handles blob URLs.
2025-08-08 17:47:51 +01:00
Jelle Raaijmakers
59a867d3e3 Tests: Enable all screenshot tests on all platforms
With the newly supported fuzzy matching in our test-web runner, we can
now define the expected maximum color channel and pixel count errors per
failing test and set a baseline they should not exceed.

The figures I added to these tests all come from my macOS M4 machine.
Most discrepancies seem to come from color calculations being slightly
off.
2025-07-17 12:59:11 +01:00
Lucien Fiorini
4711c38aa1 Tests: Add screenshot test for the background SVG in the LB website 2025-07-09 18:07:12 +01:00
Psychpsyo
baf2063e31 LibWeb: Fix selection when start node is inside end node
Fixes a regression introduced in
bc8870d019 (in a performant way this
time)
2025-07-04 20:19:50 +02:00
Manuel Zahariev
51b4b4a270 LibWeb: Tests for recalculating ordinals after list manipulation
FIXME: Rendering modifications to a list is sometimes not pixel-perfect
       vs. reference (likely a bug). After this is fixed, screenshot
       tests from this commit will likely fail + can be moved to
       ref tests.
2025-06-16 12:44:58 +01:00