1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qsgpainteditem.h"
43 #include <private/qsgpainteditem_p.h>
44 #include <private/qsgpainternode_p.h>
46 #include <private/qsgcontext_p.h>
47 #include <private/qsgadaptationlayer_p.h>
53 \brief The QSGPaintedItem class provides a way to use the QPainter API in the
56 The QSGPaintedItem makes it possible to use the QPainter API with the QML Scene Graph.
57 It sets up a textured rectangle in the Scene Graph and uses a QPainter to paint
58 onto the texture. The render target can be either a QImage or a QGLFramebufferObject.
59 When the render target is a QImage, QPainter first renders into the image then
60 the content is uploaded to the texture.
61 When a QGLFramebufferObject is used, QPainter paints directly onto the texture.
62 Call update() to trigger a repaint.
64 Set the \l smooth property to true to enable QPainter to do anti-aliased rendering.
66 QSGPaintedItem is meant to make it easier to port old code that is using the
67 QPainter API to the QML Scene Graph API and it should be used only for that purpose.
69 To write your own painted item, you first create a subclass of QSGPaintedItem, and then
70 start by implementing its only pure virtual public function: paint(), which implements
71 the actual painting. To get the size of the area painted by the item, use
72 QSGItem::width() and QSGItem::height().
76 \enum QSGPaintedItem::RenderTarget
78 This enum describes QSGPaintedItem's render targets. The render target is the
79 surface QPainter paints onto before the item is rendered on screen.
81 \value Image The default; QPainter paints into a QImage using the raster paint engine.
82 The image's content needs to be uploaded to graphics memory afterward, this operation
83 can potentially be slow if the item is large. This render target allows high quality
84 anti-aliasing and fast item resizing.
86 \value FramebufferObject QPainter paints into a QGLFramebufferObject using the GL
87 paint engine. Painting can be faster as no texture upload is required, but anti-aliasing
88 quality is not as good as if using an image. This render target allows faster rendering
89 in some cases, but you should avoid using it if the item is resized often.
97 QSGPaintedItemPrivate::QSGPaintedItemPrivate()
99 , fillColor(Qt::transparent)
100 , renderTarget(QSGPaintedItem::Image)
101 , geometryDirty(false)
102 , contentsDirty(false)
103 , opaquePainting(false)
108 Constructs a QSGPaintedItem with the given \a parent item.
110 QSGPaintedItem::QSGPaintedItem(QSGItem *parent)
111 : QSGItem(*(new QSGPaintedItemPrivate), parent)
113 setFlag(ItemHasContents);
119 QSGPaintedItem::QSGPaintedItem(QSGPaintedItemPrivate &dd, QSGItem *parent)
120 : QSGItem(dd, parent)
122 setFlag(ItemHasContents);
126 Destroys the QSGPaintedItem.
128 QSGPaintedItem::~QSGPaintedItem()
133 Schedules a redraw of the area covered by \a rect in this item. You can call this function
134 whenever your item needs to be redrawn, such as if it changes appearance or size.
136 This function does not cause an immediate paint; instead it schedules a paint request that
137 is processed by the QML Scene Graph when the next frame is rendered. The item will only be
138 redrawn if it is visible.
140 Note that calling this function will trigger a repaint of the whole scene.
144 void QSGPaintedItem::update(const QRect &rect)
147 d->contentsDirty = true;
148 if (rect.isNull() && !d->dirtyRect.isNull())
149 d->dirtyRect = boundingRect().toAlignedRect();
151 d->dirtyRect |= (boundingRect() & rect).toAlignedRect();
156 Returns true if this item is opaque; otherwise, false is returned.
158 By default, painted items are not opaque.
160 \sa setOpaquePainting()
162 bool QSGPaintedItem::opaquePainting() const
164 Q_D(const QSGPaintedItem);
165 return d->opaquePainting;
169 If \a opaque is true, the item is opaque; otherwise, it is considered as translucent.
171 Opaque items are not blended with the rest of the scene, you should set this to true
172 if the content of the item is opaque to speed up rendering.
174 By default, painted items are not opaque.
178 void QSGPaintedItem::setOpaquePainting(bool opaque)
182 if (d->opaquePainting == opaque)
185 d->opaquePainting = opaque;
189 QSize QSGPaintedItem::contentsSize() const
195 void QSGPaintedItem::setContentsSize(const QSize &)
200 void QSGPaintedItem::resetContentsSize()
205 qreal QSGPaintedItem::contentsScale() const
211 void QSGPaintedItem::setContentsScale(qreal)
216 int QSGPaintedItem::pixelCacheSize() const
222 void QSGPaintedItem::setPixelCacheSize(int)
227 bool QSGPaintedItem::smoothCache() const
233 void QSGPaintedItem::setSmoothCache(bool)
239 \property QSGPaintedItem::fillColor
240 \brief The item's background fill color.
242 By default, the fill color is set to Qt::transparent.
244 QColor QSGPaintedItem::fillColor() const
246 Q_D(const QSGPaintedItem);
250 void QSGPaintedItem::setFillColor(const QColor &c)
254 if (d->fillColor == c)
260 emit fillColorChanged();
264 \property QSGPaintedItem::renderTarget
265 \brief The item's render target.
267 This property defines which render target the QPainter renders into, it can be either
268 QSGPaintedItem::Image or QSGPaintedItem::FramebufferObject. Both have certains benefits,
269 typically performance versus quality. Using a framebuffer object avoids a costly upload
270 of the image contents to the texture in graphics memory, while using an image enables
271 high quality anti-aliasing.
273 \warning Resizing a framebuffer object is a costly operation, avoid using
274 the QSGPaintedItem::FramebufferObject render target if the item gets resized often.
276 By default, the render target is QSGPaintedItem::Image.
278 QSGPaintedItem::RenderTarget QSGPaintedItem::renderTarget() const
280 Q_D(const QSGPaintedItem);
281 return d->renderTarget;
284 void QSGPaintedItem::setRenderTarget(RenderTarget target)
288 if (d->renderTarget == target)
291 d->renderTarget = target;
294 emit renderTargetChanged();
298 \fn virtual void QSGPaintedItem::paint(QPainter *painter) = 0
300 This function, which is usually called by the QML Scene Graph, paints the
301 contents of an item in local coordinates.
303 The function is called after the item has been filled with the fillColor.
305 Reimplement this function in a QSGPaintedItem subclass to provide the
306 item's painting implementation, using \a painter.
310 This function is called after the item's geometry has changed.
312 void QSGPaintedItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
315 d->geometryDirty = true;
316 QSGItem::geometryChanged(newGeometry, oldGeometry);
321 This function is called when the Scene Graph node associated to the item needs to
324 QSGNode *QSGPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
329 if (width() <= 0 || height() <= 0) {
334 QSGPainterNode *node = static_cast<QSGPainterNode *>(oldNode);
336 node = new QSGPainterNode(this);
338 node->setPreferredRenderTarget(d->renderTarget);
339 node->setSize(QSize(d->width, d->height));
340 node->setSmoothPainting(d->smooth);
341 node->setLinearFiltering(d->smooth);
342 node->setOpaquePainting(d->opaquePainting);
343 node->setFillColor(d->fillColor);
344 node->setDirty(d->contentsDirty || d->geometryDirty, d->dirtyRect);
347 d->contentsDirty = false;
348 d->geometryDirty = false;
349 d->dirtyRect = QRect();