By using enclosing_int_rect(), borders and backgrounds of boxes were
sometimes 1 pixel off, making things slightly larger than they should
be. Fix this by using to_rounded() instead of enclosing_int_rect().
There's definitely more of these type of issues lurking in the code,
and we'll get to them in time.
Relatively positioned boxes should not affect the *layout* of their
siblings. So instead of applying relative inset as a layout-time
translation on the box, we now perform the adjustment at the paintable
level instead.
This makes position:relative actually work as expected, and exposes some
new bugs we need to take care of for Acid2. :^)
Instead of using the absolute_rect(), use absolute_border_box_rect() -
at least for PaintableBox - and inflate it by 2px on each side.
This looks much nicer for text input elements, especially when they have
padding, which would be applied outside the focus rect previously.
Normally, paintable coordinates are relative to the nearest containing
block, but in the SVG case, since <svg> doesn't form a containing block,
we have to specialize the computation of SVGPaintable::absolute_rect().
We don't yet take the spread-distance parameter into account, since we
don't have a way to "inflate" the text shadow.
Also, I'm not sure if we need to inflate the shadow slightly anyway.
Blurred shadows of our pixel fonts seem very faint. Part of this is
that a blur of < 3px does nothing, see #13231, but even so we might
want to inflate it a little.
The `text-shadow` property is almost identical to `box-shadow`:
> Values are interpreted as for box-shadow [CSS-BACKGROUNDS-3].
> (But note that the inset keyword are not allowed.)
So, let's use the same data structures and parsing code for both. :^)
We already walk the entire paint tree within each stacking context in
the main hit testing function (StackingContext::hit_test()), so there's
no need for each individual paintable to walk its own children again.
By not doing that, we remove a source of O(n^2) traversal which made hit
testing on deeply nested web pages unbearably slow.
There's no actual need to build the stacking context tree before
performing layout. Instead, make it lazy and build the tree when it's
actually needed for something.
This avoids a bunch of work in situations where multiple synchronous
layouts are forced (typically by JavaScript) without painting or hit
testing taking place in between.
It also opens up for style invalidations that only target the stacking
context tree.
Since paintables have a default content size of 0x0, we were neglecting
to notify the corresponding layout node about size changes, if the used
content size came out to 0x0.
This fixes an issue where resizing an iframe to 0x0 didn't take effect.
No need to call the expensive establishes_stacking_context() here, as
we've already built the stacking context tree and can simply test for
the presence of existing stacking contexts.
The absolute rect of a paintable is somewhat expensive to compute. This
is because all coordinates are relative to the nearest containing block,
so we have to traverse the containing block chain and apply each offset
to get the final rect.
Paintables will never move between containing blocks, nor will their
absolute rect change. If anything changes, we'll simpl make a new
paintable and replace the old one.
Take advantage of this by caching the containing block and absolute rect
after first access.