diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 82 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 3 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 34 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.h | 3 |
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) |