fix: window resizing
This commit is contained in:
7
build.sh
7
build.sh
@@ -9,10 +9,11 @@ pushd "$(dirname $0)"
|
||||
compiler=${CC:-g++}
|
||||
|
||||
src_files=(
|
||||
src/main.cxx
|
||||
src/main.cxx
|
||||
src/util/random.cxx
|
||||
src/layout/layout_tree.cxx
|
||||
src/rendering.cxx
|
||||
src/rendering_context.cxx
|
||||
)
|
||||
|
||||
rapidxml_version="1.13"
|
||||
@@ -44,8 +45,8 @@ gl_flags=$(pkg-config --cflags --libs gl)
|
||||
|
||||
misc_lib_flags=$(pkg-config --cflags --libs libwebp libwebpmux libwebpdemux libpng libjpeg fontconfig)
|
||||
|
||||
common_opts="$rapidxml_flags $skia_flags $glfw_flags $gl_flags -I$root/src -Wall --std=c++20 -v -L$root/vendor/skia/out/Static -lskia -lz $misc_lib_flags"
|
||||
debug_opts="--debug --optimize -DDEBUG $common_opts"
|
||||
common_opts="$rapidxml_flags $skia_flags $glfw_flags $gl_flags -I$root/src -Wall --std=c++20 -L$root/vendor/skia/out/Static -lskia -lz $misc_lib_flags"
|
||||
debug_opts="--debug -g --optimize -DDEBUG $common_opts"
|
||||
|
||||
mkdir -p build
|
||||
pushd build >> /dev/null
|
||||
|
15
src/layout/layout_bound.hxx
Normal file
15
src/layout/layout_bound.hxx
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef __CLEF_LAYOUT_LAYOUT_BOUND_HXX_
|
||||
#define __CLEF_LAYOUT_LAYOUT_BOUND_HXX_
|
||||
|
||||
namespace Clef {
|
||||
|
||||
struct LayoutBound {
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
float height;
|
||||
};
|
||||
|
||||
} // namespace Clef
|
||||
|
||||
#endif
|
@@ -6,6 +6,7 @@
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypeface.h"
|
||||
#include "rapidxml.hpp"
|
||||
#include "rendering.hxx"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
@@ -32,8 +33,6 @@ Clef::LayoutBound Clef::ContainerNode::measure() {
|
||||
float total_height = 0;
|
||||
for (const auto &child : children) {
|
||||
const auto bound = child->measure();
|
||||
std::cout << "bound width" << bound.width << " height " << bound.height
|
||||
<< std::endl;
|
||||
if (bound.width > max_child_width) {
|
||||
max_child_width = bound.width;
|
||||
}
|
||||
@@ -60,8 +59,8 @@ Clef::LayoutBound Clef::TextNode::measure() {
|
||||
Clef::LayoutTree::LayoutTree(Clef::LayoutTree::Node *root) : root(root) {}
|
||||
|
||||
Clef::LayoutTree::Node *
|
||||
Clef::LayoutTree::Node::from_xml_node(rapidxml::xml_node<char> *node,
|
||||
const SkFontMgr &font_mgr) {
|
||||
Clef::LayoutTree::Node::from_xml_node(const RenderingContext &ctx,
|
||||
rapidxml::xml_node<char> *node) {
|
||||
std::cout << "encountered node:" << node->name() << std::endl;
|
||||
|
||||
if (std::strncmp("box", node->name(), 3) == 0) {
|
||||
@@ -70,10 +69,10 @@ Clef::LayoutTree::Node::from_xml_node(rapidxml::xml_node<char> *node,
|
||||
|
||||
std::cout << "assigned id " << container_node->id << std::endl;
|
||||
auto current_node = node->first_node();
|
||||
Node *last_node;
|
||||
Node *last_node = nullptr;
|
||||
|
||||
while (current_node) {
|
||||
auto n = Node::from_xml_node(current_node, font_mgr);
|
||||
auto n = Node::from_xml_node(ctx, current_node);
|
||||
if (!n) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -102,7 +101,7 @@ Clef::LayoutTree::Node::from_xml_node(rapidxml::xml_node<char> *node,
|
||||
}
|
||||
|
||||
auto typeface =
|
||||
font_mgr.matchFamilyStyle("Inter", SkFontStyle::Normal());
|
||||
ctx.font_mgr->matchFamilyStyle("Inter", SkFontStyle::Normal());
|
||||
SkFont f(typeface, 20);
|
||||
|
||||
auto n = new TextNode(content, f);
|
||||
@@ -116,8 +115,9 @@ Clef::LayoutTree::Node::from_xml_node(rapidxml::xml_node<char> *node,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Clef::LayoutTree Clef::LayoutTree::from_xml(const rapidxml::xml_document<> &doc,
|
||||
const SkFontMgr &font_mgr) {
|
||||
Clef::LayoutTree
|
||||
Clef::LayoutTree::from_xml(const RenderingContext &ctx,
|
||||
const rapidxml::xml_document<> &doc) {
|
||||
Clef::LayoutTree::Node *root;
|
||||
|
||||
auto xml_root = doc.first_node("box");
|
||||
@@ -126,7 +126,7 @@ Clef::LayoutTree Clef::LayoutTree::from_xml(const rapidxml::xml_document<> &doc,
|
||||
"cml layout must start with a container node.");
|
||||
}
|
||||
|
||||
root = Node::from_xml_node(xml_root, font_mgr);
|
||||
root = Node::from_xml_node(ctx, xml_root);
|
||||
if (!root) {
|
||||
throw std::runtime_error("failed to parse cml");
|
||||
}
|
||||
|
@@ -1,23 +1,17 @@
|
||||
#ifndef __CLEF_LAYOUT_LAYOUT_TREE_HXX__
|
||||
#define __CLEF_LAYOUT_LAYOUT_TREE_HXX__
|
||||
|
||||
#include "include/core/SkColorSpace.h"
|
||||
#include "include/core/SkFont.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypeface.h"
|
||||
#include "layout_bound.hxx"
|
||||
#include "rapidxml.hpp"
|
||||
#include "rendering_context.hxx"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Clef {
|
||||
|
||||
struct LayoutBound {
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
float height;
|
||||
};
|
||||
|
||||
struct LayoutTree {
|
||||
enum class NodeType { Text, Container };
|
||||
|
||||
@@ -28,16 +22,16 @@ struct LayoutTree {
|
||||
Node *next_sibiling;
|
||||
NodeType type;
|
||||
|
||||
static Node *from_xml_node(rapidxml::xml_node<char> *node,
|
||||
const SkFontMgr &font_mgr);
|
||||
static Node *from_xml_node(const RenderingContext &ctx,
|
||||
rapidxml::xml_node<char> *node);
|
||||
|
||||
virtual Clef::LayoutBound measure() = 0;
|
||||
};
|
||||
|
||||
Node *root;
|
||||
|
||||
static LayoutTree from_xml(const rapidxml::xml_document<> &doc,
|
||||
const SkFontMgr &font_mgr);
|
||||
static LayoutTree from_xml(const RenderingContext &ctx,
|
||||
const rapidxml::xml_document<> &doc);
|
||||
|
||||
private:
|
||||
LayoutTree(Node *root);
|
||||
|
100
src/main.cxx
100
src/main.cxx
@@ -1,20 +1,12 @@
|
||||
#include "GL/gl.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkColorType.h"
|
||||
#include "include/core/SkFontStyle.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/core/SkTypeface.h"
|
||||
#include "include/gpu/ganesh/GrDirectContext.h"
|
||||
#include "include/gpu/ganesh/GrTypes.h"
|
||||
#include "include/gpu/ganesh/gl/GrGLTypes.h"
|
||||
#include "layout/layout_tree.hxx"
|
||||
#include "rapidxml.hpp"
|
||||
#include "rendering.hxx"
|
||||
#include "rendering_context.hxx"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <include/core/SkColorSpace.h>
|
||||
#include <include/core/SkFont.h>
|
||||
#include <include/core/SkFontMgr.h>
|
||||
@@ -30,11 +22,19 @@
|
||||
#include <iostream>
|
||||
#include <rapidxml_utils.hpp>
|
||||
|
||||
const auto INITIAL_WINDOW_WIDTH = 800;
|
||||
const auto INITIAL_WINDOW_HEIGHT = 600;
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
|
||||
auto ctx =
|
||||
static_cast<Clef::RenderingContext *>(glfwGetWindowUserPointer(window));
|
||||
|
||||
GLFWmonitor *mon = glfwGetPrimaryMonitor();
|
||||
float xscale, yscale;
|
||||
glfwGetMonitorContentScale(mon, &xscale, &yscale);
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
Clef::update_skia_surface(*ctx, width, height);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@@ -50,7 +50,8 @@ int main(int argc, char *argv[]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
window = glfwCreateWindow(200, 200, "Clef", nullptr, nullptr);
|
||||
window = glfwCreateWindow(INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT,
|
||||
"Clef", nullptr, nullptr);
|
||||
if (!window) {
|
||||
std::cout << "window cannot be created" << std::endl;
|
||||
glfwTerminate();
|
||||
@@ -58,85 +59,30 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
glfwSwapInterval(1);
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
auto interface = GrGLMakeNativeInterface();
|
||||
if (!interface) {
|
||||
interface = GrGLMakeAssembledInterface(
|
||||
nullptr, (GrGLGetProc) * [](void *, const char *p) -> void * {
|
||||
return (void *)glfwGetProcAddress(p);
|
||||
});
|
||||
if (!interface) {
|
||||
std::cout << "failed to make native interface" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
float xscale, yscale;
|
||||
GLFWmonitor *mon = glfwGetPrimaryMonitor();
|
||||
glfwGetMonitorContentScale(mon, &xscale, &yscale);
|
||||
|
||||
auto context = GrDirectContexts::MakeGL(interface);
|
||||
if (!context) {
|
||||
std::cout << "failed to make DirectContext" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
Clef::RenderingContext rendering_ctx = Clef::new_rendering_context(
|
||||
INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT);
|
||||
|
||||
std::cout << "gl direct context created" << std::endl;
|
||||
|
||||
GrGLFramebufferInfo framebufferInfo;
|
||||
framebufferInfo.fFBOID = 0;
|
||||
framebufferInfo.fFormat = GL_RGBA8;
|
||||
|
||||
std::cout << "frame buffer info created" << std::endl;
|
||||
|
||||
SkColorType colorType = kRGBA_8888_SkColorType;
|
||||
auto target =
|
||||
GrBackendRenderTargets::MakeGL(400, 400, 0, 0, framebufferInfo);
|
||||
|
||||
auto skSurface = SkSurfaces::WrapBackendRenderTarget(
|
||||
context.get(), target, kBottomLeft_GrSurfaceOrigin, colorType, nullptr,
|
||||
nullptr);
|
||||
if (!skSurface) {
|
||||
std::cout << "failed to create skia surface" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::cout << "skia surface created" << std::endl;
|
||||
|
||||
SkCanvas *canvas = skSurface->getCanvas();
|
||||
if (!canvas) {
|
||||
std::cout << "failed to obtain skia canvas" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwSwapInterval(1);
|
||||
|
||||
std::cout << "canvas obtained. entering run loop..." << std::endl;
|
||||
|
||||
auto fontMgr = SkFontMgr_New_Custom_Directory("../resources/font/Inter");
|
||||
std::cout << "fonts found: " << fontMgr->countFamilies() << std::endl;
|
||||
|
||||
auto interRegular =
|
||||
fontMgr->matchFamilyStyle("Inter", SkFontStyle::Normal());
|
||||
if (!interRegular) {
|
||||
std::cout << "WARNING: inter regular not found" << std::endl;
|
||||
}
|
||||
glfwSetWindowUserPointer(window, (void *)&rendering_ctx);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
rapidxml::file<> input_file(argv[1]);
|
||||
rapidxml::xml_document<> doc;
|
||||
doc.parse<rapidxml::parse_default>(input_file.data());
|
||||
|
||||
Clef::RenderingContext ctx{
|
||||
.canvas = canvas,
|
||||
.font_mgr = fontMgr,
|
||||
};
|
||||
|
||||
Clef::LayoutTree tree = Clef::LayoutTree::from_xml(doc, *fontMgr.get());
|
||||
Clef::LayoutTree tree = Clef::LayoutTree::from_xml(rendering_ctx, doc);
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
Clef::render_tree(ctx, tree);
|
||||
Clef::render_tree(rendering_ctx, tree);
|
||||
|
||||
context->flush();
|
||||
rendering_ctx.gr_direct_context->flush();
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
|
@@ -4,26 +4,15 @@
|
||||
#include "include/core/SkFont.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkSurfaceProps.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/ports/SkFontMgr_directory.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();
|
||||
@@ -60,8 +49,6 @@ void clef_render_node(Clef::RenderingContext &ctx,
|
||||
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});
|
||||
|
@@ -1,29 +1,11 @@
|
||||
#ifndef __CLEF__RENDERING_HXX__
|
||||
#define __CLEF__RENDERING_HXX__
|
||||
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkFontMgr.h"
|
||||
#include "include/core/SkFontStyle.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "layout/layout_tree.hxx"
|
||||
#include "rapidxml.hpp"
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Clef {
|
||||
|
||||
struct RenderingContext {
|
||||
SkCanvas *canvas;
|
||||
std::unordered_map<uint64_t, LayoutBound> layout_map;
|
||||
sk_sp<SkFontMgr> font_mgr;
|
||||
std::uniform_int_distribution<std::mt19937::result_type> random_id;
|
||||
};
|
||||
|
||||
RenderingContext new_rendering_context(SkCanvas *canvas,
|
||||
sk_sp<SkFontMgr> font_mgr);
|
||||
|
||||
void render_document(RenderingContext &ctx,
|
||||
const rapidxml::xml_document<> &doc);
|
||||
|
||||
|
48
src/rendering_context.cxx
Normal file
48
src/rendering_context.cxx
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "rendering_context.hxx"
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
|
||||
#include "include/gpu/ganesh/gl/GrGLAssembleInterface.h"
|
||||
#include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
|
||||
#include "include/gpu/ganesh/gl/GrGLDirectContext.h"
|
||||
#include "include/ports/SkFontMgr_directory.h"
|
||||
#include <iostream>
|
||||
|
||||
Clef::RenderingContext Clef::new_rendering_context(int width, int height) {
|
||||
Clef::RenderingContext ctx{
|
||||
.framebuffer_info{0, GL_RGBA8},
|
||||
.font_mgr = SkFontMgr_New_Custom_Directory("../resources/font/Inter"),
|
||||
};
|
||||
|
||||
sk_sp<const GrGLInterface> interface = GrGLMakeNativeInterface();
|
||||
if (!interface) {
|
||||
interface = GrGLMakeAssembledInterface(
|
||||
nullptr, (GrGLGetProc) * [](void *, const char *p) -> void * {
|
||||
return (void *)glfwGetProcAddress(p);
|
||||
});
|
||||
if (!interface) {
|
||||
std::cout << "failed to make native interface" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.gl_interface = interface;
|
||||
ctx.gr_direct_context = GrDirectContexts::MakeGL(interface);
|
||||
|
||||
Clef::update_skia_surface(ctx, width, height);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void Clef::update_skia_surface(Clef::RenderingContext &ctx, int width,
|
||||
int height) {
|
||||
ctx.render_target = GrBackendRenderTargets::MakeGL(width, height, 0, 0,
|
||||
ctx.framebuffer_info);
|
||||
ctx.sk_surface = SkSurfaces::WrapBackendRenderTarget(
|
||||
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;
|
||||
}
|
34
src/rendering_context.hxx
Normal file
34
src/rendering_context.hxx
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef __CLEF_RENDERING_CONTEXT_HXX__
|
||||
#define __CLEF_RENDERING_CONTEXT_HXX__
|
||||
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkColorSpace.h"
|
||||
#include "include/core/SkFontMgr.h"
|
||||
#include "include/gpu/ganesh/GrBackendSurface.h"
|
||||
#include "include/gpu/ganesh/GrDirectContext.h"
|
||||
#include "include/gpu/ganesh/gl/GrGLInterface.h"
|
||||
#include "include/gpu/ganesh/gl/GrGLTypes.h"
|
||||
#include "layout/layout_bound.hxx"
|
||||
#include <random>
|
||||
|
||||
namespace Clef {
|
||||
|
||||
struct RenderingContext {
|
||||
GrGLFramebufferInfo framebuffer_info;
|
||||
GrBackendRenderTarget render_target;
|
||||
sk_sp<const GrGLInterface> gl_interface;
|
||||
sk_sp<GrDirectContext> gr_direct_context;
|
||||
sk_sp<SkSurface> sk_surface;
|
||||
SkCanvas *canvas;
|
||||
std::unordered_map<uint64_t, LayoutBound> layout_map;
|
||||
sk_sp<SkFontMgr> font_mgr;
|
||||
std::uniform_int_distribution<std::mt19937::result_type> random_id;
|
||||
};
|
||||
|
||||
RenderingContext new_rendering_context(int width, int height);
|
||||
|
||||
void update_skia_surface(RenderingContext &ctx, int width, int height);
|
||||
|
||||
} // namespace Clef
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user