Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
svg_preview_cache.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
5/*
6 * Authors:
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * Bryce Harrington <brycehar@bryceharrington.org>
9 * bulia byak <buliabyak@users.sf.net>
10 *
11 * Copyright (C) 2001-2005 authors
12 * Copyright (C) 2001 Ximian, Inc.
13 * Copyright (C) 2004 John Cliff
14 *
15 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
16 *
17 */
18
19#include <2geom/transforms.h>
20
21#include "display/cairo-utils.h"
24#include "display/drawing.h"
25
26
28
29cairo_surface_t* render_surface(Inkscape::Drawing &drawing, double scale_factor, Geom::Rect const &dbox,
30 Geom::IntPoint pixsize, double device_scale, const guint32* checkerboard_color, bool no_clip)
31{
32 scale_factor *= device_scale;
33 pixsize.x() *= device_scale;
34 pixsize.y() *= device_scale;
35
36 Geom::IntRect ibox = (dbox * Geom::Scale(scale_factor)).roundOutwards();
37
38 if (no_clip) {
39 // check if object fits in the surface
40 if (ibox.width() > pixsize.x() || ibox.height() > pixsize.y()) {
41 auto sx = static_cast<double>(ibox.width()) / pixsize.x();
42 auto sy = static_cast<double>(ibox.height()) / pixsize.y();
43 // reduce scale
44 scale_factor /= std::max(sx, sy);
45 ibox = (dbox * Geom::Scale(scale_factor)).roundOutwards();
46 }
47 }
48
49 drawing.root()->setTransform(Geom::Scale(scale_factor));
50
51 drawing.update(ibox);
52
53 /* Find visible area */
54 int width = ibox.width();
55 int height = ibox.height();
56 int dx = pixsize.x();
57 int dy = pixsize.y();
58 dx = (dx - width)/2; // watch out for size, since 'unsigned'-'signed' can cause problems if the result is negative
59 dy = (dy - height)/2;
60
61 Geom::IntRect area = Geom::IntRect::from_xywh(ibox.min() - Geom::IntPoint(dx, dy), pixsize);
62
63 /* Render */
64 cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, pixsize.x(), pixsize.y());
65 Inkscape::DrawingContext dc(s, area.min());
66
67 if (checkerboard_color) {
68 guint rgba = *checkerboard_color;
69 auto pattern = ink_cairo_pattern_create_checkerboard(rgba);
70 dc.save();
71 dc.transform(Geom::Scale(device_scale));
72 dc.setOperator(CAIRO_OPERATOR_SOURCE);
73 dc.setSource(pattern);
74 dc.paint();
75 dc.restore();
76 cairo_pattern_destroy(pattern);
77 }
78
80 cairo_surface_flush(s);
81
82 return s;
83}
84
85GdkPixbuf* render_pixbuf(Inkscape::Drawing &drawing, double scale_factor, Geom::Rect const &dbox, unsigned psize) {
86 auto s = render_surface(drawing, scale_factor, dbox, Geom::IntPoint(psize, psize), 1, nullptr, true);
88 return pixbuf;
89}
90
91namespace Inkscape {
92namespace UI {
93namespace Cache {
94
96= default;
97
99{
100 for (auto & i : _pixmap_cache)
101 {
102 g_object_unref(i.second);
103 i.second = NULL;
104 }
105}
106
107Glib::ustring SvgPreview::cache_key(gchar const *uri, gchar const *name, unsigned psize) const {
108 Glib::ustring key;
109 key += (uri!=nullptr) ? uri : "";
110 key += ":";
111 key += (name!=nullptr) ? name : "unknown";
112 key += ":";
113 key += psize;
114 return key;
115}
116
118 std::map<Glib::ustring, GdkPixbuf *>::iterator found = _pixmap_cache.find(key);
119 if ( found != _pixmap_cache.end() ) {
120 return found->second;
121 }
122 return nullptr;
123}
124
125void SvgPreview::set_preview_in_cache(const Glib::ustring& key, GdkPixbuf* px) {
126 g_object_ref(px);
127 _pixmap_cache[key] = px;
128}
129
130GdkPixbuf* SvgPreview::get_preview(const gchar* uri, const gchar* id, Inkscape::DrawingItem */*root*/,
131 double /*scale_factor*/, unsigned int psize) {
132 // First try looking up the cached preview in the cache map
133 Glib::ustring key = cache_key(uri, id, psize);
135
136 if (px == nullptr) {
137 /*
138 px = render_pixbuf(root, scale_factor, dbox, psize);
139 set_preview_in_cache(key, px);
140 */
141 }
142 return px;
143}
144
145void SvgPreview::remove_preview_from_cache(const Glib::ustring& key) {
146 std::map<Glib::ustring, GdkPixbuf *>::iterator found = _pixmap_cache.find(key);
147 if ( found != _pixmap_cache.end() ) {
148 g_object_unref(found->second);
149 found->second = NULL;
150 _pixmap_cache.erase(key);
151 }
152}
153
154
155}
156}
157}
158
159/*
160 Local Variables:
161 mode:c++
162 c-file-style:"stroustrup"
163 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
164 indent-tabs-mode:nil
165 fill-column:99
166 End:
167*/
168// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
cairo_pattern_t * ink_cairo_pattern_create_checkerboard(guint32 rgba, bool use_alpha)
GdkPixbuf * ink_pixbuf_create_from_cairo_surface(cairo_surface_t *s)
Converts the Cairo surface to a GdkPixbuf pixel format, without allocating extra memory.
Cairo integration helpers.
struct _GdkPixbuf GdkPixbuf
Definition cairo-utils.h:20
Axis aligned, non-empty, generic rectangle.
static CRect from_xywh(C x, C y, C w, C h)
Create rectangle from origin and dimensions.
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
Two-dimensional point with integer coordinates.
Definition int-point.h:57
constexpr IntCoord x() const noexcept
Definition int-point.h:77
constexpr IntCoord y() const noexcept
Definition int-point.h:79
Axis aligned, non-empty rectangle.
Definition rect.h:92
Scaling from the origin.
Definition transforms.h:150
Minimal wrapper over Cairo.
void setSource(cairo_pattern_t *source)
void transform(Geom::Affine const &trans)
void paint(double alpha=1.0)
void setOperator(cairo_operator_t op)
SVG drawing item for display.
void setTransform(Geom::Affine const &trans)
DrawingItem * root()
Definition drawing.h:47
void update(Geom::IntRect const &area=Geom::IntRect::infinite(), Geom::Affine const &affine=Geom::identity(), unsigned flags=DrawingItem::STATE_ALL, unsigned reset=0)
Definition drawing.cpp:231
void render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags=0) const
Definition drawing.cpp:242
std::map< Glib::ustring, GdkPixbuf * > _pixmap_cache
Glib::ustring cache_key(gchar const *uri, gchar const *name, unsigned psize) const
void remove_preview_from_cache(const Glib::ustring &key)
GdkPixbuf * get_preview_from_cache(const Glib::ustring &key)
GdkPixbuf * get_preview(const gchar *uri, const gchar *id, Inkscape::DrawingItem *root, double scale_factor, unsigned int psize)
void set_preview_in_cache(const Glib::ustring &key, GdkPixbuf *px)
Cairo drawing context with Inkscape extensions.
unsigned int guint32
Canvas item belonging to an SVG drawing element.
struct _cairo_surface cairo_surface_t
SVG drawing for display.
Helper class to stream background task notifications as a series of messages.
static cairo_user_data_key_t key
GdkPixbuf * render_pixbuf(Inkscape::Drawing &drawing, double scale_factor, Geom::Rect const &dbox, unsigned psize)
cairo_surface_t * render_surface(Inkscape::Drawing &drawing, double scale_factor, Geom::Rect const &dbox, Geom::IntPoint pixsize, double device_scale, const guint32 *checkerboard_color, bool no_clip)
Preview cache.
double height
double width
Glib::ustring name
Definition toolbars.cpp:55
Affine transformation classes.