From ebe34ecebbe2a336cd09e45b80c91d8016b3161a Mon Sep 17 00:00:00 2001 From: Kenneth Date: Sun, 13 Oct 2024 18:29:58 +0100 Subject: [PATCH] feat: add row/col tags --- src/layout/layout.hxx | 10 ++++++ src/layout/layout_tree.cxx | 70 +++++++++++++++++++++++++------------- src/layout/layout_tree.hxx | 8 +++-- src/rendering.cxx | 26 +++++++++----- src/rendering_context.cxx | 3 -- test_cml/code.cml | 1 + test_cml/header.cml | 9 +++++ test_cml/hello.cml | 12 +++++++ test_cml/permission.cml | 17 +++++++++ test_cml/test.cml | 4 +++ 10 files changed, 123 insertions(+), 37 deletions(-) create mode 100644 src/layout/layout.hxx create mode 100644 test_cml/code.cml create mode 100644 test_cml/header.cml create mode 100644 test_cml/permission.cml create mode 100644 test_cml/test.cml diff --git a/src/layout/layout.hxx b/src/layout/layout.hxx new file mode 100644 index 0000000..fe788f2 --- /dev/null +++ b/src/layout/layout.hxx @@ -0,0 +1,10 @@ +#ifndef __CLEF_LAYOUT_LAYOUT_HXX__ +#define __CLEF_LAYOUT_LAYOUT_HXX__ + +namespace Clef { + +enum class Orientation { Horizontal, Vertical }; + +} + +#endif diff --git a/src/layout/layout_tree.cxx b/src/layout/layout_tree.cxx index f2e4ec0..4fca5fc 100644 --- a/src/layout/layout_tree.cxx +++ b/src/layout/layout_tree.cxx @@ -5,8 +5,8 @@ #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" #include "include/core/SkTypeface.h" +#include "layout/layout.hxx" #include "rapidxml.hpp" -#include "rendering.hxx" #include #include #include @@ -19,26 +19,49 @@ static std::uniform_int_distribution static std::random_device dev; static std::mt19937 rng(dev()); +inline const auto NODE_TYPE_BOX = "box"; +inline const auto NODE_TYPE_ROW = "row"; +inline const auto NODE_TYPE_COL = "col"; +inline const auto NODE_TYPE_TEXT = "text"; + uint64_t __generate_random_node_id() { return random_id(rng); }; -Clef::ContainerNode::ContainerNode() { +Clef::BoxNode::BoxNode() : orientation(Orientation::Vertical) { prev_sibiling = nullptr; next_sibiling = nullptr; parent = nullptr; - type = Clef::LayoutTree::NodeType::Container; + type = Clef::LayoutTree::NodeType::Box; } -Clef::LayoutBound Clef::ContainerNode::measure() { - float max_child_width = -1; - float total_height = 0; - for (const auto &child : children) { - const auto bound = child->measure(); - if (bound.width > max_child_width) { - max_child_width = bound.width; +Clef::LayoutBound Clef::BoxNode::measure() { + switch (orientation) { + case Orientation::Vertical: { + + float max_child_width = -1; + float total_height = 0; + for (const auto &child : children) { + const auto bound = child->measure(); + if (bound.width > max_child_width) { + max_child_width = bound.width; + } + total_height += bound.height; } - total_height += bound.height; + return {0, 0, max_child_width, total_height}; + } + + case Orientation::Horizontal: { + float max_child_height = -1; + float total_width = 0; + for (const auto &child : children) { + const auto bound = child->measure(); + if (bound.height > max_child_height) { + max_child_height = bound.height; + } + total_width += bound.width; + } + return {0, 0, total_width, max_child_height}; + } } - return {0, 0, max_child_width, total_height}; } Clef::TextNode::TextNode(const char *content, SkFont font) @@ -61,13 +84,17 @@ Clef::LayoutTree::LayoutTree(Clef::LayoutTree::Node *root) : root(root) {} Clef::LayoutTree::Node * Clef::LayoutTree::Node::from_xml_node(const RenderingContext &ctx, rapidxml::xml_node *node) { - std::cout << "encountered node:" << node->name() << std::endl; - - if (std::strncmp("box", node->name(), 3) == 0) { - auto container_node = new ContainerNode(); + if (std::strncmp(NODE_TYPE_ROW, node->name(), 3) == 0 || + std::strncmp(NODE_TYPE_COL, node->name(), 3) == 0) { + auto container_node = new BoxNode(); container_node->id = __generate_random_node_id(); - std::cout << "assigned id " << container_node->id << std::endl; + if (std::strncmp(NODE_TYPE_ROW, node->name(), 3) == 0) { + container_node->orientation = Orientation::Horizontal; + } else { + container_node->orientation = Orientation::Vertical; + } + auto current_node = node->first_node(); Node *last_node = nullptr; @@ -80,8 +107,6 @@ Clef::LayoutTree::Node::from_xml_node(const RenderingContext &ctx, if (last_node) { n->prev_sibiling = last_node; last_node->next_sibiling = n; - std::cout << n << std::endl; - std::cout << last_node << std::endl; } n->parent = container_node; @@ -94,7 +119,7 @@ Clef::LayoutTree::Node::from_xml_node(const RenderingContext &ctx, return container_node; } - if (std::strncmp("text", node->name(), 4) == 0) { + if (std::strncmp(NODE_TYPE_TEXT, node->name(), 4) == 0) { const auto content = node->value(); if (!content) { return nullptr; @@ -120,10 +145,9 @@ Clef::LayoutTree::from_xml(const RenderingContext &ctx, const rapidxml::xml_document<> &doc) { Clef::LayoutTree::Node *root; - auto xml_root = doc.first_node("box"); + auto xml_root = doc.first_node(); if (!xml_root) { - throw std::runtime_error( - "cml layout must start with a container node."); + throw std::runtime_error("provided layout file appears to be empty."); } root = Node::from_xml_node(ctx, xml_root); diff --git a/src/layout/layout_tree.hxx b/src/layout/layout_tree.hxx index 6de1117..f3b03c8 100644 --- a/src/layout/layout_tree.hxx +++ b/src/layout/layout_tree.hxx @@ -3,6 +3,7 @@ #include "include/core/SkColorSpace.h" #include "include/core/SkFont.h" +#include "layout/layout.hxx" #include "layout_bound.hxx" #include "rapidxml.hpp" #include "rendering_context.hxx" @@ -13,7 +14,7 @@ namespace Clef { struct LayoutTree { - enum class NodeType { Text, Container }; + enum class NodeType { Text, Box }; struct Node { uint64_t id; @@ -37,12 +38,13 @@ struct LayoutTree { LayoutTree(Node *root); }; -struct ContainerNode : LayoutTree::Node { +struct BoxNode : LayoutTree::Node { + Orientation orientation; std::vector children; Clef::LayoutBound measure() override; - ContainerNode(); + BoxNode(); }; struct TextNode : LayoutTree::Node { diff --git a/src/rendering.cxx b/src/rendering.cxx index 7efe4f5..b865163 100644 --- a/src/rendering.cxx +++ b/src/rendering.cxx @@ -6,13 +6,10 @@ #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" #include "include/ports/SkFontMgr_directory.h" +#include "layout/layout.hxx" #include "layout/layout_tree.hxx" -#include #include -inline const auto NODE_TYPE_BOX = "box"; -inline const auto NODE_TYPE_TEXT = "text"; - Clef::LayoutBound __calculate_node_position(Clef::RenderingContext &ctx, Clef::LayoutTree::Node *node) { auto bounds = node->measure(); @@ -26,8 +23,21 @@ Clef::LayoutBound __calculate_node_position(Clef::RenderingContext &ctx, return {0, 0, bounds.width, bounds.height}; } + const auto parent = node->parent; const auto prev_bound = entry->second; - return {prev_bound.x, prev_bound.y + prev_bound.height, bounds.width, + if (parent->type == Clef::LayoutTree::NodeType::Box) { + const auto parent_box = static_cast(parent); + switch (parent_box->orientation) { + case Clef::Orientation::Vertical: + return {prev_bound.x, prev_bound.y + prev_bound.height, + bounds.width, bounds.height}; + case Clef::Orientation::Horizontal: + return {prev_bound.x + prev_bound.width, prev_bound.y, + bounds.width, bounds.height}; + } + } + + return {prev_bound.x + prev_bound.width, prev_bound.y, bounds.width, bounds.height}; } @@ -55,8 +65,8 @@ void clef_render_node(Clef::RenderingContext &ctx, break; } - case Clef::LayoutTree::NodeType::Container: { - auto cn = static_cast(node); + case Clef::LayoutTree::NodeType::Box: { + const auto box = static_cast(node); const auto pos = __calculate_node_position(ctx, node); SkRect rect{pos.x, pos.y, pos.x + pos.width, pos.y + pos.height}; SkPaint paint; @@ -64,7 +74,7 @@ void clef_render_node(Clef::RenderingContext &ctx, ctx.canvas->drawRect(rect, paint); ctx.layout_map.insert({node->id, pos}); - for (const auto &child : cn->children) { + for (const auto &child : box->children) { clef_render_node(ctx, child); } break; diff --git a/src/rendering_context.cxx b/src/rendering_context.cxx index 4d644e3..41e928e 100644 --- a/src/rendering_context.cxx +++ b/src/rendering_context.cxx @@ -41,8 +41,5 @@ void Clef::update_skia_surface(Clef::RenderingContext &ctx, int width, ctx.gr_direct_context.get(), ctx.render_target, kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, SkColorSpace::MakeSRGB(), nullptr); - std::cout << "sk surface" << ctx.sk_surface << std::endl; ctx.canvas = ctx.sk_surface->getCanvas(); - std::cout << " kasdjkjsak" << ctx.sk_surface->getCanvas() << std::endl; - std::cout << "new canvas address " << ctx.canvas << std::endl; } diff --git a/test_cml/code.cml b/test_cml/code.cml new file mode 100644 index 0000000..8aec1a1 --- /dev/null +++ b/test_cml/code.cml @@ -0,0 +1 @@ + diff --git a/test_cml/header.cml b/test_cml/header.cml new file mode 100644 index 0000000..8185359 --- /dev/null +++ b/test_cml/header.cml @@ -0,0 +1,9 @@ + + + header + + + + +{content} + diff --git a/test_cml/hello.cml b/test_cml/hello.cml index 5aabc2c..2b36e88 100644 --- a/test_cml/hello.cml +++ b/test_cml/hello.cml @@ -1,4 +1,16 @@ + + hello from clef this is rendered from hello.cml + +
+ + + hello from clef + this is rendered from hello.cml + + + + diff --git a/test_cml/permission.cml b/test_cml/permission.cml new file mode 100644 index 0000000..6c60435 --- /dev/null +++ b/test_cml/permission.cml @@ -0,0 +1,17 @@ + + asdklasdk + askdjksajdk + + + + + + + + + + + + + + diff --git a/test_cml/test.cml b/test_cml/test.cml new file mode 100644 index 0000000..f97b93e --- /dev/null +++ b/test_cml/test.cml @@ -0,0 +1,4 @@ + + hello from clef + this is rendered from test.cml +