/src/qtsvg/src/svg/qsvgrenderer.cpp
Line | Count | Source |
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 | 0 | Q_DECLARE_PUBLIC(QSvgRenderer) |
73 | 0 | public: |
74 | 0 | explicit QSvgRendererPrivate() |
75 | 42.1k | : QObjectPrivate(), |
76 | 42.1k | timer(0), |
77 | 42.1k | fps(30) |
78 | 42.1k | { |
79 | 42.1k | options = defaultOptions(); |
80 | 42.1k | } |
81 | | |
82 | | void startOrStopTimer() |
83 | 42.1k | { |
84 | 42.1k | if (animationEnabled && render && render->animated() && fps > 0) { |
85 | 0 | ensureTimerCreated(); |
86 | 0 | timer->start(1000 / fps); |
87 | 42.1k | } else if (timer) { |
88 | 0 | timer->stop(); |
89 | 0 | } |
90 | 42.1k | } |
91 | | |
92 | | void ensureTimerCreated() |
93 | 0 | { |
94 | 0 | Q_Q(QSvgRenderer); |
95 | 0 | if (!timer) { |
96 | 0 | timer = new QTimer(q); |
97 | 0 | q->connect(timer, &QTimer::timeout, q, &QSvgRenderer::repaintNeeded); |
98 | 0 | } |
99 | 0 | } |
100 | | |
101 | | static void callRepaintNeeded(QSvgRenderer *const q); |
102 | | |
103 | | static QtSvg::Options defaultOptions() |
104 | 42.1k | { |
105 | 42.1k | static bool envOk = false; |
106 | 42.1k | static QtSvg::Options envOpts = QtSvg::Options::fromInt( |
107 | 42.1k | qEnvironmentVariableIntValue("QT_SVG_DEFAULT_OPTIONS", &envOk)); |
108 | 42.1k | return envOk ? envOpts : appDefaultOptions; |
109 | 42.1k | } |
110 | | |
111 | | std::unique_ptr<QSvgDocument> render; |
112 | | QTimer *timer; |
113 | | int fps; |
114 | | QtSvg::Options options; |
115 | | static QtSvg::Options appDefaultOptions; |
116 | | bool animationEnabled = true; |
117 | | }; |
118 | | |
119 | | QtSvg::Options QSvgRendererPrivate::appDefaultOptions; |
120 | | |
121 | | /*! |
122 | | Constructs a new renderer with the given \a parent. |
123 | | */ |
124 | | QSvgRenderer::QSvgRenderer(QObject *parent) |
125 | 32.4k | : QObject(*(new QSvgRendererPrivate), parent) |
126 | 32.4k | { |
127 | 32.4k | } |
128 | | |
129 | | /*! |
130 | | Constructs a new renderer with the given \a parent and loads the contents of the |
131 | | SVG file with the specified \a filename. |
132 | | */ |
133 | | QSvgRenderer::QSvgRenderer(const QString &filename, QObject *parent) |
134 | 9.67k | : QObject(*new QSvgRendererPrivate, parent) |
135 | 9.67k | { |
136 | 9.67k | load(filename); |
137 | 9.67k | } |
138 | | |
139 | | /*! |
140 | | Constructs a new renderer with the given \a parent and loads the SVG data |
141 | | from the byte array specified by \a contents. |
142 | | */ |
143 | | QSvgRenderer::QSvgRenderer(const QByteArray &contents, QObject *parent) |
144 | 0 | : QObject(*new QSvgRendererPrivate, parent) |
145 | 0 | { |
146 | 0 | load(contents); |
147 | 0 | } |
148 | | |
149 | | /*! |
150 | | \since 4.5 |
151 | | |
152 | | Constructs a new renderer with the given \a parent and loads the SVG data |
153 | | using the stream reader specified by \a contents. |
154 | | */ |
155 | | QSvgRenderer::QSvgRenderer(QXmlStreamReader *contents, QObject *parent) |
156 | 0 | : QObject(*new QSvgRendererPrivate, parent) |
157 | 0 | { |
158 | 0 | load(contents); |
159 | 0 | } |
160 | | |
161 | | /*! |
162 | | Destroys the renderer. |
163 | | */ |
164 | | QSvgRenderer::~QSvgRenderer() |
165 | 42.1k | { |
166 | | |
167 | 42.1k | } |
168 | | |
169 | | /*! |
170 | | Returns true if there is a valid current document; otherwise returns false. |
171 | | */ |
172 | | bool QSvgRenderer::isValid() const |
173 | 9.67k | { |
174 | 9.67k | Q_D(const QSvgRenderer); |
175 | 9.67k | return bool(d->render); |
176 | 9.67k | } |
177 | | |
178 | | /*! |
179 | | Returns the default size of the document contents. |
180 | | */ |
181 | | QSize QSvgRenderer::defaultSize() const |
182 | 2.09k | { |
183 | 2.09k | Q_D(const QSvgRenderer); |
184 | 2.09k | if (d->render) |
185 | 2.09k | return d->render->size(); |
186 | 0 | else |
187 | 0 | return QSize(); |
188 | 2.09k | } |
189 | | |
190 | | /*! |
191 | | Returns viewBoxF().toRect(). |
192 | | |
193 | | \sa viewBoxF() |
194 | | */ |
195 | | QRect QSvgRenderer::viewBox() const |
196 | 0 | { |
197 | 0 | Q_D(const QSvgRenderer); |
198 | 0 | if (d->render) |
199 | 0 | return d->render->viewBox().toRect(); |
200 | 0 | else |
201 | 0 | return QRect(); |
202 | 0 | } |
203 | | |
204 | | /*! |
205 | | \property QSvgRenderer::viewBox |
206 | | \brief the rectangle specifying the visible area of the document in logical coordinates |
207 | | \since 4.2 |
208 | | */ |
209 | | void QSvgRenderer::setViewBox(const QRect &viewbox) |
210 | 0 | { |
211 | 0 | Q_D(QSvgRenderer); |
212 | 0 | if (d->render) |
213 | 0 | d->render->setViewBox(viewbox); |
214 | 0 | } |
215 | | |
216 | | /*! |
217 | | Returns true if the current document contains animated elements; otherwise |
218 | | returns false. |
219 | | |
220 | | \sa framesPerSecond() |
221 | | */ |
222 | | bool QSvgRenderer::animated() const |
223 | 285 | { |
224 | 285 | Q_D(const QSvgRenderer); |
225 | 285 | if (d->render) |
226 | 285 | return d->render->animated(); |
227 | 0 | else |
228 | 0 | return false; |
229 | 285 | } |
230 | | |
231 | | /*! |
232 | | \property QSvgRenderer::animationEnabled |
233 | | \brief whether the animation should run, if the SVG is animated |
234 | | |
235 | | Setting the property to false stops the animation timer. |
236 | | Setting the property to true starts the animation timer, |
237 | | provided that the SVG contains animated elements. |
238 | | |
239 | | If the SVG is not animated, the property will have no effect. |
240 | | Otherwise, the property defaults to true. |
241 | | |
242 | | \sa animated() |
243 | | |
244 | | \since 6.7 |
245 | | */ |
246 | | bool QSvgRenderer::isAnimationEnabled() const |
247 | 0 | { |
248 | 0 | Q_D(const QSvgRenderer); |
249 | 0 | return d->animationEnabled; |
250 | 0 | } |
251 | | |
252 | | void QSvgRenderer::setAnimationEnabled(bool enable) |
253 | 0 | { |
254 | 0 | Q_D(QSvgRenderer); |
255 | 0 | d->animationEnabled = enable; |
256 | 0 | d->startOrStopTimer(); |
257 | 0 | } |
258 | | |
259 | | /*! |
260 | | \property QSvgRenderer::framesPerSecond |
261 | | \brief the number of frames per second to be shown |
262 | | |
263 | | The number of frames per second is 0 if the current document is not animated. |
264 | | |
265 | | \sa animated() |
266 | | */ |
267 | | int QSvgRenderer::framesPerSecond() const |
268 | 0 | { |
269 | 0 | Q_D(const QSvgRenderer); |
270 | 0 | return d->fps; |
271 | 0 | } |
272 | | |
273 | | void QSvgRenderer::setFramesPerSecond(int num) |
274 | 0 | { |
275 | 0 | Q_D(QSvgRenderer); |
276 | 0 | if (num < 0) { |
277 | 0 | qWarning("QSvgRenderer::setFramesPerSecond: Cannot set negative value %d", num); |
278 | 0 | return; |
279 | 0 | } |
280 | 0 | d->fps = num; |
281 | 0 | d->startOrStopTimer(); |
282 | 0 | } |
283 | | |
284 | | /*! |
285 | | \property QSvgRenderer::aspectRatioMode |
286 | | |
287 | | \brief how rendering adheres to the SVG view box aspect ratio |
288 | | |
289 | | The accepted modes are: |
290 | | \list |
291 | | \li Qt::IgnoreAspectRatio (the default): the aspect ratio is ignored and the |
292 | | rendering is stretched to the target bounds. |
293 | | \li Qt::KeepAspectRatio: rendering is centered and scaled as large as possible |
294 | | within the target bounds while preserving aspect ratio. |
295 | | \endlist |
296 | | |
297 | | \since 5.15 |
298 | | */ |
299 | | |
300 | | Qt::AspectRatioMode QSvgRenderer::aspectRatioMode() const |
301 | 0 | { |
302 | 0 | Q_D(const QSvgRenderer); |
303 | 0 | if (d->render && d->render->preserveAspectRatio()) |
304 | 0 | return Qt::KeepAspectRatio; |
305 | 0 | return Qt::IgnoreAspectRatio; |
306 | 0 | } |
307 | | |
308 | | void QSvgRenderer::setAspectRatioMode(Qt::AspectRatioMode mode) |
309 | 0 | { |
310 | 0 | Q_D(QSvgRenderer); |
311 | 0 | if (d->render) { |
312 | 0 | if (mode == Qt::KeepAspectRatio) |
313 | 0 | d->render->setPreserveAspectRatio(true); |
314 | 0 | else if (mode == Qt::IgnoreAspectRatio) |
315 | 0 | d->render->setPreserveAspectRatio(false); |
316 | 0 | } |
317 | 0 | } |
318 | | |
319 | | /*! |
320 | | \property QSvgRenderer::options |
321 | | \since 6.7 |
322 | | |
323 | | This property holds a set of QtSvg::Option flags that can be used |
324 | | to enable or disable various features of the parsing and rendering of SVG files. |
325 | | |
326 | | In order to take effect, this property must be set \c before load() is executed. Note that the |
327 | | constructors taking an SVG source parameter will perform loading during construction. |
328 | | |
329 | | \sa setDefaultOptions |
330 | | */ |
331 | | QtSvg::Options QSvgRenderer::options() const |
332 | 0 | { |
333 | 0 | Q_D(const QSvgRenderer); |
334 | 0 | return d->options; |
335 | 0 | } |
336 | | |
337 | | void QSvgRenderer::setOptions(QtSvg::Options flags) |
338 | 0 | { |
339 | 0 | Q_D(QSvgRenderer); |
340 | 0 | d->options = flags; |
341 | 0 | } |
342 | | |
343 | | /*! |
344 | | Sets the option flags that renderers will be created with to \a flags. |
345 | | By default, no flags are set. |
346 | | |
347 | | At runtime, this can be overridden by the QT_SVG_DEFAULT_OPTIONS environment variable. |
348 | | |
349 | | \since 6.8 |
350 | | */ |
351 | | |
352 | | void QSvgRenderer::setDefaultOptions(QtSvg::Options flags) |
353 | 0 | { |
354 | 0 | QSvgRendererPrivate::appDefaultOptions = flags; |
355 | 0 | } |
356 | | |
357 | | /*! |
358 | | \property QSvgRenderer::currentFrame |
359 | | \brief the current frame of the document's animation, or 0 if the document is not animated |
360 | | \internal |
361 | | |
362 | | \sa animationDuration(), framesPerSecond, animated() |
363 | | */ |
364 | | |
365 | | /*! |
366 | | \internal |
367 | | */ |
368 | | int QSvgRenderer::currentFrame() const |
369 | 0 | { |
370 | 0 | Q_D(const QSvgRenderer); |
371 | 0 | return d->render->currentFrame(); |
372 | 0 | } |
373 | | |
374 | | /*! |
375 | | \internal |
376 | | */ |
377 | | void QSvgRenderer::setCurrentFrame(int frame) |
378 | 0 | { |
379 | 0 | Q_D(QSvgRenderer); |
380 | 0 | d->render->setCurrentFrame(frame); |
381 | 0 | } |
382 | | |
383 | | /*! |
384 | | \internal |
385 | | |
386 | | Returns the number of frames in the animation, or 0 if the current document is not |
387 | | animated. |
388 | | |
389 | | \sa animated(), framesPerSecond |
390 | | */ |
391 | | int QSvgRenderer::animationDuration() const |
392 | 0 | { |
393 | 0 | Q_D(const QSvgRenderer); |
394 | 0 | return d->render->animationDuration(); |
395 | 0 | } |
396 | | |
397 | | /*! |
398 | | \internal |
399 | | \since 4.5 |
400 | | |
401 | | We can't have template functions, that's loadDocument(), as friends, for this |
402 | | code, so we let this function be a friend of QSvgRenderer instead. |
403 | | */ |
404 | | void QSvgRendererPrivate::callRepaintNeeded(QSvgRenderer *const q) |
405 | 42.1k | { |
406 | 42.1k | emit q->repaintNeeded(); |
407 | 42.1k | } |
408 | | |
409 | | template<typename TInputType> |
410 | | static bool loadDocument(QSvgRenderer *const q, |
411 | | QSvgRendererPrivate *const d, |
412 | | const TInputType &in) |
413 | 42.1k | { |
414 | 42.1k | d->render = QSvgDocument::load(in, d->options); |
415 | 42.1k | if (d->render && !d->render->size().isValid()) |
416 | 0 | d->render.reset(); |
417 | | |
418 | 42.1k | d->startOrStopTimer(); |
419 | | |
420 | 42.1k | if (d->render) |
421 | 2.09k | d->render->restartAnimation(); |
422 | | |
423 | | //force first update |
424 | 42.1k | QSvgRendererPrivate::callRepaintNeeded(q); |
425 | | |
426 | 42.1k | return bool(d->render); |
427 | 42.1k | } qsvgrenderer.cpp:bool loadDocument<QString>(QSvgRenderer*, QSvgRendererPrivate*, QString const&) Line | Count | Source | 413 | 9.67k | { | 414 | 9.67k | d->render = QSvgDocument::load(in, d->options); | 415 | 9.67k | if (d->render && !d->render->size().isValid()) | 416 | 0 | d->render.reset(); | 417 | | | 418 | 9.67k | d->startOrStopTimer(); | 419 | | | 420 | 9.67k | if (d->render) | 421 | 1.99k | d->render->restartAnimation(); | 422 | | | 423 | | //force first update | 424 | 9.67k | QSvgRendererPrivate::callRepaintNeeded(q); | 425 | | | 426 | 9.67k | return bool(d->render); | 427 | 9.67k | } |
qsvgrenderer.cpp:bool loadDocument<QByteArray>(QSvgRenderer*, QSvgRendererPrivate*, QByteArray const&) Line | Count | Source | 413 | 9.79k | { | 414 | 9.79k | d->render = QSvgDocument::load(in, d->options); | 415 | 9.79k | if (d->render && !d->render->size().isValid()) | 416 | 0 | d->render.reset(); | 417 | | | 418 | 9.79k | d->startOrStopTimer(); | 419 | | | 420 | 9.79k | if (d->render) | 421 | 19 | d->render->restartAnimation(); | 422 | | | 423 | | //force first update | 424 | 9.79k | QSvgRendererPrivate::callRepaintNeeded(q); | 425 | | | 426 | 9.79k | return bool(d->render); | 427 | 9.79k | } |
qsvgrenderer.cpp:bool loadDocument<QXmlStreamReader*>(QSvgRenderer*, QSvgRendererPrivate*, QXmlStreamReader* const&) Line | Count | Source | 413 | 22.7k | { | 414 | 22.7k | d->render = QSvgDocument::load(in, d->options); | 415 | 22.7k | if (d->render && !d->render->size().isValid()) | 416 | 0 | d->render.reset(); | 417 | | | 418 | 22.7k | d->startOrStopTimer(); | 419 | | | 420 | 22.7k | if (d->render) | 421 | 76 | d->render->restartAnimation(); | 422 | | | 423 | | //force first update | 424 | 22.7k | QSvgRendererPrivate::callRepaintNeeded(q); | 425 | | | 426 | 22.7k | return bool(d->render); | 427 | 22.7k | } |
|
428 | | |
429 | | /*! |
430 | | Loads the SVG file specified by \a filename, returning true if the content |
431 | | was successfully parsed; otherwise returns false. |
432 | | */ |
433 | | bool QSvgRenderer::load(const QString &filename) |
434 | 9.67k | { |
435 | 9.67k | Q_D(QSvgRenderer); |
436 | 9.67k | return loadDocument(this, d, filename); |
437 | 9.67k | } |
438 | | |
439 | | /*! |
440 | | Loads the specified SVG format \a contents, returning true if the content |
441 | | was successfully parsed; otherwise returns false. |
442 | | */ |
443 | | bool QSvgRenderer::load(const QByteArray &contents) |
444 | 9.79k | { |
445 | 9.79k | Q_D(QSvgRenderer); |
446 | 9.79k | return loadDocument(this, d, contents); |
447 | 9.79k | } |
448 | | |
449 | | /*! |
450 | | Loads the specified SVG in \a contents, returning true if the content |
451 | | was successfully parsed; otherwise returns false. |
452 | | |
453 | | The reader will be used from where it currently is positioned. If \a contents |
454 | | is \c null, behavior is undefined. |
455 | | |
456 | | \since 4.5 |
457 | | */ |
458 | | bool QSvgRenderer::load(QXmlStreamReader *contents) |
459 | 22.7k | { |
460 | 22.7k | Q_D(QSvgRenderer); |
461 | 22.7k | return loadDocument(this, d, contents); |
462 | 22.7k | } |
463 | | |
464 | | /*! |
465 | | Renders the current document, or the current frame of an animated |
466 | | document, using the given \a painter. |
467 | | */ |
468 | | void QSvgRenderer::render(QPainter *painter) |
469 | 0 | { |
470 | 0 | Q_D(QSvgRenderer); |
471 | 0 | if (d->render) { |
472 | 0 | if (d->render->animator()) |
473 | 0 | d->render->animator()->advanceAnimations(); |
474 | 0 | d->render->draw(painter); |
475 | 0 | } |
476 | 0 | } |
477 | | |
478 | | /*! |
479 | | \fn void QSvgRenderer::repaintNeeded() |
480 | | |
481 | | This signal is emitted whenever the rendering of the document |
482 | | needs to be updated, usually for the purposes of animation. |
483 | | */ |
484 | | |
485 | | /*! |
486 | | Renders the given element with \a elementId using the given \a painter |
487 | | on the specified \a bounds. If the bounding rectangle is not specified |
488 | | the SVG element is mapped to the whole paint device. |
489 | | */ |
490 | | void QSvgRenderer::render(QPainter *painter, const QString &elementId, |
491 | | const QRectF &bounds) |
492 | 0 | { |
493 | 0 | Q_D(QSvgRenderer); |
494 | 0 | if (d->render) { |
495 | 0 | if (d->render->animator()) |
496 | 0 | d->render->animator()->advanceAnimations(); |
497 | 0 | d->render->draw(painter, elementId, bounds); |
498 | 0 | } |
499 | 0 | } |
500 | | |
501 | | /*! |
502 | | Renders the current document, or the current frame of an animated document, |
503 | | using the given \a painter on the specified \a bounds within the painter. |
504 | | If \a bounds is not empty, the output will be scaled to fill it, ignoring |
505 | | any aspect ratio implied by the SVG. |
506 | | */ |
507 | | void QSvgRenderer::render(QPainter *painter, const QRectF &bounds) |
508 | 1.99k | { |
509 | 1.99k | Q_D(QSvgRenderer); |
510 | 1.99k | if (d->render) { |
511 | 1.99k | if (d->render->animator()) |
512 | 1.99k | d->render->animator()->advanceAnimations(); |
513 | 1.99k | d->render->draw(painter, bounds); |
514 | 1.99k | } |
515 | 1.99k | } |
516 | | |
517 | | QRectF QSvgRenderer::viewBoxF() const |
518 | 0 | { |
519 | 0 | Q_D(const QSvgRenderer); |
520 | 0 | if (d->render) |
521 | 0 | return d->render->viewBox(); |
522 | 0 | else |
523 | 0 | return QRect(); |
524 | 0 | } |
525 | | |
526 | | void QSvgRenderer::setViewBox(const QRectF &viewbox) |
527 | 0 | { |
528 | 0 | Q_D(QSvgRenderer); |
529 | 0 | if (d->render) |
530 | 0 | d->render->setViewBox(viewbox); |
531 | 0 | } |
532 | | |
533 | | /*! |
534 | | \since 4.2 |
535 | | |
536 | | Returns bounding rectangle of the item with the given \a id. |
537 | | The transformation matrix of parent elements is not affecting |
538 | | the bounds of the element. |
539 | | |
540 | | \sa transformForElement() |
541 | | */ |
542 | | QRectF QSvgRenderer::boundsOnElement(const QString &id) const |
543 | 0 | { |
544 | 0 | Q_D(const QSvgRenderer); |
545 | 0 | QRectF bounds; |
546 | 0 | if (d->render) |
547 | 0 | bounds = d->render->boundsOnElement(id); |
548 | 0 | return bounds; |
549 | 0 | } |
550 | | |
551 | | |
552 | | /*! |
553 | | \since 4.2 |
554 | | |
555 | | Returns true if the element with the given \a id exists |
556 | | in the currently parsed SVG file and is a renderable |
557 | | element. |
558 | | |
559 | | Note: this method returns true only for elements that |
560 | | can be rendered. Which implies that elements that are considered |
561 | | part of the fill/stroke style properties, e.g. radialGradients |
562 | | even tough marked with "id" attributes will not be found by this |
563 | | method. |
564 | | */ |
565 | | bool QSvgRenderer::elementExists(const QString &id) const |
566 | 0 | { |
567 | 0 | Q_D(const QSvgRenderer); |
568 | 0 | bool exists = false; |
569 | 0 | if (d->render) |
570 | 0 | exists = d->render->elementExists(id); |
571 | 0 | return exists; |
572 | 0 | } |
573 | | |
574 | | /*! |
575 | | \since 5.15 |
576 | | |
577 | | Returns the transformation matrix for the element |
578 | | with the given \a id. The matrix is a product of |
579 | | the transformation of the element's parents. The transformation of |
580 | | the element itself is not included. |
581 | | |
582 | | To find the bounding rectangle of the element in logical coordinates, |
583 | | you can apply the matrix on the rectangle returned from boundsOnElement(). |
584 | | |
585 | | \sa boundsOnElement() |
586 | | */ |
587 | | QTransform QSvgRenderer::transformForElement(const QString &id) const |
588 | 0 | { |
589 | 0 | Q_D(const QSvgRenderer); |
590 | 0 | QTransform trans; |
591 | 0 | if (d->render) |
592 | 0 | trans = d->render->transformForElement(id); |
593 | 0 | return trans; |
594 | 0 | } |
595 | | |
596 | | QT_END_NAMESPACE |
597 | | |
598 | | #include "moc_qsvgrenderer.cpp" |
599 | | |
600 | | #endif // QT_NO_SVGRENDERER |