mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:47:44 +00:00
LibWeb: Layout SVG <mask> elements (but don't paint them)
This allows SVG mask elements to have layout computed, but not connected to the main paint tree. They should only be reachable if (and painted) if referenced by the "mask" attribute of another element. This is controlled by the forms_unconnected_subtree() function on the paintable, which (if it returns true) prevents the paintable from being added as a child to what would be its parent.
This commit is contained in:
parent
c5b50ec2f4
commit
0af8d81f48
8 changed files with 19 additions and 29 deletions
|
@ -1,17 +0,0 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x116 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x100 children: inline
|
||||
line 0 width: 100, height: 100, bottom: 100, baseline: 100
|
||||
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 100x100]
|
||||
SVGSVGBox <svg> at (8,8) content-size 100x100 [SVG] children: inline
|
||||
TextNode <#text>
|
||||
SVGGeometryBox <rect> at (8,8) content-size 100x100 children: not-inline
|
||||
TextNode <#text>
|
||||
TextNode <#text>
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x116]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x100]
|
||||
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 100x100]
|
||||
SVGGeometryPaintable (SVGGeometryBox<rect>) [8,8 100x100]
|
|
@ -1,7 +0,0 @@
|
|||
<!doctype html>
|
||||
<svg width="100" height="100" viewBox="0 0 1 1" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="1" height="1" fill="green"/>
|
||||
<mask id="mask" x="0" y="0" width="1" height="1">
|
||||
<rect x="0" y="0" width="1" height="1" fill="red"/>
|
||||
</mask>
|
||||
</svg>
|
|
@ -201,7 +201,7 @@ static void build_paint_tree(Node& node, Painting::Paintable* parent_paintable =
|
|||
Painting::Paintable* paintable = nullptr;
|
||||
if (node.paintable()) {
|
||||
paintable = const_cast<Painting::Paintable*>(node.paintable());
|
||||
if (parent_paintable) {
|
||||
if (parent_paintable && !paintable->forms_unconnected_subtree()) {
|
||||
VERIFY(!paintable->parent());
|
||||
parent_paintable->append_child(*paintable);
|
||||
}
|
||||
|
|
|
@ -124,6 +124,8 @@ public:
|
|||
|
||||
virtual bool wants_mouse_events() const { return false; }
|
||||
|
||||
virtual bool forms_unconnected_subtree() const { return false; }
|
||||
|
||||
enum class DispatchEventOfSameName {
|
||||
Yes,
|
||||
No,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <LibWeb/Layout/ImageBox.h>
|
||||
#include <LibWeb/Painting/SVGGraphicsPaintable.h>
|
||||
#include <LibWeb/SVG/SVGMaskElement.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
||||
|
@ -19,6 +20,12 @@ SVGGraphicsPaintable::SVGGraphicsPaintable(Layout::SVGGraphicsBox const& layout_
|
|||
{
|
||||
}
|
||||
|
||||
bool SVGGraphicsPaintable::forms_unconnected_subtree() const
|
||||
{
|
||||
// Masks should not be painted (i.e. reachable) unless referenced by another element.
|
||||
return is<SVG::SVGMaskElement>(dom_node());
|
||||
}
|
||||
|
||||
Layout::SVGGraphicsBox const& SVGGraphicsPaintable::layout_box() const
|
||||
{
|
||||
return static_cast<Layout::SVGGraphicsBox const&>(layout_node());
|
||||
|
|
|
@ -19,6 +19,8 @@ public:
|
|||
|
||||
Layout::SVGGraphicsBox const& layout_box() const;
|
||||
|
||||
virtual bool forms_unconnected_subtree() const override;
|
||||
|
||||
protected:
|
||||
SVGGraphicsPaintable(Layout::SVGGraphicsBox const&);
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Layout/SVGBox.h>
|
||||
#include <LibWeb/SVG/SVGDefsElement.h>
|
||||
|
||||
namespace Web::SVG {
|
||||
|
@ -24,9 +25,10 @@ void SVGDefsElement::initialize(JS::Realm& realm)
|
|||
set_prototype(&Bindings::ensure_web_prototype<Bindings::SVGDefsElementPrototype>(realm, "SVGDefsElement"));
|
||||
}
|
||||
|
||||
JS::GCPtr<Layout::Node> SVGDefsElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties>)
|
||||
JS::GCPtr<Layout::Node> SVGDefsElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
|
||||
{
|
||||
return nullptr;
|
||||
// FIXME: We need this layout node so any <mask>s inside this element get layout computed.
|
||||
return heap().allocate_without_realm<Layout::SVGBox>(document(), *this, move(style));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <LibWeb/Bindings/SVGMaskElementPrototype.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/Layout/SVGGraphicsBox.h>
|
||||
#include <LibWeb/SVG/SVGMaskElement.h>
|
||||
|
||||
namespace Web::SVG {
|
||||
|
@ -23,9 +24,9 @@ void SVGMaskElement::initialize(JS::Realm& realm)
|
|||
set_prototype(&Bindings::ensure_web_prototype<Bindings::SVGMaskElementPrototype>(realm, "SVGMaskElement"));
|
||||
}
|
||||
|
||||
JS::GCPtr<Layout::Node> SVGMaskElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties>)
|
||||
JS::GCPtr<Layout::Node> SVGMaskElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
|
||||
{
|
||||
return nullptr;
|
||||
return heap().allocate_without_realm<Layout::SVGGraphicsBox>(document(), *this, move(style));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue