summaryrefslogtreecommitdiffstats
path: root/src/gui/graphicsview
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r--src/gui/graphicsview/qgraphicseffect.cpp31
-rw-r--r--src/gui/graphicsview/qgraphicseffect.h8
-rw-r--r--src/gui/graphicsview/qgraphicseffect_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp29
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h1
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp37
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h6
7 files changed, 92 insertions, 26 deletions
diff --git a/src/gui/graphicsview/qgraphicseffect.cpp b/src/gui/graphicsview/qgraphicseffect.cpp
index ed529db..1281847 100644
--- a/src/gui/graphicsview/qgraphicseffect.cpp
+++ b/src/gui/graphicsview/qgraphicseffect.cpp
@@ -124,6 +124,8 @@ void QGraphicsEffectSource::draw(QPainter *painter)
bool QGraphicsEffectSource::drawIntoPixmap(QPixmap *pixmap, const QPoint &offset)
{ return d_func()->drawIntoPixmap(pixmap, offset); }
+QPixmap QGraphicsEffectSource::pixmap(bool deviceCoordinates, QPoint *offset) const
+{ return d_func()->pixmap(deviceCoordinates, offset); }
QGraphicsEffect::QGraphicsEffect()
: QObject(*new QGraphicsEffectPrivate, 0)
@@ -151,6 +153,25 @@ QRectF QGraphicsEffect::boundingRect() const
return QRectF();
}
+void QGraphicsEffect::setSourcePixmap(const QPixmap &pixmap)
+{
+ Q_D(QGraphicsEffect);
+ d->sourcePixmap = pixmap;
+ d->hasSourcePixmap = !pixmap.isNull();
+}
+
+QPixmap QGraphicsEffect::sourcePixmap() const
+{
+ Q_D(const QGraphicsEffect);
+ return d->sourcePixmap;
+}
+
+bool QGraphicsEffect::hasSourcePixmap() const
+{
+ Q_D(const QGraphicsEffect);
+ return d->hasSourcePixmap;
+}
+
QRectF QGraphicsEffect::boundingRectFor(const QRectF &rect) const
{
return rect;
@@ -398,17 +419,13 @@ QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
void QGraphicsBlurEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
{
Q_D(QGraphicsBlurEffect);
- const QRectF sourceRect = source->boundingRect(/*deviceCoordinates=*/true);
- const QRect effectRect = d->filter->boundingRectFor(sourceRect).toRect().adjusted(-1, -1, 1, 1);
-
- QPixmap pixmap(effectRect.size());
- if (!source->drawIntoPixmap(&pixmap, effectRect.topLeft()))
- return;
+ QPoint offset;
+ const QPixmap pixmap = source->pixmap(true, &offset);
// Draw the pixmap with the filter using an untransformed painter.
QTransform restoreTransform = painter->worldTransform();
painter->setWorldTransform(QTransform());
- d->filter->draw(painter, sourceRect.topLeft(), pixmap, pixmap.rect());
+ d->filter->draw(painter, offset, pixmap, pixmap.rect());
painter->setWorldTransform(restoreTransform);
}
diff --git a/src/gui/graphicsview/qgraphicseffect.h b/src/gui/graphicsview/qgraphicseffect.h
index c13461e..77eebd6 100644
--- a/src/gui/graphicsview/qgraphicseffect.h
+++ b/src/gui/graphicsview/qgraphicseffect.h
@@ -65,6 +65,7 @@ QT_MODULE(Gui)
#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
class QGraphicsEffectSourcePrivate;
+class QStyleOption;
class Q_GUI_EXPORT QGraphicsEffectSource : public QObject
{
Q_OBJECT
@@ -75,6 +76,7 @@ public:
const QStyleOption *styleOption() const;
void draw(QPainter *painter);
bool drawIntoPixmap(QPixmap *pixmap, const QPoint &offset = QPoint());
+ QPixmap pixmap(bool deviceCoordinates, QPoint *offset = 0) const;
protected:
QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent = 0);
@@ -97,9 +99,13 @@ public:
virtual ~QGraphicsEffect();
QRectF boundingRect() const;
+ void setSourcePixmap(const QPixmap &pixmap);
+ QPixmap sourcePixmap() const;
+ bool hasSourcePixmap() const;
+ virtual QRectF boundingRectFor(const QRectF &rect) const;
+
protected:
QGraphicsEffect(QGraphicsEffectPrivate &d);
- virtual QRectF boundingRectFor(const QRectF &rect) const;
virtual void draw(QPainter *painter, QGraphicsEffectSource *source) = 0;
private:
diff --git a/src/gui/graphicsview/qgraphicseffect_p.h b/src/gui/graphicsview/qgraphicseffect_p.h
index ce90193..a575d3b 100644
--- a/src/gui/graphicsview/qgraphicseffect_p.h
+++ b/src/gui/graphicsview/qgraphicseffect_p.h
@@ -73,6 +73,7 @@ public:
virtual const QStyleOption *styleOption() const = 0;
virtual void draw(QPainter *p) = 0;
virtual bool drawIntoPixmap(QPixmap *, const QPoint &offset = QPoint()) = 0;
+ virtual QPixmap pixmap(bool deviceCoordinates, QPoint *offset = 0) const = 0;
friend class QGraphicsScenePrivate;
friend class QGraphicsItem;
friend class QGraphicsItemPrivate;
@@ -82,7 +83,7 @@ class QGraphicsEffectPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsEffect)
public:
- QGraphicsEffectPrivate() : source(0) {}
+ QGraphicsEffectPrivate() : source(0), hasSourcePixmap(0) {}
QGraphicsEffectSource *source;
inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource)
{
@@ -93,6 +94,9 @@ public:
source = newSource;
}
QRectF boundingRect;
+ QPixmap sourcePixmap;
+ quint32 hasSourcePixmap : 1;
+ quint32 padding : 31; // feel free to use
};
class QGraphicsGrayscaleEffectPrivate : public QGraphicsEffectPrivate
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index b46abd4..425031f 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -9944,6 +9944,33 @@ void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
info->widget, info->opacity, 0, info->wasDirtySceneTransform, info->drawItem);
}
+QPixmap QGraphicsItemEffectSourcePrivate::pixmap(bool deviceCoordinates, QPoint *offset) const
+{
+ const QRectF sourceRect = boundingRect(deviceCoordinates);
+ const QRect effectRect = item->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
+ if (offset)
+ *offset = sourceRect.toAlignedRect().topLeft();
+
+ const QTransform translateTransform = QTransform::fromTranslate(-effectRect.x(),
+ -effectRect.y());
+ QTransform effectTransform = deviceCoordinates ? translateTransform
+ : info->transformPtr->inverted();
+ if (!deviceCoordinates)
+ effectTransform *= translateTransform;
+ *info->transformPtr *= effectTransform;
+
+ QPixmap pixmap(effectRect.size());
+ pixmap.fill(Qt::transparent);
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
+
+ QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
+ scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion,
+ info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
+ info->drawItem);
+ return pixmap;
+}
+
bool QGraphicsItemEffectSourcePrivate::drawIntoPixmap(QPixmap *pixmap, const QPoint &offset)
{
QPoint effectOffset(offset);
@@ -9969,7 +9996,7 @@ bool QGraphicsItemEffectSourcePrivate::drawIntoPixmap(QPixmap *pixmap, const QPo
pixmapPainter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
scened->draw(item, &pixmapPainter, &viewTransform, info->transformPtr, &exposedRegion,
- info->widget, info->opacity, &effectOffset, info->wasDirtySceneTransform,
+ info->widget, info->opacity, 0, info->wasDirtySceneTransform,
info->drawItem);
return true;
}
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 0823e51..db79e07 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -548,6 +548,7 @@ public:
QRectF boundingRect(bool deviceCoordinates) const;
void draw(QPainter *);
bool drawIntoPixmap(QPixmap *pixmap, const QPoint &offset);
+ QPixmap pixmap(bool deviceCoordinates, QPoint *offset) const;
QGraphicsItem *item;
QGraphicsItemPaintInfo *info;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 31ec1ba..3a899ff 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -4232,7 +4232,7 @@ void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const
void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter,
const QTransform *const viewTransform,
QRegion *exposedRegion, QWidget *widget,
- qreal parentOpacity, QPoint *effectOffset)
+ qreal parentOpacity, const QTransform *const effectTransform)
{
Q_ASSERT(item);
@@ -4285,10 +4285,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
ENSURE_TRANSFORM_PTR
QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toRect()
: transformPtr->mapRect(brect).toRect();
- if (widget) {
- item->d_ptr->paintedViewBoundingRects.insert(widget, effectOffset ?
- viewBoundingRect.translated(*effectOffset) : viewBoundingRect);
- }
+ if (widget)
+ item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
viewBoundingRect.adjust(-1, -1, 1, 1);
drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) : !viewBoundingRect.isEmpty();
if (!drawItem) {
@@ -4306,6 +4304,10 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
ENSURE_TRANSFORM_PTR;
if (item->d_ptr->graphicsEffect) {
+ if (item->type() == 7) {
+ item->d_ptr->graphicsEffect->setSourcePixmap(static_cast<QGraphicsPixmapItem*>(item)
+ ->pixmap());
+ }
ENSURE_TRANSFORM_PTR;
QGraphicsItemPaintInfo info(viewTransform, transformPtr, exposedRegion, widget, &styleOptionTmp,
opacity, wasDirtyParentSceneTransform, drawItem);
@@ -4319,13 +4321,13 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
painter->setWorldTransform(restoreTransform);
} else {
draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
- effectOffset, wasDirtyParentSceneTransform, drawItem);
+ effectTransform, wasDirtyParentSceneTransform, drawItem);
}
}
void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const QTransform *const viewTransform,
- const QTransform *const transformPtr, QRegion *exposedRegion, QWidget *widget, qreal opacity,
- QPoint *effectOffset, bool wasDirtyParentSceneTransform, bool drawItem)
+ QTransform *transformPtr, QRegion *exposedRegion, QWidget *widget, qreal opacity,
+ const QTransform *effectTransform, bool wasDirtyParentSceneTransform, bool drawItem)
{
const bool itemIsFullyTransparent = (opacity < 0.0001);
const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
@@ -4338,6 +4340,8 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q
if (itemClipsChildrenToShape) {
painter->save();
Q_ASSERT(transformPtr);
+ if (effectTransform)
+ *transformPtr *= *effectTransform;
painter->setWorldTransform(*transformPtr);
painter->setClipPath(item->shape(), Qt::IntersectClip);
}
@@ -4351,7 +4355,7 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q
break;
if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
continue;
- drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectOffset);
+ drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
}
}
@@ -4368,8 +4372,11 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q
if (savePainter)
painter->save();
- if (!itemHasChildren || !itemClipsChildrenToShape)
+ if (!itemHasChildren || !itemClipsChildrenToShape) {
+ if (effectTransform)
+ *transformPtr *= *effectTransform;
painter->setWorldTransform(*transformPtr);
+ }
if (itemClipsToShape)
painter->setClipPath(item->shape(), Qt::IntersectClip);
@@ -4392,7 +4399,7 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q
child->d_ptr->dirtySceneTransform = 1;
if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
continue;
- drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectOffset);
+ drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
}
}
@@ -4475,8 +4482,12 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
item->d_ptr->ignoreOpacity = 1;
QGraphicsItem *p = item->d_ptr->parent;
- while (p && !p->d_ptr->dirtyChildren) {
+ while (p) {
p->d_ptr->dirtyChildren = 1;
+ if (p->d_ptr->graphicsEffect) {
+ p->d_ptr->dirty = 1;
+ p->d_ptr->fullUpdatePending = 1;
+ }
p = p->d_ptr->parent;
}
}
@@ -4585,7 +4596,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
// Process item.
if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask);
- const QRectF itemBoundingRect = adjustedItemBoundingRect(item);
+ const QRectF itemBoundingRect = adjustedItemEffectiveBoundingRect(item);
if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) {
// This block of code is kept for compatibility. Since 4.5, by default
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index b602758..f380ced 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -201,9 +201,9 @@ public:
void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const,
QRegion *exposedRegion, QWidget *widget, qreal parentOpacity = qreal(1.0),
- QPoint *effectOffset = 0);
- void draw(QGraphicsItem *, QPainter *, const QTransform *const, const QTransform *const,
- QRegion *, QWidget *, qreal, QPoint *, bool, bool);
+ const QTransform *const effectTransform = 0);
+ void draw(QGraphicsItem *, QPainter *, const QTransform *const, QTransform *,
+ QRegion *, QWidget *, qreal, const QTransform *const, bool, bool);
void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false,
bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false,