svgwidget: greatly improve performance by caching render result
This commit is contained in:
parent
bbec75f451
commit
2b1706a41a
2 changed files with 38 additions and 6 deletions
|
@ -1,4 +1,7 @@
|
||||||
#include "SvgWidget.hpp"
|
#include "SvgWidget.hpp"
|
||||||
|
#include "cairomm/context.h"
|
||||||
|
#include "cairomm/enums.h"
|
||||||
|
#include "cairomm/surface.h"
|
||||||
|
|
||||||
void SvgWidget::on_init() {
|
void SvgWidget::on_init() {
|
||||||
m_file = g_file_new_for_path(m_path.c_str());
|
m_file = g_file_new_for_path(m_path.c_str());
|
||||||
|
@ -6,8 +9,7 @@ void SvgWidget::on_init() {
|
||||||
|
|
||||||
set_style(&Raven::clear_widget_style);
|
set_style(&Raven::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);
|
||||||
}
|
}
|
||||||
|
@ -15,15 +17,36 @@ void SvgWidget::on_init() {
|
||||||
set_did_init(true);
|
set_did_init(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgWidget::on_paint() {
|
void SvgWidget::on_after_layout() {
|
||||||
|
auto width = rect().width();
|
||||||
|
auto height = rect().height();
|
||||||
|
|
||||||
|
if (width == m_known_width && height == m_known_height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_known_width = width;
|
||||||
|
m_known_height = height;
|
||||||
|
|
||||||
RsvgRectangle viewport = {
|
RsvgRectangle viewport = {
|
||||||
.x = 0.0,
|
.x = 0.0,
|
||||||
.y = 0.0,
|
.y = 0.0,
|
||||||
.width = rect().width(),
|
.width = width,
|
||||||
.height = rect().height(),
|
.height = height,
|
||||||
};
|
};
|
||||||
|
|
||||||
rsvg_handle_render_document(m_handle, painter()->cairo()->cobj(), &viewport, NULL);
|
m_image_surface = Cairo::ImageSurface::create(Cairo::Format::FORMAT_ARGB32, width, height);
|
||||||
|
m_image_context = Cairo::Context::create(m_image_surface);
|
||||||
|
|
||||||
|
rsvg_handle_render_document(m_handle, m_image_context->cobj(), &viewport, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgWidget::on_paint() {
|
||||||
|
if (!m_image_surface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
painter()->cairo()->set_source(m_image_surface, 0, 0);
|
||||||
|
painter()->cairo()->paint();
|
||||||
}
|
}
|
||||||
|
|
||||||
SvgWidget::~SvgWidget() {
|
SvgWidget::~SvgWidget() {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "cairomm/context.h"
|
||||||
|
#include "cairomm/enums.h"
|
||||||
|
#include "cairomm/refptr.h"
|
||||||
|
#include "cairomm/surface.h"
|
||||||
#include "raven/Widget.hpp"
|
#include "raven/Widget.hpp"
|
||||||
#include "librsvg/rsvg.h"
|
#include "librsvg/rsvg.h"
|
||||||
|
|
||||||
|
@ -17,9 +21,14 @@ public:
|
||||||
void set_path(std::string path) { m_path = path; repaint(); }
|
void set_path(std::string path) { m_path = path; repaint(); }
|
||||||
protected:
|
protected:
|
||||||
void on_init();
|
void on_init();
|
||||||
|
void on_after_layout();
|
||||||
void on_paint();
|
void on_paint();
|
||||||
private:
|
private:
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
RsvgHandle *m_handle;
|
RsvgHandle *m_handle;
|
||||||
GFile *m_file;
|
GFile *m_file;
|
||||||
|
Cairo::RefPtr<Cairo::Context> m_image_context;
|
||||||
|
Cairo::RefPtr<Cairo::ImageSurface> m_image_surface;
|
||||||
|
double m_known_width { 0.0 };
|
||||||
|
double m_known_height { 0.0 };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue