Instead of CSSColorValue holding a Gfx::Color, make it an abstract class
with subclasses for each different color function, to match the Typed-OM
spec. This means moving the color calculations from the parsing code to
the `to_color()` method on the style value.
This lets us have calc() inside a color function, instead of having to
fully resolve the color at parse time. The canvas fillStyle tests have
been updated to reflect this.
The other test change is Screenshot/css-color-functions.html: previously
we produced slightly different colors for an alpha of 0.5 and one of
50%, and this incorrect behavior was baked into the test. So now it's
more correct. :^)
(cherry picked from commit 3af6a69f1e13803c64466a9b24b7bd7d75d459df;
amended to:
* resolve a minor conflict in Parser.cpp due to upstream not having
https://github.com/LadybirdBrowser/ladybird/pull/385#issuecomment-2227130015
* rebaseline canvas-fillstyle-rgb.png since the diff didn't apply due to
us not having https://github.com/LadybirdBrowser/ladybird/pull/999
* remove css-color-functions-ref.png and instead update
css-color-functions-ref.html since that file is still a reftest due to us
not having https://github.com/LadybirdBrowser/ladybird/pull/736
Makes it much easier to see what actually changed.
)
This change will make it easier to disable screenshot comparison tests
on a specific platform or have per-platform expectations.
Additionally, it's nice to be able to tell if a ref-test uses a
screenshot as an expectation by looking at the test path.
(cherry picked from commit 715f0330070d9f8ecc88a8e66e4d8c85f795d622;
amended to also move
Tests/LibWeb/Screenshot/canvas-stroke-styles.html and support files)
A stroked path that has the same start and end point looks different
depending on if it's closed or not: If it's closed, the start/end point
is drawn as a line join; if it's not closed, the start/end point is
drawn as a cap.
(It has an effect only for stroked paths, but not for filled paths.)
So make Path remember if it's closed or not by adding a ClosePath
segment type.
This matches the canvas, pdf, svg specs.
(TinyVG doesn't have strokes yet.)
This fixes the apparent rendering regression from #25040 / #25044
(which just made an existing bug visible).
(We should probably make an inner and an outer path when stroking a
closed path instead of just giving closed paths a round cap. When
filled, both look identical, but the current approach produces more
geometry. For now, this is good enough.)
To rebaseline image test expecatations, I ran:
out/gn/Ladybird.app/Contents/MacOS/headless-browser \
--resources $PWD/out/gn/Ladybird.app/Contents/Resources \
--dump-failed-ref-tests \
--run-tests $PWD/Tests/LibWeb \
--filter 'canvas-*'
I then copied over the new baselines with
D=Tests/LibWeb/Ref/reference/images
cp test-dumps/canvas-implict-moves-and-lines.png \
$D/canvas-implict-moves-and-lines-ref.png
(Note: No `-ref` suffix on first path, yes suffix on second path.)
We currently don't track if a path is open or closed, and paint
butt linecaps at the end of closed paths too. We did that with
round linecaps as well, but there that wasn't visible. This makes
closed paths look a bit weird now; we'll have to fix this in a
follow-up. In a way, this just exposes another not-yet-implemented
feature.
On macOS, when going from the right end of a horizontal line
to the left, and when slope_now is pi, and the current
range.end is 0 (i.e. current_angle = pi, target_angle = 0),
clockwise() would set target_angle to 2 * pi, and
`target_angle - current_angle` (ie 2 * pi - pi) would end up
being ever so sligthly more than `pi` (handwavingly due to
floating point in accuracies), and we'd go in the wrong direction.
Add an explicit check for that, and a reftest that catches this.
No observed behavior change on linux, but the reftest only passes
on macOS with the code change.
Moves paint_table_borders() call into PaintableBox::paint() to make
scroll offset and clip rectangle of enclosing scrollable be applied
in ::before_paint().
(cherry picked from commit 2cc2646f5585e4a1f617ac809806bf05e8e515a4)
The main intention of this change is to have a consistent look and
behavior across all scrollbars, including elements with
`overflow: scroll` and `overflow: auto`, iframes, and a page.
Before:
- Page's scrollbar is painted by Browser (Qt/AppKit) using the
corresponding UI framework style,
- Both WebContent and Browser know the scroll position offset.
- WebContent uses did_request_scroll_to() IPC call to send updates.
- Browser uses set_viewport_rect() to send updates.
After:
- Page's scrollbar is painted on WebContent side using the same style as
currently used for elements with `overflow: scroll` and
`overflow: auto`. A nice side effects: scrollbars are now painted for
iframes, and page's scrollbar respects scrollbar-width CSS property.
- Only WebContent knows scroll position offset.
- did_request_scroll_to() is no longer used.
- set_viewport_rect() is changed to set_viewport_size().
(cherry picked from commit 5285e22f2aa09152365179865f135e7bc5d254a5)
Co-authored-by: Jamie Mansfield <jmansfield@cadixdev.org>
Co-authored-by: Nico Weber <thakis@chromium.org>
`Painting::paint_all_borders()` only uses `.draw_line()` for simple
borders and `.fill_path()` for more complex cases. These are both
already supported by the `RecordingPainter` so removing this command
simplifies the painting API.
Two test changes:
css-background-clip-text: Borders are now drawn via the AA painter
(which makes them closer to how they appear in other browsers).
corner-clip-inside-scrollable: Borders removed (does not change test)
due to imperceptible sub-pixel changes.
All painting commands except SetClipRect are shifted by scroll offset
before command list execution. This change removes scroll offset
translation for sample/blit corner commands in
`PaintableWithLines::paint` so it is only applied once in
`CommandList::apply_scroll_offsets()`.
Fixes bug when CSS transform is applied twice to clip rect:
- While calculating absolute clip rectangles in `refresh_clip_state()`
- While executing `PushStackingContext` painting command.
Duplicated transform is already removed for PaintableBox and this change
adds this for InlinePaintable.
PaintFrame is not primitive painting command, we inherited from OS, that
is hard to replicate in GPU-painter or alternative CPU-painter API. We
should remove it as a part of refactoring towards simplifying recording
painter commands set.
Fixes: #23796
Going via the `ViewportPaintable` missed some steps (in particular
computing clip rects), which meant nested SVGs within SVGs-as-images
were completely clipped.
If an unexpected token is encountered when parsing an SVG attribute it
is now immediately propagated with ErrorOr. Previously, some situations
where an unexpected token was encountered could cause a crash.
Animation::play_state() does not consider the fill state, and thus will
not return "Playing" for a fill-forward animation in the after phase.
It is still valid for paused, as pausing is not affected by the fill
mode.
From https://drafts.csswg.org/css-backgrounds-4/#background-clip
"The background is painted within (clipped to) the intersection of the
border box and the geometry of the text in the element and its in-flow
and floated descendants"
This change implements it in the following way:
1. Traverse the descendants of the element, collecting the Gfx::Path of
glyphs into a vector.
2. The vector of collected paths is saved in the background painting
command.
3. The painting commands executor uses the list of glyphs to paint a
mask for background clipping.
Co-authored-by: Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
Introduces the rendering of scroll thumbs in vertical and horizontal
directions. Currently, the thumbs are purely graphical elements that
do not respond to mouse events. Nevertheless, this is beneficial as it
makes it easier to identify elements that should respond to scrolling
events.
Painting of scrollbars uncovers numerous bugs in the calculation of
scrollable overflow rectangles highlighting all the places where
elements are made scrollable whey they shouldn't be. Positively, this
issue might motivate us to pay more attention to this problem to
eliminate unnecessary scrollbars.
Currently, the scrollbar style is uniform across all platforms: a
semi-transparent gray rectangle with rounded corners.
Also here we add `scrollbar-width: none` to all existing scrolling
ref-tests, so they keep working with this change.
The list of border radii clips needs to be reset before being populated
with new clips that have refreshed positions. Besides fixing painting,
this also improves performance because the number of sample/blit
commands does not increase as we scroll.
Refactor to resolve paint-only properties before painting, aiming to
stop using layout nodes during recording of painting commands.
Also adds a test, as we have not had any for outlines yet.
This allows for:
* Transformed text (e.g. rotated text)
* Stroked text
* Filling/stroking text with PaintStyles (e.g. gradients)
* Squashed/condensed text (via maxWidth parameter)
Fixes part of #22817
With this change, instead of applying only the border-radius clipping
from the closest containing block with hidden overflow, we now collect
all boxes within the containing block chain and apply the clipping from
all of them.