summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-09-17 23:12:16 +0200
committerAndreas Kling <kling@serenityos.org>2021-09-18 01:39:59 +0200
commit92c08ad4ac4765f5aa23f67573c8d52e09c8ceaa (patch)
treef5ea7ba820a8e28f7988d3a0cb57083e54602af6
parent4417f26d7c5fa9bb2a116afae34dacba4c5f010a (diff)
downloadserenity-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.txt1
-rw-r--r--Userland/Libraries/LibWeb/Layout/FormattingContext.cpp8
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGBox.cpp3
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGBox.h6
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp26
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h22
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGGraphicsBox.h2
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp12
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGPathBox.h1
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp8
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGSVGBox.h2
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;