diff --git a/Tests/LibWeb/Layout/expected/svg-transforms-and-viewboxes.txt b/Tests/LibWeb/Layout/expected/svg-transforms-and-viewboxes.txt index f864015cd8..a50cfcb82c 100644 --- a/Tests/LibWeb/Layout/expected/svg-transforms-and-viewboxes.txt +++ b/Tests/LibWeb/Layout/expected/svg-transforms-and-viewboxes.txt @@ -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] SVGSVGBox at (50,150) content-size 200x100 [SVG] children: inline TextNode <#text> - SVGGraphicsBox at (50,150) content-size 0x0 children: inline + SVGGraphicsBox at (45.6875,199.828125) content-size 118.78125x47.453125 children: inline TextNode <#text> SVGGeometryBox at (45.6875,199.828125) content-size 118.78125x47.453125 children: not-inline TextNode <#text> TextNode <#text> - SVGGraphicsBox at (50,150) content-size 0x0 children: inline + SVGGraphicsBox at (84.5,159.5) content-size 81x81 children: inline TextNode <#text> SVGGeometryBox at (84.5,159.5) content-size 81x81 children: not-inline TextNode <#text> @@ -99,9 +99,9 @@ PaintableWithLines (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x700] PaintableWithLines (BlockContainer) [0,0 800x700] PaintableWithLines (BlockContainer) [50,50 700x600] SVGSVGPaintable (SVGSVGBox) [50,150 200x100] - SVGGraphicsPaintable (SVGGraphicsBox) [50,150 0x0] + SVGGraphicsPaintable (SVGGraphicsBox) [45.6875,199.828125 118.78125x47.453125] SVGGeometryPaintable (SVGGeometryBox) [45.6875,199.828125 118.78125x47.453125] - SVGGraphicsPaintable (SVGGraphicsBox) [50,150 0x0] + SVGGraphicsPaintable (SVGGraphicsBox) [84.5,159.5 81x81] SVGGeometryPaintable (SVGGeometryBox) [84.5,159.5 81x81] TextPaintable (TextNode<#text>) SVGSVGPaintable (SVGSVGBox) [258,50 200x200] diff --git a/Tests/LibWeb/Layout/expected/svg/svg-g-with-opacity.txt b/Tests/LibWeb/Layout/expected/svg/svg-g-with-opacity.txt new file mode 100644 index 0000000000..2e207af007 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/svg/svg-g-with-opacity.txt @@ -0,0 +1,23 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x800 [BFC] children: not-inline + BlockContainer 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 at (8,8) content-size 784x784 [SVG] children: inline + TextNode <#text> + SVGGraphicsBox at (121.671875,121.671875) content-size 556.65625x556.65625 children: inline + TextNode <#text> + SVGGeometryBox at (121.671875,121.671875) content-size 399.84375x399.84375 children: not-inline + TextNode <#text> + SVGGeometryBox 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) [0,0 800x800] + PaintableWithLines (BlockContainer) [8,8 784x784] + SVGSVGPaintable (SVGSVGBox) [8,8 784x784] + SVGGraphicsPaintable (SVGGraphicsBox) [121.671875,121.671875 556.65625x556.65625] + SVGGeometryPaintable (SVGGeometryBox) [121.671875,121.671875 399.84375x399.84375] + SVGGeometryPaintable (SVGGeometryBox) [278.484375,278.484375 399.84375x399.84375] diff --git a/Tests/LibWeb/Layout/expected/svg/svg-inside-svg.txt b/Tests/LibWeb/Layout/expected/svg/svg-inside-svg.txt index 0251efb413..6ccdd7f08f 100644 --- a/Tests/LibWeb/Layout/expected/svg/svg-inside-svg.txt +++ b/Tests/LibWeb/Layout/expected/svg/svg-inside-svg.txt @@ -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 frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 24x24] SVGSVGBox at (8,8) content-size 24x24 [SVG] children: inline - SVGGraphicsBox at (8,8) content-size 0x0 children: inline + SVGGraphicsBox at (8,8) content-size 24x24 children: inline SVGSVGBox at (8,8) content-size 24x24 [SVG] children: not-inline SVGGeometryBox at (8,8) content-size 24x24 children: not-inline TextNode <#text> @@ -13,6 +13,6 @@ PaintableWithLines (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x40] PaintableWithLines (BlockContainer) [8,8 784x24] SVGSVGPaintable (SVGSVGBox) [8,8 24x24] - SVGGraphicsPaintable (SVGGraphicsBox) [8,8 0x0] + SVGGraphicsPaintable (SVGGraphicsBox) [8,8 24x24] SVGSVGPaintable (SVGSVGBox) [8,8 24x24] SVGGeometryPaintable (SVGGeometryBox) [8,8 24x24] diff --git a/Tests/LibWeb/Layout/input/svg/svg-g-with-opacity.html b/Tests/LibWeb/Layout/input/svg/svg-g-with-opacity.html new file mode 100644 index 0000000000..be5d7608aa --- /dev/null +++ b/Tests/LibWeb/Layout/input/svg/svg-g-with-opacity.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp index 29c499202c..539b7e75f5 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp @@ -194,13 +194,48 @@ void SVGFormattingContext::run(Box const& box, LayoutMode layout_mode, Available m_state.get_mutable(svg_text_box); } else if (is(descendant)) { // Same hack as above. - // FIXME: This should be sized based on its children. auto const& svg_graphics_box = static_cast(descendant); m_state.get_mutable(svg_graphics_box); } 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 const& descendant) { + if (is(descendant) && !is(descendant) && !is(descendant)) { + auto const& svg_graphics_box = static_cast(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 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 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; + }); } }