Qt 4.8
qsvgiohandler.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qsvgiohandler.h"
43 
44 #ifndef QT_NO_SVGRENDERER
45 
46 #include "qsvgrenderer.h"
47 #include "qimage.h"
48 #include "qpixmap.h"
49 #include "qpainter.h"
50 #include "qvariant.h"
51 #include "qbuffer.h"
52 #include "qdebug.h"
53 
55 
57 {
58 public:
60  : q(qq), loaded(false), readDone(false), backColor(Qt::transparent)
61  {}
62 
63  bool load(QIODevice *device);
64 
72  bool loaded;
73  bool readDone;
75 };
76 
77 
79 {
80  if (loaded)
81  return true;
82  if (q->format().isEmpty())
83  q->canRead();
84 
85  // # The SVG renderer doesn't handle trailing, unrelated data, so we must
86  // assume that all available data in the device is to be read.
87  bool res = false;
88  QBuffer *buf = qobject_cast<QBuffer *>(device);
89  if (buf) {
90  const QByteArray &ba = buf->data();
91  res = r.load(QByteArray::fromRawData(ba.constData() + buf->pos(), ba.size() - buf->pos()));
92  buf->seek(ba.size());
93  } else if (q->format() == "svgz") {
94  res = r.load(device->readAll());
95  } else {
96  xmlReader.setDevice(device);
97  res = r.load(&xmlReader);
98  }
99 
100  if (res) {
102  loaded = true;
103  }
104 
105  return loaded;
106 }
107 
108 
110  : d(new QSvgIOHandlerPrivate(this))
111 {
112 
113 }
114 
115 
117 {
118  delete d;
119 }
120 
121 
123 {
124  if (!device())
125  return false;
126  if (d->loaded && !d->readDone)
127  return true; // Will happen if we have been asked for the size
128 
129  QByteArray buf = device()->peek(8);
130  if (buf.startsWith("\x1f\x8b")) {
131  setFormat("svgz");
132  return true;
133  } else if (buf.contains("<?xml") || buf.contains("<svg")) {
134  setFormat("svg");
135  return true;
136  }
137  return false;
138 }
139 
140 
142 {
143  return "svg";
144 }
145 
146 
148 {
149  if (!d->readDone && d->load(device())) {
150  bool xform = (d->clipRect.isValid() || d->scaledSize.isValid() || d->scaledClipRect.isValid());
151  QSize finalSize = d->defaultSize;
152  QRectF bounds;
153  if (xform && !d->defaultSize.isEmpty()) {
154  bounds = QRectF(QPointF(0,0), QSizeF(d->defaultSize));
155  QPoint tr1, tr2;
156  QSizeF sc(1, 1);
157  if (d->clipRect.isValid()) {
158  tr1 = -d->clipRect.topLeft();
159  finalSize = d->clipRect.size();
160  }
161  if (d->scaledSize.isValid()) {
162  sc = QSizeF(qreal(d->scaledSize.width()) / finalSize.width(),
163  qreal(d->scaledSize.height()) / finalSize.height());
164  finalSize = d->scaledSize;
165  }
166  if (d->scaledClipRect.isValid()) {
167  tr2 = -d->scaledClipRect.topLeft();
168  finalSize = d->scaledClipRect.size();
169  }
170  QTransform t;
171  t.translate(tr2.x(), tr2.y());
172  t.scale(sc.width(), sc.height());
173  t.translate(tr1.x(), tr1.y());
174  bounds = t.mapRect(bounds);
175  }
176  *image = QImage(finalSize, QImage::Format_ARGB32_Premultiplied);
177  if (!finalSize.isEmpty()) {
178  image->fill(d->backColor.rgba());
179  QPainter p(image);
180  d->r.render(&p, bounds);
181  p.end();
182  }
183  d->readDone = true;
184  return true;
185  }
186 
187  return false;
188 }
189 
190 
192 {
193  switch(option) {
194  case ImageFormat:
196  break;
197  case Size:
198  d->load(device());
199  return d->defaultSize;
200  break;
201  case ClipRect:
202  return d->clipRect;
203  break;
204  case ScaledSize:
205  return d->scaledSize;
206  break;
207  case ScaledClipRect:
208  return d->scaledClipRect;
209  break;
210  case BackgroundColor:
211  return d->backColor;
212  break;
213  default:
214  break;
215  }
216  return QVariant();
217 }
218 
219 
221 {
222  switch(option) {
223  case ClipRect:
224  d->clipRect = value.toRect();
225  break;
226  case ScaledSize:
227  d->scaledSize = value.toSize();
228  break;
229  case ScaledClipRect:
230  d->scaledClipRect = value.toRect();
231  break;
232  case BackgroundColor:
233  d->backColor = value.value<QColor>();
234  break;
235  default:
236  break;
237  }
238 }
239 
240 
242 {
243  switch(option)
244  {
245  case ImageFormat:
246  case Size:
247  case ClipRect:
248  case ScaledSize:
249  case ScaledClipRect:
250  case BackgroundColor:
251  return true;
252  default:
253  break;
254  }
255  return false;
256 }
257 
258 
260 {
261  QByteArray buf = device->peek(8);
262  return buf.startsWith("\x1f\x8b") || buf.contains("<?xml") || buf.contains("<svg");
263 }
264 
266 
267 #endif // QT_NO_SVGRENDERER
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
T qobject_cast(QObject *object)
Definition: qobject.h:375
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
QXmlStreamReader xmlReader
double qreal
Definition: qglobal.h:1193
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
const QByteArray & data() const
Returns the data contained in the buffer.
Definition: qbuffer.cpp:301
qreal width() const
Returns the width.
Definition: qsize.h:284
void fill(uint pixel)
Fills the entire image with the given pixelValue.
Definition: qimage.cpp:2032
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
qreal height() const
Returns the height.
Definition: qsize.h:287
qint64 pos() const
Reimplemented Function
Definition: qbuffer.cpp:367
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
Definition: qtransform.cpp:417
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:57
bool startsWith(const QByteArray &a) const
Returns true if this byte array starts with byte array ba; otherwise returns false.
QRectF viewBox
Returns viewBoxF().toRect().
Definition: qsvgrenderer.h:68
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
bool seek(qint64 off)
Reimplemented Function
Definition: qbuffer.cpp:384
QByteArray format() const
Returns the format that is currently assigned to QImageIOHandler.
QSvgIOHandlerPrivate(QSvgIOHandler *qq)
virtual bool supportsOption(ImageOption option) const
Returns true if the QImageIOHandler supports the option option; otherwise returns false...
int width() const
Returns the width.
Definition: qsize.h:126
QRect mapRect(const QRect &) const
Creates and returns a QRect object that is a copy of the given rectangle, mapped into the coordinate ...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
virtual QVariant option(ImageOption option) const
Returns the value assigned to option as a QVariant.
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
ImageOption
This enum describes the different options supported by QImageIOHandler.
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
static QByteArray fromRawData(const char *, int size)
Constructs a QByteArray that uses the first size bytes of the data array.
qint64 peek(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, without side effects (i.
Definition: qiodevice.cpp:1563
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
bool load(QIODevice *device)
QSize toSize() const
Returns the variant as a QSize if the variant has type() Size ; otherwise returns an invalid QSize...
Definition: qvariant.cpp:2432
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
The QSvgRenderer class is used to draw the contents of SVG files onto paint devices.
Definition: qsvgrenderer.h:64
QRect toRect() const
Returns the variant as a QRect if the variant has type() Rect ; otherwise returns an invalid QRect...
Definition: qvariant.cpp:2416
void setDevice(QIODevice *device)
Sets the current device to device.
Definition: qxmlstream.cpp:489
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
void render(QPainter *p)
Renders the current document, or the current frame of an animated document, using the given painter...
bool load(const QString &filename)
Loads the SVG file specified by filename, returning true if the content was successfully parsed; othe...
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool isValid() const
Returns true if both the width and height is equal to or greater than 0; otherwise returns false...
Definition: qsize.h:123
Definition: qnamespace.h:54
QSvgIOHandler * q
QIODevice * device() const
Returns the device currently assigned to the QImageIOHandler.
virtual void setOption(ImageOption option, const QVariant &value)
Sets the option option with the value value.
QByteArray readAll()
Reads all available data from the device, and returns it as a QByteArray.
Definition: qiodevice.cpp:1025
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
QSvgIOHandlerPrivate * d
Definition: qsvgiohandler.h:71
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QTransform & scale(qreal sx, qreal sy)
Scales the coordinate system by sx horizontally and sy vertically, and returns a reference to the mat...
Definition: qtransform.cpp:485
The QXmlStreamReader class provides a fast parser for reading well-formed XML via a simple streaming ...
Definition: qxmlstream.h:290
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
QRgb rgba() const
Returns the RGB value of the color, including its alpha.
Definition: qcolor.cpp:1019
bool isEmpty() const
Returns true if either of the width and height is less than or equal to 0; otherwise returns false...
Definition: qsize.h:120
bool isValid() const
Returns true if the rectangle is valid, otherwise returns false.
Definition: qrect.h:237
T value() const
Returns the stored value converted to the template type T.
Definition: qvariant.h:332
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
virtual QByteArray name() const
Use format() instead.
bool end()
Ends painting.
Definition: qpainter.cpp:1929
virtual bool canRead() const
Returns true if an image can be read from the device (i.
QBool contains(char c) const
Returns true if the byte array contains the character ch; otherwise returns false.
Definition: qbytearray.h:525
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
virtual bool read(QImage *image)
Read an image from the device, and stores it in image.