diff options
author | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-04-23 15:46:54 (GMT) |
---|---|---|
committer | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-04-23 15:49:36 (GMT) |
commit | 5423ba187c62ea861ccfcc013fb15fcc4a5ae28d (patch) | |
tree | 81135e3cf5ec81aff1c533c1a1157ae519d2d352 /src | |
parent | 4ec0d20bda2d7c4dfd1da41d52404481f5ecd42c (diff) | |
download | Qt-5423ba187c62ea861ccfcc013fb15fcc4a5ae28d.zip Qt-5423ba187c62ea861ccfcc013fb15fcc4a5ae28d.tar.gz Qt-5423ba187c62ea861ccfcc013fb15fcc4a5ae28d.tar.bz2 |
Fix bugs in QGraphicsItem::childrenBoundingRect()
While working on layering in Graphics View I stumbled over this bug. The
QGraphicsItem::childrenBoundingRect() function had an accumulating error
caused by recursive adding of rectangles that individually were mapped to
the local parent using QGraphicsItem::mapRectToParent() /
QTransform::mapRect. This caused the brect to be way too large for items
with children that are rotated (fex, alternating 45 and -45 degrees).
The new version should be just as fast, but with no loss of precision.
Reviewed-by: bnilsen
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 41 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 1 |
2 files changed, 35 insertions, 7 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 8a7a080..65d1e0a 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -885,6 +885,38 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de /*! \internal + Returns the bounding rect of this item's children (excluding itself). +*/ +void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect) +{ + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *child = children.at(i); + QGraphicsItemPrivate *childd = child->d_ptr; + bool hasX = childd->hasTransform; + bool hasPos = !childd->pos.isNull(); + if (hasPos || hasX) { + QTransform matrix; + if (hasX) + matrix = child->transform(); + if (hasPos) { + const QPointF &p = childd->pos; + matrix *= QTransform::fromTranslate(p.x(), p.y()); + } + matrix *= *x; + *rect |= matrix.mapRect(child->boundingRect()); + if (!childd->children.isEmpty()) + childd->childrenBoundingRectHelper(&matrix, rect); + } else { + *rect |= x->mapRect(child->boundingRect()); + if (!childd->children.isEmpty()) + childd->childrenBoundingRectHelper(x, rect); + } + } +} + +/*! + \internal + Empty all cached pixmaps from the pixmap cache. */ void QGraphicsItemCache::purge() @@ -3019,13 +3051,8 @@ void QGraphicsItem::setZValue(qreal z) QRectF QGraphicsItem::childrenBoundingRect() const { QRectF childRect; - foreach (QGraphicsItem *child, children()) { - QPointF childPos = child->pos(); - QTransform matrix = child->transform(); - if (!childPos.isNull()) - matrix *= QTransform::fromTranslate(childPos.x(), childPos.y()); - childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect()); - } + QTransform x; + d_ptr->childrenBoundingRectHelper(&x, &childRect); return childRect; } diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 078c543..940e566 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -178,6 +178,7 @@ public: void addChild(QGraphicsItem *child); void removeChild(QGraphicsItem *child); void setParentItemHelper(QGraphicsItem *parent, bool deleting); + void childrenBoundingRectHelper(QTransform *x, QRectF *rect); virtual void resolveFont(uint inheritedMask) { |