This patch just adds the new root paintable and updates the tests
expectations. The next patch will move painting logic from the layout
viewport to the paint viewport.
Until now, paint trees have been piggybacking on the layout tree for
traversal, and paintables didn't actually have their own parent/child
pointers.
This patch changes that by making Paintable inherit from TreeNode, and
adding a new pass to LayoutState::commit() where we recursively build
the new paint tree.
This effectively makes it per-Document, but we hang it off of
StyleComputer since that's what it's used for.
The purpose of this is to prevent downloaded fonts from escaping the
context that loaded them. There's probably a more elegant solution where
we still share caching of system fonts, but let's start here.
We now keep the color value as a StyleValue up until we go to paint the
gradient, which makes `currentColor` work, along with any other color
values that can't be immediately converted into a `Gfx::Color` while
parsing.
Instead of applying relative offsets (like position:relative insets)
during painting and hit testing, we now do a pass at the end of layout
and assign the final resolved offsets to paintables.
This makes painting and hit testing easier since they don't have to
think about relative offsets, and it also fixes a bug where offsets were
not applied to text fragments inside inline-flow elements that were
themselves position:relative.
Previously stacking contexts were only painted in steps 3, 8, and 9.
These steps are only meant to cover positioned elements (as per
https://www.w3.org/TR/CSS22/zindex.html). This meant that elements with
opacity (which forms a stacking context) could end up painted above
elements that actually occlude them.
Replicate the more conservative way it's done for other nodes, for
which we verify whether they have a paintable before doing
painting-related operations with it.
Fixes crash on https://www.haiku-os.org/.
Fixes painting of nested nodes in scrollable containers by moving
painter's scroll offset translation from paint_node() to
before_children_paint() and after_children_paint().
Build a grid snapped to device pixels and use it to construct the
rectangles for the cell edges, same as for collapsed borders. This is
especially important when border-spacing is set to 0 since it avoids
gaps between adjacent cells which have borders set.
Before painting the borders, build a grid snapped to device pixels and
use it to construct the rectangles for the cell edges. Also adjust
their starting coordinate and size such that they join correctly
without overhangs. This approach works at all zoom levels.
It is only PaintableBox that can have scrollable overflow so it doesn't
make sense to have handle_mousewheel() implementation in Paintable.
Also new implementation of handle_mousewheel() takes in account overflow
limits from scrollable_overflow_rect().
The volume control's slider is drawn in a rectangle shrunken by its
slider handle's size, so the handle did not move 1:1 with the user's
mouse movement.
To fix this, it will now check for a mousedown in the volume control
with a rectangle sized to fit any possible position of the handle, but
the volume value result will be calculated based on the center of the
handle instead. This allows it to move 1:1 with the mouse cursor.
Co-authored-by: trflynn89 <trflynn89@serenityos.org>
...along with `outline-color`, `outline-style`, and `outline-width`.
This re-uses the existing border-painting code, which seems to work well
enough!
This replaces the previous code for drawing focus-outlines, with generic
outline painting for any elements that want it. Focus outlines are now
instead supported by this code in Default.css:
```css
:focus-visible {
outline: auto;
}
```
This patch adds handling of the 'object-fit' CSS property to the
painting of HTML Image Elements.
This is achieved by first calculating the rect which the image would
need if it were to fully expand into open space and then adequately
cropping it to fit into the image's box.
scale-down is not supported for now.
Otherwise, in a simple page such as:
<video src=...>
<audio src=...>
The video's clip rect would "leak" to the AudioPaintable, preventing the
audio controls from rendering at all.
Not a huge deal because the base MediaPaintable class goes very out of
its way to paint within the confines of its own box, but just to be
safe, this was missed when adding the AudioPaintable class.
The `clip_shrink` optimization in `paint_background()` now also
correctly uses DevicePixels, instead of reducing a DevicePixel rect by
a CSSPixels amount.
When joined border width is zero width, then the midpoint
of the joined corner is no longer need to be computed
anymore. Just set the mid point to be the endpoint of the
corner.
Fixes broken border-radius painting because of lost precision while
converting back and forth between double and CSSPixels.
Fixed example:
```html
<style>
div {
border-radius: 9999px;
background: orange;
padding: 10px;
}
</style><div>huh</div>
```
Using fixed-point saturated arithmetics for CSSPixels allows to avoid
accumulating floating-point errors.
This implementation is not complete yet: currently saturated
arithmetics implemented only for addition. But it is enough to not
regress any of layout tests we have :)
See https://github.com/SerenityOS/serenity/issues/18566