srctree

Robin Linden parent 48de2a2b 75f83614
style: Adopt the property parsing from //layout

inlinesplit
layout/layout_box.cpp added: 43, removed: 42, total 1
@@ -9,8 +9,6 @@
#include "dom/dom.h"
#include "geom/geom.h"
#include "style/styled_node.h"
#include "style/unresolved_value.h"
#include "util/string.h"
 
#include <cassert>
#include <cstdint>
@@ -79,14 +77,6 @@ void print_box(LayoutBox const &box, std::ostream &os, std::uint8_t depth = 0) {
}
}
 
int get_root_font_size(style::StyledNode const &node) {
auto const *n = &node;
while (n->parent != nullptr) {
n = n->parent;
}
return n->get_property<css::PropertyId::FontSize>();
}
 
} // namespace
 
std::optional<std::string_view> LayoutBox::text() const {
@@ -98,15 +88,6 @@ std::optional<std::string_view> LayoutBox::text() const {
return std::visit(Visitor{}, layout_text);
}
 
std::pair<int, int> LayoutBox::get_border_radius_property(css::PropertyId id) const {
auto raw = node->get_raw_property(id);
auto [horizontal, vertical] = raw.contains('/') ? util::split_once(raw, "/") : std::pair{raw, raw};
 
int font_size = node->get_property<css::PropertyId::FontSize>();
int root_font_size = get_root_font_size(*node);
return {style::to_px(horizontal, font_size, root_font_size), style::to_px(vertical, font_size, root_font_size)};
}
 
LayoutBox const *box_at_position(LayoutBox const &box, geom::Position p) {
if (!box.dimensions.contains(p)) {
return nullptr;
 
layout/layout_box.h added: 43, removed: 42, total 1
@@ -11,13 +11,11 @@
#include "dom/dom.h"
#include "geom/geom.h"
#include "style/styled_node.h"
#include "style/unresolved_value.h"
 
#include <cassert>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>
 
@@ -39,19 +37,8 @@ struct LayoutBox {
// doesn't have a StyleNode) is a programming error.
assert(!is_anonymous_block());
assert(node);
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 || T == css::PropertyId::Width
|| T == css::PropertyId::MaxWidth) {
return style::UnresolvedValue{node->get_raw_property(T)};
} else {
return node->get_property<T>();
}
return node->get_property<T>();
}
 
private:
std::pair<int, int> get_border_radius_property(css::PropertyId) const;
};
 
LayoutBox const *box_at_position(LayoutBox const &, geom::Position);
 
style/styled_node.cpp added: 43, removed: 42, total 1
@@ -4,6 +4,8 @@
 
#include "style/styled_node.h"
 
#include "style/unresolved_value.h"
 
#include "css/property_id.h"
#include "dom/dom.h"
#include "gfx/color.h"
@@ -33,6 +35,14 @@ using namespace std::literals;
namespace style {
namespace {
 
int get_root_font_size(style::StyledNode const &node) {
auto const *n = &node;
while (n->parent != nullptr) {
n = n->parent;
}
return n->get_property<css::PropertyId::FontSize>();
}
 
std::optional<gfx::Color> try_from_hex_chars(std::string_view hex_chars) {
if (!hex_chars.starts_with('#')) {
return std::nullopt;
@@ -693,4 +703,13 @@ std::optional<WhiteSpace> StyledNode::get_white_space_property() const {
return std::nullopt;
}
 
std::pair<int, int> StyledNode::get_border_radius_property(css::PropertyId id) const {
auto raw = get_raw_property(id);
auto [horizontal, vertical] = raw.contains('/') ? util::split_once(raw, "/") : std::pair{raw, raw};
 
int font_size = get_property<css::PropertyId::FontSize>();
int root_font_size = get_root_font_size(*this);
return {to_px(horizontal, font_size, root_font_size), to_px(vertical, font_size, root_font_size)};
}
 
} // namespace style
 
style/styled_node.h added: 43, removed: 42, total 1
@@ -5,6 +5,8 @@
#ifndef STYLE_STYLED_NODE_H_
#define STYLE_STYLED_NODE_H_
 
#include "style/unresolved_value.h"
 
#include "css/property_id.h"
#include "dom/dom.h"
#include "gfx/color.h"
@@ -144,6 +146,13 @@ struct StyledNode {
return get_text_transform_property();
} else if constexpr (T == css::PropertyId::WhiteSpace) {
return get_white_space_property();
} else 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 || T == css::PropertyId::Width
|| T == css::PropertyId::MaxWidth) {
return UnresolvedValue{get_raw_property(T)};
} else {
return get_raw_property(T);
}
@@ -163,6 +172,7 @@ private:
std::vector<TextDecorationLine> get_text_decoration_line_property() const;
std::optional<TextTransform> get_text_transform_property() const;
std::optional<WhiteSpace> get_white_space_property() const;
std::pair<int, int> get_border_radius_property(css::PropertyId) const;
};
 
[[nodiscard]] inline bool operator==(style::StyledNode const &a, style::StyledNode const &b) noexcept {
 
style/styled_node_test.cpp added: 43, removed: 42, total 1
@@ -4,6 +4,8 @@
 
#include "style/styled_node.h"
 
#include "style/unresolved_value.h"
 
#include "css/property_id.h"
#include "dom/dom.h"
#include "dom/xpath.h"
@@ -54,7 +56,9 @@ void expect_relative_property_eq(std::string value,
} // namespace
 
int main() {
etest::test("get_property", [] { expect_property_eq<css::PropertyId::Width>("15px", "15px"); });
etest::test("get_property", [] {
expect_property_eq<css::PropertyId::Width>("15px", style::UnresolvedValue{"15px"}); //
});
 
etest::test("property inheritance", [] {
dom::Node dom_node = dom::Element{"dummy"s};
@@ -67,7 +71,7 @@ int main() {
auto &child = root.children.emplace_back(style::StyledNode{dom_node, {}, {}, &root});
 
// Not inherited, returns the initial value.
expect_eq(child.get_property<css::PropertyId::Width>(), "auto"sv);
expect_eq(child.get_property<css::PropertyId::Width>(), style::UnresolvedValue{"auto"});
 
// Inherited, returns the parent's value.
expect_eq(child.get_property<css::PropertyId::FontSize>(), 15);
@@ -112,7 +116,7 @@ int main() {
child.parent = &root;
 
// inherit, but not in parent, so receives initial value for property.
expect_eq(child.get_property<css::PropertyId::Width>(), "auto"sv);
expect_eq(child.get_property<css::PropertyId::Width>(), style::UnresolvedValue{"auto"});
 
// inherit, value in parent.
expect_eq(child.get_property<css::PropertyId::BackgroundColor>(), gfx::Color::from_css_name("blue"));
@@ -142,7 +146,7 @@ int main() {
child.parent = &root;
 
// unset, not inherited, so receives initial value for property.
expect_eq(child.get_property<css::PropertyId::Width>(), "auto"sv);
expect_eq(child.get_property<css::PropertyId::Width>(), style::UnresolvedValue{"auto"});
 
// unset, inherited, value in parent.
expect_eq(child.get_property<css::PropertyId::Color>(), gfx::Color::from_css_name("blue"));