srctree

Robin Linden parent 73e1d0f2 9bdbf380
layout: Support propagating parse failures out of UnresolvedValue

inlinesplit
layout/layout_box.cpp added: 42, removed: 13, total 29
@@ -135,7 +135,7 @@ std::string to_string(LayoutBox const &box) {
return std::move(ss).str();
}
 
int to_px(std::string_view property,
std::optional<int> try_to_px(std::string_view property,
int const font_size,
int const root_font_size,
std::optional<int> parent_property_value) {
@@ -148,7 +148,7 @@ int to_px(std::string_view property,
auto parse_result = util::from_chars(property.data(), property.data() + property.size(), res);
if (parse_result.ec != std::errc{}) {
spdlog::warn("Unable to parse property '{}' in to_px", property);
return 0;
return std::nullopt;
}
 
auto const parsed_length = std::distance(property.data(), parse_result.ptr);
@@ -157,7 +157,7 @@ int to_px(std::string_view property,
if (unit == "%") {
if (!parent_property_value.has_value()) {
spdlog::warn("Missing parent-value for property w/ '%' unit");
return 0;
return std::nullopt;
}
 
return static_cast<int>(res / 100.f * (*parent_property_value));
@@ -188,7 +188,7 @@ int to_px(std::string_view property,
}
 
spdlog::warn("Bad property '{}' w/ unit '{}' in to_px", property, unit);
return static_cast<int>(res);
return std::nullopt;
}
 
} // namespace layout
 
layout/layout_box.h added: 42, removed: 13, total 29
@@ -92,11 +92,18 @@ inline std::vector<LayoutBox const *> dom_children(LayoutBox const &node) {
}
 
// TODO(robinlinden): This should be internal.
int to_px(std::string_view property,
std::optional<int> try_to_px(std::string_view property,
int font_size,
int root_font_size,
std::optional<int> parent_property_value = std::nullopt);
 
inline int to_px(std::string_view property,
int font_size,
int root_font_size,
std::optional<int> parent_property_value = std::nullopt) {
return try_to_px(property, font_size, root_font_size, parent_property_value).value_or(0);
}
 
} // namespace layout
 
#endif // LAYOUT_LAYOUT_BOX_H_
 
layout/unresolved_value.cpp added: 42, removed: 13, total 29
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -9,7 +9,14 @@
#include <optional>
 
namespace layout {
 
int UnresolvedValue::resolve(int font_size, int root_font_size, std::optional<int> percent_relative_to) const {
return to_px(raw, font_size, root_font_size, percent_relative_to);
}
 
std::optional<int> UnresolvedValue::try_resolve(
int font_size, int root_font_size, std::optional<int> percent_relative_to) const {
return try_to_px(raw, font_size, root_font_size, percent_relative_to);
}
 
} // namespace layout
 
layout/unresolved_value.h added: 42, removed: 13, total 29
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -17,6 +17,8 @@ struct UnresolvedValue {
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<int> percent_relative_to = std::nullopt) const;
std::optional<int> try_resolve(
int font_size, int root_font_size, std::optional<int> percent_relative_to = std::nullopt) const;
};
 
} // namespace layout
 
layout/unresolved_value_test.cpp added: 42, removed: 13, total 29
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -6,6 +6,8 @@
 
#include "etest/etest2.h"
 
#include <optional>
 
int main() {
etest::Suite s{"UnresolvedValue"};
 
@@ -61,5 +63,16 @@ int main() {
a.expect_eq(uv.resolve(123, 456), 0);
});
 
s.add_test("try_resolve", [](etest::IActions &a) {
// %, no parent provided.
auto const percent = layout::UnresolvedValue{.raw = "50%"};
a.expect_eq(percent.try_resolve(100, 100), std::nullopt);
a.expect_eq(percent.try_resolve(100, 100, 100), 50);
 
// Nonsense.
auto const nonsense = layout::UnresolvedValue{.raw = "foo"};
a.expect_eq(nonsense.try_resolve(100, 100, 100), std::nullopt);
});
 
return s.run();
}