Although DistinctNumeric, which is supposed to abstract the underlying
type, was used to represent CSSPixels, we have a whole bunch of places
in the layout code that assume CSSPixels::value() returns a
floating-point type. This assumption makes it difficult to replace the
underlying type in CSSPixels with a non-floating type.
To make it easier to transition CSSPixels to fixed-point math, one step
we can take is to prevent access to the underlying type using value()
and instead use explicit conversions with the to_float(), to_double(),
and to_int() methods.
The spec for the `<use>` element requires a shadow tree for the
rendered content, so we need to be able to escape shadow trees when
rendering svg content.
This fixes a plethora of rounding problems on many websites.
In the future, we may want to replace this with fixed-point arithmetic
(bug #18566) for performance (and consistency with other engines),
but in the meantime this makes the web look a bit better. :^)
There's a lot more things that could be converted to doubles, which
would reduce the amount of casting necessary in this patch.
We can do that incrementally, however.
This also combines the viewbox mapping into the same transform and
reuses some code by using Path::copy_transformed() rather than manually
mapping each segment of the path.
This simplifies the ownership model between DOM/layout/paint nodes
immensely by deferring to the garbage collector for figuring out what's
live and what's not.
This fixes a few sizing issues too. The page size is now correct in most
cases! \o/
We get to remove some of the `to_type<>()` shenanigans, though it
reappears in some other places.
This patch adds a bunch of Paintable subclasses, each corresponding to
the Layout::Node subclasses that had a paint() override. All painting
logic is moved from layout nodes into their corresponding paintables.
Paintables are now created by asking a Layout::Box to produce one:
static NonnullOwnPtr<Paintable> Layout::Box::create_paintable()
Note that inline nodes still have their painting logic. Since they
are not boxes, and all paintables have a corresponding box, we'll need
to come up with some other solution for them.
The "paintable" state in Layout::Box was actually not safe to access
until after layout had been performed.
As a first step towards making this harder to mess up accidentally,
this patch moves painting information from Layout::Box to a new class:
Painting::Box. Every layout can have a corresponding paint box, and
it holds the final used metrics determined by layout.
The paint box is created and populated by FormattingState::commit().
I've also added DOM::Node::paint_box() as a convenient way to access
the paint box (if available) of a given DOM node.
Going forward, I believe this will allow us to better separate data
that belongs to layout vs painting, and also open up opportunities
for naturally invalidating caches in the paint box (since it's
reconstituted by every layout.)
This patch begins the support for the 'view-box' attribute that can be
attached to <svg>'s.
The FormattingContext determines the size of the Element according to
the specified 'width' and 'height' or if they are not given by the
'viewbox' or by the bounding box of the path if nothing is specified.
When we try to paint a SVG Path that belongs to a <svg> that has the
'view-box' and a specified 'height'/'width', all the parts of the path
get scaled/moved accordingly.
There probably are many edge cases and bugs still to be found, but this
is a nice start. :^)
This makes the selected-in-the-inspector outline appear in the right
place. We take the stroke-width into account when producing the
bounding box, which makes the fit nice and snug. :^)