summaryrefslogtreecommitdiffstats
path: root/src/gui/graphicsview/qgraphicseffect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/graphicsview/qgraphicseffect.cpp')
-rw-r--r--src/gui/graphicsview/qgraphicseffect.cpp234
1 files changed, 139 insertions, 95 deletions
diff --git a/src/gui/graphicsview/qgraphicseffect.cpp b/src/gui/graphicsview/qgraphicseffect.cpp
index c173d1b..8d2c416 100644
--- a/src/gui/graphicsview/qgraphicseffect.cpp
+++ b/src/gui/graphicsview/qgraphicseffect.cpp
@@ -104,83 +104,90 @@
QGraphicsEffect::QGraphicsEffect()
: QObject(*new QGraphicsEffectPrivate, 0)
+{}
+
+/*!
+ \internal
+*/
+QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd)
+ : QObject(dd, 0)
+{}
+
+QGraphicsEffect::~QGraphicsEffect()
{
Q_D(QGraphicsEffect);
- d->parentItem = 0;
+ d->setGraphicsEffectSource(0);
}
-QGraphicsEffect::~QGraphicsEffect()
+QRectF QGraphicsEffect::boundingRect() const
{
+ return sourceBoundingRect();
}
-QRectF QGraphicsEffect::boundingRectFor(const QGraphicsItem *item)
+QRectF QGraphicsEffect::sourceBoundingRect() 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();
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ return d->source->boundingRect();
+ return QRectF();
}
-/*! \internal
-*/
-QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd)
- : QObject(dd, 0)
+void QGraphicsEffect::drawSource(QPainter *painter)
{
Q_D(QGraphicsEffect);
- d->parentItem = 0;
+ if (d->source)
+ d->source->draw(painter);
}
-// 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)
+bool QGraphicsEffect::drawSourceIntoPixmap(QPixmap *pixmap, const QTransform &itemToPixmapTransform)
{
- if (!item->scene())
- return 0;
- return item->scene()->drawItemOnPixmap(painter, item, option, widget, flags);
+ 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);
+
}
QGraphicsColorizeEffect::QGraphicsColorizeEffect()
: QGraphicsEffect(*new QGraphicsColorizeEffectPrivate)
-{
-}
+{}
QGraphicsColorizeEffect::~QGraphicsColorizeEffect()
-{
-}
+{}
QColor QGraphicsColorizeEffect::color() const
{
@@ -194,25 +201,30 @@ 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);
}
@@ -237,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();
@@ -365,31 +382,42 @@ 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);
}
@@ -426,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
@@ -466,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);
@@ -540,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);
+
+ if (frameRect.x() != 0 || frameRect.y() != 0)
+ itemToPixmapTransform *= QTransform::fromTranslate(-frameRect.x(), -frameRect.y());
- QRectF frameRect = deviceBounds;
- frameRect.adjust(-d->width, -d->width, d->width, d->width);
+ QPixmap pixmap(frameRect.size());
+ if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform))
+ return;
painter->save();
painter->setWorldTransform(QTransform());
@@ -576,7 +613,7 @@ 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();
}
@@ -626,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;
@@ -654,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());
@@ -682,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