Inkscape
Vector Graphics Editor
export-preview.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* Authors:
3 * Anshudhar Kumar Singh <anshudhar2001@gmail.com>
4 *
5 * Copyright (C) 2021 Authors
6 *
7 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
8 */
9
10#include "export-preview.h"
11
12#include <utility>
13#include <glibmm/convert.h>
14#include <glibmm/main.h>
15#include <gdkmm/pixbuf.h>
16
17#include "document.h"
18#include "display/cairo-utils.h"
19#include "object/sp-item.h"
20#include "object/sp-root.h"
21#include "util/preview.h"
22#include "io/resource.h"
23
24namespace Inkscape::UI::Dialog {
25
33 : _document{doc}
34{
35}
36
38{
39 destruct();
40}
41
43{
44 if (!_visionkey)
45 return;
46
47 // On exiting the document root might have gone already.
48 if (auto root = _document->getRoot()) {
49 root->invoke_hide(_visionkey);
50 }
51 _drawing.reset();
52 _visionkey = 0;
53}
54
59{
60 auto drawing = std::make_shared<Inkscape::Drawing>();
62 if (auto di = _document->getRoot()->invoke_show(*drawing, _visionkey, SP_ITEM_SHOW_DISPLAY)) {
63 drawing->setRoot(di);
64 } else {
65 drawing.reset();
66 }
67
68 if (!_shown_items.empty()) {
70 }
71
72 _drawing = std::move(drawing);
73}
74
78bool PreviewDrawing::render(ExportPreview *widget, uint32_t bg, SPItem const *item, unsigned size, Geom::OptRect const &dbox)
79{
80 if (!_drawing || _to_destruct) {
82 _construct_idle = Glib::signal_timeout().connect([this]() {
83 _to_destruct = false;
84 destruct();
85 construct();
86 return false;
87 }, 100);
88 }
89 return false;
90 }
91
92 Geom::OptRect bbox = dbox;
93 DrawingItem *di = nullptr;
94
95 if (item) {
96 bbox = item->documentVisualBounds();
98 } else if (!dbox)
100
101 if (!bbox)
102 return true; // Force quit
103
104 // Use a callback to set the preview rendering;
106 return true;
107}
108
114void PreviewDrawing::set_shown_items(std::vector<SPItem const *> &&list)
115{
116 _shown_items = std::move(list);
117 _to_destruct = true;
118}
119
120void ExportPreview::resetPixels(bool new_size)
121{
122 // An icon to use when the preview hasn't loaded yet
123 static Glib::RefPtr<Gdk::Pixbuf> preview_loading;
124 if (!preview_loading || new_size) {
125 using namespace Inkscape::IO::Resource;
126 auto path_utf8 = (Glib::ustring)Inkscape::IO::Resource::get_path(SYSTEM, UIS, "resources", "preview-loading.svg");
127 auto path = Glib::filename_from_utf8(path_utf8);
128 preview_loading = Gdk::Pixbuf::create_from_file(path, size, size);
129 }
130 if (preview_loading) {
131 set_pixbuf(preview_loading);
132 }
133 set_visible(true);
134}
135
136void ExportPreview::setSize(int newSize)
137{
138 size = newSize;
139 resetPixels(true);
140}
141
143{
144 refresh_conn.disconnect();
145}
146
148{
149 _item = item;
150 _dbox = {};
151}
152
154{
155 if (bbox.hasZeroArea())
156 return;
157
158 _item = nullptr;
159 _dbox = bbox;
160}
161
162void ExportPreview::setDrawing(std::shared_ptr<PreviewDrawing> drawing)
163{
164 _drawing = std::move(drawing);
165}
166
167/*
168 * This is the main function which finally renders the preview.
169 * If dbox is given it will use it.
170 * if item is given and not dbox then item is used.
171 * If both are not given then we simply do nothing.
172 */
174{
176 return;
177
178 _render_idle = Glib::signal_timeout().connect([this]() {
179 return !_drawing->render(this, _bg_color, _item, size, _dbox);
180 }, 100);
181}
182
186void ExportPreview::setPreview(Cairo::RefPtr<Cairo::ImageSurface> surface)
187{
188 if (surface) {
189 set_pixbuf(Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()));
190 set_visible(true);
191 }
192}
193
195{
196 _bg_color = bg_color;
197}
198
199} // namespace Inkscape::UI::Dialog
200
201/*
202 Local Variables:
203 mode:c++
204 c-file-style:"stroustrup"
205 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
206 indent-tabs-mode:nil
207 fill-column:99
208 End:
209*/
210// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Cairo integration helpers.
Cairo::RefPtr< Cairo::ImageSurface > surface
Definition: canvas.cpp:137
Axis-aligned rectangle that can be empty.
Definition: rect.h:180
Axis aligned, non-empty rectangle.
Definition: rect.h:92
bool hasZeroArea(Coord eps=EPSILON) const
Check whether the rectangle has zero area up to specified tolerance.
Definition: rect.h:113
SVG drawing item for display.
Definition: drawing-item.h:82
void setItem(SPItem const *item)
void resetPixels(bool new_size=false)
Inkscape::auto_connection _render_idle
void setBox(Geom::Rect const &bbox)
void setDrawing(std::shared_ptr< PreviewDrawing > drawing)
void setBackgroundColor(std::uint32_t bg_color)
std::shared_ptr< PreviewDrawing > _drawing
void setPreview(Cairo::RefPtr< Cairo::ImageSurface >)
Callback when the rendering is complete.
PreviewDrawing(SPDocument *document)
A preview drawing object is responsible for constructing a drawing and showing it's contents.
std::vector< SPItem const * > _shown_items
void construct()
Construct the drawing, when needed.
std::shared_ptr< Inkscape::Drawing > _drawing
Inkscape::auto_connection _construct_idle
bool render(ExportPreview *widget, std::uint32_t bg, SPItem const *item, unsigned size, Geom::OptRect const &dboxIn)
Render the drawing into a cairo image surface.
void set_shown_items(std::vector< SPItem const * > &&list={})
Limit the preview to just these items.
bool connected() const noexcept
Returns whether the connection is still active.
Typed SVG document implementation.
Definition: document.h:106
SPRoot * getRoot()
Returns our SPRoot.
Definition: document.h:205
Base class for visual SVG elements.
Definition: sp-item.h:107
Geom::OptRect documentVisualBounds() const
Get item's visual bbox in document coordinate system.
Definition: sp-item.cpp:941
Inkscape::DrawingItem * invoke_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags)
Definition: sp-item.cpp:1192
Inkscape::DrawingItem * get_arenaitem(unsigned key) const
Return the arenaitem corresponding to the given item in the display with the given key.
Definition: sp-item.cpp:1771
static unsigned int display_key_new(unsigned numkeys)
Allocates unique integer keys.
Definition: sp-item.cpp:1169
void invoke_hide_except(unsigned key, const std::vector< SPItem const * > &to_keep)
Invoke hide on all non-group items, except for the list of items to keep.
Definition: sp-item.cpp:1281
RootCluster root
Definition: containment.cpp:50
SPItem * item
Definition: imagemagick.cpp:43
Util::ptr_shared get_path(Domain domain, Type type, char const *filename, char const *extra)
Definition: resource.cpp:134
Dialog code.
Definition: desktop.h:118
Cairo::RefPtr< Cairo::ImageSurface > render_preview(SPDocument *doc, std::shared_ptr< Inkscape::Drawing > drawing, uint32_t bg, Inkscape::DrawingItem *item, unsigned width_in, unsigned height_in, Geom::Rect const &dboxIn)
Launch a background task to render a drawing to a surface.
Definition: preview.cpp:26
int size
Utility functions for previewing icon representation.
Inkscape::IO::Resource - simple resource API.
Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx.
SPRoot: SVG <svg> implementation.
std::unique_ptr< Toolbar >(* create)(SPDesktop *desktop)
Definition: toolbars.cpp:63