mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:37:46 +00:00
LibWeb: Size SVG G container according to children
The SVG G container should have the same size as its children. This fixes a bug when there was an opacity value on the G element, as in StackingContext it would try and get a bitmap of the element which would be empty due to it having no size.
This commit is contained in:
parent
258af0fb1b
commit
f2047a5c32
5 changed files with 71 additions and 7 deletions
|
@ -21,12 +21,12 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
frag 0 from SVGSVGBox start: 0, length: 0, rect: [50,450 200x200]
|
frag 0 from SVGSVGBox start: 0, length: 0, rect: [50,450 200x200]
|
||||||
SVGSVGBox <svg> at (50,150) content-size 200x100 [SVG] children: inline
|
SVGSVGBox <svg> at (50,150) content-size 200x100 [SVG] children: inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
SVGGraphicsBox <g> at (50,150) content-size 0x0 children: inline
|
SVGGraphicsBox <g> at (45.6875,199.828125) content-size 118.78125x47.453125 children: inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
SVGGeometryBox <path> at (45.6875,199.828125) content-size 118.78125x47.453125 children: not-inline
|
SVGGeometryBox <path> at (45.6875,199.828125) content-size 118.78125x47.453125 children: not-inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
SVGGraphicsBox <g> at (50,150) content-size 0x0 children: inline
|
SVGGraphicsBox <g> at (84.5,159.5) content-size 81x81 children: inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
SVGGeometryBox <path> at (84.5,159.5) content-size 81x81 children: not-inline
|
SVGGeometryBox <path> at (84.5,159.5) content-size 81x81 children: not-inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
|
@ -99,9 +99,9 @@ PaintableWithLines (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x700]
|
||||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x700]
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x700]
|
||||||
PaintableWithLines (BlockContainer<BODY>) [50,50 700x600]
|
PaintableWithLines (BlockContainer<BODY>) [50,50 700x600]
|
||||||
SVGSVGPaintable (SVGSVGBox<svg>) [50,150 200x100]
|
SVGSVGPaintable (SVGSVGBox<svg>) [50,150 200x100]
|
||||||
SVGGraphicsPaintable (SVGGraphicsBox<g>) [50,150 0x0]
|
SVGGraphicsPaintable (SVGGraphicsBox<g>) [45.6875,199.828125 118.78125x47.453125]
|
||||||
SVGGeometryPaintable (SVGGeometryBox<path>) [45.6875,199.828125 118.78125x47.453125]
|
SVGGeometryPaintable (SVGGeometryBox<path>) [45.6875,199.828125 118.78125x47.453125]
|
||||||
SVGGraphicsPaintable (SVGGraphicsBox<g>) [50,150 0x0]
|
SVGGraphicsPaintable (SVGGraphicsBox<g>) [84.5,159.5 81x81]
|
||||||
SVGGeometryPaintable (SVGGeometryBox<path>) [84.5,159.5 81x81]
|
SVGGeometryPaintable (SVGGeometryBox<path>) [84.5,159.5 81x81]
|
||||||
TextPaintable (TextNode<#text>)
|
TextPaintable (TextNode<#text>)
|
||||||
SVGSVGPaintable (SVGSVGBox<svg>) [258,50 200x200]
|
SVGSVGPaintable (SVGSVGBox<svg>) [258,50 200x200]
|
||||||
|
|
23
Tests/LibWeb/Layout/expected/svg/svg-g-with-opacity.txt
Normal file
23
Tests/LibWeb/Layout/expected/svg/svg-g-with-opacity.txt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (0,0) content-size 800x800 [BFC] children: not-inline
|
||||||
|
BlockContainer <body> at (8,8) content-size 784x784 children: inline
|
||||||
|
line 0 width: 784, height: 784, bottom: 784, baseline: 784
|
||||||
|
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 784x784]
|
||||||
|
SVGSVGBox <svg> at (8,8) content-size 784x784 [SVG] children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
SVGGraphicsBox <g> at (121.671875,121.671875) content-size 556.65625x556.65625 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
SVGGeometryBox <circle> at (121.671875,121.671875) content-size 399.84375x399.84375 children: not-inline
|
||||||
|
TextNode <#text>
|
||||||
|
SVGGeometryBox <circle> at (278.484375,278.484375) content-size 399.84375x399.84375 children: not-inline
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
|
||||||
|
PaintableWithLines (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x800]
|
||||||
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x800]
|
||||||
|
PaintableWithLines (BlockContainer<BODY>) [8,8 784x784]
|
||||||
|
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 784x784]
|
||||||
|
SVGGraphicsPaintable (SVGGraphicsBox<g>) [121.671875,121.671875 556.65625x556.65625]
|
||||||
|
SVGGeometryPaintable (SVGGeometryBox<circle>) [121.671875,121.671875 399.84375x399.84375]
|
||||||
|
SVGGeometryPaintable (SVGGeometryBox<circle>) [278.484375,278.484375 399.84375x399.84375]
|
|
@ -4,7 +4,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
line 0 width: 24, height: 24, bottom: 24, baseline: 24
|
line 0 width: 24, height: 24, bottom: 24, baseline: 24
|
||||||
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 24x24]
|
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 24x24]
|
||||||
SVGSVGBox <svg> at (8,8) content-size 24x24 [SVG] children: inline
|
SVGSVGBox <svg> at (8,8) content-size 24x24 [SVG] children: inline
|
||||||
SVGGraphicsBox <g> at (8,8) content-size 0x0 children: inline
|
SVGGraphicsBox <g> at (8,8) content-size 24x24 children: inline
|
||||||
SVGSVGBox <svg> at (8,8) content-size 24x24 [SVG] children: not-inline
|
SVGSVGBox <svg> at (8,8) content-size 24x24 [SVG] children: not-inline
|
||||||
SVGGeometryBox <rect> at (8,8) content-size 24x24 children: not-inline
|
SVGGeometryBox <rect> at (8,8) content-size 24x24 children: not-inline
|
||||||
TextNode <#text>
|
TextNode <#text>
|
||||||
|
@ -13,6 +13,6 @@ PaintableWithLines (Viewport<#document>) [0,0 800x600]
|
||||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x40]
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x40]
|
||||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x24]
|
PaintableWithLines (BlockContainer<BODY>) [8,8 784x24]
|
||||||
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 24x24]
|
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 24x24]
|
||||||
SVGGraphicsPaintable (SVGGraphicsBox<g>) [8,8 0x0]
|
SVGGraphicsPaintable (SVGGraphicsBox<g>) [8,8 24x24]
|
||||||
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 24x24]
|
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 24x24]
|
||||||
SVGGeometryPaintable (SVGGeometryBox<rect>) [8,8 24x24]
|
SVGGeometryPaintable (SVGGeometryBox<rect>) [8,8 24x24]
|
||||||
|
|
6
Tests/LibWeb/Layout/input/svg/svg-g-with-opacity.html
Normal file
6
Tests/LibWeb/Layout/input/svg/svg-g-with-opacity.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="white" stroke="green" opacity="0.6">
|
||||||
|
<circle cx="40" cy="40" r="25" />
|
||||||
|
<circle cx="60" cy="60" r="25" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 205 B |
|
@ -194,13 +194,48 @@ void SVGFormattingContext::run(Box const& box, LayoutMode layout_mode, Available
|
||||||
m_state.get_mutable(svg_text_box);
|
m_state.get_mutable(svg_text_box);
|
||||||
} else if (is<SVGGraphicsBox>(descendant)) {
|
} else if (is<SVGGraphicsBox>(descendant)) {
|
||||||
// Same hack as above.
|
// Same hack as above.
|
||||||
// FIXME: This should be sized based on its children.
|
|
||||||
auto const& svg_graphics_box = static_cast<SVGGraphicsBox const&>(descendant);
|
auto const& svg_graphics_box = static_cast<SVGGraphicsBox const&>(descendant);
|
||||||
m_state.get_mutable(svg_graphics_box);
|
m_state.get_mutable(svg_graphics_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// https://svgwg.org/svg2-draft/struct.html#Groups
|
||||||
|
// 5.2. Grouping: the ‘g’ element
|
||||||
|
// The ‘g’ element is a container element for grouping together related graphics elements.
|
||||||
|
box.for_each_in_subtree_of_type<Box>([&](Box const& descendant) {
|
||||||
|
if (is<SVGGraphicsBox>(descendant) && !is<SVGGeometryBox>(descendant) && !is<SVGTextBox>(descendant)) {
|
||||||
|
auto const& svg_graphics_box = static_cast<SVGGraphicsBox const&>(descendant);
|
||||||
|
auto& graphics_box_state = m_state.get_mutable(svg_graphics_box);
|
||||||
|
auto smallest_x_position = CSSPixels(0);
|
||||||
|
auto smallest_y_position = CSSPixels(0);
|
||||||
|
auto greatest_x_position = CSSPixels(0);
|
||||||
|
auto greatest_y_position = CSSPixels(0);
|
||||||
|
|
||||||
|
descendant.for_each_in_subtree_of_type<Box>([&](Box const& child_of_svg_container) {
|
||||||
|
auto& box_state = m_state.get_mutable(child_of_svg_container);
|
||||||
|
smallest_x_position = box_state.offset.x();
|
||||||
|
smallest_y_position = box_state.offset.y();
|
||||||
|
return IterationDecision::Break;
|
||||||
|
});
|
||||||
|
|
||||||
|
descendant.for_each_in_subtree_of_type<Box>([&](Box const& child_of_svg_container) {
|
||||||
|
auto& box_state = m_state.get_mutable(child_of_svg_container);
|
||||||
|
smallest_x_position = min(smallest_x_position, box_state.offset.x());
|
||||||
|
smallest_y_position = min(smallest_y_position, box_state.offset.y());
|
||||||
|
greatest_x_position = max(greatest_x_position, box_state.offset.x() + box_state.content_width());
|
||||||
|
greatest_y_position = max(greatest_y_position, box_state.offset.y() + box_state.content_height());
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
|
||||||
|
graphics_box_state.set_content_x(smallest_x_position);
|
||||||
|
graphics_box_state.set_content_y(smallest_y_position);
|
||||||
|
graphics_box_state.set_content_width(greatest_x_position - smallest_x_position);
|
||||||
|
graphics_box_state.set_content_height(greatest_y_position - smallest_y_position);
|
||||||
|
}
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue