diff options
author | Andreas Kling <kling@serenityos.org> | 2021-09-17 23:12:16 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-18 01:39:59 +0200 |
commit | 92c08ad4ac4765f5aa23f67573c8d52e09c8ceaa (patch) | |
tree | f5ea7ba820a8e28f7988d3a0cb57083e54602af6 | |
parent | 4417f26d7c5fa9bb2a116afae34dacba4c5f010a (diff) | |
download | serenity-92c08ad4ac4765f5aa23f67573c8d52e09c8ceaa.zip |
LibWeb: Add SVGFormattingContext to handle SVG box trees
Instead of trying to layout SVG boxes as if they are regular CSS boxes,
let's invent an "SVG formatting context" and let it manage SVG boxes.
To facilitate this, Layout::SVGBox no longer inherits from ReplacedBox,
and is instead a simple, "inline-block" style BlockBox.
-rw-r--r-- | Userland/Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/FormattingContext.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGBox.cpp | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGBox.h | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp | 26 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h | 22 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGGraphicsBox.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGPathBox.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGSVGBox.h | 2 |
11 files changed, 65 insertions, 26 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 3e47e6f54a..faadd9ac60 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -193,6 +193,7 @@ set(SOURCES Layout/RadioButton.cpp Layout/ReplacedBox.cpp Layout/SVGBox.cpp + Layout/SVGFormattingContext.cpp Layout/SVGGraphicsBox.cpp Layout/SVGPathBox.cpp Layout/SVGSVGBox.cpp diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 824d7c049c..25fcd8b55d 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -11,6 +11,8 @@ #include <LibWeb/Layout/FormattingContext.h> #include <LibWeb/Layout/InlineFormattingContext.h> #include <LibWeb/Layout/ReplacedBox.h> +#include <LibWeb/Layout/SVGFormattingContext.h> +#include <LibWeb/Layout/SVGSVGBox.h> #include <LibWeb/Layout/TableBox.h> #include <LibWeb/Layout/TableCellBox.h> #include <LibWeb/Layout/TableFormattingContext.h> @@ -67,6 +69,12 @@ bool FormattingContext::creates_block_formatting_context(const Box& box) void FormattingContext::layout_inside(Box& box, LayoutMode layout_mode) { + if (is<SVGSVGBox>(box)) { + SVGFormattingContext context(box, this); + context.run(box, layout_mode); + return; + } + if (creates_block_formatting_context(box)) { BlockFormattingContext context(box, this); context.run(box, layout_mode); diff --git a/Userland/Libraries/LibWeb/Layout/SVGBox.cpp b/Userland/Libraries/LibWeb/Layout/SVGBox.cpp index 318332e889..ea82f9c2e3 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGBox.cpp @@ -10,8 +10,9 @@ namespace Web::Layout { SVGBox::SVGBox(DOM::Document& document, SVG::SVGElement& element, NonnullRefPtr<CSS::StyleProperties> style) - : ReplacedBox(document, element, move(style)) + : BlockBox(document, &element, move(style)) { + set_inline(true); } void SVGBox::before_children_paint(PaintContext& context, PaintPhase phase) diff --git a/Userland/Libraries/LibWeb/Layout/SVGBox.h b/Userland/Libraries/LibWeb/Layout/SVGBox.h index 2d9da30def..ab22f72943 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGBox.h +++ b/Userland/Libraries/LibWeb/Layout/SVGBox.h @@ -6,17 +6,19 @@ #pragma once -#include <LibWeb/Layout/ReplacedBox.h> +#include <LibWeb/Layout/BlockBox.h> #include <LibWeb/SVG/SVGElement.h> #include <LibWeb/SVG/SVGGraphicsElement.h> namespace Web::Layout { -class SVGBox : public ReplacedBox { +class SVGBox : public BlockBox { public: SVGBox(DOM::Document&, SVG::SVGElement&, NonnullRefPtr<CSS::StyleProperties>); virtual ~SVGBox() override = default; + SVG::SVGElement& dom_node() { return verify_cast<SVG::SVGElement>(*Box::dom_node()); } + virtual void before_children_paint(PaintContext& context, PaintPhase phase) override; virtual void after_children_paint(PaintContext& context, PaintPhase phase) override; }; diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp new file mode 100644 index 0000000000..4d09d8a947 --- /dev/null +++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/Format.h> +#include <LibWeb/Layout/SVGFormattingContext.h> +#include <LibWeb/Layout/SVGSVGBox.h> + +namespace Web::Layout { + +SVGFormattingContext::SVGFormattingContext(Box& box, FormattingContext* parent) + : FormattingContext(box, parent) +{ +} + +SVGFormattingContext::~SVGFormattingContext() +{ +} + +void SVGFormattingContext::run(Box&, LayoutMode) +{ +} + +} diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h new file mode 100644 index 0000000000..9fca1c4edc --- /dev/null +++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibWeb/Forward.h> +#include <LibWeb/Layout/FormattingContext.h> + +namespace Web::Layout { + +class SVGFormattingContext : public FormattingContext { +public: + explicit SVGFormattingContext(Box&, FormattingContext* parent); + ~SVGFormattingContext(); + + virtual void run(Box&, LayoutMode) override; +}; + +} diff --git a/Userland/Libraries/LibWeb/Layout/SVGGraphicsBox.h b/Userland/Libraries/LibWeb/Layout/SVGGraphicsBox.h index 22320a8d34..205b7443fc 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGGraphicsBox.h +++ b/Userland/Libraries/LibWeb/Layout/SVGGraphicsBox.h @@ -17,6 +17,8 @@ public: SVGGraphicsBox(DOM::Document&, SVG::SVGGraphicsElement&, NonnullRefPtr<CSS::StyleProperties>); virtual ~SVGGraphicsBox() override = default; + SVG::SVGGraphicsElement& dom_node() { return verify_cast<SVG::SVGGraphicsElement>(SVGBox::dom_node()); } + virtual void before_children_paint(PaintContext& context, PaintPhase phase) override; }; diff --git a/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp b/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp index b93a05c90d..9d4b2e9462 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp @@ -16,18 +16,6 @@ SVGPathBox::SVGPathBox(DOM::Document& document, SVG::SVGPathElement& element, No { } -void SVGPathBox::prepare_for_replaced_layout() -{ - auto& bounding_box = dom_node().get_path().bounding_box(); - set_has_intrinsic_width(true); - set_has_intrinsic_height(true); - set_intrinsic_width(bounding_box.width()); - set_intrinsic_height(bounding_box.height()); - - // FIXME: This does not belong here! Someone at a higher level should place this box. - set_offset(bounding_box.top_left()); -} - void SVGPathBox::paint(PaintContext& context, PaintPhase phase) { if (!is_visible()) diff --git a/Userland/Libraries/LibWeb/Layout/SVGPathBox.h b/Userland/Libraries/LibWeb/Layout/SVGPathBox.h index 3060238cb9..5984443613 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGPathBox.h +++ b/Userland/Libraries/LibWeb/Layout/SVGPathBox.h @@ -18,7 +18,6 @@ public: SVG::SVGPathElement& dom_node() { return verify_cast<SVG::SVGPathElement>(SVGGraphicsBox::dom_node()); } - virtual void prepare_for_replaced_layout() override; virtual void paint(PaintContext& context, PaintPhase phase) override; }; diff --git a/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp b/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp index f53bbbbebe..ce051bb9b7 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp @@ -13,14 +13,6 @@ SVGSVGBox::SVGSVGBox(DOM::Document& document, SVG::SVGSVGElement& element, Nonnu { } -void SVGSVGBox::prepare_for_replaced_layout() -{ - set_has_intrinsic_width(true); - set_has_intrinsic_height(true); - set_intrinsic_width(dom_node().width()); - set_intrinsic_height(dom_node().height()); -} - void SVGSVGBox::before_children_paint(PaintContext& context, PaintPhase phase) { if (phase != PaintPhase::Foreground) diff --git a/Userland/Libraries/LibWeb/Layout/SVGSVGBox.h b/Userland/Libraries/LibWeb/Layout/SVGSVGBox.h index 241a7d3405..5a1cf124d1 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGSVGBox.h +++ b/Userland/Libraries/LibWeb/Layout/SVGSVGBox.h @@ -18,8 +18,6 @@ public: SVG::SVGSVGElement& dom_node() { return verify_cast<SVG::SVGSVGElement>(SVGGraphicsBox::dom_node()); } - virtual void prepare_for_replaced_layout() override; - virtual void before_children_paint(PaintContext& context, PaintPhase phase) override; virtual void after_children_paint(PaintContext& context, PaintPhase phase) override; |