100 lines
2.8 KiB
C++
100 lines
2.8 KiB
C++
#include "rendering.hxx"
|
|
#include "include/core/SkCanvas.h"
|
|
#include "include/core/SkColor.h"
|
|
#include "include/core/SkFont.h"
|
|
#include "include/core/SkPaint.h"
|
|
#include "include/core/SkRect.h"
|
|
#include "include/core/SkSurfaceProps.h"
|
|
#include "layout/layout_tree.hxx"
|
|
#include <cstdint>
|
|
#include <iostream>
|
|
#include <limits>
|
|
#include <utility>
|
|
|
|
inline const auto NODE_TYPE_BOX = "box";
|
|
inline const auto NODE_TYPE_TEXT = "text";
|
|
|
|
Clef::RenderingContext new_rendering_context(SkCanvas *canvas,
|
|
sk_sp<SkFontMgr> font_mgr) {
|
|
return {
|
|
.canvas = canvas,
|
|
.layout_map{},
|
|
.font_mgr = font_mgr,
|
|
.random_id{0, std::numeric_limits<uint64_t>::max()},
|
|
};
|
|
}
|
|
|
|
Clef::LayoutBound __calculate_node_position(Clef::RenderingContext &ctx,
|
|
Clef::LayoutTree::Node *node) {
|
|
auto bounds = node->measure();
|
|
if (!node->parent) {
|
|
return {0, 0, bounds.width, bounds.height};
|
|
}
|
|
|
|
if (node->prev_sibiling != nullptr) {
|
|
const auto entry = ctx.layout_map.find(node->prev_sibiling->id);
|
|
if (entry == ctx.layout_map.end()) {
|
|
return {0, 0, bounds.width, bounds.height};
|
|
}
|
|
|
|
const auto prev_bound = entry->second;
|
|
return {prev_bound.x, prev_bound.y + prev_bound.height, bounds.width,
|
|
bounds.height};
|
|
}
|
|
|
|
const auto entry = ctx.layout_map.find(node->parent->id);
|
|
if (entry == ctx.layout_map.end()) {
|
|
return {0, 0, bounds.width, bounds.height};
|
|
}
|
|
|
|
const auto parent_bound = entry->second;
|
|
return {parent_bound.x, parent_bound.y, bounds.width, bounds.height};
|
|
}
|
|
|
|
void clef_render_node(Clef::RenderingContext &ctx,
|
|
Clef::LayoutTree::Node *node) {
|
|
|
|
switch (node->type) {
|
|
case Clef::LayoutTree::NodeType::Text: {
|
|
const auto pos = __calculate_node_position(ctx, node);
|
|
auto tn = static_cast<Clef::TextNode *>(node);
|
|
SkPaint paint;
|
|
paint.setColor(SK_ColorBLACK);
|
|
std::cout << "rendering text: " << tn->content << " at x = " << pos.x
|
|
<< " y = " << pos.y << std::endl;
|
|
ctx.canvas->drawString(tn->content.c_str(), pos.x, pos.y + pos.height,
|
|
tn->font, paint);
|
|
ctx.layout_map.insert({node->id, pos});
|
|
break;
|
|
}
|
|
|
|
case Clef::LayoutTree::NodeType::Container: {
|
|
auto cn = static_cast<Clef::ContainerNode *>(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;
|
|
paint.setColor(SK_ColorCYAN);
|
|
ctx.canvas->drawRect(rect, paint);
|
|
ctx.layout_map.insert({node->id, pos});
|
|
|
|
for (const auto &child : cn->children) {
|
|
clef_render_node(ctx, child);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Clef::render_tree(Clef::RenderingContext &ctx, const LayoutTree &tree) {
|
|
SkPaint paint;
|
|
paint.setColor(SK_ColorWHITE);
|
|
ctx.canvas->drawPaint(paint);
|
|
|
|
paint.setColor(SK_ColorBLACK);
|
|
auto tf = ctx.font_mgr->matchFamilyStyle("Inter", SkFontStyle::Normal());
|
|
SkFont f(tf, 20);
|
|
ctx.canvas->drawString("hello", 0, 10, f, paint);
|
|
|
|
clef_render_node(ctx, tree.root);
|
|
}
|