summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.cpp6
-rw-r--r--Userland/Libraries/LibWeb/Layout/AvailableSpace.cpp53
-rw-r--r--Userland/Libraries/LibWeb/Layout/AvailableSpace.h63
-rw-r--r--Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp23
-rw-r--r--Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h3
-rw-r--r--Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp8
-rw-r--r--Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h6
-rw-r--r--Userland/Libraries/LibWeb/Layout/FormattingContext.cpp21
-rw-r--r--Userland/Libraries/LibWeb/Layout/FormattingContext.h5
-rw-r--r--Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Layout/GridFormattingContext.h2
-rw-r--r--Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h2
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h2
-rw-r--r--Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Layout/TableFormattingContext.h2
17 files changed, 163 insertions, 41 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp
index 8d2d0b11f3..317fb3163d 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Document.cpp
@@ -809,7 +809,11 @@ void Document::update_layout()
icb_state.set_content_width(viewport_rect.width());
icb_state.set_content_height(viewport_rect.height());
- root_formatting_context.run(*m_layout_root, Layout::LayoutMode::Normal);
+ root_formatting_context.run(
+ *m_layout_root,
+ Layout::LayoutMode::Normal,
+ Layout::AvailableSpace::make_definite(viewport_rect.width()),
+ Layout::AvailableSpace::make_definite(viewport_rect.height()));
}
layout_state.commit();
diff --git a/Userland/Libraries/LibWeb/Layout/AvailableSpace.cpp b/Userland/Libraries/LibWeb/Layout/AvailableSpace.cpp
new file mode 100644
index 0000000000..026fe90311
--- /dev/null
+++ b/Userland/Libraries/LibWeb/Layout/AvailableSpace.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/Layout/AvailableSpace.h>
+#include <math.h>
+
+namespace Web::Layout {
+
+AvailableSpace AvailableSpace::make_definite(float value)
+{
+ return AvailableSpace { Type::Definite, value };
+}
+
+AvailableSpace AvailableSpace::make_indefinite()
+{
+ return AvailableSpace { Type::Indefinite, INFINITY };
+}
+
+AvailableSpace AvailableSpace::make_min_content()
+{
+ return AvailableSpace { Type::MinContent, 0 };
+}
+
+AvailableSpace AvailableSpace::make_max_content()
+{
+ return AvailableSpace { Type::MaxContent, INFINITY };
+}
+
+String AvailableSpace::to_string() const
+{
+ switch (m_type) {
+ case Type::Definite:
+ return String::formatted("definite({})", m_value);
+ case Type::Indefinite:
+ return "indefinite";
+ case Type::MinContent:
+ return "min-content";
+ case Type::MaxContent:
+ return "max-content";
+ }
+ VERIFY_NOT_REACHED();
+}
+
+AvailableSpace::AvailableSpace(Type type, float value)
+ : m_type(type)
+ , m_value(value)
+{
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/Layout/AvailableSpace.h b/Userland/Libraries/LibWeb/Layout/AvailableSpace.h
new file mode 100644
index 0000000000..7f319ab9cb
--- /dev/null
+++ b/Userland/Libraries/LibWeb/Layout/AvailableSpace.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Format.h>
+#include <AK/String.h>
+#include <LibWeb/Forward.h>
+
+namespace Web::Layout {
+
+class AvailableSpace {
+public:
+ enum class Type {
+ Definite,
+ Indefinite,
+ MinContent,
+ MaxContent,
+ };
+
+ static AvailableSpace make_definite(float);
+ static AvailableSpace make_indefinite();
+ static AvailableSpace make_min_content();
+ static AvailableSpace make_max_content();
+
+ bool is_definite() const { return m_type == Type::Definite; }
+ bool is_indefinite() const { return m_type == Type::Indefinite; }
+ bool is_min_content() const { return m_type == Type::MinContent; }
+ bool is_max_content() const { return m_type == Type::MaxContent; }
+ bool is_intrinsic_sizing_constraint() const { return is_min_content() || is_max_content(); }
+
+ float definite_value() const
+ {
+ VERIFY(is_definite());
+ return m_value;
+ }
+
+ float to_px() const
+ {
+ return m_value;
+ }
+
+ String to_string() const;
+
+private:
+ AvailableSpace(Type type, float);
+
+ Type m_type {};
+ float m_value {};
+};
+
+}
+
+template<>
+struct AK::Formatter<Web::Layout::AvailableSpace> : Formatter<StringView> {
+ ErrorOr<void> format(FormatBuilder& builder, Web::Layout::AvailableSpace const& available_space)
+ {
+ return Formatter<StringView>::format(builder, available_space.to_string());
+ }
+};
diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
index 773f352d75..9732a86363 100644
--- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
@@ -44,7 +44,7 @@ float BlockFormattingContext::automatic_content_height() const
return compute_auto_height_for_block_formatting_context_root(m_state, root());
}
-void BlockFormattingContext::run(Box const&, LayoutMode layout_mode)
+void BlockFormattingContext::run(Box const&, LayoutMode layout_mode, [[maybe_unused]] AvailableSpace const& available_width, [[maybe_unused]] AvailableSpace const& available_height)
{
if (is_initial()) {
layout_initial_containing_block(layout_mode);
@@ -366,7 +366,11 @@ void BlockFormattingContext::layout_inline_children(BlockContainer const& block_
}
InlineFormattingContext context(m_state, block_container, *this);
- context.run(block_container, layout_mode);
+ context.run(
+ block_container,
+ layout_mode,
+ AvailableSpace::make_definite(containing_block_width_for(block_container)),
+ AvailableSpace::make_definite(containing_block_height_for(block_container)));
float max_line_width = 0;
float content_height = 0;
@@ -419,7 +423,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
} else {
independent_formatting_context = create_independent_formatting_context_if_needed(m_state, box);
if (independent_formatting_context)
- independent_formatting_context->run(box, layout_mode);
+ independent_formatting_context->run(box, layout_mode, AvailableSpace::make_indefinite(), AvailableSpace::make_indefinite());
else
layout_block_level_children(verify_cast<BlockContainer>(box), layout_mode);
}
@@ -442,19 +446,6 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
independent_formatting_context->parent_context_did_dimension_child_root_box();
}
-void BlockFormattingContext::run_intrinsic_sizing(Box const& box)
-{
- auto& box_state = m_state.get_mutable(box);
-
- if (box_state.has_definite_width())
- box_state.set_content_width(box.computed_values().width().resolved(box, CSS::Length::make_px(containing_block_width_for(box))).to_px(box));
-
- if (box_state.has_definite_height())
- box_state.set_content_height(box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box));
-
- run(box, LayoutMode::IntrinsicSizing);
-}
-
void BlockFormattingContext::layout_block_level_children(BlockContainer const& block_container, LayoutMode layout_mode)
{
VERIFY(!block_container.children_are_inline());
diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h
index 4d4b827ad0..03b1e5ef63 100644
--- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h
@@ -21,8 +21,7 @@ public:
explicit BlockFormattingContext(LayoutState&, BlockContainer const&, FormattingContext* parent);
~BlockFormattingContext();
- virtual void run(Box const&, LayoutMode) override;
- virtual void run_intrinsic_sizing(Box const&) override;
+ virtual void run(Box const&, LayoutMode, AvailableSpace const& available_width, AvailableSpace const& available_height) override;
virtual float automatic_content_height() const override;
bool is_initial() const;
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
index de329ee8f0..6159f29dc3 100644
--- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
@@ -67,7 +67,7 @@ float FlexFormattingContext::automatic_content_height() const
return m_state.get(flex_container()).content_height();
}
-void FlexFormattingContext::run(Box const& run_box, LayoutMode layout_mode)
+void FlexFormattingContext::run(Box const& run_box, LayoutMode layout_mode, [[maybe_unused]] AvailableSpace const& available_width, [[maybe_unused]] AvailableSpace const& available_height)
{
VERIFY(&run_box == &flex_container());
@@ -598,7 +598,7 @@ void FlexFormattingContext::determine_available_main_and_cross_space(bool& main_
cross_available_space = cross_max_size;
}
- m_available_space = AvailableSpace { .main = main_available_space, .cross = cross_available_space };
+ m_available_space = AvailableSpaceForItems { .main = main_available_space, .cross = cross_available_space };
}
float FlexFormattingContext::calculate_indefinite_main_size(FlexItem const& item)
@@ -635,7 +635,7 @@ float FlexFormattingContext::calculate_indefinite_main_size(FlexItem const& item
VERIFY(independent_formatting_context);
box_state.set_content_width(fit_content_cross_size);
- independent_formatting_context->run(item.box, LayoutMode::Normal);
+ independent_formatting_context->run(item.box, LayoutMode::Normal, AvailableSpace::make_indefinite(), AvailableSpace::make_indefinite());
return independent_formatting_context->automatic_content_height();
}
@@ -1100,7 +1100,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
// NOTE: Flex items should always create an independent formatting context!
VERIFY(independent_formatting_context);
- independent_formatting_context->run(item.box, LayoutMode::Normal);
+ independent_formatting_context->run(item.box, LayoutMode::Normal, AvailableSpace::make_indefinite(), AvailableSpace::make_indefinite());
auto automatic_cross_size = is_row_layout() ? independent_formatting_context->automatic_content_height()
: box_state.content_width();
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h
index 4a95aa77ad..c9f786e828 100644
--- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h
@@ -18,7 +18,7 @@ public:
virtual bool inhibits_floating() const override { return true; }
- virtual void run(Box const&, LayoutMode) override;
+ virtual void run(Box const&, LayoutMode, AvailableSpace const& available_width, AvailableSpace const& available_height) override;
virtual float automatic_content_height() const override;
Box const& flex_container() const { return context_box(); }
@@ -190,11 +190,11 @@ private:
Vector<FlexItem> m_flex_items;
CSS::FlexDirection m_flex_direction {};
- struct AvailableSpace {
+ struct AvailableSpaceForItems {
Optional<float> main;
Optional<float> cross;
};
- Optional<AvailableSpace> m_available_space;
+ Optional<AvailableSpaceForItems> m_available_space;
};
}
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
index 870e6c4183..1fe9effafb 100644
--- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
@@ -39,7 +39,18 @@ void FormattingContext::run_intrinsic_sizing(Box const& box)
if (box_state.has_definite_height())
box_state.set_content_height(box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box));
- run(box, LayoutMode::IntrinsicSizing);
+ auto to_available_space = [&](SizeConstraint constraint) {
+ if (constraint == SizeConstraint::MinContent)
+ return AvailableSpace::make_min_content();
+ if (constraint == SizeConstraint::MaxContent)
+ return AvailableSpace::make_max_content();
+ return AvailableSpace::make_indefinite();
+ };
+
+ auto available_width = to_available_space(box_state.width_constraint);
+ auto available_height = to_available_space(box_state.height_constraint);
+
+ run(box, LayoutMode::IntrinsicSizing, available_width, available_height);
}
bool FormattingContext::creates_block_formatting_context(Box const& box)
@@ -104,7 +115,7 @@ OwnPtr<FormattingContext> FormattingContext::create_independent_formatting_conte
{
}
virtual float automatic_content_height() const override { return 0; };
- virtual void run(Box const&, LayoutMode) override { }
+ virtual void run(Box const&, LayoutMode, AvailableSpace const&, AvailableSpace const&) override { }
};
return make<ReplacedFormattingContext>(state, child_box);
}
@@ -146,7 +157,7 @@ OwnPtr<FormattingContext> FormattingContext::create_independent_formatting_conte
{
}
virtual float automatic_content_height() const override { return 0; };
- virtual void run(Box const&, LayoutMode) override { }
+ virtual void run(Box const&, LayoutMode, AvailableSpace const&, AvailableSpace const&) override { }
};
return make<DummyFormattingContext>(state, child_box);
}
@@ -176,9 +187,9 @@ OwnPtr<FormattingContext> FormattingContext::layout_inside(Box const& child_box,
auto independent_formatting_context = create_independent_formatting_context_if_needed(m_state, child_box);
if (independent_formatting_context)
- independent_formatting_context->run(child_box, layout_mode);
+ independent_formatting_context->run(child_box, layout_mode, AvailableSpace::make_indefinite(), AvailableSpace::make_indefinite());
else
- run(child_box, layout_mode);
+ run(child_box, layout_mode, AvailableSpace::make_indefinite(), AvailableSpace::make_indefinite());
return independent_formatting_context;
}
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.h b/Userland/Libraries/LibWeb/Layout/FormattingContext.h
index e091d31c7d..76b7556a30 100644
--- a/Userland/Libraries/LibWeb/Layout/FormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.h
@@ -8,6 +8,7 @@
#include <AK/OwnPtr.h>
#include <LibWeb/Forward.h>
+#include <LibWeb/Layout/AvailableSpace.h>
#include <LibWeb/Layout/LayoutState.h>
namespace Web::Layout {
@@ -24,7 +25,7 @@ public:
SVG,
};
- virtual void run(Box const&, LayoutMode) = 0;
+ virtual void run(Box const&, LayoutMode, AvailableSpace const& available_width, AvailableSpace const& available_height) = 0;
// This function returns the automatic content height of the context's root box.
virtual float automatic_content_height() const = 0;
@@ -64,7 +65,7 @@ public:
static float containing_block_width_for(Box const&, LayoutState const&);
static float containing_block_height_for(Box const&, LayoutState const&);
- virtual void run_intrinsic_sizing(Box const&);
+ void run_intrinsic_sizing(Box const&);
float compute_box_y_position_with_respect_to_siblings(Box const&, LayoutState::UsedValues const&);
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
index c9f68f9c2f..1ac3ee8941 100644
--- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
@@ -17,7 +17,7 @@ GridFormattingContext::GridFormattingContext(LayoutState& state, BlockContainer
GridFormattingContext::~GridFormattingContext() = default;
-void GridFormattingContext::run(Box const& box, LayoutMode)
+void GridFormattingContext::run(Box const& box, LayoutMode, [[maybe_unused]] AvailableSpace const& available_width, [[maybe_unused]] AvailableSpace const& available_height)
{
auto should_skip_is_anonymous_text_run = [&](Box& child_box) -> bool {
if (child_box.is_anonymous() && !child_box.first_child_of_type<BlockContainer>()) {
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h
index 05696a3d38..09a5450ed3 100644
--- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h
@@ -17,7 +17,7 @@ public:
explicit GridFormattingContext(LayoutState&, BlockContainer const&, FormattingContext* parent);
~GridFormattingContext();
- virtual void run(Box const&, LayoutMode) override;
+ virtual void run(Box const&, LayoutMode, AvailableSpace const& available_width, AvailableSpace const& available_height) override;
virtual float automatic_content_height() const override;
private:
diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp
index c6f5069232..351288f67e 100644
--- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp
@@ -83,7 +83,7 @@ float InlineFormattingContext::automatic_content_height() const
return compute_auto_height_for_block_formatting_context_root(m_state, containing_block());
}
-void InlineFormattingContext::run(Box const&, LayoutMode layout_mode)
+void InlineFormattingContext::run(Box const&, LayoutMode layout_mode, [[maybe_unused]] AvailableSpace const& available_width, [[maybe_unused]] AvailableSpace const& available_height)
{
VERIFY(containing_block().children_are_inline());
generate_line_boxes(layout_mode);
diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h
index e5dd3a29ed..8bb801f658 100644
--- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h
@@ -23,7 +23,7 @@ public:
BlockContainer const& containing_block() const { return static_cast<BlockContainer const&>(context_box()); }
- virtual void run(Box const&, LayoutMode) override;
+ virtual void run(Box const&, LayoutMode, AvailableSpace const& available_width, AvailableSpace const& available_height) override;
virtual float automatic_content_height() const override;
void dimension_box_on_line(Box const&, LayoutMode);
diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
index e7cf8757fb..e7b0f5f154 100644
--- a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
@@ -25,7 +25,7 @@ float SVGFormattingContext::automatic_content_height() const
return 0;
}
-void SVGFormattingContext::run(Box const& box, LayoutMode)
+void SVGFormattingContext::run(Box const& box, LayoutMode, [[maybe_unused]] AvailableSpace const& available_width, [[maybe_unused]] AvailableSpace const& available_height)
{
auto& svg_svg_element = verify_cast<SVG::SVGSVGElement>(*box.dom_node());
diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h
index bfc561947f..6c6d011f1b 100644
--- a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h
@@ -16,7 +16,7 @@ public:
explicit SVGFormattingContext(LayoutState&, Box const&, FormattingContext* parent);
~SVGFormattingContext();
- virtual void run(Box const&, LayoutMode) override;
+ virtual void run(Box const&, LayoutMode, AvailableSpace const& available_width, AvailableSpace const& available_height) override;
virtual float automatic_content_height() const override;
};
diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp
index 23eca43e10..f391be5efb 100644
--- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp
@@ -23,7 +23,7 @@ TableFormattingContext::TableFormattingContext(LayoutState& state, BlockContaine
TableFormattingContext::~TableFormattingContext() = default;
-void TableFormattingContext::run(Box const& box, LayoutMode)
+void TableFormattingContext::run(Box const& box, LayoutMode, [[maybe_unused]] AvailableSpace const& available_width, [[maybe_unused]] AvailableSpace const& available_height)
{
auto& box_state = m_state.get_mutable(box);
diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h
index 05690f8e8c..afef496e96 100644
--- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h
@@ -23,7 +23,7 @@ public:
explicit TableFormattingContext(LayoutState&, BlockContainer const&, FormattingContext* parent);
~TableFormattingContext();
- virtual void run(Box const&, LayoutMode) override;
+ virtual void run(Box const&, LayoutMode, AvailableSpace const& available_width, AvailableSpace const& available_height) override;
virtual float automatic_content_height() const override;
private: