Commit Graph

228 Commits

Author SHA1 Message Date
Aliaksandr Kalenik
adf0262b54 LubWeb: Call before_children_paint for positioned descendants
Add before_children_paint and after_children_paint calls for
positioned descendants with z-index: auto during painting
2022-11-15 22:53:47 +01:00
Aliaksandr Kalenik
f3d57e1157 LibWeb: Clip hidden overflow by absolute rect of containing block
Since handling overflow: hidden in PaintableBox::before_children_paint
while following paint traversal order can't result in correctly computed
clip rectangle for elements that create their own stacking context
(because before_children_paint is called only for parent but overflow:
hidden can be set somewhere deeper but not in direct ancestor), here
introduced new function PaintableBox::clip_rect() that computes clip
rectangle by looking into containing block.

should_clip_overflow flag that disables clip for absolutely positioned
elements in before_children_paint and after_children_paint is removed
because after changing clip rectangle to be computed from not parent
but containing block it is not needed anymore (absolutely positioned
item is clipped if it's containing block has hidden overflow)
2022-11-15 22:53:47 +01:00
MacDue
7e21fe61b4 LibWeb: Paint repeating-conic-gradient()s
Shares the same machinery as linear-gradient()s so this is quite easy.
2022-11-07 13:13:22 +00:00
Luke Wilde
bee4df7bfb LibWeb: Skip hit testing a line box fragment if it has no container
The container appears to be null for certain elements such as the
"update your browser" box when clicking on the document during certain
parts of loading. Skipping it works fine, but should obviously be
fixed, so it prints a debug output when this happens.
2022-11-07 14:10:41 +01:00
MacDue
b2a0d70ef3 LibWeb: Fix some conic-gradient() painting issues
This makes the center position the center of the pixel rather than
the top left corner (which fixes some small artifacts on a few
gradients).

This also now floors the angle used to sample from the gradient line,
this avoids the colors diverging the further away from the center you
get (which is noticeable on hard-edge gradients).
2022-11-06 01:42:55 +00:00
MacDue
6c6c94f05a LibWeb: Use relative units for gradients until painting
This commit tweaks gradients so resolve_color_stop_positions() no
longer cares about the actual length of the gradient. All stops
are resolved to relative positions along the gradient line
(between 0 and 1), and are only scaled back to pixels (if required)
during the actual painting.

This has no immediate benefit right now, but it might make using
CSS pixels for gradients easier :^)

This also includes some mild refactoring.
2022-11-05 14:12:23 +00:00
Andreas Kling
4de3449ad6 LibWeb: Recurse into block-level children when hit testing a box
Otherwise, we always say you hit the parent, even when you're really
clicking on a child that's visually above the parent.
2022-11-04 10:38:00 +01:00
Andreas Kling
5aeb6fec68 LibWeb: Make hit testing traverse positioned descendants in right order
We were doing a forward traversal in hit testing which led to sometimes
incorrect results when multiple boxes were occupying the same X and Y
coordinate.
2022-11-04 10:38:00 +01:00
Aliaksandr Kalenik
e4db71c88b LibWeb: Support translate3d 2022-11-02 11:04:23 +00:00
MacDue
fdcc73d4b1 LibWeb: Paint conic-gradient()s
This is a first pass at painting conic-gradient()s, I've yet to try to
optimize this much, but I feel like you could do better than atan2
in a loop.
2022-11-01 23:07:05 +00:00
Sam Atkins
ff0a2b1a60 LibGfx+Everywhere: Make DisjointRectSet work for non-int Rects
For convenience, `DisjointIntRectSet` is an alias for
`DisjointRectSet<int>`, and is used everywhere for now.
2022-10-27 13:06:33 +02:00
Andreas Kling
8aab33de5f LibWeb: Skip positioned children in paint_descendants()
Positioned descendants are now handled entirely by paint_internal()
so we can just skip over positioned children in paint_descendants().
This avoids drawing the same boxes multiple times.
2022-10-23 23:32:42 +02:00
Andreas Kling
8bf0e71c0c LibWeb: Paint non-positioned stacking contexts with z-index 0 or auto
As I understand it, these have to be painted interleaved with positioned
descendants in the same z-index category, in tree order.
2022-10-23 23:32:42 +02:00
Andreas Kling
447519f678 LibWeb: Paint positioned descendants with z-index: auto
This "worked" before because all positioned elements would create their
own stacking context. When we stopped doing this, there was nobody to
actually paint positioned descendants with `z-index: auto`.

This patch splits up steps 8 and 9 of the paint order algorithm and
implements step 8 as a paint tree traversal. There's more to step 8 than
I've implemented here, so I've left a FIXME for our future selves.
2022-10-23 23:32:42 +02:00
Andreas Kling
8a0e40c5b0 LibWeb: Update StackingContext::paint_descendants() for new rule
Since positioned elements no longer automatically create stacking
contexts, we can't rely on this assumption when painting descendants of
a stacking context.

In this commit, we fix an issue that manifested as a failure to
Gfx::Painter::restore() in the "Overlay" paint phase. What happened was
that a CSS clip was being applied in the "Background" paint phase, and
then unapplied in the "Overlay" phase. Due to bogus checks in
paint_descendants(), the "Background" phase never ran for positioned
elements, but the "Overlay" phase did.

The check for positioned elements was bogus in the first place and had
never actually worked before, since we would always skip over positioned
descendants due to them having stacking contexts.
2022-10-23 23:32:42 +02:00
Andreas Kling
055a1998c1 LibWeb: StackingContext::paint_descendants() can take const layout node
It doesn't mutate the layout tree in any way.
2022-10-23 23:32:42 +02:00
Aliaksandr Kalenik
66e424a084 LibWeb: Fix pointer-events check in hit_test 2022-10-20 17:58:16 +02:00
Andreas Kling
268b9c5d90 LibWeb: Make the layout tree GC-allocated
This removes a set of complex reference cycles between DOM, layout tree
and browsing context.

It also makes lifetimes much easier to reason about, as the DOM and
layout trees are now free to keep each other alive.
2022-10-20 15:16:23 +02:00
Andreas Kling
83c5ff57d8 LibWeb: Make BrowsingContext GC-allocated
(And BrowsingContextGroup had to come along for the ride as well.)
This solves a number of nasty reference cycles between browsing
contexts, history items, and their documents.
2022-10-20 15:16:23 +02:00
Aliaksandr Kalenik
dfc3a4772b LibWeb: Ignore "pointer-events: none" elements in hit_test 2022-10-19 16:11:15 +02:00
MacDue
c6fbeb5845 LibWeb: Don't attempt to paint text shadows for empty text fragments
This avoids the debug spam that happens then the shadow painting fails
to allocate a zero sized bitmap.
2022-10-18 23:18:53 +02:00
MacDue
89e308726e LibWeb: Print requested bitmap sizes in shadow painting debug logs
Also replace "box-shadow" with "text-shadow" in the text shadow
painting debug logs.
2022-10-18 23:18:53 +02:00
MacDue
4507920187 LibWeb: Fix position: fixed canvases/images disappearing when scrolling
This fixes the Serenity logo vanishing after scrolling on the 4th
birthday post.

The previous check did not account for any translation in the painter.
This now uses the painter's clip rect and translation to work out
if a rect is visible. It also makes use of `absolute_paint_rect()`
rather than `absolute_rect()` which can account for things like
box-shadows.
2022-10-13 11:16:27 +02:00
MacDue
35b714163d LibWeb: Fix wrapping glitches on repeating-linear-gradient()s
This fixes some off-by-one wrapping issues that became visible when
running on x86_64. The problem still existed on i686, but by chance
did not show up due to a -/+ 0.000001 difference between the two.
2022-10-10 10:47:50 +02:00
MacDue
b877d71db7 LibWeb: Add missing hue-rotate() filter spec comment 2022-10-07 13:08:24 +01:00
MacDue
60cc96d243 LibWeb: Support painting the saturate() filter effect 2022-10-07 13:08:24 +01:00
Andreas Kling
90b66533d0 LibWeb: Don't hit test all child stacking contexts twice
We're supposed to hit test positive z-index stacking contexts first,
and negative z-index stacking contexts later. Instead, we were hit
testing all stacking contexts both times.

This made hit testing unbearably slow on some websites.

While we're here, also add an extra comment about why stacking contexts
are traversed in reverse order. It tripped me up while looking at this,
so I'm sure it could trip someone else up too.

Regressed in 44057c9482.
2022-10-07 12:10:59 +02:00
MacDue
e697a72c99 LibWeb: Support painting the hue-rotate() filter effect 2022-10-02 21:17:41 +02:00
Andreas Kling
95a3da86c3 LibWeb: Reset painter translation when painting fixed-position elements
This makes nested position:fixed elements work, previously we'd apply
the viewport scroll offset once at every nesting level.
2022-10-02 21:14:02 +02:00
Hendiadyoin1
e68309144b LibWeb: Don't scale by x, x when a scale x, y is provided as a transform 2022-10-01 21:08:50 +01:00
Luke Wilde
dbe12662b8 LibWeb: Implement matrix3d transform function from css-transforms-2 2022-10-01 14:07:47 +02:00
Luke Wilde
0fdd924db2 LibWeb: Implement rotation transform functions from css-transforms-2 2022-10-01 14:07:47 +02:00
Andreas Kling
b7f9387f69 LibWeb: Don't draw only-translated stacking contexts via bitmap
If the 2D transform in effect is just a simple translation, we don't
need to draw into a temporary bitmap and then transform it. We can
just translate the painter. :^)
2022-09-29 20:10:02 +02:00
MacDue
f6264523b9 LibWeb: Fix destination bitmap edge clip case in transform painting
This fixes an edge case, where the destination rect falls partly
outside the painter, so is clipped to a smaller size in
`get_region_bitmap()` (which needs to be accounted for with an extra
offset).
2022-09-26 01:38:30 +02:00
MacDue
e3537e4374 LibWeb: Fix shadow painting when the target painter is translated 2022-09-25 18:37:31 +02:00
MacDue
3fad64dfbc LibWeb: Sample the destination when painting element opacity/transform
This now copies the area under the destination to a new bitmap, that
is then scaled to the size of the source. The element is then painted
into that bitmap, which is then scaled and painted back to
the destination. This is done as many effects such as shadows, border
radii, filters, etc require being able to read pixels from the painter.

This does work (and is not that noticeable in many cases), but it does
mean there may be a few scaling artifacts in the background
around transformed elements. Though that was already the case before
anyway for the elements (since it is just a bitmap scale).

What we really want is to (where possible) just scale the paintable
and its descendants, then paint things normally, which would give
much nicer results (but is much more tricky to achieve).

This also now makes it so only a bitmap of the size of the paintable is
copied/created, rather than the whole page.
2022-09-25 18:37:31 +02:00
MacDue
8967fe9d92 LibWeb: Add PaintableBox::absolute_paint_rect()
This method returns the total area this element will paint to.
Currently, this just means accounting for box-shadows, though
there are likely more effects that need to be accounted for here.
2022-09-25 18:37:31 +02:00
Andreas Kling
5c6621547c LibWeb: Compute StackingContext transform origin only once
When mousing over twitter, 17% of time was spent computing stacking
context transform origins. Since this never changes after the stacking
context is created, we can cache it and avoid all that work.
2022-09-24 23:06:09 +02:00
MacDue
c3841e1667 LibWeb: Restore clipping of positioned descendants
63c727a was meant to stop clipping absolutely positioned descendants,
but used `is_positioned()` rather than `is_absolutely_positioned()`,
which meant it disabled clipping in many more cases that it should
have.
2022-09-24 19:06:57 +02:00
Andreas Kling
e72896e35e LibWeb: Get default fonts via Platform::FontPlugin
Instead of asking Gfx::FontDatabase for the "default font" and the
"default fixed-width font", we now proxy those requests out via
the Platform::FontPlugin. This will allow Ladybird to use other default
fonts as fallback.
2022-09-17 21:27:32 +02:00
MacDue
011439d3e3 LibWeb: Paint backdrop-filter effects!
This implements all the filters other than `saturate()`,
`hue-rotate()`, and `drop-shadow()`.

There are still a lot of FIXMEs to handle in the actual implementation
though, particularly around supporting transforms, but this handles
the most common use cases :^)
2022-09-16 10:50:48 +01:00
MacDue
7bc0c66290 LibWeb+LibGfx: Move premultiplied alpha mixing to color.mixed_with()
This will be needed for mixing filters in LibGfx (and may be
generally useful elsewhere).
2022-09-16 10:50:48 +01:00
Brian Gianforcaro
d0a1775369 Everywhere: Fix a variety of typos
Spelling fixes found by `codespell`.
2022-09-14 04:46:49 +00:00
Andreas Kling
63c727a4a3 LibWeb: Don't clip to containing block when painting abspos descendants 2022-09-14 00:09:49 +02:00
MacDue
50ab2de10e LibWeb: Remove done TODO and fix typo 2022-08-23 13:27:02 +01:00
MacDue
40ad8b793d LibWeb: Avoid infinite loops in background painting
Previously if `background-size` was 0px in any dimension we would
go into in infinite loop whilst painting.
2022-08-23 13:27:02 +01:00
MacDue
698717d102 LibWeb: Resolve double-position linear-gradient() color stops
These just resolve to an extra color stop.
Something like "red 10% 40%"  is just shorthand for "red 10%, red 40%".
2022-08-23 01:02:49 +02:00
MacDue
3a1f8d714a LibWeb: Parse double-position linear-gradient() color stops
The only accepted syntax for these seems to be
<color> <length percentage> <length percentage>, no other order.

But that's just gathered from looking at other browsers as though
these are supported by all major browsers, they don't appear in
the W3C spec.
2022-08-23 01:02:49 +02:00
MacDue
e294b7929a LibWeb: Support painting repeating-linear-gradient()s 2022-08-18 15:58:05 +02:00
MacDue
ffdcc60b03 LibWeb: Avoid NaNs from zero-length gradient color stops 2022-08-18 15:58:05 +02:00