diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-08-05 15:29:23 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-08-06 12:03:59 (GMT) |
commit | 4909d2661d47a28c0ee932d9dfb5b8c47a376044 (patch) | |
tree | 9596a9a18c15ecc33c548b7a5a7e30599831ab7a | |
parent | befbee33497290b6e5448b1249e4ace83fcda27b (diff) | |
download | Qt-4909d2661d47a28c0ee932d9dfb5b8c47a376044.zip Qt-4909d2661d47a28c0ee932d9dfb5b8c47a376044.tar.gz Qt-4909d2661d47a28c0ee932d9dfb5b8c47a376044.tar.bz2 |
Wrong caching of QGraphicsItem::childrenBoundingRect.
We cannot cache the bounding rect on the fly for children, because the
bounding rect is mapped to the callee's local coordinate system.
Auto-test included.
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 24 | ||||
-rw-r--r-- | tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 34 |
2 files changed, 44 insertions, 14 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 07a063e..47f8a90 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1016,11 +1016,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) */ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect) { - if (!dirtyChildrenBoundingRect) { - *rect |= x->mapRect(childrenBoundingRect); - return; - } - for (int i = 0; i < children.size(); ++i) { QGraphicsItem *child = children.at(i); QGraphicsItemPrivate *childd = child->d_ptr; @@ -1028,19 +1023,20 @@ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rec if (hasPos || childd->transformData) { // COMBINE QTransform matrix = childd->transformToParent(); - matrix *= *x; + if (x) + matrix *= *x; *rect |= matrix.mapRect(child->boundingRect()); if (!childd->children.isEmpty()) childd->childrenBoundingRectHelper(&matrix, rect); } else { - *rect |= x->mapRect(child->boundingRect()); + if (x) + *rect |= x->mapRect(child->boundingRect()); + else + *rect |= child->boundingRect(); if (!childd->children.isEmpty()) childd->childrenBoundingRectHelper(x, rect); } } - - childrenBoundingRect = *rect; - dirtyChildrenBoundingRect = 0; } void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, @@ -3930,10 +3926,10 @@ QRectF QGraphicsItem::childrenBoundingRect() const if (!d_ptr->dirtyChildrenBoundingRect) return d_ptr->childrenBoundingRect; - QRectF childRect; - QTransform x; - d_ptr->childrenBoundingRectHelper(&x, &childRect); - return childRect; + d_ptr->childrenBoundingRect = QRectF(); + d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect); + d_ptr->dirtyChildrenBoundingRect = 0; + return d_ptr->childrenBoundingRect; } /*! diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index ceb033e..d07c6fd 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -215,6 +215,7 @@ private slots: void childrenBoundingRect(); void childrenBoundingRectTransformed(); void childrenBoundingRect2(); + void childrenBoundingRect3(); void group(); void setGroup(); void nestedGroups(); @@ -3052,6 +3053,39 @@ void tst_QGraphicsItem::childrenBoundingRect2() QCOMPARE(box.childrenBoundingRect(), QRectF(0, 0, 100, 100)); } +void tst_QGraphicsItem::childrenBoundingRect3() +{ + QGraphicsScene scene; + + QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100)); + QGraphicsRectItem *rect2 = scene.addRect(QRectF(0, 0, 100, 100)); + QGraphicsRectItem *rect3 = scene.addRect(QRectF(0, 0, 100, 100)); + QGraphicsRectItem *rect4 = scene.addRect(QRectF(0, 0, 100, 100)); + QGraphicsRectItem *rect5 = scene.addRect(QRectF(0, 0, 100, 100)); + rect2->setParentItem(rect); + rect3->setParentItem(rect2); + rect4->setParentItem(rect3); + rect5->setParentItem(rect4); + + rect2->setTransform(QTransform().translate(50, 50).rotate(45)); + rect2->setPos(25, 25); + rect3->setTransform(QTransform().translate(50, 50).rotate(45)); + rect3->setPos(25, 25); + rect4->setTransform(QTransform().translate(50, 50).rotate(45)); + rect4->setPos(25, 25); + rect5->setTransform(QTransform().translate(50, 50).rotate(45)); + rect5->setPos(25, 25); + + // Try to mess up the cached bounding rect. + (void)rect2->childrenBoundingRect(); + + QRectF subTreeRect = rect->childrenBoundingRect(); + QCOMPARE(subTreeRect.left(), qreal(-206.0660171779821)); + QCOMPARE(subTreeRect.top(), qreal(75.0)); + QCOMPARE(subTreeRect.width(), qreal(351.7766952966369)); + QCOMPARE(subTreeRect.height(), qreal(251.7766952966369)); +} + void tst_QGraphicsItem::group() { QGraphicsScene scene; |