svgwidget: greatly improve performance by caching render result

This commit is contained in:
hippoz 2022-07-27 03:19:20 +03:00
parent bbec75f451
commit 2b1706a41a
No known key found for this signature in database
GPG key ID: 7C52899193467641
2 changed files with 38 additions and 6 deletions

View file

@ -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() {

View file

@ -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 };
}; };