diff options
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 27 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 14 | ||||
-rw-r--r-- | tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp | 15 |
3 files changed, 49 insertions, 7 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 074e571..88e9952 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1205,8 +1205,14 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q Returns the bounding rect of this item's children (excluding itself). */ -void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect) +void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, bool doClip) { + Q_Q(QGraphicsItem); + + QRectF childrenRect; + QRectF *result = rect; + rect = &childrenRect; + for (int i = 0; i < children.size(); ++i) { QGraphicsItem *child = children.at(i); QGraphicsItemPrivate *childd = child->d_ptr.data(); @@ -1228,6 +1234,15 @@ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rec childd->childrenBoundingRectHelper(x, rect); } } + + if (doClip && (flags & QGraphicsItem::ItemClipsChildrenToShape)){ + if (x) + *rect &= x->mapRect(q->boundingRect()); + else + *rect &= q->boundingRect(); + } + + *result |= *rect; } void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, @@ -10816,8 +10831,14 @@ QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem syste } QRectF rect = item->boundingRect(); - if (!item->d_ptr->children.isEmpty()) - rect |= item->childrenBoundingRect(); + if (!item->d_ptr->children.isEmpty()) { + if (dirtyChildrenBoundingRect) { + childrenBoundingRect = QRectF(); + item->d_ptr->childrenBoundingRectHelper(0, &childrenBoundingRect, true); + dirtyChildrenBoundingRect = false; + } + rect |= childrenBoundingRect; + } if (deviceCoordinates) { Q_ASSERT(info->painter); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index e737773..ead240b 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -239,7 +239,7 @@ public: void removeChild(QGraphicsItem *child); void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, const QVariant *thisPointerVariant); - void childrenBoundingRectHelper(QTransform *x, QRectF *rect); + void childrenBoundingRectHelper(QTransform *x, QRectF *rect, bool doClip = true); void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems = false) const; QRectF effectiveBoundingRect() const; @@ -580,7 +580,7 @@ class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate { public: QGraphicsItemEffectSourcePrivate(QGraphicsItem *i) - : QGraphicsEffectSourcePrivate(), item(i), info(0) + : QGraphicsEffectSourcePrivate(), dirtyChildrenBoundingRect(true), item(i), info(0) {} inline void detach() @@ -631,6 +631,9 @@ public: QGraphicsEffect::PixmapPadMode mode) const; QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const; + mutable bool dirtyChildrenBoundingRect; + mutable QRectF childrenBoundingRect; + QGraphicsItem *item; QGraphicsItemPaintInfo *info; QTransform lastEffectTransform; @@ -788,9 +791,12 @@ inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect) #ifndef QT_NO_GRAPHICSEFFECT if (parentp->graphicsEffect) { if (updateBoundingRect) { + QGraphicsItemEffectSourcePrivate *sourcep = + static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func() + ->source->d_func()); + parentp->dirtyChildrenBoundingRect = 1; parentp->notifyInvalidated = 1; - static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func() - ->source->d_func())->invalidateCache(); + sourcep->invalidateCache(); } if (parentp->graphicsEffect->isEnabled()) { parentp->dirty = 1; diff --git a/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp b/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp index 49f110e..49a76fa 100644 --- a/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp +++ b/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp @@ -161,6 +161,7 @@ private slots: void draw(); void update(); void boundingRect(); + void clippedBoundingRect(); void deviceRect(); void pixmap(); @@ -282,6 +283,20 @@ void tst_QGraphicsEffectSource::boundingRect() QTRY_COMPARE(effect->source()->boundingRect(), itemBoundingRect); } +void tst_QGraphicsEffectSource::clippedBoundingRect() +{ + QRectF itemBoundingRect = item->boundingRect(); + item->setFlag(QGraphicsItem::ItemClipsChildrenToShape); + + QGraphicsRectItem *child = new QGraphicsRectItem(-1000, -1000, 2000, 2000); + child->setBrush(Qt::red); + child->setParentItem(item); + + effect->storeDeviceDependentStuff = true; + effect->source()->update(); + QTRY_COMPARE(effect->source()->boundingRect(Qt::LogicalCoordinates), itemBoundingRect); +} + void tst_QGraphicsEffectSource::deviceRect() { effect->storeDeviceDependentStuff = true; |