Previously, we were handling viewBoxes/viewports in a slightly hacky
way, asking graphics elements to figure out what viewBox to use during
layout. This does not work in all cases, and can't allow for more
complex SVGs where it is possible to have nested viewports.
This commit makes the SVGFormattingContext keep track of the
viewport/boxes, and it now lays out each viewport recursively, where
each nested `<svg>` or `<symbol>` can establish a new viewport.
This fixes some previous edge cases, and starts to allow nested
viewports (there's still some issues to resolve there).
Fixes#22931
This modification introduces a new layer to the painting process. The
stacking context traversal no longer immediately calls the
Gfx::Painter methods. Instead, it writes serialized painting commands
into newly introduced RecordingPainter. Created list of commands is
executed later to produce resulting bitmap.
Producing painting command list will make it easier to add new
optimizations:
- It's simpler to check if the painting result is not visible in the
viewport at the command level rather than during stacking context
traversal.
- Run painting in a separate thread. The painting thread can process
serialized painting commands, while the main thread can work on the
next paintable tree and safely invalidate the previous one.
- As we consider GPU-accelerated painting support, it would be easier
to back each painting command rather than constructing an alternative
for the entire Gfx::Painter API.
This commit removes DeprecatedString's "null" state, and replaces all
its users with one of the following:
- A normal, empty DeprecatedString
- Optional<DeprecatedString>
Note that null states of DeprecatedFlyString/StringView/etc are *not*
affected by this commit. However, DeprecatedString::empty() is now
considered equal to a null StringView.
This allows applying SVG <mask>s to elements. It is only implemented for
the simplest (and default) case:
- mask-type = luminance
- maskContentUnits = maskContentUnits
- maskUnits = objectBoundingBox
- Default masking area
It should be possible to extend to cover more cases. Though the layout
for maskContentUnits = objectBoundingBox will be tricky to figure out.
Rather than modify the transform of the parent (which could change
independently), this adds a new override element_transform() where
element specific tranfroms can be applied. This will always stay in
sync with the attributes.
A ref test comparing a .svg and .html version of the same file is
added as due to differences in attribute parsing order, the .svg version
was previously drawn incorrectly.
Fixes#20859
Previously, we did an evenodd fill for everything which while for most
SVGs works, it is not correct default (it should be nonzero), and broke
some SVGs. This fixes a few of the icons on https://shopify.com/.
This implements the stop-opacity, fill-opacity, and stroke-opacity
properties (in CSS). This replaces the existing more ad-hoc
fill-opacity attribute handling.
This bit is mostly ad-hoc for now. This simply turns fill: url(#grad1)
into document().get_element_by_id('grad1') then resolves the gradient.
This seems to do the trick for most use cases, but this is not
attempting to follow the spec yet to keep things simple.
This uses the new attribute parser functionality, and then resolves the
transform list into a single Gfx::AffineTransform.
This also adds a .get_transform() function which resolves the final
transform, by applying all parent transforms.
Note that as of this commit, there aren't any such throwers, and the
call site in Heap::allocate will drop exceptions on the floor. This
commit only serves to change the declaration of the overrides, make sure
they return an empty value, and to propagate OOM errors frm their base
initialize invocations.
This needs to happen before prototype/constructor intitialization can be
made lazy. Otherwise, GC could run during the C++ constructor and try to
collect the object currently being created.
This is a monster patch that turns all EventTargets into GC-allocated
PlatformObjects. Their C++ wrapper classes are removed, and the LibJS
garbage collector is now responsible for their lifetimes.
There's a fair amount of hacks and band-aids in this patch, and we'll
have a lot of cleanup to do after this.
Rather than having separate systems for the attributes and their CSS
equivalents, we can treat the attributes as presentational hints and
convert them to CSS properties. This means they can be inherited, as
they should. :^)
As noted, the `fill` and `stroke` attributes do not fully match the
`fill` and `stroke` properties. The CSS spec is still an early draft and
not entirely helpful, so we can just pretend they are the same for now.
In the spec, `fill` and `stroke` are supposed to be a shorthands for
various properties. But since the spec is still a working draft, and
neither Firefox or Chrome support the `fill-color` or `stroke-color`
properties, we'll stick with `fill` and `stroke` as simple colors for
now.
Also, note that SVG expects things in "user units", and we are assuming
that 1px = 1 user unit for now.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *