mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-07 08:29:58 +00:00
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.
This commit is contained in:
parent
4417f26d7c
commit
92c08ad4ac
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
26
Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
Normal file
26
Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
Normal file
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
22
Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h
Normal file
22
Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h
Normal file
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue