/
qgssvgcache.h
344 lines (299 loc) · 16.5 KB
/
qgssvgcache.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
/***************************************************************************
qgssvgcache.h
------------------------------
begin : 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSSVGCACHE_H
#define QGSSVGCACHE_H
#include "qgsabstractcontentcache.h"
#include "qgis.h"
#include <QPicture>
class QDomElement;
#ifndef SIP_RUN
///@cond PRIVATE
/**
* \ingroup core
* \class QgsSvgCacheEntry
*/
class CORE_EXPORT QgsSvgCacheEntry : public QgsAbstractContentCacheEntry
{
public:
/**
* Constructor.
* \param path Absolute path to SVG file (relative paths are not resolved).
* \param size
* \param strokeWidth width of stroke
* \param widthScaleFactor width scale factor
* \param fill color of fill
* \param stroke color of stroke
* \param fixedAspectRatio fixed aspect ratio (optional)
* \param parameters an optional map of parameters to dynamically replace content in the SVG
*/
QgsSvgCacheEntry( const QString &path, double size, double strokeWidth, double widthScaleFactor, const QColor &fill, const QColor &stroke,
double fixedAspectRatio = 0, const QMap<QString, QString> ¶meters = QMap<QString, QString>() ) ;
//! QgsSvgCacheEntry cannot be copied.
QgsSvgCacheEntry( const QgsSvgCacheEntry &rh ) = delete;
//! QgsSvgCacheEntry cannot be copied.
QgsSvgCacheEntry &operator=( const QgsSvgCacheEntry &rh ) = delete;
double size = 0.0; //size in pixels (cast to int for QImage)
double strokeWidth = 0;
double widthScaleFactor = 1.0;
//! Fixed aspect ratio
double fixedAspectRatio = 0;
/**
* SVG viewbox size.
* \since QGIS 2.14
*/
QSizeF viewboxSize;
QColor fill = Qt::black;
QColor stroke = Qt::black;
QMap<QString, QString> parameters;
std::unique_ptr< QImage > image;
std::unique_ptr< QPicture > picture;
//content (with params replaced)
QByteArray svgContent;
/**
* TRUE if the image represents a broken/missing path.
*
* \since QGIS 3.14
*/
bool isMissingImage = false;
bool isEqual( const QgsAbstractContentCacheEntry *other ) const override;
int dataSize() const override;
void dump() const override;
};
///@endcond
#endif
/**
* \ingroup core
* A cache for images / pictures derived from SVG files
*
* This class supports parameter replacement in SVG files according to the SVG params specification
* (http://www.w3.org/TR/2009/WD-SVGParamPrimer-20090616/).
*
* Supported parameters are:
*
* - \a param(fill): fill color (with no opacity value)
* - \a param(fill-opacity): fill color opacity
* - \a param(outline): outline color (with no opacity value)
* - \a param(outline-opacity): outline color opacity
* - \a param(outline-width): width of outline strokes
*
* E.g:
*
* <circle fill="param(fill-color red)" stroke="param(pen-color black)" stroke-width="param(outline-width 1)"
*
* \note QgsSvgCache is not usually directly created, but rather accessed through QgsApplication::svgCache().
*/
#ifdef SIP_RUN
class CORE_EXPORT QgsSvgCache : public QgsAbstractContentCacheBase // for sip we skip to the base class and avoid the template difficulty
{
#else
class CORE_EXPORT QgsSvgCache : public QgsAbstractContentCache< QgsSvgCacheEntry >
{
#endif
Q_OBJECT
public:
/**
* Constructor for QgsSvgCache.
*/
QgsSvgCache( QObject *parent SIP_TRANSFERTHIS = nullptr );
/**
* Returns an SVG drawing as a QImage.
*
* \param path Absolute path to SVG file.
* \param size size of cached image
* \param fill color of fill
* \param stroke color of stroke
* \param strokeWidth width of stroke
* \param widthScaleFactor width scale factor
* \param fitsInCache
* \param fixedAspectRatio fixed aspect ratio (optional)
* \param blocking forces to wait for loading before returning image (optional).
*
* \warning The \a blocking parameter must NEVER be TRUE from GUI based applications (like the main QGIS
* application) or crashes will result. Only for use in external scripts or QGIS server.
* \param parameters is a map of parameters to dynamically replace content in SVG.
*/
QImage svgAsImage( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio = 0, bool blocking = false,
const QMap<QString, QString> ¶meters = QMap<QString, QString>() );
/**
* Returns an SVG drawing as a QPicture.
*
* \param path Absolute path to SVG file.
* \param size size of cached image
* \param fill color of fill
* \param stroke color of stroke
* \param strokeWidth width of stroke
* \param widthScaleFactor width scale factor
* \param forceVectorOutput
* \param fixedAspectRatio fixed aspect ratio (optional)
* \param blocking forces to wait for loading before returning image (optional)
*
* \note The returned QPicture contains the SVG file centered over the picture origin. I.e. if it is rendered
* using QPainter::drawPicture( QPointF( 5, 10 ), picture ) it will be drawn centered over the point (5, 10).
* Appropriate translation to the destination painter based on the picture's boundingRect may need to be applied
* if rendering the SVG using the top-left or other reference point is desired.
*
* \warning The \a blocking parameter must NEVER be TRUE from GUI based applications (like the main QGIS
* application) or crashes will result. Only for use in external scripts or QGIS server.
* \param parameters is a map of parameters to dynamically replace content in SVG.
*/
QPicture svgAsPicture( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
double widthScaleFactor, bool forceVectorOutput = false, double fixedAspectRatio = 0, bool blocking = false,
const QMap<QString, QString> ¶meters = QMap<QString, QString>() );
/**
* Calculates the viewbox size of a (possibly cached) SVG file.
* \param path Absolute path to SVG file.
* \param size size of cached image
* \param fill color of fill
* \param stroke color of stroke
* \param strokeWidth width of stroke
* \param widthScaleFactor width scale factor
* \param fixedAspectRatio fixed aspect ratio (optional)
* \param blocking forces to wait for loading before returning image (optional).
* \returns viewbox size set in SVG file
*
* \warning The blocking parameter must NEVER be TRUE from GUI based applications (like the main QGIS
* application) or crashes will result. Only for use in external scripts or QGIS server.
* \param parameters is a map of parameters to dynamically replace content in SVG.
*
* \since QGIS 2.14
*/
QSizeF svgViewboxSize( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
double widthScaleFactor, double fixedAspectRatio = 0, bool blocking = false, const QMap<QString, QString> ¶meters = QMap<QString, QString>() );
/**
* Tests if an SVG file contains parameters for fill, stroke color, stroke width. If yes, possible default values are returned. If there are several
* default values in the SVG file, only the first one is considered. Blocking forces to wait for loading before returning image (optional). WARNING: the
* blocking parameter must NEVER be TRUE from GUI based applications (like the main QGIS application) or crashes will result. Only for use in external
* scripts or QGIS server.
*/
void containsParams( const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam,
double &defaultStrokeWidth, bool blocking = false ) const;
/**
* Tests if an SVG file contains parameters for fill, stroke color, stroke width. If yes, possible default values are returned. If there are several
* default values in the SVG file, only the first one is considered.
* \param path path to SVG file
* \param hasFillParam will be TRUE if fill param present in SVG
* \param hasDefaultFillParam will be TRUE if fill param has a default value specified
* \param defaultFillColor will be set to default fill color specified in SVG, if present
* \param hasFillOpacityParam will be TRUE if fill opacity param present in SVG
* \param hasDefaultFillOpacity will be TRUE if fill opacity param has a default value specified
* \param defaultFillOpacity will be set to default fill opacity specified in SVG, if present
* \param hasStrokeParam will be TRUE if stroke param present in SVG
* \param hasDefaultStrokeColor will be TRUE if stroke param has a default value specified
* \param defaultStrokeColor will be set to default stroke color specified in SVG, if present
* \param hasStrokeWidthParam will be TRUE if stroke width param present in SVG
* \param hasDefaultStrokeWidth will be TRUE if stroke width param has a default value specified
* \param defaultStrokeWidth will be set to default stroke width specified in SVG, if present
* \param hasStrokeOpacityParam will be TRUE if stroke opacity param present in SVG
* \param hasDefaultStrokeOpacity will be TRUE if stroke opacity param has a default value specified
* \param defaultStrokeOpacity will be set to default stroke opacity specified in SVG, if present
* \param blocking forces to wait for loading before returning image (optional).
*
* \note Available in Python bindings as containsParamsV3
*
* \warning The \a blocking parameter must NEVER be TRUE from GUI based applications (like the main QGIS
* application) or crashes will result. Only for use in external scripts or QGIS server.
*
* \since QGIS 2.14
*/
void containsParams( const QString &path, bool &hasFillParam, bool &hasDefaultFillParam, QColor &defaultFillColor,
bool &hasFillOpacityParam, bool &hasDefaultFillOpacity, double &defaultFillOpacity,
bool &hasStrokeParam, bool &hasDefaultStrokeColor, QColor &defaultStrokeColor,
bool &hasStrokeWidthParam, bool &hasDefaultStrokeWidth, double &defaultStrokeWidth,
bool &hasStrokeOpacityParam, bool &hasDefaultStrokeOpacity, double &defaultStrokeOpacity,
bool blocking = false ) const SIP_PYNAME( containsParamsV3 );
/**
* Gets the SVG content corresponding to the given \a path.
*
* \a path may be a local file, remote (HTTP) url, or a base 64 encoded string (with a "base64:" prefix).
*
* The class default missingContent byte array is returned if the \a path could not be resolved or is broken. If
* the \a path corresponds to a remote URL, then class default fetchingContent will be returned while the content
* is in the process of being fetched.
* The \a blocking boolean forces to wait for loading before returning result. The content is loaded
* in the same thread to ensure provided the remote content.
*
* \warning The \a blocking parameter must NEVER be TRUE from GUI based applications (like the main QGIS application)
* or crashes will result. Only for use in external scripts or QGIS server.
*/
QByteArray getImageData( const QString &path, bool blocking = false ) const;
/**
* Gets the SVG content corresponding to the given \a path.
*
* \a path may be a local file, remote (HTTP) url, or a base 64 encoded string (with a "base64:" prefix).
*
* The parameters \a size, \a strokeWidth for width of stroke, \a widthScaleFactor for width scale factor,
* \a fill for color of fill, \a stroke for color of stroke and \a fixedAspectRatio for fixed aspect ratio (optional)
* are needed to get the entry from cache or creates a new entry if it does not exist already.
*
* The \a blocking boolean forces to wait for loading before returning image. The content is loaded
* in the same thread to ensure provided the image.
*
* \warning The \a blocking parameter must NEVER be TRUE from GUI based applications (like the main QGIS application)
* or crashes will result. Only for use in external scripts or QGIS server.
*/
#ifndef SIP_RUN
QByteArray svgContent( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
double widthScaleFactor, double fixedAspectRatio = 0, bool blocking = false, const QMap<QString, QString> ¶meters = QMap<QString, QString>(), bool *isMissingImage = nullptr );
#else
QByteArray svgContent( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
double widthScaleFactor, double fixedAspectRatio = 0, bool blocking = false, const QMap<QString, QString> ¶meters = QMap<QString, QString>() );
#endif
signals:
/**
* Emit a signal to be caught by qgisapp and display a msg on status bar.
* \deprecated Deprecated since QGIS 3.6 -- no longer emitted.
*/
Q_DECL_DEPRECATED void statusChanged( const QString &statusQString ) SIP_DEPRECATED;
/**
* Emitted when the cache has finished retrieving an SVG file from a remote \a url.
* \since QGIS 3.2
*/
void remoteSvgFetched( const QString &url );
protected:
bool checkReply( QNetworkReply *reply, const QString &path ) const override;
private:
void replaceParamsAndCacheSvg( QgsSvgCacheEntry *entry, bool blocking = false );
void cacheImage( QgsSvgCacheEntry *entry );
void cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput = false );
//! Returns entry from cache or creates a new entry if it does not exist already
QgsSvgCacheEntry *cacheEntry( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
double widthScaleFactor, double fixedAspectRatio = 0, const QMap<QString, QString> ¶meters = QMap<QString, QString>(), bool blocking = false, bool *isMissingImage = nullptr );
//! Replaces parameters in elements of a dom node and calls method for all child nodes
void replaceElemParams( QDomElement &elem, const QColor &fill, const QColor &stroke, double strokeWidth, const QMap<QString, QString> ¶meters );
void containsElemParams( const QDomElement &elem,
bool &hasFillParam, bool &hasDefaultFill, QColor &defaultFill,
bool &hasFillOpacityParam, bool &hasDefaultFillOpacity, double &defaultFillOpacity,
bool &hasStrokeParam, bool &hasDefaultStroke, QColor &defaultStroke,
bool &hasStrokeWidthParam, bool &hasDefaultStrokeWidth, double &defaultStrokeWidth,
bool &hasStrokeOpacityParam, bool &hasDefaultStrokeOpacity, double &defaultStrokeOpacity ) const SIP_PYNAME( containsParamsV3 );
//! Calculates scaling for rendered image sizes to SVG logical sizes
double calcSizeScaleFactor( QgsSvgCacheEntry *entry, const QDomElement &docElem, QSizeF &viewboxSize ) const;
/**
* Returns the target size (in pixels) and calculates the \a viewBoxSize
* for a cache \a entry.
*/
QSize sizeForImage( const QgsSvgCacheEntry &entry, QSizeF &viewBoxSize, QSizeF &scaledSize ) const;
/**
* Returns a rendered image for a cached picture \a entry.
*/
QImage imageFromCachedPicture( const QgsSvgCacheEntry &entry ) const;
//! SVG content to be rendered if SVG file was not found.
QByteArray mMissingSvg;
QByteArray mFetchingSvg;
friend class TestQgsSvgCache;
};
#endif // QGSSVGCACHE_H