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

Last change on this file since 452 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 11.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtSvg module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
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 QObjectPrivate
56{
57public:
58 Q_DECLARE_PUBLIC(QGraphicsSvgItem)
59
60 QGraphicsSvgItemPrivate()
61 : renderer(0), shared(false)
62 {
63 }
64
65 void init()
66 {
67 Q_Q(QGraphicsSvgItem);
68 renderer = new QSvgRenderer(q);
69 QObject::connect(renderer, SIGNAL(repaintNeeded()),
70 q, SLOT(_q_repaintItem()));
71 q->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
72 q->setMaximumCacheSize(QSize(1024, 768));
73 }
74
75 void _q_repaintItem()
76 {
77 q_func()->update();
78 }
79
80 inline void updateDefaultSize()
81 {
82 QRectF bounds;
83 if (elemId.isEmpty()) {
84 bounds = QRectF(QPointF(0, 0), renderer->defaultSize());
85 } else {
86 bounds = renderer->boundsOnElement(elemId);
87 }
88 if (boundingRect.size() != bounds.size()) {
89 q_func()->prepareGeometryChange();
90 boundingRect.setSize(bounds.size());
91 }
92 }
93
94 QSvgRenderer *renderer;
95 QRectF boundingRect;
96 bool shared;
97 QString elemId;
98};
99
100/*!
101 \class QGraphicsSvgItem
102 \ingroup multimedia
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 : QObject(*new QGraphicsSvgItemPrivate(), 0), QGraphicsItem(parent)
142{
143 Q_D(QGraphicsSvgItem);
144 d->init();
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 : QObject(*new QGraphicsSvgItemPrivate(), 0), QGraphicsItem(parent)
153{
154 Q_D(QGraphicsSvgItem);
155 d->init();
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 (qFuzzyCompare(qMax(murect.width(), murect.height()) + 1, 1))
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/*!
270 Sets the maximum device coordinate cache size of the item to \a size.
271 If the item is cached using QGraphicsItem::DeviceCoordinateCache mode,
272 caching is bypassed if the extension of the item in device coordinates
273 is larger than \a size.
274
275 The cache corresponds to the QPixmap which is used to cache the
276 results of the rendering.
277 Use QPixmapCache::setCacheLimit() to set limitations on the whole cache
278 and use setMaximumCacheSize() when setting cache size for individual
279 items.
280
281 \sa QGraphicsItem::cacheMode()
282*/
283void QGraphicsSvgItem::setMaximumCacheSize(const QSize &size)
284{
285 QGraphicsItem::d_ptr->setExtra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize, size);
286 update();
287}
288
289/*!
290 Returns the current maximum size of the device coordinate cache for this item.
291 If the item is cached using QGraphicsItem::DeviceCoordinateCache mode,
292 caching is bypassed if the extension of the item in device coordinates
293 is larger than the maximum size.
294
295 The default maximum cache size is 1024x768.
296 QPixmapCache::cacheLimit() gives the
297 cumulative bounds of the whole cache, whereas maximumCacheSize() refers
298 to a maximum cache size for this particular item.
299
300 \sa QGraphicsItem::cacheMode()
301*/
302QSize QGraphicsSvgItem::maximumCacheSize() const
303{
304 return QGraphicsItem::d_ptr->extra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize).toSize();
305}
306
307/*!
308 Sets the XML ID of the element that this item should render to \a
309 id.
310*/
311void QGraphicsSvgItem::setElementId(const QString &id)
312{
313 Q_D(QGraphicsSvgItem);
314 d->elemId = id;
315 d->updateDefaultSize();
316 update();
317}
318
319/*!
320 Returns the XML ID the element that is currently
321 being renderer. Returns an empty string if the whole
322 file is being rendered.
323*/
324QString QGraphicsSvgItem::elementId() const
325{
326 Q_D(const QGraphicsSvgItem);
327 return d->elemId;
328}
329
330/*!
331 Sets \a renderer to be a shared QSvgRenderer on the item. By
332 using this method one can share the same QSvgRenderer on a number
333 of items. This means that the SVG file will be parsed only once.
334 QSvgRenderer passed to this method has to exist for as long as
335 this item is used.
336*/
337void QGraphicsSvgItem::setSharedRenderer(QSvgRenderer *renderer)
338{
339 Q_D(QGraphicsSvgItem);
340 if (!d->shared)
341 delete d->renderer;
342
343 d->renderer = renderer;
344 d->shared = true;
345
346 d->updateDefaultSize();
347
348 update();
349}
350
351/*!
352 \obsolete
353
354 Use QGraphicsItem::setCacheMode() instead. Passing true to this function is equivalent
355 to QGraphicsItem::setCacheMode(QGraphicsItem::DeviceCoordinateCache).
356*/
357void QGraphicsSvgItem::setCachingEnabled(bool caching)
358{
359 setCacheMode(caching ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache);
360}
361
362/*!
363 \obsolete
364
365 Use QGraphicsItem::cacheMode() instead.
366*/
367bool QGraphicsSvgItem::isCachingEnabled() const
368{
369 return cacheMode() != QGraphicsItem::NoCache;
370}
371
372QT_END_NAMESPACE
373
374#include "moc_qgraphicssvgitem.cpp"
375
376#endif // QT_NO_GRAPHICSSVGITEM
Note: See TracBrowser for help on using the repository browser.