aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2011-05-05 15:41:36 +0200
committerYoann Lopes <yoann.lopes@nokia.com>2011-05-05 15:41:36 +0200
commit8883e0500eb7dee2439fce884acfd2177e07811a (patch)
treec7b28c70abec013e0b9a4c4bf373b318d348eeec
parent9815adf88c50af4f5249cfa631d9c565f87428c3 (diff)
Implemented contentsSize and contentsScale for QSGPaintedItem.
-rw-r--r--src/declarative/items/qsgpainteditem.cpp99
-rw-r--r--src/declarative/items/qsgpainteditem.h3
-rw-r--r--src/declarative/items/qsgpainteditem_p.h2
-rw-r--r--src/declarative/scenegraph/util/qsgpainternode.cpp25
-rw-r--r--src/declarative/scenegraph/util/qsgpainternode_p.h4
5 files changed, 114 insertions, 19 deletions
diff --git a/src/declarative/items/qsgpainteditem.cpp b/src/declarative/items/qsgpainteditem.cpp
index e9f4f73448..b93406a3d7 100644
--- a/src/declarative/items/qsgpainteditem.cpp
+++ b/src/declarative/items/qsgpainteditem.cpp
@@ -45,6 +45,7 @@
#include <private/qsgcontext_p.h>
#include <private/qsgadaptationlayer_p.h>
+#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -61,7 +62,7 @@ QT_BEGIN_NAMESPACE
When a QGLFramebufferObject is used, QPainter paints directly onto the texture.
Call update() to trigger a repaint.
- Set the \l smooth property to true to enable QPainter to do anti-aliased rendering.
+ To enable QPainter to do anti-aliased rendering, use setAntialiasing().
QSGPaintedItem is meant to make it easier to port old code that is using the
QPainter API to the QML Scene Graph API and it should be used only for that purpose.
@@ -69,7 +70,7 @@ QT_BEGIN_NAMESPACE
To write your own painted item, you first create a subclass of QSGPaintedItem, and then
start by implementing its only pure virtual public function: paint(), which implements
the actual painting. To get the size of the area painted by the item, use
- QSGItem::width() and QSGItem::height().
+ contentsBoundingRect().
*/
/*!
@@ -96,6 +97,7 @@ QT_BEGIN_NAMESPACE
*/
QSGPaintedItemPrivate::QSGPaintedItemPrivate()
: QSGItemPrivate()
+ , contentsScale(1.0)
, fillColor(Qt::transparent)
, renderTarget(QSGPaintedItem::Image)
, geometryDirty(false)
@@ -145,10 +147,16 @@ void QSGPaintedItem::update(const QRect &rect)
{
Q_D(QSGPaintedItem);
d->contentsDirty = true;
- if (rect.isNull() && !d->dirtyRect.isNull())
- d->dirtyRect = boundingRect().toAlignedRect();
+
+ QRect srect(qCeil(rect.x()*d->contentsScale),
+ qCeil(rect.y()*d->contentsScale),
+ qCeil(rect.width()*d->contentsScale),
+ qCeil(rect.height()*d->contentsScale));
+
+ if (srect.isNull() && !d->dirtyRect.isNull())
+ d->dirtyRect = contentsBoundingRect().toAlignedRect();
else
- d->dirtyRect |= (boundingRect() & rect).toAlignedRect();
+ d->dirtyRect |= (contentsBoundingRect() & srect).toAlignedRect();
QSGItem::update();
}
@@ -217,31 +225,89 @@ void QSGPaintedItem::setAntialiasing(bool enable)
update();
}
+/*!
+ This function returns the outer bounds of the item as a rectangle; all painting must be
+ restricted to inside an item's bounding rect.
+
+ If the contents size has not been set it reflects the size of the item; otherwise
+ it reflects the contents size scaled by the contents scale.
+
+ Use this function to know the area painted by the item.
+
+ \sa QSGItem::width(), QSGItem::height(), contentsSize(), contentsScale()
+*/
+QRectF QSGPaintedItem::contentsBoundingRect() const
+{
+ Q_D(const QSGPaintedItem);
+
+ qreal w = d->width;
+ QSizeF sz = d->contentsSize * d->contentsScale;
+ if (w < sz.width())
+ w = sz.width();
+ qreal h = d->height;
+ if (h < sz.height())
+ h = sz.height();
+
+ return QRectF(0, 0, w, h);
+}
+
+/*!
+ \property QSGPaintedItem::contentsSize
+ \brief The size of the contents
+
+ The contents size is the size of the item in regards to how it is painted
+ using the paint() function. This is distinct from the size of the
+ item in regards to height() and width().
+*/
QSize QSGPaintedItem::contentsSize() const
{
- // XXX todo
- return QSize();
+ Q_D(const QSGPaintedItem);
+ return d->contentsSize;
}
-void QSGPaintedItem::setContentsSize(const QSize &)
+void QSGPaintedItem::setContentsSize(const QSize &size)
{
- // XXX todo
+ Q_D(QSGPaintedItem);
+
+ if (d->contentsSize == size)
+ return;
+
+ d->contentsSize = size;
+ update();
}
+/*!
+ This convenience function is equivalent to calling setContentsSize(QSize()).
+*/
void QSGPaintedItem::resetContentsSize()
{
- // XXX todo
+ setContentsSize(QSize());
}
+/*!
+ \property QSGPaintedItem::contentsScale
+ \brief The scale of the contents
+
+ All painting happening in paint() is scaled by the contents scale. This is distinct
+ from the scale of the item in regards to scale().
+
+ The default value is 1.
+*/
qreal QSGPaintedItem::contentsScale() const
{
- // XXX todo
- return 1;
+ Q_D(const QSGPaintedItem);
+ return d->contentsScale;
}
-void QSGPaintedItem::setContentsScale(qreal)
+void QSGPaintedItem::setContentsScale(qreal scale)
{
- // XXX todo
+ Q_D(QSGPaintedItem);
+
+ if (d->contentsScale == scale)
+ return;
+
+ d->contentsScale = scale;
+ update();
}
/*!
@@ -344,12 +410,15 @@ QSGNode *QSGPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
if (!node)
node = new QSGPainterNode(this);
+ QRectF br = contentsBoundingRect();
+
node->setPreferredRenderTarget(d->renderTarget);
- node->setSize(QSize(d->width, d->height));
+ node->setSize(QSize(qRound(br.width()), qRound(br.height())));
node->setSmoothPainting(d->antialiasing);
node->setLinearFiltering(d->smooth);
node->setOpaquePainting(d->opaquePainting);
node->setFillColor(d->fillColor);
+ node->setContentsScale(d->contentsScale);
node->setDirty(d->contentsDirty || d->geometryDirty, d->dirtyRect);
node->update();
diff --git a/src/declarative/items/qsgpainteditem.h b/src/declarative/items/qsgpainteditem.h
index 8d4b466922..2c0884d146 100644
--- a/src/declarative/items/qsgpainteditem.h
+++ b/src/declarative/items/qsgpainteditem.h
@@ -1,4 +1,3 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -76,6 +75,8 @@ public:
bool antialiasing() const;
void setAntialiasing(bool enable);
+ QRectF contentsBoundingRect() const;
+
QSize contentsSize() const;
void setContentsSize(const QSize &);
void resetContentsSize();
diff --git a/src/declarative/items/qsgpainteditem_p.h b/src/declarative/items/qsgpainteditem_p.h
index ee76319a92..ac3e09e73b 100644
--- a/src/declarative/items/qsgpainteditem_p.h
+++ b/src/declarative/items/qsgpainteditem_p.h
@@ -52,6 +52,8 @@ class QSGPaintedItemPrivate : public QSGItemPrivate
public:
QSGPaintedItemPrivate();
+ QSize contentsSize;
+ qreal contentsScale;
QColor fillColor;
QSGPaintedItem::RenderTarget renderTarget;
diff --git a/src/declarative/scenegraph/util/qsgpainternode.cpp b/src/declarative/scenegraph/util/qsgpainternode.cpp
index 569f1be19e..1f38c6a932 100644
--- a/src/declarative/scenegraph/util/qsgpainternode.cpp
+++ b/src/declarative/scenegraph/util/qsgpainternode.cpp
@@ -45,6 +45,7 @@
#include <private/qsgcontext_p.h>
#include <qglframebufferobject.h>
#include <qglfunctions.h>
+#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -111,6 +112,7 @@ QSGPainterNode::QSGPainterNode(QSGPaintedItem *item)
, m_extensionsChecked(false)
, m_multisamplingSupported(false)
, m_fillColor(Qt::transparent)
+ , m_contentsScale(1.0)
, m_dirtyGeometry(false)
, m_dirtyRenderTarget(false)
, m_dirtyTexture(false)
@@ -148,12 +150,20 @@ void QSGPainterNode::preprocess()
| QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
}
+ painter.scale(m_contentsScale, m_contentsScale);
+
+ QRect sclip(qFloor(dirtyRect.x()/m_contentsScale),
+ qFloor(dirtyRect.y()/m_contentsScale),
+ qCeil(dirtyRect.width()/m_contentsScale+dirtyRect.x()/m_contentsScale-qFloor(dirtyRect.x()/m_contentsScale)),
+ qCeil(dirtyRect.height()/m_contentsScale+dirtyRect.y()/m_contentsScale-qFloor(dirtyRect.y()/m_contentsScale)));
+
+ if (!m_dirtyRect.isNull())
+ painter.setClipRect(sclip);
+
painter.setCompositionMode(QPainter::CompositionMode_Source);
- painter.fillRect(dirtyRect, m_fillColor);
+ painter.fillRect(sclip, m_fillColor);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
- if (!m_dirtyRect.isNull())
- painter.setClipRect(dirtyRect);
m_item->paint(&painter);
painter.end();
@@ -369,5 +379,14 @@ void QSGPainterNode::setFillColor(const QColor &c)
markDirty(DirtyMaterial);
}
+void QSGPainterNode::setContentsScale(qreal s)
+{
+ if (s == m_contentsScale)
+ return;
+
+ m_contentsScale = s;
+ markDirty(DirtyMaterial);
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/scenegraph/util/qsgpainternode_p.h b/src/declarative/scenegraph/util/qsgpainternode_p.h
index ef1f3f1dde..a5f42ca27e 100644
--- a/src/declarative/scenegraph/util/qsgpainternode_p.h
+++ b/src/declarative/scenegraph/util/qsgpainternode_p.h
@@ -93,6 +93,9 @@ public:
void setFillColor(const QColor &c);
QColor fillColor() const { return m_fillColor; }
+ void setContentsScale(qreal s);
+ qreal contentsScale() const { return m_contentsScale; }
+
void update();
void preprocess();
@@ -127,6 +130,7 @@ private:
bool m_extensionsChecked;
bool m_multisamplingSupported;
QColor m_fillColor;
+ qreal m_contentsScale;
bool m_dirtyGeometry;
bool m_dirtyRenderTarget;