diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/graphicsview/graphicsview.pri | 3 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicseffect.cpp | 396 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicseffect.h | 93 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicseffect_p.h | 171 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 100 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.h | 6 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 45 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 72 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.h | 5 |
9 files changed, 456 insertions, 435 deletions
diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index c3cb574..55bb9e0 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -21,7 +21,8 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \ graphicsview/qgraphicswidget.h \ graphicsview/qgraphicswidget_p.h \ graphicsview/qgridlayoutengine_p.h \ - graphicsview/qgraphicseffect.h + graphicsview/qgraphicseffect.h \ + graphicsview/qgraphicseffect_p.h \ SOURCES += graphicsview/qgraphicsgridlayout.cpp \ graphicsview/qgraphicsitem.cpp \ diff --git a/src/gui/graphicsview/qgraphicseffect.cpp b/src/gui/graphicsview/qgraphicseffect.cpp index 6b1f12a..8d2c416 100644 --- a/src/gui/graphicsview/qgraphicseffect.cpp +++ b/src/gui/graphicsview/qgraphicseffect.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qgraphicseffect.h" +#include "qgraphicseffect_p.h" #ifndef QT_NO_GRAPHICSVIEW @@ -48,9 +48,6 @@ #include <QtGui/qgraphicsscene.h> #include <QtGui/qpainter.h> -#include <private/qobject_p.h> -#include <private/qpixmapfilter_p.h> - /* List of known drawbacks which are being discussed: @@ -105,128 +102,92 @@ */ +QGraphicsEffect::QGraphicsEffect() + : QObject(*new QGraphicsEffectPrivate, 0) +{} + /*! \internal */ -class QGraphicsEffectPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsEffect) -public: - QGraphicsEffectPrivate() {} -}; - -QGraphicsEffect::QGraphicsEffect(QObject *parent) - : QObject(*new QGraphicsEffectPrivate, parent) -{ -} +QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd) + : QObject(dd, 0) +{} QGraphicsEffect::~QGraphicsEffect() { + Q_D(QGraphicsEffect); + d->setGraphicsEffectSource(0); } -QRectF QGraphicsEffect::boundingRectFor(const QGraphicsItem *item) +QRectF QGraphicsEffect::boundingRect() const { - // default is to give the item's bounding rect - // do NOT call item->effectiveBoundRect() because - // that function will call this one (infinite loop) - return item->boundingRect(); + return sourceBoundingRect(); } -/*! \internal -*/ -QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd, QObject *parent) - : QObject(dd, parent) +QRectF QGraphicsEffect::sourceBoundingRect() const { + Q_D(const QGraphicsEffect); + if (d->source) + return d->source->boundingRect(); + return QRectF(); } -// this helper function is only for subclasses of QGraphicsEffect -// the implementation is trivial, but this allows us to keep -// QGraphicsScene::drawItem() as a protected function -// (since QGraphicsEffect is a friend of QGraphicsScene) -QPixmap* QGraphicsEffect::drawItemOnPixmap(QPainter *painter, QGraphicsItem *item, - const QStyleOptionGraphicsItem *option, QWidget *widget, int flags) +void QGraphicsEffect::drawSource(QPainter *painter) { - if (!item->scene()) - return 0; - return item->scene()->drawItemOnPixmap(painter, item, option, widget, flags); + Q_D(QGraphicsEffect); + if (d->source) + d->source->draw(painter); } -/*! - \internal -*/ -class QGraphicsGrayscaleEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsGrayscaleEffect) -public: - QGraphicsGrayscaleEffectPrivate() { - filter = new QPixmapColorizeFilter; - filter->setColor(Qt::black); - } - - ~QGraphicsGrayscaleEffectPrivate() { - delete filter; - } - - QPixmapColorizeFilter *filter; -}; - -QGraphicsGrayscaleEffect::QGraphicsGrayscaleEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsGrayscaleEffectPrivate, parent) +bool QGraphicsEffect::drawSourceIntoPixmap(QPixmap *pixmap, const QTransform &itemToPixmapTransform) { + Q_D(QGraphicsEffect); + if (d->source) + return d->source->drawIntoPixmap(pixmap, itemToPixmapTransform); + return false; } +QGraphicsGrayscaleEffect::QGraphicsGrayscaleEffect() + : QGraphicsEffect(*new QGraphicsGrayscaleEffectPrivate) +{} + QGraphicsGrayscaleEffect::~QGraphicsGrayscaleEffect() -{ -} +{} -void QGraphicsGrayscaleEffect::drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option, QWidget *widget) +void QGraphicsGrayscaleEffect::draw(QPainter *painter) { Q_D(QGraphicsGrayscaleEffect); + if (!d->source) + return; // Find the item's bounds in device coordinates. - QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect()); + QTransform itemToPixmapTransform(painter->worldTransform()); + QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect()); QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); if (deviceRect.isEmpty()) return; - QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0); - if (!pixmap) + if (deviceRect.x() != 0 || deviceRect.y() != 0) + itemToPixmapTransform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y()); + + QPixmap pixmap(deviceRect.size()); + if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform)) return; // Draw the pixmap with the filter using an untransformed painter. QTransform restoreTransform = painter->worldTransform(); painter->setWorldTransform(QTransform()); - d->filter->draw(painter, deviceRect.topLeft(), *pixmap, pixmap->rect()); + d->filter->draw(painter, deviceRect.topLeft(), pixmap, pixmap.rect()); painter->setWorldTransform(restoreTransform); -} - -/*! - \internal -*/ -class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsColorizeEffect) -public: - QGraphicsColorizeEffectPrivate() { - filter = new QPixmapColorizeFilter; - } - - ~QGraphicsColorizeEffectPrivate() { - delete filter; - } - - QPixmapColorizeFilter *filter; -}; -QGraphicsColorizeEffect::QGraphicsColorizeEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate, parent) -{ } +QGraphicsColorizeEffect::QGraphicsColorizeEffect() + : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate) +{} + QGraphicsColorizeEffect::~QGraphicsColorizeEffect() -{ -} +{} QColor QGraphicsColorizeEffect::color() const { @@ -240,43 +201,35 @@ void QGraphicsColorizeEffect::setColor(const QColor &c) d->filter->setColor(c); } -void QGraphicsColorizeEffect::drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option, QWidget *widget) +void QGraphicsColorizeEffect::draw(QPainter *painter) { Q_D(QGraphicsColorizeEffect); + if (!d->source) + return; // Find the item's bounds in device coordinates. - QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect()); + QTransform itemToPixmapTransform(painter->worldTransform()); + QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect()); QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); if (deviceRect.isEmpty()) return; - QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0); - if (!pixmap) + if (deviceRect.x() != 0 || deviceRect.y() != 0) + itemToPixmapTransform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y()); + + QPixmap pixmap(deviceRect.size()); + if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform)) return; // Draw the pixmap with the filter using an untransformed painter. QTransform restoreTransform = painter->worldTransform(); painter->setWorldTransform(QTransform()); - d->filter->draw(painter, deviceRect.topLeft(), *pixmap, pixmap->rect()); + d->filter->draw(painter, deviceRect.topLeft(), pixmap, pixmap.rect()); painter->setWorldTransform(restoreTransform); } -/*! - \internal -*/ -class QGraphicsPixelizeEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsPixelizeEffect) -public: - QGraphicsPixelizeEffectPrivate() - : pixelSize(3) { } - - int pixelSize; -}; - -QGraphicsPixelizeEffect::QGraphicsPixelizeEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsPixelizeEffectPrivate, parent) +QGraphicsPixelizeEffect::QGraphicsPixelizeEffect() + : QGraphicsEffect(*new QGraphicsPixelizeEffectPrivate) { } @@ -296,23 +249,28 @@ void QGraphicsPixelizeEffect::setPixelSize(int size) d->pixelSize = size; } -void QGraphicsPixelizeEffect::drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option, QWidget *widget) +void QGraphicsPixelizeEffect::draw(QPainter *painter) { Q_D(QGraphicsPixelizeEffect); + if (!d->source) + return; // Find the item's bounds in device coordinates. - QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect()); + QTransform itemToPixmapTransform(painter->worldTransform()); + QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect()); QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); if (deviceRect.isEmpty()) return; - QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0); - if (!pixmap) + if (deviceRect.x() != 0 || deviceRect.y() != 0) + itemToPixmapTransform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y()); + + QPixmap pixmap(deviceRect.size()); + if (!d->source->drawIntoPixmap(&pixmap)) return; // pixelize routine - QImage img = pixmap->toImage().convertToFormat(QImage::Format_ARGB32); + QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); if (d->pixelSize > 0) { int width = img.width(); int height = img.height(); @@ -338,27 +296,8 @@ void QGraphicsPixelizeEffect::drawItem(QGraphicsItem *item, QPainter *painter, painter->setWorldTransform(restoreTransform); } -/*! - \internal -*/ -class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsBlurEffect) -public: - QGraphicsBlurEffectPrivate() - { - filter = new QPixmapBlurFilter; - } - ~QGraphicsBlurEffectPrivate() - { - delete filter; - } - - QPixmapBlurFilter *filter; -}; - -QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent) +QGraphicsBlurEffect::QGraphicsBlurEffect() + : QGraphicsEffect(*new QGraphicsBlurEffectPrivate) { } @@ -443,51 +382,47 @@ void QGraphicsBlurEffect::setBlurRadius(int radius) d->filter->setBlurRadius(radius); } -QRectF QGraphicsBlurEffect::boundingRectFor(const QGraphicsItem *item) +QRectF QGraphicsBlurEffect::boundingRect() const { Q_D(const QGraphicsBlurEffect); - return d->filter->boundingRectFor(item->boundingRect()); + if (d->source) + return d->filter->boundingRectFor(d->source->boundingRect()); + return QRectF(); } -void QGraphicsBlurEffect::drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option, QWidget *widget) +void QGraphicsBlurEffect::draw(QPainter *painter) { Q_D(QGraphicsBlurEffect); + if (!d->source) + return; // Find the item's bounds in device coordinates. - QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect()); + QTransform itemToPixmapTransform(painter->worldTransform()); + QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect()); QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); if (deviceRect.isEmpty()) return; - QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0); - if (!pixmap) + // ### Potentially big rect; must be clipped to the viewport rect. + const qreal delta = d->blurRadius * 3; + const QRect effectRect = deviceBounds.adjusted(-delta, -delta, delta, delta) + .toRect().adjusted(-1, -1, 1, 1); + if (effectRect.x() != 0 || effectRect.y() != 0) + itemToPixmapTransform *= QTransform::fromTranslate(-effectRect.x(), -effectRect.y()); + + QPixmap pixmap(effectRect.size()); + if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform)) return; // Draw the pixmap with the filter using an untransformed painter. QTransform restoreTransform = painter->worldTransform(); painter->setWorldTransform(QTransform()); - d->filter->draw(painter, deviceRect.topLeft(), *pixmap, pixmap->rect()); + d->filter->draw(painter, deviceRect.topLeft(), pixmap, pixmap.rect()); painter->setWorldTransform(restoreTransform); } -/*! - \internal -*/ -class QGraphicsBloomEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsBlurEffect) -public: - QGraphicsBloomEffectPrivate() - : blurRadius(6) - , opacity(0.7) { } - - int blurRadius; - qreal opacity; -}; - -QGraphicsBloomEffect::QGraphicsBloomEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsBloomEffectPrivate, parent) +QGraphicsBloomEffect::QGraphicsBloomEffect() + : QGraphicsEffect(*new QGraphicsBloomEffectPrivate) { } @@ -519,13 +454,13 @@ void QGraphicsBloomEffect::setOpacity(qreal alpha) d->opacity = alpha; } -QRectF QGraphicsBloomEffect::boundingRectFor(const QGraphicsItem *item) +QRectF QGraphicsBloomEffect::boundingRect() const { - Q_D(QGraphicsBloomEffect); + Q_D(const QGraphicsBloomEffect); + if (!d->source) + return QRectF(); qreal delta = d->blurRadius * 3; - QRectF blurRect = item->boundingRect(); - blurRect.adjust(-delta, -delta, delta, delta); - return blurRect; + return d->source->boundingRect().adjusted(-delta, -delta, delta, delta); } // Change brightness (positive integer) of each pixel @@ -559,24 +494,29 @@ static QImage composited(const QImage& img1, const QImage& img2, qreal opacity, return result; } -void QGraphicsBloomEffect::drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option, QWidget *widget) +void QGraphicsBloomEffect::draw(QPainter *painter) { Q_D(QGraphicsBloomEffect); + if (!d->source) + return; // Find the item's bounds in device coordinates. - QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect()); + QTransform itemToPixmapTransform(painter->worldTransform()); + QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect()); QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); if (deviceRect.isEmpty()) return; - QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0); - if (!pixmap) + if (deviceRect.x() != 0 || deviceRect.y() != 0) + itemToPixmapTransform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y()); + + QPixmap pixmap(deviceRect.size()); + if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform)) return; // bloom routine int radius = d->blurRadius; - QImage img = pixmap->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); + QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); QImage overlay = blurred(img, img.rect(), radius); overlay = brightened(overlay, 70); img = composited(img, overlay, d->opacity, QPainter::CompositionMode_Overlay); @@ -588,27 +528,8 @@ void QGraphicsBloomEffect::drawItem(QGraphicsItem *item, QPainter *painter, painter->setWorldTransform(restoreTransform); } -/*! - \internal -*/ -class QGraphicsFrameEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsFrameEffect) -public: - QGraphicsFrameEffectPrivate() - : color(Qt::blue) - , width(5) - , alpha(0.6) - { - } - - QColor color; - qreal width; - qreal alpha; -}; - -QGraphicsFrameEffect::QGraphicsFrameEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsFrameEffectPrivate, parent) +QGraphicsFrameEffect::QGraphicsFrameEffect() + : QGraphicsEffect(*new QGraphicsFrameEffectPrivate) { } @@ -652,31 +573,35 @@ void QGraphicsFrameEffect::setFrameOpacity(qreal opacity) d->alpha = opacity; } -QRectF QGraphicsFrameEffect::boundingRectFor(const QGraphicsItem *item) +QRectF QGraphicsFrameEffect::boundingRect() const { - Q_D(QGraphicsFrameEffect); - QRectF frameRect = item->boundingRect(); - frameRect.adjust(-d->width, -d->width, d->width, d->width); - return frameRect; + Q_D(const QGraphicsFrameEffect); + if (!d->source) + return QRectF(); + return d->source->boundingRect().adjusted(-d->width, -d->width, d->width, d->width); } -void QGraphicsFrameEffect::drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option, QWidget *widget) +void QGraphicsFrameEffect::draw(QPainter *painter) { Q_D(QGraphicsFrameEffect); + if (!d->source) + return; // Find the item's bounds in device coordinates. - QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect()); - QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); - if (deviceRect.isEmpty()) + QTransform itemToPixmapTransform(painter->worldTransform()); + QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect()); + if (deviceBounds.isEmpty()) return; - QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0); - if (!pixmap) - return; + QRect frameRect = deviceBounds.adjusted(-d->width, -d->width, d->width, d->width) + .toRect().adjusted(-1, -1, 1, 1); - QRectF frameRect = deviceBounds; - frameRect.adjust(-d->width, -d->width, d->width, d->width); + if (frameRect.x() != 0 || frameRect.y() != 0) + itemToPixmapTransform *= QTransform::fromTranslate(-frameRect.x(), -frameRect.y()); + + QPixmap pixmap(frameRect.size()); + if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform)) + return; painter->save(); painter->setWorldTransform(QTransform()); @@ -688,33 +613,13 @@ void QGraphicsFrameEffect::drawItem(QGraphicsItem *item, QPainter *painter, painter->drawRoundedRect(frameRect, 20, 20, Qt::RelativeSize); painter->restore(); - painter->drawPixmap(frameRect.topLeft(), *pixmap); + painter->drawPixmap(frameRect.topLeft(), pixmap); painter->restore(); } - -/*! - \internal -*/ -class QGraphicsShadowEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsShadowEffect) -public: - QGraphicsShadowEffectPrivate() - : offset(4,4) - , radius(8) - , alpha(0.7) - { - } - - QPointF offset; - int radius; - qreal alpha; -}; - -QGraphicsShadowEffect::QGraphicsShadowEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsShadowEffectPrivate, parent) +QGraphicsShadowEffect::QGraphicsShadowEffect() + : QGraphicsEffect(*new QGraphicsShadowEffectPrivate) { } @@ -758,25 +663,30 @@ void QGraphicsShadowEffect::setOpacity(qreal opacity) d->alpha = opacity; } -QRectF QGraphicsShadowEffect::boundingRectFor(const QGraphicsItem *item) +QRectF QGraphicsShadowEffect::boundingRect() const { - Q_D(QGraphicsShadowEffect); - QRectF shadowRect = item->boundingRect(); + Q_D(const QGraphicsShadowEffect); + if (!d->source) + return QRectF(); + const QRectF srcBrect = d->source->boundingRect(); + QRectF shadowRect = srcBrect; shadowRect.adjust(d->offset.x(), d->offset.y(), d->offset.x(), d->offset.y()); QRectF blurRect = shadowRect; qreal delta = d->radius * 3; blurRect.adjust(-delta, -delta, delta, delta); - QRectF totalRect = blurRect.united(item->boundingRect()); + QRectF totalRect = blurRect.united(srcBrect); return totalRect; } -void QGraphicsShadowEffect::drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option, QWidget *widget) +void QGraphicsShadowEffect::draw(QPainter *painter) { Q_D(QGraphicsShadowEffect); + if (!d->source) + return; // Find the item's bounds in device coordinates. - QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect()); + QTransform itemToPixmapTransform(painter->worldTransform()); + QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect()); QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); if (deviceRect.isEmpty()) return; @@ -786,13 +696,16 @@ void QGraphicsShadowEffect::drawItem(QGraphicsItem *item, QPainter *painter, QRectF blurRect = shadowRect; qreal delta = d->radius * 3; blurRect.adjust(-delta, -delta, delta, delta); - QRectF totalRect = blurRect.united(deviceRect); + QRect totalRect = blurRect.united(deviceRect).toRect().adjusted(-1, -1, 1, 1); - QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0); - if (!pixmap) + if (totalRect.x() != 0 || totalRect.y() != 0) + itemToPixmapTransform *= QTransform::fromTranslate(-totalRect.x(), -totalRect.y()); + + QPixmap pixmap(totalRect.size()); + if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform)) return; - QImage img = pixmap->toImage(); + QImage img = pixmap.toImage(); QImage shadowImage(img.size(), QImage::Format_ARGB32); shadowImage.fill(qRgba(0, 0, 0, d->alpha * 255)); shadowImage.setAlphaChannel(img.alphaChannel()); @@ -814,10 +727,9 @@ void QGraphicsShadowEffect::drawItem(QGraphicsItem *item, QPainter *painter, qreal itemx = qMin(blurRect.x(), deviceBounds.x()); qreal itemy = qMin(blurRect.y(), deviceBounds.y()); - painter->drawPixmap(itemx, itemy, *pixmap); + painter->drawPixmap(itemx, itemy, pixmap); painter->setWorldTransform(restoreTransform); } - #endif diff --git a/src/gui/graphicsview/qgraphicseffect.h b/src/gui/graphicsview/qgraphicseffect.h index 29d97a6..74a8430 100644 --- a/src/gui/graphicsview/qgraphicseffect.h +++ b/src/gui/graphicsview/qgraphicseffect.h @@ -46,6 +46,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qpoint.h> #include <QtCore/qvariant.h> +#include <QtGui/qtransform.h> #include <QtGui/qcolor.h> QT_FORWARD_DECLARE_CLASS(QGraphicsItem); @@ -67,24 +68,22 @@ class QGraphicsEffectPrivate; class Q_GUI_EXPORT QGraphicsEffect : public QObject { Q_OBJECT - public: - - QGraphicsEffect(QObject *parent = 0); + QGraphicsEffect(); virtual ~QGraphicsEffect(); - virtual QRectF boundingRectFor(const QGraphicsItem *item); - - virtual void drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option = 0, - QWidget *widget = 0) = 0; + virtual QRectF boundingRect() const; protected: - QGraphicsEffect(QGraphicsEffectPrivate &d, QObject* parent); - QPixmap* drawItemOnPixmap(QPainter *painter, QGraphicsItem *item, - const QStyleOptionGraphicsItem *option, QWidget *widget, int flags); + QGraphicsEffect(QGraphicsEffectPrivate &d); + virtual void draw(QPainter *painter) = 0; + void drawSource(QPainter *painter); + bool drawSourceIntoPixmap(QPixmap *pixmap, const QTransform &xform = QTransform()); + QRectF sourceBoundingRect() const; private: + friend class QGraphicsScenePrivate; + friend class QGraphicsItem; Q_DECLARE_PRIVATE(QGraphicsEffect) Q_DISABLE_COPY(QGraphicsEffect) }; @@ -93,15 +92,12 @@ class QGraphicsGrayscaleEffectPrivate; class Q_GUI_EXPORT QGraphicsGrayscaleEffect: public QGraphicsEffect { Q_OBJECT - public: - - QGraphicsGrayscaleEffect(QObject *parent = 0); + QGraphicsGrayscaleEffect(); ~QGraphicsGrayscaleEffect(); - void drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option = 0, - QWidget *widget = 0); +protected: + void draw(QPainter *painter); private: Q_DECLARE_PRIVATE(QGraphicsGrayscaleEffect) @@ -111,18 +107,15 @@ private: class QGraphicsColorizeEffectPrivate; class Q_GUI_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect { Q_OBJECT - public: - - QGraphicsColorizeEffect(QObject *parent = 0); + QGraphicsColorizeEffect(); ~QGraphicsColorizeEffect(); QColor color() const; void setColor(const QColor &c); - void drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option = 0, - QWidget *widget = 0); +protected: + void draw(QPainter *painter); private: Q_DECLARE_PRIVATE(QGraphicsColorizeEffect) @@ -132,18 +125,15 @@ private: class QGraphicsPixelizeEffectPrivate; class Q_GUI_EXPORT QGraphicsPixelizeEffect: public QGraphicsEffect { Q_OBJECT - public: - - QGraphicsPixelizeEffect(QObject *parent = 0); + QGraphicsPixelizeEffect(); ~QGraphicsPixelizeEffect(); int pixelSize() const; void setPixelSize(int pixelSize); - void drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option = 0, - QWidget *widget = 0); +protected: + void draw(QPainter *painter); private: Q_DECLARE_PRIVATE(QGraphicsPixelizeEffect) @@ -153,20 +143,17 @@ private: class QGraphicsBlurEffectPrivate; class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect { Q_OBJECT - public: - - QGraphicsBlurEffect(QObject *parent = 0); + QGraphicsBlurEffect(); ~QGraphicsBlurEffect(); int blurRadius() const; void setBlurRadius(int blurRadius); - QRectF boundingRectFor(const QGraphicsItem *item); + QRectF boundingRect() const; - void drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option = 0, - QWidget *widget = 0); +protected: + void draw(QPainter *painter); private: Q_DECLARE_PRIVATE(QGraphicsBlurEffect) @@ -176,10 +163,8 @@ private: class QGraphicsBloomEffectPrivate; class Q_GUI_EXPORT QGraphicsBloomEffect: public QGraphicsEffect { Q_OBJECT - public: - - QGraphicsBloomEffect(QObject *parent = 0); + QGraphicsBloomEffect(); ~QGraphicsBloomEffect(); int blurRadius() const; @@ -188,11 +173,10 @@ public: qreal opacity() const; void setOpacity(qreal opacity); - QRectF boundingRectFor(const QGraphicsItem *item); + QRectF boundingRect() const; - void drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option = 0, - QWidget *widget = 0); +protected: + void draw(QPainter *painter); private: Q_DECLARE_PRIVATE(QGraphicsBloomEffect) @@ -202,10 +186,8 @@ private: class QGraphicsFrameEffectPrivate; class Q_GUI_EXPORT QGraphicsFrameEffect: public QGraphicsEffect { Q_OBJECT - public: - - QGraphicsFrameEffect(QObject *parent = 0); + QGraphicsFrameEffect(); ~QGraphicsFrameEffect(); QColor frameColor() const; @@ -217,11 +199,11 @@ public: qreal frameOpacity() const; void setFrameOpacity(qreal opacity); - QRectF boundingRectFor(const QGraphicsItem *item); + QRectF boundingRect() const; + +protected: + void draw(QPainter *painter); - void drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option = 0, - QWidget *widget = 0); private: Q_DECLARE_PRIVATE(QGraphicsFrameEffect) Q_DISABLE_COPY(QGraphicsFrameEffect) @@ -230,10 +212,8 @@ private: class QGraphicsShadowEffectPrivate; class Q_GUI_EXPORT QGraphicsShadowEffect: public QGraphicsEffect { Q_OBJECT - public: - - QGraphicsShadowEffect(QObject *parent = 0); + QGraphicsShadowEffect(); ~QGraphicsShadowEffect(); QPointF shadowOffset() const; @@ -247,13 +227,10 @@ public: qreal opacity() const; void setOpacity(qreal opacity); - QRectF boundingRectFor(const QGraphicsItem *item); - - void drawItem(QGraphicsItem *item, QPainter *painter, - const QStyleOptionGraphicsItem *option = 0, - QWidget *widget = 0); + QRectF boundingRect() const; protected: + void draw(QPainter *painter); private: Q_DECLARE_PRIVATE(QGraphicsShadowEffect) diff --git a/src/gui/graphicsview/qgraphicseffect_p.h b/src/gui/graphicsview/qgraphicseffect_p.h new file mode 100644 index 0000000..9204789 --- /dev/null +++ b/src/gui/graphicsview/qgraphicseffect_p.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSEFFECT_P_H +#define QGRAPHICSEFFECT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qgraphicseffect.h" +#include <private/qobject_p.h> +#include <private/qpixmapfilter_p.h> + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +QT_BEGIN_NAMESPACE + +class QGraphicsEffectSource +{ +public: + QGraphicsEffectSource() {} + virtual ~QGraphicsEffectSource() {} + virtual void detach() = 0; + virtual QRectF boundingRect() = 0; + virtual void draw(QPainter *p) = 0; + virtual bool drawIntoPixmap(QPixmap *, const QTransform & = QTransform()) = 0; +}; + +class QGraphicsEffectPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsEffect) +public: + QGraphicsEffectPrivate() : source(0) {} + QGraphicsEffectSource *source; + inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource) + { + if (source) { + source->detach(); + delete source; + } + source = newSource; + } +}; + +class QGraphicsGrayscaleEffectPrivate : public QGraphicsEffectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsGrayscaleEffect) +public: + QGraphicsGrayscaleEffectPrivate() + { + filter = new QPixmapColorizeFilter; + filter->setColor(Qt::black); + } + ~QGraphicsGrayscaleEffectPrivate() { delete filter; } + + QPixmapColorizeFilter *filter; +}; + +class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsColorizeEffect) +public: + QGraphicsColorizeEffectPrivate() { filter = new QPixmapColorizeFilter; } + ~QGraphicsColorizeEffectPrivate() { delete filter; } + + QPixmapColorizeFilter *filter; +}; + +class QGraphicsPixelizeEffectPrivate : public QGraphicsEffectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsPixelizeEffect) +public: + QGraphicsPixelizeEffectPrivate() : pixelSize(3) {} + + int pixelSize; +}; + +class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsBlurEffect) +public: + QGraphicsBlurEffectPrivate() : filter(new QPixmapBlurFilter), blurRadius(4) {} + ~QGraphicsBlurEffectPrivate() { delete filter; } + + QPixmapBlurFilter *filter; + int blurRadius; +}; + +class QGraphicsBloomEffectPrivate : public QGraphicsEffectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsBlurEffect) +public: + QGraphicsBloomEffectPrivate() : blurRadius(6), opacity(0.7) {} + + int blurRadius; + qreal opacity; +}; + +class QGraphicsFrameEffectPrivate : public QGraphicsEffectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsFrameEffect) +public: + QGraphicsFrameEffectPrivate() : color(Qt::blue), width(5), alpha(0.6) {} + + QColor color; + qreal width; + qreal alpha; +}; + +class QGraphicsShadowEffectPrivate : public QGraphicsEffectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsShadowEffect) +public: + QGraphicsShadowEffectPrivate() : offset(4,4), radius(8), alpha(0.7) {} + + QPointF offset; + int radius; + qreal alpha; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_GRAPHICSVIEW + +#endif // QGRAPHICSEFFECT_P_H diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c395e21..7533fa4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -552,7 +552,6 @@ #ifndef QT_NO_GRAPHICSVIEW -#include "qgraphicseffect.h" #include "qgraphicsscene.h" #include "qgraphicsscene_p.h" #include "qgraphicssceneevent.h" @@ -1180,6 +1179,7 @@ QGraphicsItem::~QGraphicsItem() else d_ptr->setParentItemHelper(0); + delete d_ptr->graphicsEffect; delete d_ptr->transformData; delete d_ptr; @@ -2190,39 +2190,53 @@ void QGraphicsItem::setOpacity(qreal opacity) } /*! + Returns a pointer to this item's effect if it has one; otherwise 0. + \since 4.6 - Returns this item's \e effect if it has one; otherwise, - returns 0. */ -QGraphicsEffect *QGraphicsItem::effect() const +QGraphicsEffect *QGraphicsItem::graphicsEffect() const { - QGraphicsEffect *fx = 0; - if (d_ptr->hasEffect) - fx = d_ptr->extra(QGraphicsItemPrivate::ExtraEffect).value<QGraphicsEffect*>(); - - return fx; + return d_ptr->graphicsEffect; } /*! + Sets \a effect as the item's effect. If there already is an effect installed + on this item, QGraphicsItem won't let you install another. You must first + delete the existing effect (returned by graphicsEffect()) before you can call + setGraphicsEffect() with the new effect. + + If \a effect is the installed on a different item, setGraphicsEffect() will remove + the effect from the item and install it on this item. + + \note This function will apply the effect on itself and all its children. + \since 4.6 - Sets \e effect as the item's effect. It will replace the previous effect - the item might have. */ -void QGraphicsItem::setEffect(QGraphicsEffect *effect) +void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) { - if (effect) { - d_ptr->hasEffect = true; - d_ptr->setExtra(QGraphicsItemPrivate::ExtraEffect, QVariant::fromValue(effect)); + if (d_ptr->graphicsEffect == effect) + return; + + if (d_ptr->graphicsEffect && effect) { + qWarning("QGraphicsItem::setGraphicsEffect: Attempting to set QGraphicsEffect " + "%p on %p, which already has an effect installed", effect, this); + return; + } + + if (!effect) { + // Unset current effect. + QGraphicsEffectPrivate *oldEffectPrivate = d_ptr->graphicsEffect->d_func(); + d_ptr->graphicsEffect = 0; + if (oldEffectPrivate) + oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source. } else { - d_ptr->hasEffect = false; - d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraEffect); - void *ptr = d_ptr->extra(QGraphicsItemPrivate::ExtraEffectPixmap).value<void*>(); - QPixmap *pixmap = reinterpret_cast<QPixmap*>(ptr); - delete pixmap; - d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraEffectPixmap); + // Set new effect. + effect->d_func()->setGraphicsEffectSource(new QGraphicsItemEffectSource(this)); + d_ptr->graphicsEffect = effect; } - update(); + if (d_ptr->scene) + d_ptr->scene->d_func()->markDirty(this); } /*! @@ -2236,10 +2250,8 @@ void QGraphicsItem::setEffect(QGraphicsEffect *effect) */ QRectF QGraphicsItem::effectiveBoundingRect() const { - QGraphicsEffect *fx = effect(); - if (fx) - return fx->boundingRectFor(this); - + if (d_ptr->graphicsEffect) + return d_ptr->graphicsEffect->boundingRect(); return boundingRect(); } @@ -2273,42 +2285,6 @@ QRectF QGraphicsItem::sceneEffectiveBoundingRect() const } /*! - \internal - - Used by QGraphicsScene. -*/ -QPixmap *QGraphicsItem::effectPixmap() -{ - if (!d_ptr->hasEffect) - return 0; - - // the exact size of the pixmap is not a big deal - // as long as it contains the effective bounding rect - // TODO: use smart resizing etc - // TODO: store per device and do everything in device coordinate? - // TODO: use layer - QRect rect = effectiveBoundingRect().toAlignedRect(); - - void *ptr = d_ptr->extra(QGraphicsItemPrivate::ExtraEffectPixmap).value<void*>(); - QPixmap *pixmap = reinterpret_cast<QPixmap*>(ptr); - bool avail = true; - if (!pixmap) - avail = false; - if (avail && pixmap->size() != rect.size()) - avail = false; - - if (!avail) { - delete pixmap; - pixmap = new QPixmap(rect.size()); - pixmap->fill(Qt::transparent); - ptr = reinterpret_cast<void*>(pixmap); - d_ptr->setExtra(QGraphicsItemPrivate::ExtraEffectPixmap, QVariant::fromValue(ptr)); - } - - return pixmap; -} - -/*! Returns true if this item can accept drag and drop events; otherwise, returns false. By default, items do not accept drag and drop events; items are transparent to drag and drop. diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 4cb94bf..1bcf0e0 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -208,8 +208,8 @@ public: void setOpacity(qreal opacity); // Effect - QGraphicsEffect *effect() const; - void setEffect(QGraphicsEffect *effect); + QGraphicsEffect *graphicsEffect() const; + void setGraphicsEffect(QGraphicsEffect *effect); QRectF effectiveBoundingRect() const; QRectF sceneEffectiveBoundingRect() const; @@ -443,8 +443,6 @@ protected: void removeFromIndex(); void prepareGeometryChange(); - QPixmap *effectPixmap(); - private: Q_DISABLE_COPY(QGraphicsItem) Q_DECLARE_PRIVATE(QGraphicsItem) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 3f02560..1fedca8 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -57,6 +57,7 @@ #include "qset.h" #include "qpixmapcache.h" #include "qgraphicsview_p.h" +#include "qgraphicseffect_p.h" #include <QtCore/qpoint.h> @@ -103,8 +104,6 @@ public: ExtraCacheData, ExtraMaxDeviceCoordCacheSize, ExtraBoundingRegionGranularity, - ExtraEffect, - ExtraEffectPixmap, ExtraGestures }; @@ -122,6 +121,7 @@ public: scene(0), parent(0), transformData(0), + graphicsEffect(0), index(-1), siblingIndex(-1), depth(0), @@ -152,7 +152,6 @@ public: allChildrenDirty(0), fullUpdatePending(0), flags(0), - hasEffect(0), dirtyChildrenBoundingRect(1), paintedViewBoundingRectsNeedRepaint(0), dirtySceneTransform(1), @@ -410,6 +409,7 @@ public: QList<QGraphicsItem *> children; struct TransformData; TransformData *transformData; + QGraphicsEffect *graphicsEffect; QTransform sceneTransform; int index; int siblingIndex; @@ -445,7 +445,6 @@ public: // New 32 bits quint32 fullUpdatePending : 1; quint32 flags : 12; - quint32 hasEffect : 1; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; quint32 dirtySceneTransform : 1; @@ -513,6 +512,44 @@ struct QGraphicsItemPrivate::TransformData { } }; +class QGraphicsItemEffectSource : public QGraphicsEffectSource +{ +public: + QGraphicsItemEffectSource(QGraphicsItem *i) + : QGraphicsEffectSource(), item(i), option(0), widget(0) + {} + + inline void detach() + { item->setGraphicsEffect(0); } + + inline QRectF boundingRect() + { return item->boundingRect(); } + + inline void draw(QPainter *painter) + { item->paint(painter, option, widget); } + + inline bool drawIntoPixmap(QPixmap *pixmap, const QTransform &itemToPixmapTransform) + { + pixmap->fill(Qt::transparent); + QPainter pixmapPainter(pixmap); + if (!itemToPixmapTransform.isIdentity()) + pixmapPainter.setWorldTransform(itemToPixmapTransform); + item->paint(&pixmapPainter, option, widget); + return true; + } + + inline void setPaintInfo(const QStyleOptionGraphicsItem *o, QWidget *w) + { option = o; widget = w; } + + void resetPaintInfo() + { option = 0; widget = 0; } + +private: + QGraphicsItem *item; + const QStyleOptionGraphicsItem *option; + QWidget *widget; +}; + /*! \internal */ diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index b2b9ebd..41bcb76 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -3971,8 +3971,8 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte #endif // Render using effect, works now only for no cache mode - if (noCache && itemd->hasEffect && item->effect()) { - item->effect()->drawItem(item, painter, option, widget); + if (noCache && itemd->graphicsEffect) { + itemd->graphicsEffect->draw(painter); return; } @@ -4271,62 +4271,6 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte } } -// FIXME: merge this with drawItems (needs refactoring) -QPixmap* QGraphicsScene::drawItemOnPixmap(QPainter *painter, - QGraphicsItem *item, - const QStyleOptionGraphicsItem *option, - QWidget *widget, - int flags) -{ - // TODO: use for choosing item or device coordinate - // FIXME: how about source, dest, and exposed rects? - Q_UNUSED(flags); - - // Item's (local) bounding rect, including the effect - QRectF brect = item->effectiveBoundingRect(); - QRectF adjustedBrect(brect); - _q_adjustRect(&adjustedBrect); - if (adjustedBrect.isEmpty()) - return 0; - - // Find the item's bounds in device coordinates. - QRectF deviceBounds = painter->worldTransform().mapRect(brect); - QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); - if (deviceRect.isEmpty()) - return 0; - - // If widget, check if it intersects or not - QRect viewRect = widget ? widget->rect() : QRect(); - if (widget && !viewRect.intersects(deviceRect)) - return 0; - - // Create offscreen pixmap - // TODO: use the pixmap from the layer - QPixmap *targetPixmap = item->effectPixmap(); - if (!targetPixmap) - targetPixmap = new QPixmap(deviceRect.size()); - - // FIXME: this is brute force - QRegion pixmapExposed; - pixmapExposed += targetPixmap->rect(); - - // Construct an item-to-pixmap transform. - QPointF p = deviceRect.topLeft(); - QTransform itemToPixmap = painter->worldTransform(); - if (!p.isNull()) - itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y()); - - // Calculate the style option's exposedRect. - QStyleOptionGraphicsItem fxOption = *option; - fxOption.exposedRect = brect.adjusted(-1, -1, 1, 1); - - // Render - _q_paintIntoCache(targetPixmap, item, pixmapExposed, itemToPixmap, painter->renderHints(), - &fxOption, false); - - return targetPixmap; -} - void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const viewTransform, QRegion *exposedRegion, QWidget *widget) { @@ -4455,11 +4399,21 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * painter->setClipPath(item->shape(), Qt::IntersectClip); painter->setOpacity(opacity); - if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget && !item->d_ptr->hasEffect) + QGraphicsItemEffectSource *source = item->d_ptr->graphicsEffect + ? static_cast<QGraphicsItemEffectSource *> + (item->d_ptr->graphicsEffect->d_func()->source) + : 0; + if (source) + source->setPaintInfo(&styleOptionTmp, widget); + + if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget && !source) item->paint(painter, &styleOptionTmp, widget); else drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection); + if (source) + source->resetPaintInfo(); + if (savePainter) painter->restore(); } diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 6292afa..89436aa 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -282,11 +282,6 @@ protected: const QStyleOptionGraphicsItem options[], QWidget *widget = 0); - QPixmap* drawItemOnPixmap(QPainter *painter, QGraphicsItem *item, - const QStyleOptionGraphicsItem *option, QWidget *widget, int flags); - - - protected Q_SLOTS: bool focusNextPrevChild(bool next); |