Commit graph

45 commits

Author SHA1 Message Date
Aliaksandr Kalenik
8f39aa0d4a LibWeb: Verify that save and restore are balanced within StackingContext
Unbalanced save and restore means that effects only relevant to a
stacking context leak outside, which is never expected behavior. Having
a `VERIFY()` for that makes it much easier to catch such issues.
2025-07-06 22:18:27 +02:00
Aliaksandr Kalenik
809e465e05 LibWeb: Delete before_children_paint and after_children_paint hooks
These were only used in SVGSVGPaintable to apply scroll frame id, which
is already handled by `before_paint()` and `after_paint()` hooks in
PaintableBox.
2025-07-06 19:21:46 +02:00
Aliaksandr Kalenik
3dffd71695 LibWeb: Verify that save/restore are balanced within paintable
Unbalanced save/restore within display list items recorded for a
paintable means that some state only relevant for the paintable leaks to
subsequent paintables, which is never expected behavior.
2025-07-06 19:21:13 +02:00
Jelle Raaijmakers
ade5709939 LibWeb: Lazily obtain the Z-index for children in StackingContext
In `StackingContext::paint_descendants()`, we don't need to obtain the
computed values nor the Z-index of a child unless certain other
conditions are true. Let these conditions short-circuit before actually
reaching into the computed values, which shows up in profiles.
2025-06-17 11:55:28 +02:00
Jelle Raaijmakers
c999dd0c9f LibWeb: Remove unused includes
No functional changes.
2025-06-17 11:55:28 +02:00
Aliaksandr Kalenik
39fff3cf8a LibWeb: Don't early return when masking area of StackingContext is empty
An early return was occurring between the emission of
PushStackingContext and PopStackingContext, resulting in a
PushStackingContext without a corresponding PopStackingContext in the
display list, which caused broken painting.

Fixes black screen on Discord login page.
2025-06-06 00:52:19 +02:00
Lucien Fiorini
0fcb574041 LibGfx+LibWeb: Turn Gfx::Filter into a SkImageFilter wrapper 2025-06-01 23:22:10 +02:00
InvalidUsernameException
164afdcc59 LibWeb: Ensure scroll offset is applied to mask-images
When recording the display list for a stacking context, the following
operations (relevant to this bug) happened:
* push a stacking context
  * as part of that push a None-value to the scroll frame id stack
* apply filters
* apply masking
* paint recursively

This meant that mask-images were always recorded without scroll frame
id, causing them to be painted without any scroll offset. As a result
mask-images would break as soon as the website using them was scrolled.

Instead, push to the scroll frame id stack later to solve the problem:
* push a stacking context
* apply filters
* apply masking
* push a None-value to the scroll frame id stack
* paint recursively
2025-05-29 22:02:07 +02:00
Glenn Skrzypczak
9973b01848 LibWeb/CSS: Improved implementation of background-blend-mode
This is a improved version of a73cd88f0c
The old commit was reverted in 552dd18696

The new version only paints an element into a new layer if background
blend modes other than normal are used. The rasterization performance
of most websites should therefore not suffer.

Co-Authored-By: Alexander Kalenik <kalenik.aliaksandr@gmail.com>
2025-04-01 13:38:00 +02:00
Andreas Kling
ba8aabdeb0 Revert "LibWeb: Skip "overlay" paint phase when there's no inspected node"
This reverts commit dc56435ecd.

It broke overlay scrollbars.
2025-03-28 20:08:48 +00:00
Aliaksandr Kalenik
552dd18696 Revert "LibWeb/CSS: Implement 'background-blend-mode'"
This reverts commit a73cd88f0c.

Emitting SaveLayer for each paintable made rasterization a lot slower
on every website because now Skia has to allocate enormous amounts of
temporary surfaces. Let's revert it for now and figure how to implement
it with less aggressive SaveLayer usage.
2025-03-28 16:48:03 +00:00
Glenn Skrzypczak
a73cd88f0c LibWeb/CSS: Implement 'background-blend-mode'
This implements the 'background-blend-mode' CSS property.
2025-03-28 09:41:06 +00:00
Aliaksandr Kalenik
e655b77393 LibWeb: Fix scroll offset application for SVG root box
Now we use `before_paint()` and `after_paint()` calls for SVG root box
to make sure that both clip and scroll are applied.

Fixes painting of SVG arrows on www.ubereats.com
2025-03-26 20:12:45 +00:00
Andreas Kling
dc56435ecd LibWeb: Skip "overlay" paint phase when there's no inspected node
This avoids a bunch of tree traversal that doesn't find anything to
paint anyway.
2025-03-25 07:31:42 +00:00
InvalidUsernameException
5f1a146afd LibWeb: Draw floating replaced elements more correctly
Previously floating replaced elements were drawn incorrectly and also
twice.
2025-03-03 21:49:44 +01:00
InvalidUsernameException
be47f95180 LibWeb: Reduce number of recompiled files for display list headers
This reduces the number of `.cpp` files that need to be recompiled when
one of the below header files changes as follows:

Painting/Command.h: 1030 -> 61
Painting/DisplayList.h: 1030 -> 60
Painting/DisplayListRecorder.h: 557 -> 59
2025-02-23 10:14:39 -05:00
Glenn Skrzypczak
0fe30886f5 LibWeb/CSS: Implement mix-blend-mode
This adds support for the `mix-blend-mode` CSS property.
2025-02-05 11:26:58 +00:00
Jelle Raaijmakers
522aa41667 LibWeb: Honor pointer-events for PaintableBox in own stacking context
If a block element with its own stacking context has `pointer-events:
none` set, it should be ignored as far as hit-testing goes.

Fixes #3357.
2025-01-26 17:30:00 +01:00
Jelle Raaijmakers
e076cb9b0e LibWeb: Simplify hit testing coordinate calculations
There are many simpler APIs that we can use here. No functional changes.
2025-01-23 09:33:10 +01:00
Timothy Flynn
85b424464a AK+Everywhere: Rename verify_cast to as
Follow-up to fc20e61e72.
2025-01-21 11:34:06 -05:00
Lucien Fiorini
9fd1223992 LibWeb+LibGfx: Refactor CSS filters into LibGfx
CSS filters work similarly to canvas filters, so it makes sense to have
Gfx::Filter that can be used by both libraries in an analogous way
as Gfx::Color.
2024-12-18 18:54:20 +01:00
Aliaksandr Kalenik
86f1c03c06 LibWeb: Fix CSS filters painting
restore() corresponding to ApplyFilters should be called after stacking
context content is painted, not before.

Fixes regression introduced in c94b4316e7
2024-12-01 21:27:29 +01:00
Aliaksandr Kalenik
c94b4316e7 LibWeb: Use separate restore() for each ApplyFilters display list item
ApplyFilter internally calls canvas.saveLayer() which requires a
matching canvas.restore() to be called.

Fixes painting on https://supabase.com/ regressed by
8562b0e33b
2024-12-01 15:49:32 +01:00
Psychpsyo
6f52064c4f LibWeb: Make SVGs respect their CSS transforms 2024-11-24 14:30:32 +01:00
Saksham Mittal
ecdb53cca6 LibWeb: Deduplicate opacity code in ApplyFilters
The opacity is still being set separately by using
ApplyOpacity for both CSS and SVG
2024-11-23 20:20:12 +01:00
Saksham Mittal
8562b0e33b LibWeb: Migrate CSS filter application to new ApplyFilters command
This helps reuse this code in other areas, such as for filters for SVGs
2024-11-23 20:20:12 +01:00
Aliaksandr Kalenik
96a35767b6 LibWeb: Implement mask-image CSS property support
Implemented by reusing AddMask display list item that was initially
added for `background-clip` property.

Progress on flashlight effect on https://null.com/games/athena-crisis
2024-11-18 22:58:58 +01:00
Aliaksandr Kalenik
9f541c363d LibWeb: Allow stacking context to only be created by PaintableBox
For a while we used the wider Paintable type for stacking context,
because it was allowed to be created by InlinePaintable and
PaintableBox. Now, when InlinePaintable type is gone, we can use more
specific PaintableBox type for a stacking context.
2024-11-18 20:07:30 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Andreas Kling
e5490ae1d1 LibWeb: Rename Layout::Node::style() => computed_values() 2021-01-06 14:58:48 +01:00
Andreas Kling
07dd73c351 LibWeb: Remove hand-rolled is_foo() helpers in Layout::Node classes 2021-01-01 18:56:49 +01:00
Andreas Kling
fc86717f43 LibWeb: Demangle the names returned by Layout::Node::class_name()
Note that these are only used in debugging/test output so it's not
performance sensitive.
2021-01-01 16:42:44 +01:00
Andreas Kling
169a9150cb LibWeb: Rename LayoutNode::is_root() => is_initial_containing_block()
Let's use spec language for this. :^)
2020-12-04 16:27:07 +01:00
Andreas Kling
d129e68da8 LibWeb: Move PaintPhase enum out of Layout::Node
Now it's just Layout::PaintPhase instead of Layout::Node::PaintPhase.
2020-12-03 21:45:41 +01:00
Andreas Kling
5aeab9878e LibWeb: Rename LayoutNode classes and move them into Layout namespace
Bring the names of various boxes closer to spec language. This should
hopefully make things easier to understand and hack on. :^)

Some notable changes:

- LayoutNode -> Layout::Node
- LayoutBox -> Layout::Box
- LayoutBlock -> Layout::BlockBox
- LayoutReplaced -> Layout::ReplacedBox
- LayoutDocument -> Layout::InitialContainingBlockBox
- LayoutText -> Layout::TextNode
- LayoutInline -> Layout::InlineNode

Note that this is not strictly a "box tree" as we also hang inline/text
nodes in the same tree, and they don't generate boxes. (Instead, they
contribute line box fragments to their containing block!)
2020-11-22 15:56:27 +01:00
Andreas Kling
f358f2255f LibWeb: Rename LayoutNode::node() => LayoutNode::dom_node() 2020-11-22 14:46:36 +01:00
Andreas Kling
e2b4fef6c7 LibWeb: Specialize hit testing for text cursor purposes
The text cursor follows slightly different "intuitive" rules than the
regular hit testing. Clicking past the right edge of a text box should
still "hit" the text box, and place the cursor at its end, for example.

We solve this by adding a HitTestType enum that is passed to hit_test()
and determines whether past-the-edge candidates are considered.
2020-08-05 16:57:51 +02:00
Andreas Kling
71556e39a4 LibWeb: Switch to using AK::is and AK::downcast 2020-07-26 17:51:00 +02:00
Andreas Kling
392b055806 LibWeb: Use the StackingContext tree for hit testing
This makes it possible to click links that are above other content due
to stacking context order (e.g via CSS z-index.)
2020-07-01 19:10:58 +02:00
Andreas Kling
f7a900367f LibWeb: StackingContext was sorting the wrong list of children
Oops, we're supposed to sort the *parent's* children, not our own.
2020-07-01 18:35:50 +02:00
Andreas Kling
6f28f08096 LibWeb: Add LayoutStyle, a place to store style info for layout & paint
StyleProperties is really only the specified "input" to what eventually
becomes the used/computed style we use for layout and painting.

Unlike StyleProperties, LayoutStyle will have strongly typed values for
everything it contains (i.e no CSS::ValueID or strings, etc.)

This first patch moves z-index into LayoutStyle.
2020-06-24 16:49:51 +02:00
Andreas Kling
5e83a97fa2 LibWeb: Rename LayoutNode::style() => specified_style()
Let's make way for a slightly-more-cooked style() that will eventually
replace the raw specified_style() for layout and paint purposes.
2020-06-24 13:54:31 +02:00
Andreas Kling
07b06cdc7e LibWeb: Fix broken #include after moving files around 2020-06-18 22:01:05 +02:00
Andreas Kling
995d93c9d9 LibWeb: Move StackingContext from Layout/ to Painting/
The stacking context tree doesn't affect layout at all, so let's move
it into the Painting/ directory. I'm not sure yet if it's worth going
for a fullly separate painting tree. So far I'm thinking a stacking
context tree with pointers into the layout tree might be enough.
2020-06-18 21:42:19 +02:00
Renamed from Libraries/LibWeb/Layout/StackingContext.cpp (Browse further)