Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qsvgrenderer.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
6
#
include
"qsvgrenderer.h"
7
8
#
ifndef
QT_NO_SVGRENDERER
9
10
#
include
"qsvgdocument_p.h"
11
12
#
include
"qbytearray.h"
13
#
include
"qtimer.h"
14
#
include
"qtransform.h"
15
#
include
"qdebug.h"
16
#
include
"private/qobject_p.h"
17
18
19
QT_BEGIN_NAMESPACE
20
21
/*!
22
\class QSvgRenderer
23
\inmodule QtSvg
24
\ingroup painting
25
26
\brief The QSvgRenderer class is used to draw the contents of SVG files onto paint devices.
27
\since 4.1
28
\reentrant
29
30
Using QSvgRenderer, Scalable Vector Graphics (SVG) can be rendered onto any QPaintDevice
31
subclass, including QWidget, QImage, and QGLWidget.
32
33
QSvgRenderer provides an API that supports basic features of SVG rendering, such as loading
34
and rendering of static drawings, and more interactive features like animation. Since the
35
rendering is performed using QPainter, SVG drawings can be rendered on any subclass of
36
QPaintDevice.
37
38
SVG drawings are either loaded when an QSvgRenderer is constructed, or loaded later
39
using the load() functions. Data is either supplied directly as serialized XML, or
40
indirectly using a file name. If a valid file has been loaded, either when the renderer
41
is constructed or at some later time, isValid() returns true; otherwise it returns false.
42
QSvgRenderer provides the render() slot to render the current document, or the current
43
frame of an animated document, using a given painter.
44
45
The defaultSize() function provides information about the amount of space that is required
46
to render the currently loaded SVG file. This is useful for paint devices, such as QWidget,
47
that often need to supply a size hint to their parent layout.
48
The default size of a drawing may differ from its visible area, found using the \l viewBox
49
property.
50
51
Animated SVG drawings are supported, and can be controlled with a simple collection of
52
functions and properties:
53
54
\list
55
\li The animated() function indicates whether a drawing contains animation information.
56
\omit
57
\li The animationDuration() function provides the duration in milliseconds of the
58
animation, without taking any looping into account.
59
\li The \l currentFrame property contains the current frame of the animation.
60
\endomit
61
\li The \l framesPerSecond property contains the rate at which the animation plays.
62
\endlist
63
64
Finally, the QSvgRenderer class provides the repaintNeeded() signal which is emitted
65
whenever the rendering of the document needs to be updated.
66
67
\sa QSvgWidget, {Qt SVG C++ Classes}, QPicture
68
*/
69
70
class
QSvgRendererPrivate
:
public
QObjectPrivate
71
{
72
Q_DECLARE_PUBLIC(QSvgRenderer)
73
public
:
74
explicit
QSvgRendererPrivate
()
75
:
QObjectPrivate
()
76
{
77
options
=
defaultOptions
();
78
}
79
80
void
startOrStopTimer
()
81
{
82
if
(
animationEnabled
&&
render
&&
render
->
animated
() &&
fps
> 0) {
83
ensureTimerCreated
();
84
timer
->
start
(1000 /
fps
);
85
}
else
if
(
timer
) {
86
timer
->
stop
();
87
}
88
}
89
90
void
ensureTimerCreated
()
91
{
92
Q_Q
(
QSvgRenderer
);
93
if
(!
timer
) {
94
timer
=
new
QTimer
(
q
);
95
q
->
connect
(
timer
, &
QTimer
::
timeout
,
q
, &
QSvgRenderer
::
repaintNeeded
);
96
}
97
}
98
99
static
void
callRepaintNeeded
(
QSvgRenderer
*
const
q
);
100
101
static
QtSvg
::
Options
defaultOptions
()
102
{
103
static
bool
envOk =
false
;
104
static
QtSvg::Options envOpts = QtSvg::Options::fromInt(
105
qEnvironmentVariableIntValue(
"QT_SVG_DEFAULT_OPTIONS"
, &envOk));
106
return
envOk ? envOpts : appDefaultOptions;
107
}
108
109
std
::
unique_ptr
<
QSvgDocument
>
render
;
110
QTimer
*
timer
{
nullptr
};
111
int
fps
{30};
112
QtSvg
::
Options
options
;
113
static
QtSvg
::
Options
appDefaultOptions
;
114
bool
animationEnabled
{
true
};
115
};
116
117
QtSvg
::
Options
QSvgRendererPrivate
::
appDefaultOptions
;
118
119
/*!
120
Constructs a new renderer with the given \a parent.
121
*/
122
QSvgRenderer::QSvgRenderer(QObject *parent)
123
: QObject(*(
new
QSvgRendererPrivate), parent)
124
{
125
}
126
127
/*!
128
Constructs a new renderer with the given \a parent and loads the contents of the
129
SVG file with the specified \a filename.
130
*/
131
QSvgRenderer::QSvgRenderer(
const
QString &filename, QObject *parent)
132
: QObject(*
new
QSvgRendererPrivate, parent)
133
{
134
load(filename);
135
}
136
137
/*!
138
Constructs a new renderer with the given \a parent and loads the SVG data
139
from the byte array specified by \a contents.
140
*/
141
QSvgRenderer::QSvgRenderer(
const
QByteArray &contents, QObject *parent)
142
: QObject(*
new
QSvgRendererPrivate, parent)
143
{
144
load(contents);
145
}
146
147
/*!
148
\since 4.5
149
150
Constructs a new renderer with the given \a parent and loads the SVG data
151
using the stream reader specified by \a contents.
152
*/
153
QSvgRenderer::QSvgRenderer(QXmlStreamReader *contents, QObject *parent)
154
: QObject(*
new
QSvgRendererPrivate, parent)
155
{
156
load(contents);
157
}
158
159
/*!
160
Destroys the renderer.
161
*/
162
QSvgRenderer::~QSvgRenderer()
163
{
164
165
}
166
167
/*!
168
Returns true if there is a valid current document; otherwise returns false.
169
*/
170
bool
QSvgRenderer::isValid()
const
171
{
172
Q_D(
const
QSvgRenderer);
173
return
bool
(d->render);
174
}
175
176
/*!
177
Returns the default size of the document contents.
178
*/
179
QSize QSvgRenderer::defaultSize()
const
180
{
181
Q_D(
const
QSvgRenderer);
182
if
(d->render)
183
return
d->render->size();
184
else
185
return
QSize();
186
}
187
188
/*!
189
Returns viewBoxF().toRect().
190
191
\sa viewBoxF()
192
*/
193
QRect QSvgRenderer::viewBox()
const
194
{
195
Q_D(
const
QSvgRenderer);
196
if
(d->render)
197
return
d->render->viewBox().toRect();
198
else
199
return
QRect();
200
}
201
202
/*!
203
\property QSvgRenderer::viewBox
204
\brief the rectangle specifying the visible area of the document in logical coordinates
205
\since 4.2
206
*/
207
void
QSvgRenderer::setViewBox(
const
QRect &viewbox)
208
{
209
Q_D(QSvgRenderer);
210
if
(d->render)
211
d->render->setViewBox(viewbox);
212
}
213
214
/*!
215
Returns true if the current document contains animated elements; otherwise
216
returns false.
217
218
\sa framesPerSecond()
219
*/
220
bool
QSvgRenderer::animated()
const
221
{
222
Q_D(
const
QSvgRenderer);
223
if
(d->render)
224
return
d->render->animated();
225
else
226
return
false
;
227
}
228
229
/*!
230
\property QSvgRenderer::animationEnabled
231
\brief whether the animation should run, if the SVG is animated
232
233
Setting the property to false stops the animation timer.
234
Setting the property to true starts the animation timer,
235
provided that the SVG contains animated elements.
236
237
If the SVG is not animated, the property will have no effect.
238
Otherwise, the property defaults to true.
239
240
\sa animated()
241
242
\since 6.7
243
*/
244
bool
QSvgRenderer::isAnimationEnabled()
const
245
{
246
Q_D(
const
QSvgRenderer);
247
return
d->animationEnabled;
248
}
249
250
void
QSvgRenderer::setAnimationEnabled(
bool
enable)
251
{
252
Q_D(QSvgRenderer);
253
d->animationEnabled = enable;
254
d->startOrStopTimer();
255
}
256
257
/*!
258
\property QSvgRenderer::framesPerSecond
259
\brief the number of frames per second to be shown
260
261
The number of frames per second is 0 if the current document is not animated.
262
263
\sa animated()
264
*/
265
int
QSvgRenderer::framesPerSecond()
const
266
{
267
Q_D(
const
QSvgRenderer);
268
return
d->fps;
269
}
270
271
void
QSvgRenderer::setFramesPerSecond(
int
num)
272
{
273
Q_D(QSvgRenderer);
274
if
(num < 0) {
275
qWarning(
"QSvgRenderer::setFramesPerSecond: Cannot set negative value %d"
, num);
276
return
;
277
}
278
d->fps = num;
279
d->startOrStopTimer();
280
}
281
282
/*!
283
\property QSvgRenderer::aspectRatioMode
284
285
\brief how rendering adheres to the SVG view box aspect ratio
286
287
The accepted modes are:
288
\list
289
\li Qt::IgnoreAspectRatio (the default): the aspect ratio is ignored and the
290
rendering is stretched to the target bounds.
291
\li Qt::KeepAspectRatio: rendering is centered and scaled as large as possible
292
within the target bounds while preserving aspect ratio.
293
\endlist
294
295
\since 5.15
296
*/
297
298
Qt::AspectRatioMode QSvgRenderer::aspectRatioMode()
const
299
{
300
Q_D(
const
QSvgRenderer);
301
if
(d->render && d->render->preserveAspectRatio())
302
return
Qt::KeepAspectRatio;
303
return
Qt::IgnoreAspectRatio;
304
}
305
306
void
QSvgRenderer::setAspectRatioMode(Qt::AspectRatioMode mode)
307
{
308
Q_D(QSvgRenderer);
309
if
(d->render) {
310
if
(mode == Qt::KeepAspectRatio)
311
d->render->setPreserveAspectRatio(
true
);
312
else
if
(mode == Qt::IgnoreAspectRatio)
313
d->render->setPreserveAspectRatio(
false
);
314
}
315
}
316
317
/*!
318
\property QSvgRenderer::options
319
\since 6.7
320
321
This property holds a set of QtSvg::Option flags that can be used
322
to enable or disable various features of the parsing and rendering of SVG files.
323
324
In order to take effect, this property must be set \c before load() is executed. Note that the
325
constructors taking an SVG source parameter will perform loading during construction.
326
327
\sa setDefaultOptions
328
*/
329
QtSvg::Options QSvgRenderer::options()
const
330
{
331
Q_D(
const
QSvgRenderer);
332
return
d->options;
333
}
334
335
void
QSvgRenderer::setOptions(QtSvg::Options flags)
336
{
337
Q_D(QSvgRenderer);
338
d->options = flags;
339
}
340
341
/*!
342
Sets the option flags that renderers will be created with to \a flags.
343
By default, no flags are set.
344
345
At runtime, this can be overridden by the QT_SVG_DEFAULT_OPTIONS environment variable.
346
347
\since 6.8
348
*/
349
350
void
QSvgRenderer::setDefaultOptions(QtSvg::Options flags)
351
{
352
QSvgRendererPrivate::appDefaultOptions = flags;
353
}
354
355
/*!
356
\property QSvgRenderer::currentFrame
357
\brief the current frame of the document's animation, or 0 if the document is not animated
358
\internal
359
360
\sa animationDuration(), framesPerSecond, animated()
361
*/
362
363
/*!
364
\internal
365
*/
366
int
QSvgRenderer::currentFrame()
const
367
{
368
Q_D(
const
QSvgRenderer);
369
return
d->render->currentFrame();
370
}
371
372
/*!
373
\internal
374
*/
375
void
QSvgRenderer::setCurrentFrame(
int
frame)
376
{
377
Q_D(QSvgRenderer);
378
d->render->setCurrentFrame(frame);
379
}
380
381
/*!
382
\internal
383
384
Returns the number of frames in the animation, or 0 if the current document is not
385
animated.
386
387
\sa animated(), framesPerSecond
388
*/
389
int
QSvgRenderer::animationDuration()
const
390
{
391
Q_D(
const
QSvgRenderer);
392
return
d->render->animationDuration();
393
}
394
395
/*!
396
\internal
397
\since 4.5
398
399
We can't have template functions, that's loadDocument(), as friends, for this
400
code, so we let this function be a friend of QSvgRenderer instead.
401
*/
402
void
QSvgRendererPrivate
::callRepaintNeeded(QSvgRenderer *
const
q)
403
{
404
emit q->repaintNeeded();
405
}
406
407
template
<
typename
TInputType
>
408
static
bool
loadDocument
(QSvgRenderer *
const
q,
409
QSvgRendererPrivate *
const
d,
410
const
TInputType &in)
411
{
412
d->render = QSvgDocument::load(in, d->options);
413
if
(d->render && !d->render->size().isValid())
414
d->render.reset();
415
416
d->startOrStopTimer();
417
418
if
(d->render)
419
d->render->restartAnimation();
420
421
//force first update
422
QSvgRendererPrivate::callRepaintNeeded(q);
423
424
return
bool
(d->render);
425
}
426
427
/*!
428
Loads the SVG file specified by \a filename, returning true if the content
429
was successfully parsed; otherwise returns false.
430
*/
431
bool
QSvgRenderer::load(
const
QString &filename)
432
{
433
Q_D(QSvgRenderer);
434
return
loadDocument(
this
, d, filename);
435
}
436
437
/*!
438
Loads the specified SVG format \a contents, returning true if the content
439
was successfully parsed; otherwise returns false.
440
*/
441
bool
QSvgRenderer::load(
const
QByteArray &contents)
442
{
443
Q_D(QSvgRenderer);
444
return
loadDocument(
this
, d, contents);
445
}
446
447
/*!
448
Loads the specified SVG in \a contents, returning true if the content
449
was successfully parsed; otherwise returns false.
450
451
The reader will be used from where it currently is positioned. If \a contents
452
is \c null, behavior is undefined.
453
454
\since 4.5
455
*/
456
bool
QSvgRenderer::load(QXmlStreamReader *contents)
457
{
458
Q_D(QSvgRenderer);
459
return
loadDocument(
this
, d, contents);
460
}
461
462
/*!
463
Renders the current document, or the current frame of an animated
464
document, using the given \a painter.
465
*/
466
void
QSvgRenderer::render(QPainter *painter)
467
{
468
Q_D(QSvgRenderer);
469
if
(d->render) {
470
if
(d->render->animator())
471
d->render->animator()->advanceAnimations();
472
d->render->draw(painter);
473
}
474
}
475
476
/*!
477
\fn void QSvgRenderer::repaintNeeded()
478
479
This signal is emitted whenever the rendering of the document
480
needs to be updated, usually for the purposes of animation.
481
*/
482
483
/*!
484
Renders the given element with \a elementId using the given \a painter
485
on the specified \a bounds. If the bounding rectangle is not specified
486
the SVG element is mapped to the whole paint device.
487
*/
488
void
QSvgRenderer::render(QPainter *painter,
const
QString &elementId,
489
const
QRectF &bounds)
490
{
491
Q_D(QSvgRenderer);
492
if
(d->render) {
493
if
(d->render->animator())
494
d->render->animator()->advanceAnimations();
495
d->render->draw(painter, elementId, bounds);
496
}
497
}
498
499
/*!
500
Renders the current document, or the current frame of an animated document,
501
using the given \a painter on the specified \a bounds within the painter.
502
If \a bounds is not empty, the output will be scaled to fill it, ignoring
503
any aspect ratio implied by the SVG.
504
*/
505
void
QSvgRenderer::render(QPainter *painter,
const
QRectF &bounds)
506
{
507
Q_D(QSvgRenderer);
508
if
(d->render) {
509
if
(d->render->animator())
510
d->render->animator()->advanceAnimations();
511
d->render->draw(painter, bounds);
512
}
513
}
514
515
QRectF QSvgRenderer::viewBoxF()
const
516
{
517
Q_D(
const
QSvgRenderer);
518
if
(d->render)
519
return
d->render->viewBox();
520
else
521
return
QRect();
522
}
523
524
void
QSvgRenderer::setViewBox(
const
QRectF &viewbox)
525
{
526
Q_D(QSvgRenderer);
527
if
(d->render)
528
d->render->setViewBox(viewbox);
529
}
530
531
/*!
532
\since 4.2
533
534
Returns bounding rectangle of the item with the given \a id.
535
The transformation matrix of parent elements is not affecting
536
the bounds of the element.
537
538
\sa transformForElement()
539
*/
540
QRectF QSvgRenderer::boundsOnElement(
const
QString &id)
const
541
{
542
Q_D(
const
QSvgRenderer);
543
QRectF bounds;
544
if
(d->render)
545
bounds = d->render->boundsOnElement(id);
546
return
bounds;
547
}
548
549
550
/*!
551
\since 4.2
552
553
Returns true if the element with the given \a id exists
554
in the currently parsed SVG file and is a renderable
555
element.
556
557
Note: this method returns true only for elements that
558
can be rendered. Which implies that elements that are considered
559
part of the fill/stroke style properties, e.g. radialGradients
560
even tough marked with "id" attributes will not be found by this
561
method.
562
*/
563
bool
QSvgRenderer::elementExists(
const
QString &id)
const
564
{
565
Q_D(
const
QSvgRenderer);
566
bool
exists =
false
;
567
if
(d->render)
568
exists = d->render->elementExists(id);
569
return
exists;
570
}
571
572
/*!
573
\since 5.15
574
575
Returns the transformation matrix for the element
576
with the given \a id. The matrix is a product of
577
the transformation of the element's parents. The transformation of
578
the element itself is not included.
579
580
To find the bounding rectangle of the element in logical coordinates,
581
you can apply the matrix on the rectangle returned from boundsOnElement().
582
583
\sa boundsOnElement()
584
*/
585
QTransform QSvgRenderer::transformForElement(
const
QString &id)
const
586
{
587
Q_D(
const
QSvgRenderer);
588
QTransform trans;
589
if
(d->render)
590
trans = d->render->transformForElement(id);
591
return
trans;
592
}
593
594
QT_END_NAMESPACE
595
596
#
include
"moc_qsvgrenderer.cpp"
597
598
#
endif
// QT_NO_SVGRENDERER
QSvgRendererPrivate
Definition
qsvgrenderer.cpp:71
QSvgRendererPrivate::fps
int fps
Definition
qsvgrenderer.cpp:111
QSvgRendererPrivate::defaultOptions
static QtSvg::Options defaultOptions()
Definition
qsvgrenderer.cpp:101
QSvgRendererPrivate::animationEnabled
bool animationEnabled
Definition
qsvgrenderer.cpp:114
QSvgRendererPrivate::timer
QTimer * timer
Definition
qsvgrenderer.cpp:110
QSvgRendererPrivate::appDefaultOptions
static QtSvg::Options appDefaultOptions
Definition
qsvgrenderer.cpp:113
QSvgRendererPrivate::render
std::unique_ptr< QSvgDocument > render
Definition
qsvgrenderer.cpp:109
QSvgRendererPrivate::options
QtSvg::Options options
Definition
qsvgrenderer.cpp:112
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
loadDocument
static bool loadDocument(QSvgRenderer *const q, QSvgRendererPrivate *const d, const TInputType &in)
Definition
qsvgrenderer.cpp:408
qtsvg
src
svg
qsvgrenderer.cpp
Generated on
for Qt by
1.18.0