From f2072891c498863b6d0a228525e241e951b50d27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20Lind=C3=A9n?= Date: Sat, 25 Nov 2023 01:25:14 +0100 Subject: [PATCH] layout: Handle relative max/min-width properties --- layout/layout.cpp | 14 ++++++++------ layout/layout_box.cpp | 22 ---------------------- layout/layout_box.h | 7 ++----- layout/layout_property_test.cpp | 8 ++++---- layout/layout_test.cpp | 12 ++++++------ layout/unresolved_value.h | 1 + 6 files changed, 21 insertions(+), 43 deletions(-) diff --git a/layout/layout.cpp b/layout/layout.cpp index 3f429f07..62f13a8d 100644 --- a/layout/layout.cpp +++ b/layout/layout.cpp @@ -191,16 +191,18 @@ void calculate_width_and_margin( box.dimensions.content.width = parent.width - box.dimensions.margin_box().width; } - if (auto min = box.get_property()) { - if (box.dimensions.content.width < *min) { - box.dimensions.content.width = *min; + if (auto min = box.get_property(); !min.is_auto()) { + auto resolved = min.resolve(font_size, root_font_size, parent.width); + if (box.dimensions.content.width < resolved) { + box.dimensions.content.width = resolved; calculate_left_and_right_margin(box, parent, margin_left, margin_right, font_size, root_font_size); } } - if (auto max = box.get_property()) { - if (box.dimensions.content.width > *max) { - box.dimensions.content.width = *max; + if (auto max = box.get_property(); !max.is_none()) { + auto resolved = max.resolve(font_size, root_font_size, parent.width); + if (box.dimensions.content.width > resolved) { + box.dimensions.content.width = resolved; calculate_left_and_right_margin(box, parent, margin_left, margin_right, font_size, root_font_size); } } diff --git a/layout/layout_box.cpp b/layout/layout_box.cpp index 6befc964..df7fc2c5 100644 --- a/layout/layout_box.cpp +++ b/layout/layout_box.cpp @@ -100,28 +100,6 @@ std::pair LayoutBox::get_border_radius_property(css::PropertyId id) co return {to_px(horizontal, font_size, root_font_size), to_px(vertical, font_size, root_font_size)}; } -std::optional LayoutBox::get_min_width_property() const { - auto raw = node->get_raw_property(css::PropertyId::MinWidth); - if (raw == "auto") { - return std::nullopt; - } - - int font_size = node->get_property(); - int root_font_size = get_root_font_size(*node); - return to_px(raw, font_size, root_font_size); -} - -std::optional LayoutBox::get_max_width_property() const { - auto raw = node->get_raw_property(css::PropertyId::MaxWidth); - if (raw == "none") { - return std::nullopt; - } - - int font_size = node->get_property(); - int root_font_size = get_root_font_size(*node); - return to_px(raw, font_size, root_font_size); -} - LayoutBox const *box_at_position(LayoutBox const &box, geom::Position p) { if (!box.dimensions.contains(p)) { return nullptr; diff --git a/layout/layout_box.h b/layout/layout_box.h index e75d7be2..0eb9a246 100644 --- a/layout/layout_box.h +++ b/layout/layout_box.h @@ -48,12 +48,9 @@ struct LayoutBox { if constexpr (T == css::PropertyId::BorderBottomLeftRadius || T == css::PropertyId::BorderBottomRightRadius || T == css::PropertyId::BorderTopLeftRadius || T == css::PropertyId::BorderTopRightRadius) { return get_border_radius_property(T); - } else if constexpr (T == css::PropertyId::MinWidth) { - return get_min_width_property(); - } else if constexpr (T == css::PropertyId::Width) { + } else if constexpr (T == css::PropertyId::MinWidth || T == css::PropertyId::Width + || T == css::PropertyId::MaxWidth) { return UnresolvedValue{node->get_raw_property(T)}; - } else if constexpr (T == css::PropertyId::MaxWidth) { - return get_max_width_property(); } else { return node->get_property(); } diff --git a/layout/layout_property_test.cpp b/layout/layout_property_test.cpp index ec509d5b..0b962408 100644 --- a/layout/layout_property_test.cpp +++ b/layout/layout_property_test.cpp @@ -61,14 +61,14 @@ int main() { }); etest::test("width", [] { - expect_property_eq("13px", 13); - expect_property_eq("auto", std::nullopt); + expect_property_eq("13px", layout::UnresolvedValue{"13px"}); + expect_property_eq("auto", layout::UnresolvedValue{"auto"}); expect_property_eq("42px", layout::UnresolvedValue{"42px"}); expect_property_eq("auto", layout::UnresolvedValue{"auto"}); - expect_property_eq("420px", 420); - expect_property_eq("none", std::nullopt); + expect_property_eq("420px", layout::UnresolvedValue{"420px"}); + expect_property_eq("none", layout::UnresolvedValue{"none"}); }); return etest::run_all_tests(); diff --git a/layout/layout_test.cpp b/layout/layout_test.cpp index 2a64f641..d3d8c19f 100644 --- a/layout/layout_test.cpp +++ b/layout/layout_test.cpp @@ -552,7 +552,7 @@ int main() { .node = dom_root, .properties = {{css::PropertyId::MinWidth, "100px"}, {css::PropertyId::Display, "block"}}, .children = { - {children[0], {{css::PropertyId::MinWidth, "50px"}, {css::PropertyId::Display, "block"}}, { + {children[0], {{css::PropertyId::MinWidth, "50%"}, {css::PropertyId::Display, "block"}}, { {std::get(children[0]).children[0], {{css::PropertyId::Display, "block"}}, {}}, }}, }, @@ -582,9 +582,9 @@ int main() { auto const &children = std::get(dom_root).children; auto style_root = style::StyledNode{ .node = dom_root, - .properties = {{css::PropertyId::MaxWidth, "100px"}, {css::PropertyId::Display, "block"}}, + .properties = {{css::PropertyId::MaxWidth, "200px"}, {css::PropertyId::Display, "block"}}, .children = { - {children[0], {{css::PropertyId::MaxWidth, "50px"}, {css::PropertyId::Display, "block"}}, { + {children[0], {{css::PropertyId::MaxWidth, "50%"}, {css::PropertyId::Display, "block"}}, { {std::get(children[0]).children[0], {{css::PropertyId::Display, "block"}}, {}}, }}, }, @@ -593,10 +593,10 @@ int main() { auto expected_layout = layout::LayoutBox{ .node = &style_root, .type = LayoutType::Block, - .dimensions = {{0, 0, 100, 0}}, + .dimensions = {{0, 0, 200, 0}}, .children = { - {&style_root.children[0], LayoutType::Block, {{0, 0, 50, 0}}, { - {&style_root.children[0].children[0], LayoutType::Block, {{0, 0, 50, 0}}, {}}, + {&style_root.children[0], LayoutType::Block, {{0, 0, 100, 0}}, { + {&style_root.children[0].children[0], LayoutType::Block, {{0, 0, 100, 0}}, {}}, }}, } }; diff --git a/layout/unresolved_value.h b/layout/unresolved_value.h index 5c7fb7ab..7bb66539 100644 --- a/layout/unresolved_value.h +++ b/layout/unresolved_value.h @@ -15,6 +15,7 @@ struct UnresolvedValue { [[nodiscard]] bool operator==(UnresolvedValue const &) const = default; constexpr bool is_auto() const { return raw == "auto"; } + constexpr bool is_none() const { return raw == "none"; } int resolve(int font_size, int root_font_size, std::optional percent_relative_to = std::nullopt) const; };