summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBjoern Erik Nilsen <bjorn.nilsen@nokia.com>2009-04-03 09:47:59 (GMT)
committerJason McDonald <jason.mcdonald@nokia.com>2009-04-15 10:23:44 (GMT)
commitd715f695b96e408c5858ab708c18dca16b69d91e (patch)
tree5a6c7516ac1bab8f24af7f8529e629453d62a35b /src
parent87259e48aed0ac684fea18a656710ea96429518d (diff)
downloadQt-d715f695b96e408c5858ab708c18dca16b69d91e.zip
Qt-d715f695b96e408c5858ab708c18dca16b69d91e.tar.gz
Qt-d715f695b96e408c5858ab708c18dca16b69d91e.tar.bz2
Fixes: Optimize the way we adjust rectangles.
RevBy: Olivier AutoTest: Still pass (cherry picked from commit 32767aa5699937a3737b9515f4f82acc04ccdfcd)
Diffstat (limited to 'src')
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp39
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp76
2 files changed, 68 insertions, 47 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 9e2c93a..175b128 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -528,25 +528,22 @@ QT_BEGIN_NAMESPACE
// QRectF::intersects() returns false always if either the source or target
// rectangle's width or height are 0. This works around that problem.
-static QRectF _q_adjustedRect(const QRectF &rect)
-{
- static const qreal p = (qreal)0.00001;
- QRectF r = rect;
- if (!r.width())
- r.adjust(-p, 0, p, 0);
- if (!r.height())
- r.adjust(0, -p, 0, p);
- return r;
+static inline void _q_adjustRect(QRectF *rect)
+{
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(-0.00001, 0, 0.00001, 0);
+ if (!rect->height())
+ rect->adjust(0, -0.00001, 0, 0.00001);
}
-static QRect _q_adjustedRect(const QRect &rect)
+static inline void _q_adjustRect(QRect *rect)
{
- QRect r = rect;
- if (!r.width())
- r.adjust(0, 0, 1, 0);
- if (!r.height())
- r.adjust(0, 0, 0, 1);
- return r;
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(0, 0, 1, 0);
+ if (!rect->height())
+ rect->adjust(0, 0, 0, 1);
}
/*
@@ -3305,8 +3302,10 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection
return false;
}
- const QRectF rectA = _q_adjustedRect(boundingRect());
- const QRectF rectB = _q_adjustedRect(path.controlPointRect());
+ QRectF rectA(boundingRect());
+ _q_adjustRect(&rectA);
+ QRectF rectB(path.controlPointRect());
+ _q_adjustRect(&rectB);
if (!rectA.intersects(rectB)) {
// This we can determine efficiently. If the two rects neither
// intersect nor contain eachother, then the two items do not collide.
@@ -3489,7 +3488,9 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c
// into the bitmap, converts the result to a QRegion and scales the region
// back to device space with inverse granularity.
qreal granularity = boundingRegionGranularity();
- QRect deviceRect = _q_adjustedRect(itemToDeviceTransform.mapRect(boundingRect()).toRect());
+ QRectF adjustedMappedBoundingRect(itemToDeviceTransform.mapRect(boundingRect()));
+ _q_adjustRect(&adjustedMappedBoundingRect);
+ QRect deviceRect = adjustedMappedBoundingRect.toRect();
if (granularity == 0.0)
return QRegion(deviceRect);
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 172e0a2..e946f0f 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -292,15 +292,21 @@ static inline bool QRectF_intersects(const QRectF &s, const QRectF &r)
// QRectF::intersects() returns false always if either the source or target
// rectangle's width or height are 0. This works around that problem.
-static QRectF _q_adjustedRect(const QRectF &rect)
+static inline void _q_adjustRect(QRectF *rect)
{
- static const qreal p = (qreal)0.00001;
- QRectF r = rect;
- if (!r.width())
- r.adjust(-p, 0, p, 0);
- if (!r.height())
- r.adjust(0, -p, 0, p);
- return r;
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(-0.00001, 0, 0.00001, 0);
+ if (!rect->height())
+ rect->adjust(0, -0.00001, 0, 0.00001);
+}
+
+static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
+{
+ Q_ASSERT(item);
+ QRectF boundingRect(item->boundingRect());
+ _q_adjustRect(&boundingRect);
+ return boundingRect;
}
static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
@@ -1383,7 +1389,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPointF &pos) c
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
// Rect intersects/contains item's shape
if (QRectF_intersects(adjustedRect, x.mapRect(br))) {
bool ok;
@@ -1419,7 +1425,8 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QRectF &rect,
// The index returns a rough estimate of what items are inside the rect.
// Refine it by iterating through all returned items.
- QRectF adjustedRect = _q_adjustedRect(rect);
+ QRectF adjustedRect(rect);
+ _q_adjustRect(&adjustedRect);
foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) {
// Find the item's scene transform in a clever way.
QTransform x = item->sceneTransform();
@@ -1428,7 +1435,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QRectF &rect,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Rect intersects/contains item's bounding rect
QRectF mbr = x.mapRect(br);
@@ -1480,7 +1487,8 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPolygonF &poly
{
QList<QGraphicsItem *> items;
- QRectF polyRect = _q_adjustedRect(polygon.boundingRect());
+ QRectF polyRect(polygon.boundingRect());
+ _q_adjustRect(&polyRect);
QPainterPath path;
// The index returns a rough estimate of what items are inside the rect.
@@ -1493,7 +1501,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPolygonF &poly
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Polygon contains/intersects item's bounding rect
if (path == QPainterPath())
@@ -1538,7 +1546,8 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPainterPath &p
Qt::SortOrder order) const
{
QList<QGraphicsItem *> items;
- const QRectF pathRect = _q_adjustedRect(path.controlPointRect());
+ QRectF pathRect(path.controlPointRect());
+ _q_adjustRect(&pathRect);
// The index returns a rough estimate of what items are inside the rect.
// Refine it by iterating through all returned items.
@@ -1550,7 +1559,7 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPainterPath &p
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Path contains/intersects item's bounding rect
if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br)))
@@ -1629,7 +1638,9 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
if (parentClip && parent->d_ptr->isClippedAway())
return;
- QRectF r = !parentClip ? _q_adjustedRect(rect) : _q_adjustedRect(rect).intersected(_q_adjustedRect(parent->boundingRect()));
+ QRectF adjustedRect(rect);
+ _q_adjustRect(&adjustedRect);
+ QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent));
if (r.isEmpty())
return;
@@ -1649,7 +1660,7 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
QRectF mbr = item->mapRectToParent(br);
if (mode >= Qt::ContainsItemBoundingRect) {
// Rect intersects/contains item's bounding rect
@@ -1693,8 +1704,9 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
if (parentClip && parent->d_ptr->isClippedAway())
return;
- QRectF polyRect = _q_adjustedRect(polygon.boundingRect());
- QRectF r = !parentClip ? polyRect : polyRect.intersected(_q_adjustedRect(parent->boundingRect()));
+ QRectF polyRect(polygon.boundingRect());
+ _q_adjustRect(&polyRect);
+ QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent));
if (r.isEmpty())
return;
@@ -1714,7 +1726,7 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Polygon contains/intersects item's bounding rect
if (path == QPainterPath())
@@ -1752,8 +1764,9 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
if (parentClip && parent->d_ptr->isClippedAway())
return;
- QRectF pathRect = _q_adjustedRect(path.boundingRect());
- QRectF r = !parentClip ? pathRect : pathRect.intersected(_q_adjustedRect(parent->boundingRect()));
+ QRectF pathRect(path.boundingRect());
+ _q_adjustRect(&pathRect);
+ QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent));
if (r.isEmpty())
return;
@@ -1772,7 +1785,7 @@ void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
// ### _q_adjustedRect is only needed because QRectF::intersects,
// QRectF::contains and QTransform::map() and friends don't work with
// flat rectangles.
- QRectF br = _q_adjustedRect(item->boundingRect());
+ const QRectF br(adjustedItemBoundingRect(item));
if (mode >= Qt::ContainsItemBoundingRect) {
// Polygon contains/intersects item's bounding rect
if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
@@ -4709,7 +4722,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Item's (local) bounding rect
QRectF brect = item->boundingRect();
- if (_q_adjustedRect(brect).isEmpty())
+ QRectF adjustedBrect(brect);
+ _q_adjustRect(&adjustedBrect);
+ if (adjustedBrect.isEmpty())
return;
// Fetch the off-screen transparent buffer and exposed area info.
@@ -5251,9 +5266,12 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
update(item->sceneBoundingRect());
} else {
// ### Remove _q_adjustedRects().
- QRectF boundingRect = _q_adjustedRect(item->boundingRect());
- if (!rect.isNull())
- boundingRect &= _q_adjustedRect(rect);
+ QRectF boundingRect(adjustedItemBoundingRect(item));
+ if (!rect.isNull()) {
+ QRectF adjustedRect(rect);
+ _q_adjustRect(&adjustedRect);
+ boundingRect &= adjustedRect;
+ }
// Update each view directly.
for (int i = 0; i < d->views.size(); ++i)
@@ -5283,7 +5301,9 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect)
// defined scene rect.
if (!d->hasSceneRect) {
QRectF oldGrowingItemsBoundingRect = d->growingItemsBoundingRect;
- d->growingItemsBoundingRect |= _q_adjustedRect(item->sceneBoundingRect());
+ QRectF adjustedItemSceneBoundingRect(item->sceneBoundingRect());
+ _q_adjustRect(&adjustedItemSceneBoundingRect);
+ d->growingItemsBoundingRect |= adjustedItemSceneBoundingRect;
if (d->growingItemsBoundingRect != oldGrowingItemsBoundingRect)
emit sceneRectChanged(d->growingItemsBoundingRect);
}