source: trunk/src/svg/qgraphicssvgitem.cpp@ 769

Last change on this file since 769 was 769, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

File size: 11.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtSvg module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41#include "qgraphicssvgitem.h"
42
43#ifndef QT_NO_GRAPHICSSVGITEM
44
45#include "qpainter.h"
46#include "qstyleoption.h"
47#include "qsvgrenderer.h"
48#include "qdebug.h"
49
50#include "private/qobject_p.h"
51#include "private/qgraphicsitem_p.h"
52
53QT_BEGIN_NAMESPACE
54
55class QGraphicsSvgItemPrivate : public QGraphicsItemPrivate
56{
57public:
58 Q_DECLARE_PUBLIC(QGraphicsSvgItem)
59
60 QGraphicsSvgItemPrivate()
61 : renderer(0), shared(false)
62 {
63 }
64
65 void init(QGraphicsItem *parent)
66 {
67 Q_Q(QGraphicsSvgItem);
68 q->setParentItem(parent);
69 renderer = new QSvgRenderer(q);
70 QObject::connect(renderer, SIGNAL(repaintNeeded()),
71 q, SLOT(_q_repaintItem()));
72 q->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
73 q->setMaximumCacheSize(QSize(1024, 768));
74 }
75
76 void _q_repaintItem()
77 {
78 q_func()->update();
79 }
80
81 inline void updateDefaultSize()
82 {
83 QRectF bounds;
84 if (elemId.isEmpty()) {
85 bounds = QRectF(QPointF(0, 0), renderer->defaultSize());
86 } else {
87 bounds = renderer->boundsOnElement(elemId);
88 }
89 if (boundingRect.size() != bounds.size()) {
90 q_func()->prepareGeometryChange();
91 boundingRect.setSize(bounds.size());
92 }
93 }
94
95 QSvgRenderer *renderer;
96 QRectF boundingRect;
97 bool shared;
98 QString elemId;
99};
100
101/*!
102 \class QGraphicsSvgItem
103 \ingroup graphicsview-api
104 \brief The QGraphicsSvgItem class is a QGraphicsItem that can be used to render
105 the contents of SVG files.
106
107 \since 4.2
108
109 QGraphicsSvgItem provides a way of rendering SVG files onto QGraphicsView.
110 QGraphicsSvgItem can be created by passing the SVG file to be rendered to
111 its constructor or by explicit setting a shared QSvgRenderer on it.
112
113 Note that setting QSvgRenderer on a QGraphicsSvgItem doesn't make the item take
114 ownership of the renderer, therefore if using setSharedRenderer() method one has
115 to make sure that the lifetime of the QSvgRenderer object will be at least as long
116 as that of the QGraphicsSvgItem.
117
118 QGraphicsSvgItem provides a way of rendering only parts of the SVG files via
119 the setElementId. If setElementId() method is called, only the SVG element
120 (and its children) with the passed id will be renderer. This provides a convenient
121 way of selectively rendering large SVG files that contain a number of discrete
122 elements. For example the following code renders only jokers from a SVG file
123 containing a whole card deck:
124
125 \snippet doc/src/snippets/code/src_svg_qgraphicssvgitem.cpp 0
126
127 Size of the item can be set via the setSize() method or via
128 direct manipulation of the items transformation matrix.
129
130 By default the SVG rendering is cached using QGraphicsItem::DeviceCoordinateCache
131 mode to speedup the display of items. Caching can be disabled by passing
132 QGraphicsItem::NoCache to the QGraphicsItem::setCacheMode() method.
133
134 \sa QSvgWidget, {QtSvg Module}, QGraphicsItem, QGraphicsView
135*/
136
137/*!
138 Constructs a new SVG item with the given \a parent.
139*/
140QGraphicsSvgItem::QGraphicsSvgItem(QGraphicsItem *parent)
141 : QGraphicsObject(*new QGraphicsSvgItemPrivate(), 0, 0)
142{
143 Q_D(QGraphicsSvgItem);
144 d->init(parent);
145}
146
147/*!
148 Constructs a new item with the given \a parent and loads the contents of the
149 SVG file with the specified \a fileName.
150*/
151QGraphicsSvgItem::QGraphicsSvgItem(const QString &fileName, QGraphicsItem *parent)
152 : QGraphicsObject(*new QGraphicsSvgItemPrivate(), 0, 0)
153{
154 Q_D(QGraphicsSvgItem);
155 d->init(parent);
156 d->renderer->load(fileName);
157 d->updateDefaultSize();
158}
159
160/*!
161 Returns the currently use QSvgRenderer.
162*/
163QSvgRenderer *QGraphicsSvgItem::renderer() const
164{
165 return d_func()->renderer;
166}
167
168
169/*!
170 Returns the bounding rectangle of this item.
171*/
172QRectF QGraphicsSvgItem::boundingRect() const
173{
174 Q_D(const QGraphicsSvgItem);
175 return d->boundingRect;
176}
177
178/*!
179 \internal
180
181 Highlights \a item as selected.
182
183 NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in qgraphicsitem.cpp!
184*/
185static void qt_graphicsItem_highlightSelected(
186 QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
187{
188 const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
189 if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
190 return;
191
192 const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
193 if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
194 return;
195
196 qreal itemPenWidth;
197 switch (item->type()) {
198 case QGraphicsEllipseItem::Type:
199 itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
200 break;
201 case QGraphicsPathItem::Type:
202 itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
203 break;
204 case QGraphicsPolygonItem::Type:
205 itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
206 break;
207 case QGraphicsRectItem::Type:
208 itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
209 break;
210 case QGraphicsSimpleTextItem::Type:
211 itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
212 break;
213 case QGraphicsLineItem::Type:
214 itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
215 break;
216 default:
217 itemPenWidth = 1.0;
218 }
219 const qreal pad = itemPenWidth / 2;
220
221 const qreal penWidth = 0; // cosmetic pen
222
223 const QColor fgcolor = option->palette.windowText().color();
224 const QColor bgcolor( // ensure good contrast against fgcolor
225 fgcolor.red() > 127 ? 0 : 255,
226 fgcolor.green() > 127 ? 0 : 255,
227 fgcolor.blue() > 127 ? 0 : 255);
228
229 painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
230 painter->setBrush(Qt::NoBrush);
231 painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
232
233 painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
234 painter->setBrush(Qt::NoBrush);
235 painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
236}
237
238/*!
239 \reimp
240*/
241void QGraphicsSvgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
242 QWidget *widget)
243{
244// Q_UNUSED(option);
245 Q_UNUSED(widget);
246
247 Q_D(QGraphicsSvgItem);
248 if (!d->renderer->isValid())
249 return;
250
251 if (d->elemId.isEmpty())
252 d->renderer->render(painter, d->boundingRect);
253 else
254 d->renderer->render(painter, d->elemId, d->boundingRect);
255
256 if (option->state & QStyle::State_Selected)
257 qt_graphicsItem_highlightSelected(this, painter, option);
258}
259
260/*!
261 \reimp
262*/
263int QGraphicsSvgItem::type() const
264{
265 return Type;
266}
267
268/*!
269 \property QGraphicsSvgItem::maximumCacheSize
270 \since 4.6
271
272 This property holds the maximum size of the device coordinate cache
273 for this item.
274 */
275
276/*!
277 Sets the maximum device coordinate cache size of the item to \a size.
278 If the item is cached using QGraphicsItem::DeviceCoordinateCache mode,
279 caching is bypassed if the extension of the item in device coordinates
280 is larger than \a size.
281
282 The cache corresponds to the QPixmap which is used to cache the
283 results of the rendering.
284 Use QPixmapCache::setCacheLimit() to set limitations on the whole cache
285 and use setMaximumCacheSize() when setting cache size for individual
286 items.
287
288 \sa QGraphicsItem::cacheMode()
289*/
290void QGraphicsSvgItem::setMaximumCacheSize(const QSize &size)
291{
292 QGraphicsItem::d_ptr->setExtra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize, size);
293 update();
294}
295
296/*!
297 Returns the current maximum size of the device coordinate cache for this item.
298 If the item is cached using QGraphicsItem::DeviceCoordinateCache mode,
299 caching is bypassed if the extension of the item in device coordinates
300 is larger than the maximum size.
301
302 The default maximum cache size is 1024x768.
303 QPixmapCache::cacheLimit() gives the
304 cumulative bounds of the whole cache, whereas maximumCacheSize() refers
305 to a maximum cache size for this particular item.
306
307 \sa QGraphicsItem::cacheMode()
308*/
309QSize QGraphicsSvgItem::maximumCacheSize() const
310{
311 return QGraphicsItem::d_ptr->extra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize).toSize();
312}
313
314/*!
315 \property QGraphicsSvgItem::elementId
316 \since 4.6
317
318 This property holds the element's XML ID.
319 */
320
321/*!
322 Sets the XML ID of the element to \a id.
323*/
324void QGraphicsSvgItem::setElementId(const QString &id)
325{
326 Q_D(QGraphicsSvgItem);
327 d->elemId = id;
328 d->updateDefaultSize();
329 update();
330}
331
332/*!
333 Returns the XML ID the element that is currently
334 being rendered. Returns an empty string if the whole
335 file is being rendered.
336*/
337QString QGraphicsSvgItem::elementId() const
338{
339 Q_D(const QGraphicsSvgItem);
340 return d->elemId;
341}
342
343/*!
344 Sets \a renderer to be a shared QSvgRenderer on the item. By
345 using this method one can share the same QSvgRenderer on a number
346 of items. This means that the SVG file will be parsed only once.
347 QSvgRenderer passed to this method has to exist for as long as
348 this item is used.
349*/
350void QGraphicsSvgItem::setSharedRenderer(QSvgRenderer *renderer)
351{
352 Q_D(QGraphicsSvgItem);
353 if (!d->shared)
354 delete d->renderer;
355
356 d->renderer = renderer;
357 d->shared = true;
358
359 d->updateDefaultSize();
360
361 update();
362}
363
364/*!
365 \obsolete
366
367 Use QGraphicsItem::setCacheMode() instead. Passing true to this function is equivalent
368 to QGraphicsItem::setCacheMode(QGraphicsItem::DeviceCoordinateCache).
369*/
370void QGraphicsSvgItem::setCachingEnabled(bool caching)
371{
372 setCacheMode(caching ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache);
373}
374
375/*!
376 \obsolete
377
378 Use QGraphicsItem::cacheMode() instead.
379*/
380bool QGraphicsSvgItem::isCachingEnabled() const
381{
382 return cacheMode() != QGraphicsItem::NoCache;
383}
384
385QT_END_NAMESPACE
386
387#include "moc_qgraphicssvgitem.cpp"
388
389#endif // QT_NO_GRAPHICSSVGITEM
Note: See TracBrowser for help on using the repository browser.