summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp82
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h3
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp34
-rw-r--r--src/gui/graphicsview/qgraphicsview.h3
4 files changed, 107 insertions, 15 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 49c2329..362d66d 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -1870,6 +1870,11 @@ inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item
return z1 != z2 ? z1 > z2 : d1->siblingIndex > d2->siblingIndex;
}
+static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ return qt_closestLeaf(item2, item1);
+}
+
/*!
\internal
@@ -5013,6 +5018,83 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
}
}
+void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform &viewTransform,
+ const QRegion &exposedRegion, QWidget *widget)
+{
+ if (item && (!item->isVisible() || qFuzzyIsNull(item->opacity())))
+ return;
+
+ painter->save();
+
+ // Set transform
+ if (item) {
+ if (item->d_ptr->itemIsUntransformable()) {
+ painter->setWorldTransform(item->deviceTransform(viewTransform), false);
+ } else {
+ const QPointF &pos = item->d_ptr->pos;
+ bool posNull = pos.isNull();
+ if (!posNull || item->d_ptr->hasTransform) {
+ if (item->d_ptr->hasTransform) {
+ QTransform x = item->transform();
+ if (!posNull)
+ x *= QTransform::fromTranslate(pos.x(), pos.y());
+ painter->setWorldTransform(x, true);
+ } else {
+ painter->setWorldTransform(QTransform::fromTranslate(pos.x(), pos.y()), true);
+ }
+ }
+ }
+ }
+
+ // Setup recursive clipping.
+ if (item && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape))
+ painter->setClipPath(item->shape(), Qt::IntersectClip);
+
+#if 0
+ const QList<QGraphicsItem *> &children = item ? item->d_ptr->children : topLevelItems;
+#else
+ // ### if we ensure all children are sorted by Z by default, we don't have
+ // to sort this list for each paint.
+ QList<QGraphicsItem *> children = item ? item->d_ptr->children : topLevelItems;
+ qSort(children.begin(), children.end(), qt_notclosestLeaf);
+#endif
+
+ // Draw children behind
+ int i;
+ for (i = 0; i < children.size(); ++i) {
+ QGraphicsItem *child = children.at(i);
+ if (!(child->flags() & QGraphicsItem::ItemStacksBehindParent))
+ break;
+ drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget);
+ }
+
+ // Draw item
+ if (item) {
+ QRect itemViewRect = painter->worldTransform().mapRect(item->boundingRect()).toRect().adjusted(-1, -1, 1, 1);
+ if (itemViewRect.intersects(exposedRegion.boundingRect())) {
+ QStyleOptionGraphicsItem option;
+ item->d_ptr->initStyleOption(&option, painter->worldTransform(), exposedRegion);
+
+ bool clipsToShape = (item->flags() & QGraphicsItem::ItemClipsToShape);
+ if (clipsToShape) {
+ painter->save();
+ painter->setClipPath(item->shape(), Qt::IntersectClip);
+ }
+
+ drawItemHelper(item, painter, &option, widget, false);
+
+ if (clipsToShape)
+ painter->restore();
+ }
+ }
+
+ // Draw children in front
+ for (; i < children.size(); ++i)
+ drawSubtreeRecursive(children.at(i), painter, viewTransform, exposedRegion, widget);
+
+ painter->restore();
+}
+
/*!
Paints the given \a items using the provided \a painter, after the
background has been drawn, and before the foreground has been
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 9ace725..369b0ef 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -253,6 +253,9 @@ public:
const QStyleOptionGraphicsItem *option, QWidget *widget,
bool painterStateProtection);
+ void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform &viewTransform,
+ const QRegion &exposedRegion, QWidget *widget);
+
QStyle *style;
QFont font;
void setFont_helper(const QFont &font);
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 10b837a..2459c49 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -3387,10 +3387,6 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
bool allItems = false;
QList<QGraphicsItem *> itemList = d->findItems(exposedRegion, &allItems);
-#ifdef QGRAPHICSVIEW_DEBUG
- int exposedTime = stopWatch.elapsed();
-#endif
-
if ((d->cacheMode & CacheBackground)
#ifdef Q_WS_X11
&& X11->use_xrender
@@ -3436,16 +3432,26 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
int backgroundTime = stopWatch.elapsed() - exposedTime;
#endif
- if (!itemList.isEmpty()) {
- // Generate the style options.
- const int numItems = itemList.size();
- QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
- QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
- for (int i = 0; i < numItems; ++i)
- itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], viewTransform, exposedRegion, allItems);
- // Draw the items.
- drawItems(&painter, numItems, itemArray, styleOptionArray);
- d->freeStyleOptionsArray(styleOptionArray);
+ const char *directEnv = getenv("QGRAPHICSVIEW_DIRECT");
+ bool overrideDirectPaint = directEnv && atoi(directEnv) != 0;
+ if (overrideDirectPaint || (d->optimizationFlags & BypassDrawItems)) {
+ d->scene->d_func()->drawSubtreeRecursive(0, &painter, viewTransform, exposedRegion, viewport());
+ } else {
+ // Find all exposed items
+ bool allItems = false;
+ QList<QGraphicsItem *> itemList = d->findItems(exposedRegion, &allItems);
+
+ if (!itemList.isEmpty()) {
+ // Generate the style options.
+ const int numItems = itemList.size();
+ QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
+ QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
+ for (int i = 0; i < numItems; ++i)
+ itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], viewTransform, exposedRegion, allItems);
+ // Draw the items.
+ drawItems(&painter, numItems, itemArray, styleOptionArray);
+ d->freeStyleOptionsArray(styleOptionArray);
+ }
}
#ifdef QGRAPHICSVIEW_DEBUG
diff --git a/src/gui/graphicsview/qgraphicsview.h b/src/gui/graphicsview/qgraphicsview.h
index c3ea6e5..7692e16 100644
--- a/src/gui/graphicsview/qgraphicsview.h
+++ b/src/gui/graphicsview/qgraphicsview.h
@@ -112,7 +112,8 @@ public:
enum OptimizationFlag {
DontClipPainter = 0x1, // obsolete
DontSavePainterState = 0x2,
- DontAdjustForAntialiasing = 0x4
+ DontAdjustForAntialiasing = 0x4,
+ BypassDrawItems = 0x8
};
Q_DECLARE_FLAGS(OptimizationFlags, OptimizationFlag)