Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qsvgiohandler.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
4#include "qsvgiohandler.h"
5
6#ifndef QT_NO_SVGRENDERER
7
8#include "qsvgrenderer.h"
9#include "qimage.h"
10#include "qpixmap.h"
11#include "qpainter.h"
12#include "qvariant.h"
13#include "qbuffer.h"
14#include "qdebug.h"
15
17
19{
20public:
22 : q(qq), loaded(false), readDone(false), backColor(Qt::transparent)
23 {}
24
25 bool load(QIODevice *device);
26
29 QXmlStreamReader xmlReader;
34 bool loaded;
37};
38
39
41{
42 if (loaded)
43 return true;
44 if (q->format().isEmpty())
45 q->canRead();
46
47 // # The SVG renderer doesn't handle trailing, unrelated data, so we must
48 // assume that all available data in the device is to be read.
49 bool res = false;
50 QBuffer *buf = qobject_cast<QBuffer *>(device);
51 if (buf) {
52 const QByteArray &ba = buf->data();
53 res = r.load(QByteArray::fromRawData(ba.constData() + buf->pos(), ba.size() - buf->pos()));
54 buf->seek(ba.size());
55#ifndef QT_NO_COMPRESS
56 } else if (q->format() == "svgz") {
57 res = r.load(device->readAll());
58#endif
59 } else {
60 xmlReader.setDevice(device);
61 res = r.load(&xmlReader);
62 }
63
64 if (res) {
65 defaultSize = r.defaultSize();
66 loaded = true;
67 }
68
69 return loaded;
70}
71
72
75{
76
77}
78
79
81{
82 delete d;
83}
84
85static bool isPossiblySvg(QIODevice *device, bool *isCompressed = nullptr)
86{
87 constexpr int bufSize = 64;
88 char buf[bufSize];
89 const qint64 readLen = device->peek(buf, bufSize);
90 if (readLen < 8)
91 return false;
92# ifndef QT_NO_COMPRESS
93 if (quint8(buf[0]) == 0x1f && quint8(buf[1]) == 0x8b) {
94 if (isCompressed)
95 *isCompressed = true;
96 return true;
97 }
98# endif
100 QByteArray ba = str.read(16).trimmed().toLatin1();
101 return ba.startsWith("<?xml") || ba.startsWith("<svg") || ba.startsWith("<!--") || ba.startsWith("<!DOCTYPE svg");
102}
103
105{
106 if (!device())
107 return false;
108 if (d->loaded && !d->readDone)
109 return true; // Will happen if we have been asked for the size
110
111 bool isCompressed = false;
112 if (isPossiblySvg(device(), &isCompressed)) {
113 setFormat(isCompressed ? "svgz" : "svg");
114 return true;
115 }
116 return false;
117}
118
120{
121 if (!d->readDone && d->load(device())) {
122 bool xform = (d->clipRect.isValid() || d->scaledSize.isValid() || d->scaledClipRect.isValid());
123 QSize finalSize = d->defaultSize;
124 QRectF bounds;
125 if (xform && !d->defaultSize.isEmpty()) {
126 bounds = QRectF(QPointF(0,0), QSizeF(d->defaultSize));
127 QPoint tr1, tr2;
128 QSizeF sc(1, 1);
129 if (d->clipRect.isValid()) {
130 tr1 = -d->clipRect.topLeft();
131 finalSize = d->clipRect.size();
132 }
133 if (d->scaledSize.isValid()) {
134 sc = QSizeF(qreal(d->scaledSize.width()) / finalSize.width(),
135 qreal(d->scaledSize.height()) / finalSize.height());
136 finalSize = d->scaledSize;
137 }
138 if (d->scaledClipRect.isValid()) {
139 tr2 = -d->scaledClipRect.topLeft();
140 finalSize = d->scaledClipRect.size();
141 }
143 t.translate(tr2.x(), tr2.y());
144 t.scale(sc.width(), sc.height());
145 t.translate(tr1.x(), tr1.y());
146 bounds = t.mapRect(bounds);
147 }
148 if (finalSize.isEmpty()) {
149 *image = QImage();
150 } else {
151 if (qMax(finalSize.width(), finalSize.height()) > 0xffff)
152 return false; // Assume corrupted file
154 return false;
155 image->fill(d->backColor.rgba());
157 d->r.render(&p, bounds);
158 p.end();
159 }
160 d->readDone = true;
161 return true;
162 }
163
164 return false;
165}
166
167
169{
170 switch(option) {
171 case ImageFormat:
173 break;
174 case Size:
175 d->load(device());
176 return d->defaultSize;
177 break;
178 case ClipRect:
179 return d->clipRect;
180 break;
181 case ScaledSize:
182 return d->scaledSize;
183 break;
184 case ScaledClipRect:
185 return d->scaledClipRect;
186 break;
187 case BackgroundColor:
188 return d->backColor;
189 break;
190 default:
191 break;
192 }
193 return QVariant();
194}
195
196
198{
199 switch(option) {
200 case ClipRect:
201 d->clipRect = value.toRect();
202 break;
203 case ScaledSize:
204 d->scaledSize = value.toSize();
205 break;
206 case ScaledClipRect:
207 d->scaledClipRect = value.toRect();
208 break;
209 case BackgroundColor:
210 d->backColor = value.value<QColor>();
211 break;
212 default:
213 break;
214 }
215}
216
217
219{
220 switch(option)
221 {
222 case ImageFormat:
223 case Size:
224 case ClipRect:
225 case ScaledSize:
226 case ScaledClipRect:
227 case BackgroundColor:
228 return true;
229 default:
230 break;
231 }
232 return false;
233}
234
235
237{
238 return isPossiblySvg(device);
239}
240
242
243#endif // QT_NO_SVGRENDERER
IOBluetoothDevice * device
\inmodule QtCore \reentrant
Definition qbuffer.h:16
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:534
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:474
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
bool startsWith(QByteArrayView bv) const
Definition qbytearray.h:170
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:394
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
QRgb rgba() const noexcept
Returns the RGB value of the color, including its alpha.
Definition qcolor.cpp:1376
int value() const noexcept
Returns the value color component of this color.
Definition qcolor.cpp:1756
\inmodule QtCore \reentrant
Definition qiodevice.h:34
ImageOption
This enum describes the different options supported by QImageIOHandler.
static bool allocateImage(QSize size, QImage::Format format, QImage *image)
QIODevice * device() const
Returns the device currently assigned to the QImageIOHandler.
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
\inmodule QtGui
Definition qimage.h:37
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
\inmodule QtCore\reentrant
Definition qpoint.h:214
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
\inmodule QtCore\reentrant
Definition qrect.h:483
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr bool isValid() const noexcept
Returns true if the rectangle is valid, otherwise returns false.
Definition qrect.h:169
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:220
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:241
\inmodule QtCore
Definition qsize.h:207
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:321
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:324
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:123
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
Definition qsize.h:126
QByteArray toLatin1() const &
Definition qstring.h:559
QString trimmed() const &
Definition qstring.h:380
bool load(QIODevice *device)
QXmlStreamReader xmlReader
QSvgIOHandlerPrivate(QSvgIOHandler *qq)
bool canRead() const override
Returns true if an image can be read from the device (i.e., the image format is supported,...
QVariant option(ImageOption option) const override
Returns the value assigned to option as a QVariant.
bool read(QImage *image) override
Read an image from the device, and stores it in image.
bool supportsOption(ImageOption option) const override
Returns true if the QImageIOHandler supports the option option; otherwise returns false.
void setOption(ImageOption option, const QVariant &value) override
Sets the option option with the value value.
\inmodule QtSvg
void render(QPainter *p)
Renders the current document, or the current frame of an animated document, using the given painter.
\inmodule QtCore
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
\inmodule QtCore
Definition qvariant.h:64
#define this
Definition dialogs.cpp:9
QString str
[2]
Combined button and popup list for selecting options.
Definition image.cpp:4
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean r
[2]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei bufSize
GLuint res
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
GLuint GLenum option
static bool isPossiblySvg(QIODevice *device, bool *isCompressed=nullptr)
long long qint64
Definition qtypes.h:55
double qreal
Definition qtypes.h:92
unsigned char quint8
Definition qtypes.h:41
QByteArray ba
[0]