add a way to pre-render svgs to fix duplication of surfaces
This commit is contained in:
parent
d07340217c
commit
43eec85adc
7 changed files with 83 additions and 20 deletions
|
@ -5,7 +5,7 @@ project(
|
||||||
)
|
)
|
||||||
project_description = 'The Raven user interface library'
|
project_description = 'The Raven user interface library'
|
||||||
|
|
||||||
add_project_arguments('-g3', language : 'cpp')
|
add_project_arguments('-O3', language : 'cpp')
|
||||||
|
|
||||||
cairomm_dep = dependency('cairomm-1.0')
|
cairomm_dep = dependency('cairomm-1.0')
|
||||||
pangocairo_dep = dependency('pangocairo')
|
pangocairo_dep = dependency('pangocairo')
|
||||||
|
@ -22,6 +22,7 @@ raven_dependencies = [
|
||||||
headers = include_directories('src')
|
headers = include_directories('src')
|
||||||
|
|
||||||
raven_source_files = [
|
raven_source_files = [
|
||||||
|
'./src/SvgUtil.cpp',
|
||||||
'./src/Box.cpp',
|
'./src/Box.cpp',
|
||||||
'./src/Styles.cpp',
|
'./src/Styles.cpp',
|
||||||
'./src/Painter.cpp',
|
'./src/Painter.cpp',
|
||||||
|
@ -38,6 +39,7 @@ raven_source_files = [
|
||||||
]
|
]
|
||||||
|
|
||||||
raven_header_files = [
|
raven_header_files = [
|
||||||
|
'./src/SvgUtil.hpp',
|
||||||
'./src/Logging.hpp',
|
'./src/Logging.hpp',
|
||||||
'./src/Box.hpp',
|
'./src/Box.hpp',
|
||||||
'./src/BoxLayout.hpp',
|
'./src/BoxLayout.hpp',
|
||||||
|
|
35
src/SvgUtil.cpp
Normal file
35
src/SvgUtil.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include "SvgUtil.hpp"
|
||||||
|
#include "librsvg/rsvg.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "cairomm/context.h"
|
||||||
|
|
||||||
|
namespace Raven {
|
||||||
|
|
||||||
|
Cairo::RefPtr<Cairo::ImageSurface> render_svg(std::string path, double x, double y, double width, double height) {
|
||||||
|
auto file = g_file_new_for_path(path.c_str());
|
||||||
|
auto handle = rsvg_handle_new_from_gfile_sync(file, RSVG_HANDLE_FLAGS_NONE, NULL, NULL);
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
std::cerr << "could not load svg file: " << path << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
RsvgRectangle viewport = {
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
};
|
||||||
|
|
||||||
|
auto surface = Cairo::ImageSurface::create(Cairo::Format::FORMAT_ARGB32, width, height);
|
||||||
|
auto context = Cairo::Context::create(surface);
|
||||||
|
|
||||||
|
rsvg_handle_render_document(handle, context->cobj(), &viewport, NULL);
|
||||||
|
|
||||||
|
g_object_unref(file);
|
||||||
|
g_object_unref(handle);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
10
src/SvgUtil.hpp
Normal file
10
src/SvgUtil.hpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cairomm/refptr.h"
|
||||||
|
#include "cairomm/surface.h"
|
||||||
|
|
||||||
|
namespace Raven {
|
||||||
|
|
||||||
|
Cairo::RefPtr<Cairo::ImageSurface> render_svg(std::string path, double x, double y, double width, double height);
|
||||||
|
|
||||||
|
}
|
|
@ -6,11 +6,16 @@
|
||||||
namespace Raven {
|
namespace Raven {
|
||||||
|
|
||||||
void SvgWidget::on_init() {
|
void SvgWidget::on_init() {
|
||||||
|
set_style(&clear_widget_style);
|
||||||
|
|
||||||
|
if (m_user_defined_surface) {
|
||||||
|
set_did_init(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_file = g_file_new_for_path(m_path.c_str());
|
m_file = g_file_new_for_path(m_path.c_str());
|
||||||
m_handle = rsvg_handle_new_from_gfile_sync(m_file, RSVG_HANDLE_FLAGS_NONE, NULL, NULL);
|
m_handle = rsvg_handle_new_from_gfile_sync(m_file, RSVG_HANDLE_FLAGS_NONE, NULL, NULL);
|
||||||
|
|
||||||
set_style(&clear_widget_style);
|
|
||||||
|
|
||||||
if (!m_handle) {
|
if (!m_handle) {
|
||||||
std::cerr << "could not load svg file: " << m_path << std::endl;
|
std::cerr << "could not load svg file: " << m_path << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -20,6 +25,10 @@ void SvgWidget::on_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgWidget::on_after_layout() {
|
void SvgWidget::on_after_layout() {
|
||||||
|
if (m_user_defined_surface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto width = rect().width();
|
auto width = rect().width();
|
||||||
auto height = rect().height();
|
auto height = rect().height();
|
||||||
|
|
||||||
|
@ -52,7 +61,9 @@ void SvgWidget::on_paint() {
|
||||||
}
|
}
|
||||||
|
|
||||||
SvgWidget::~SvgWidget() {
|
SvgWidget::~SvgWidget() {
|
||||||
|
if (m_file)
|
||||||
g_object_unref(m_file);
|
g_object_unref(m_file);
|
||||||
|
if (m_handle)
|
||||||
g_object_unref(m_handle);
|
g_object_unref(m_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,11 @@ public:
|
||||||
: Raven::Widget()
|
: Raven::Widget()
|
||||||
, m_path(path) {}
|
, m_path(path) {}
|
||||||
|
|
||||||
|
SvgWidget(Cairo::RefPtr<Cairo::ImageSurface> image_surface)
|
||||||
|
: Raven::Widget()
|
||||||
|
, m_image_surface(image_surface)
|
||||||
|
, m_user_defined_surface(true) {}
|
||||||
|
|
||||||
~SvgWidget();
|
~SvgWidget();
|
||||||
|
|
||||||
std::string &path() { return m_path; }
|
std::string &path() { return m_path; }
|
||||||
|
@ -26,12 +31,13 @@ protected:
|
||||||
void on_paint();
|
void on_paint();
|
||||||
private:
|
private:
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
RsvgHandle *m_handle;
|
RsvgHandle *m_handle { nullptr };
|
||||||
GFile *m_file;
|
GFile *m_file { nullptr };
|
||||||
Cairo::RefPtr<Cairo::Context> m_image_context;
|
Cairo::RefPtr<Cairo::Context> m_image_context { nullptr };
|
||||||
Cairo::RefPtr<Cairo::ImageSurface> m_image_surface;
|
Cairo::RefPtr<Cairo::ImageSurface> m_image_surface { nullptr };
|
||||||
double m_known_width { 0.0 };
|
double m_known_width { 0.0 };
|
||||||
double m_known_height { 0.0 };
|
double m_known_height { 0.0 };
|
||||||
|
bool m_user_defined_surface { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,7 @@ void Widget::remove_child(std::shared_ptr<Widget> child) {
|
||||||
|
|
||||||
void Widget::clear_children() {
|
void Widget::clear_children() {
|
||||||
m_children.clear();
|
m_children.clear();
|
||||||
|
m_children.shrink_to_fit();
|
||||||
reflow();
|
reflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
src/main.cpp
18
src/main.cpp
|
@ -29,24 +29,22 @@ int main() {
|
||||||
top_bar->set_layout<Raven::BoxLayout>(Raven::Direction::Horizontal);
|
top_bar->set_layout<Raven::BoxLayout>(Raven::Direction::Horizontal);
|
||||||
|
|
||||||
auto container_widget = main_widget->add<Raven::Widget>();
|
auto container_widget = main_widget->add<Raven::Widget>();
|
||||||
auto container_layout = container_widget->set_layout<Raven::BoxLayout>(Raven::Direction::Vertical);
|
container_widget->set_layout<Raven::DocumentLayout>();
|
||||||
container_layout->set_spacing(5);
|
|
||||||
container_layout->set_margin(18);
|
|
||||||
container_widget->resize(400, 400);
|
|
||||||
|
|
||||||
auto new_button = top_bar->add<Raven::Button>("add");
|
auto new_button = top_bar->add<Raven::Button>("add");
|
||||||
new_button->rect().set_max_width(50);
|
new_button->rect().set_max_width(50);
|
||||||
new_button->on_click = [container_widget]() {
|
new_button->on_click = [&window, container_widget]() {
|
||||||
|
window.queue_microtask([container_widget]() {
|
||||||
|
for (int i = 0; i < 5000; i++) {
|
||||||
container_widget->add<Raven::Button>("hello");
|
container_widget->add<Raven::Button>("hello");
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
auto remove_button = top_bar->add<Raven::Button>("remove");
|
auto remove_button = top_bar->add<Raven::Button>("remove");
|
||||||
remove_button->on_click = [container_widget]() {
|
remove_button->on_click = [container_widget]() {
|
||||||
if (container_widget->children().size() > 0) {
|
container_widget->clear_children();
|
||||||
container_widget->remove_child(container_widget->children()[0]);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
auto dummy_button = top_bar->add<Raven::Button>("dummy");
|
|
||||||
dummy_button->rect().set_max_width(60);
|
|
||||||
|
|
||||||
window.run(true);
|
window.run(true);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue