From 502bc5fbe547283f2723c26c35b630a10f275c28 Mon Sep 17 00:00:00 2001 From: Robin Linden Date: Tue, 14 Nov 2023 00:10:48 +0100 Subject: [PATCH] layout: Add %-unit-support to UnresolvedValue Whatever % is resolved relative to still has to be added to the properties we want it to work for. --- layout/layout_box.cpp | 17 +++++++++++++++-- layout/layout_box.h | 5 ++++- layout/unresolved_value.cpp | 4 ++-- layout/unresolved_value.h | 3 ++- layout/unresolved_value_test.cpp | 12 ++++++++++++ 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/layout/layout_box.cpp b/layout/layout_box.cpp index 792b787a..6befc964 100644 --- a/layout/layout_box.cpp +++ b/layout/layout_box.cpp @@ -146,8 +146,11 @@ std::string to_string(LayoutBox const &box) { return std::move(ss).str(); } -// NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -int to_px(std::string_view property, int const font_size, int const root_font_size) { +// NOLINTBEGIN(bugprone-easily-swappable-parameters) +int to_px(std::string_view property, + int const font_size, + int const root_font_size, + std::optional parent_property_value) { // Special case for 0 since it won't ever have a unit that needs to be handled. if (property == "0") { return 0; @@ -163,6 +166,15 @@ int to_px(std::string_view property, int const font_size, int const root_font_si auto const parsed_length = std::distance(property.data(), parse_result.ptr); auto const unit = property.substr(parsed_length); + if (unit == "%") { + if (!parent_property_value.has_value()) { + spdlog::warn("Missing parent-value for property w/ '%' unit"); + return 0; + } + + return static_cast(res / 100.f * (*parent_property_value)); + } + if (unit == "px") { return static_cast(res); } @@ -180,5 +192,6 @@ int to_px(std::string_view property, int const font_size, int const root_font_si spdlog::warn("Bad property '{}' w/ unit '{}' in to_px", property, unit); return static_cast(res); } +// NOLINTEND(bugprone-easily-swappable-parameters) } // namespace layout diff --git a/layout/layout_box.h b/layout/layout_box.h index 74edf8d1..e75d7be2 100644 --- a/layout/layout_box.h +++ b/layout/layout_box.h @@ -102,7 +102,10 @@ inline std::vector dom_children(LayoutBox const &node) { // TODO(robinlinden): This should be internal. // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -int to_px(std::string_view property, int const font_size, int const root_font_size); +int to_px(std::string_view property, + int const font_size, + int const root_font_size, + std::optional parent_property_value = std::nullopt); } // namespace layout diff --git a/layout/unresolved_value.cpp b/layout/unresolved_value.cpp index 208aca22..c2eb8955 100644 --- a/layout/unresolved_value.cpp +++ b/layout/unresolved_value.cpp @@ -8,7 +8,7 @@ namespace layout { // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -int UnresolvedValue::resolve(int font_size, int root_font_size) const { - return to_px(raw, font_size, root_font_size); +int UnresolvedValue::resolve(int font_size, int root_font_size, std::optional percent_relative_to) const { + return to_px(raw, font_size, root_font_size, percent_relative_to); } } // namespace layout diff --git a/layout/unresolved_value.h b/layout/unresolved_value.h index a4fd6553..5c7fb7ab 100644 --- a/layout/unresolved_value.h +++ b/layout/unresolved_value.h @@ -5,6 +5,7 @@ #ifndef LAYOUT_UNRESOLVED_VALUE_H_ #define LAYOUT_UNRESOLVED_VALUE_H_ +#include #include namespace layout { @@ -14,7 +15,7 @@ struct UnresolvedValue { [[nodiscard]] bool operator==(UnresolvedValue const &) const = default; constexpr bool is_auto() const { return raw == "auto"; } - int resolve(int font_size, int root_font_size) const; + int resolve(int font_size, int root_font_size, std::optional percent_relative_to = std::nullopt) const; }; } // namespace layout diff --git a/layout/unresolved_value_test.cpp b/layout/unresolved_value_test.cpp index 28d109d1..b0b07ace 100644 --- a/layout/unresolved_value_test.cpp +++ b/layout/unresolved_value_test.cpp @@ -33,5 +33,17 @@ int main() { a.expect_eq(uv.resolve(0, 0), 0); }); + s.add_test("unit/%", [](etest::IActions &a) { + // Based on the third argument, whatever the spec wants the property + // this came from to be resolved against. + auto const uv = layout::UnresolvedValue{.raw = "50%"}; + a.expect_eq(uv.resolve(100, 100, 100), 50); + a.expect_eq(uv.resolve(100, 100, 200), 100); + a.expect_eq(uv.resolve(0, 0, 1000), 500); + + // If the third argument is not provided, you get nothing. + a.expect_eq(uv.resolve(123, 456), 0); + }); + return s.run(); }