From 2b1706a41a1e72cdbc4af537a64727627444bb23 Mon Sep 17 00:00:00 2001 From: hippoz <10706925-hippoz@users.noreply.gitlab.com> Date: Wed, 27 Jul 2022 03:19:20 +0300 Subject: [PATCH] svgwidget: greatly improve performance by caching render result --- src/SvgWidget.cpp | 35 +++++++++++++++++++++++++++++------ src/SvgWidget.hpp | 9 +++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/SvgWidget.cpp b/src/SvgWidget.cpp index 0c3fe6f..2880470 100644 --- a/src/SvgWidget.cpp +++ b/src/SvgWidget.cpp @@ -1,4 +1,7 @@ #include "SvgWidget.hpp" +#include "cairomm/context.h" +#include "cairomm/enums.h" +#include "cairomm/surface.h" void SvgWidget::on_init() { 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); - if (!m_handle) - { + if (!m_handle) { std::cerr << "could not load svg file: " << m_path << std::endl; exit(EXIT_FAILURE); } @@ -15,15 +17,36 @@ void SvgWidget::on_init() { 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 = { .x = 0.0, .y = 0.0, - .width = rect().width(), - .height = rect().height(), + .width = width, + .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() { diff --git a/src/SvgWidget.hpp b/src/SvgWidget.hpp index 7eafbae..24a00e2 100644 --- a/src/SvgWidget.hpp +++ b/src/SvgWidget.hpp @@ -1,6 +1,10 @@ #pragma once #include +#include "cairomm/context.h" +#include "cairomm/enums.h" +#include "cairomm/refptr.h" +#include "cairomm/surface.h" #include "raven/Widget.hpp" #include "librsvg/rsvg.h" @@ -17,9 +21,14 @@ public: void set_path(std::string path) { m_path = path; repaint(); } protected: void on_init(); + void on_after_layout(); void on_paint(); private: std::string m_path; RsvgHandle *m_handle; GFile *m_file; + Cairo::RefPtr m_image_context; + Cairo::RefPtr m_image_surface; + double m_known_width { 0.0 }; + double m_known_height { 0.0 }; };