diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 20d1d30..7975f8c 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -122,6 +122,8 @@ #include "qtabwidget.h" // Needed in inTabWidget() #endif // QT_KEYPAD_NAVIGATION +#include "QtCore/qbitarray.h" + // widget/widget data creation count //#define QWIDGET_EXTRA_DEBUG //#define ALIEN_DEBUG @@ -5368,7 +5370,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP } if (recursive && !children.isEmpty()) { - paintSiblingsRecursive(pdev, children, children.size() - 1, rgn, offset, flags & ~DrawAsRoot + paintSiblingsIterative(pdev, children, rgn, offset, flags & ~DrawAsRoot #ifdef Q_BACKINGSTORE_SUBSURFACES , q->windowSurface() #endif @@ -5466,67 +5468,73 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset, #endif } -void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn, - const QPoint &offset, int flags +void QWidgetPrivate::paintSiblingsIterative(QPaintDevice *pdev, const QObjectList& siblings, + const QRegion &rgn, const QPoint &offset, int flags #ifdef Q_BACKINGSTORE_SUBSURFACES - , const QWindowSurface *currentSurface + , const QWindowSurface *currentSurface #endif - , QPainter *sharedPainter, QWidgetBackingStore *backingStore) + , QPainter *sharedPainter, QWidgetBackingStore *backingStore) { - QWidget *w = 0; + QBitArray skipArray; QRect boundingRect; bool dirtyBoundingRect = true; const bool exludeOpaqueChildren = (flags & DontDrawOpaqueChildren); + QRegion wr(rgn); - do { - QWidget *x = qobject_cast(siblings.at(index)); - if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() && !x->isWindow()) { + const int count = siblings.count(); + skipArray.resize(count); + + for (int index = count - 1; index >= 0; --index) { + QWidget *x = qobject_cast (siblings.at(index)); + bool skip = true; + if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() + && !x->isWindow()) { if (dirtyBoundingRect) { - boundingRect = rgn.boundingRect(); + boundingRect = wr.boundingRect(); dirtyBoundingRect = false; } - if (qRectIntersects(boundingRect, x->d_func()->effectiveRectFor(x->data->crect))) { + if (qRectIntersects(boundingRect, x->d_func()->effectiveRectFor(x->data->crect)) #ifdef Q_BACKINGSTORE_SUBSURFACES - if (x->windowSurface() == currentSurface) -#endif - { - w = x; - break; + && (x->windowSurface() == currentSurface) +#endif + ) { + QWidgetPrivate *wd = x->d_func(); + const QPoint widgetPos(x->data->crect.topLeft()); + const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect; + if (index > 0) { + if (wd->isOpaque) { + wr -= hasMask ? wd->extra->mask.translated(widgetPos) : x->data->crect; + dirtyBoundingRect = true; + } + } + if (x->updatesEnabled() +#ifndef QT_NO_GRAPHICSVIEW + && (!wd->extra || !wd->extra->proxyWidget) +#endif //QT_NO_GRAPHICSVIEW + ) { + skip = false; } } } - --index; - } while (index >= 0); - - if (!w) - return; - - QWidgetPrivate *wd = w->d_func(); - const QPoint widgetPos(w->data->crect.topLeft()); - const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect; - if (index > 0) { - QRegion wr(rgn); - if (wd->isOpaque) - wr -= hasMask ? wd->extra->mask.translated(widgetPos) : w->data->crect; - paintSiblingsRecursive(pdev, siblings, --index, wr, offset, flags -#ifdef Q_BACKINGSTORE_SUBSURFACES - , currentSurface -#endif - , sharedPainter, backingStore); + skipArray.setBit(index, skip); } - if (w->updatesEnabled() -#ifndef QT_NO_GRAPHICSVIEW - && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget) -#endif //QT_NO_GRAPHICSVIEW - ) { + for (int index = 0; index < count; index++) { + if (skipArray.testBit(index)) + continue; QRegion wRegion(rgn); - wRegion &= wd->effectiveRectFor(w->data->crect); - wRegion.translate(-widgetPos); - if (hasMask) - wRegion &= wd->extra->mask; - wd->drawWidget(pdev, wRegion, offset + widgetPos, flags, sharedPainter, backingStore); + QWidget* w = qobject_cast (siblings.at(index)); + if (w) { + QWidgetPrivate *wd = w->d_func(); + const QPoint widgetPos(w->data->crect.topLeft()); + wRegion &= wd->effectiveRectFor(w->data->crect); + wRegion.translate(-widgetPos); + const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect; + if (hasMask) + wRegion &= wd->extra->mask; + wd->drawWidget(pdev, wRegion, offset + widgetPos, flags, sharedPainter, backingStore); + } } } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index cad60b5..4d9a97e 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -392,7 +392,7 @@ public: QPainter *sharedPainter = 0, QWidgetBackingStore *backingStore = 0); - void paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& children, int index, + void paintSiblingsIterative(QPaintDevice *pdev, const QObjectList& children, const QRegion &rgn, const QPoint &offset, int flags #ifdef Q_BACKINGSTORE_SUBSURFACES , const QWindowSurface *currentSurface