mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-21 18:00:16 +00:00
LibWeb: Lay out SVG <clipPath>
uses
This uses the same trick as done for masks in #23554. Each use of an SVG `<clipPath>` becomes it's own layout subtree rooted at it's user. This allows each use have it's own layout (which allows supporting features such as `clipPathUnits`).
This commit is contained in:
parent
0a061a6a63
commit
c1b5fe61d1
Notes:
sideshowbarker
2024-07-17 08:13:43 +09:00
Author: https://github.com/MacDue
Commit: c1b5fe61d1
Pull-request: https://github.com/SerenityOS/serenity/pull/23736
Issue: https://github.com/SerenityOS/serenity/issues/19648
Issue: https://github.com/SerenityOS/serenity/issues/23006
Reviewed-by: https://github.com/nico
11 changed files with 192 additions and 35 deletions
|
@ -26,6 +26,7 @@
|
|||
#include <LibWeb/Layout/ListItemBox.h>
|
||||
#include <LibWeb/Layout/ListItemMarkerBox.h>
|
||||
#include <LibWeb/Layout/Node.h>
|
||||
#include <LibWeb/Layout/SVGClipBox.h>
|
||||
#include <LibWeb/Layout/SVGMaskBox.h>
|
||||
#include <LibWeb/Layout/TableGrid.h>
|
||||
#include <LibWeb/Layout/TableWrapper.h>
|
||||
|
@ -349,10 +350,15 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
|
|||
display = CSS::Display(CSS::DisplayOutside::Inline, CSS::DisplayInside::Flow);
|
||||
}
|
||||
|
||||
if (context.layout_svg_mask && is<SVG::SVGMaskElement>(dom_node)) {
|
||||
layout_node = document.heap().allocate_without_realm<Layout::SVGMaskBox>(document, static_cast<SVG::SVGMaskElement&>(dom_node), *style);
|
||||
// We're here if our parent is a use of an SVG mask, but we don't want to lay out any <mask> elements that could be a child of this mask.
|
||||
context.layout_svg_mask = false;
|
||||
if (context.layout_svg_mask_or_clip_path) {
|
||||
if (is<SVG::SVGMaskElement>(dom_node))
|
||||
layout_node = document.heap().allocate_without_realm<Layout::SVGMaskBox>(document, static_cast<SVG::SVGMaskElement&>(dom_node), *style);
|
||||
else if (is<SVG::SVGClipPathElement>(dom_node))
|
||||
layout_node = document.heap().allocate_without_realm<Layout::SVGClipBox>(document, static_cast<SVG::SVGClipPathElement&>(dom_node), *style);
|
||||
else
|
||||
VERIFY_NOT_REACHED();
|
||||
// Only layout direct uses of SVG masks/clipPaths.
|
||||
context.layout_svg_mask_or_clip_path = false;
|
||||
}
|
||||
|
||||
if (!layout_node)
|
||||
|
@ -419,15 +425,20 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
|
|||
|
||||
if (is<SVG::SVGGraphicsElement>(dom_node)) {
|
||||
auto& graphics_element = static_cast<SVG::SVGGraphicsElement&>(dom_node);
|
||||
// Create the layout tree for the SVG mask as a child of the masked element. Note: This will create
|
||||
// a new subtree for each use of the mask (so there's not a 1-to-1 mapping from DOM node to mask
|
||||
// layout node). Each use of a mask may be laid out differently so this duplication is necessary.
|
||||
if (auto mask = graphics_element.mask()) {
|
||||
TemporaryChange<bool> layout_mask(context.layout_svg_mask, true);
|
||||
// Create the layout tree for the SVG mask/clip paths as a child of the masked element.
|
||||
// Note: This will create a new subtree for each use of the mask (so there's not a 1-to-1 mapping
|
||||
// from DOM node to mask layout node). Each use of a mask may be laid out differently so this
|
||||
// duplication is necessary.
|
||||
auto layout_mask_or_clip_path = [&](JS::GCPtr<SVG::SVGElement const> mask_or_clip_path) {
|
||||
TemporaryChange<bool> layout_mask(context.layout_svg_mask_or_clip_path, true);
|
||||
push_parent(verify_cast<NodeWithStyle>(*layout_node));
|
||||
create_layout_tree(const_cast<SVG::SVGMaskElement&>(*mask), context);
|
||||
create_layout_tree(const_cast<SVG::SVGElement&>(*mask_or_clip_path), context);
|
||||
pop_parent();
|
||||
}
|
||||
};
|
||||
if (auto mask = graphics_element.mask())
|
||||
layout_mask_or_clip_path(mask);
|
||||
if (auto clip_path = graphics_element.clip_path())
|
||||
layout_mask_or_clip_path(clip_path);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/rendering.html#button-layout
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue