summaryrefslogtreecommitdiffstats
path: root/src/gui/effects
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/effects')
-rw-r--r--src/gui/effects/qgraphicseffect.cpp876
-rw-r--r--src/gui/effects/qgraphicseffect.h291
-rw-r--r--src/gui/effects/qgraphicseffect_p.h195
3 files changed, 1362 insertions, 0 deletions
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
new file mode 100644
index 0000000..b04af7a
--- /dev/null
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -0,0 +1,876 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QGraphicsEffect
+ \brief The QGraphicsEffect class is the base class for all graphics effects.
+ \since 4.6
+ \ingroup multimedia
+ \ingroup graphicsview-api
+
+ Effects alter the appearance of elements by hooking into the rendering
+ pipeline and operating between the source (e.g., a QGraphicsPixmapItem),
+ and the destination device (e.g., QGraphicsView's viewport). Effects can be
+ disabled by calling setEnabled(); if the effect is disabled, the source is
+ rendered directly.
+
+ If you want to add a visual effect to a QGraphicsItem, you can either use
+ one of the standard effects, or create your own effect by making a subclass
+ of QGraphicsEffect.
+
+ Qt provides several standard effects, including:
+
+ \list
+ \o QGraphicsGrayScaleEffect - renders the item in shades of gray
+ \o QGraphicsColorizeEffect - renders the item in shades of any given color
+ \o QGraphicsPixelizeEffect - pixelizes the item with any pixel size
+ \o QGraphicsBlurEffect - blurs the item by a given radius
+ \o QGraphicsBloomEffect - applies a blooming / glowing effect
+ \o QGraphicsFrameEffect - adds a frame to the item
+ \o QGraphicsShadowEffect - renders a dropshadow behind the item
+ \endlist
+
+ If all you want is to add an effect to an item, you should visit the
+ documentation for the specific effect to learn more about how each effect
+ can be used.
+
+ If you want to create your own custom effect, you can start by creating a
+ subclass of QGraphicsEffect (or any of the existing effects), and
+ reimplement the virtual function draw(). This function is called whenever
+ the effect needs to redraw. draw() has two arguments: the painter, and a
+ pointer to the source (QGraphicsEffectSource). The source provides extra
+ context information, such as a pointer to the item that is rendering the
+ effect, any cached pixmap data, and the device rect bounds. See the draw()
+ documentation for more details. You can also get a pointer to the current
+ source by calling source().
+
+ If your effect changes, you can call update() to request a redraw. If your
+ custom effect changes the bounding rectangle of the source (e.g., a radial
+ glow effect may need to apply an extra margin), you can reimplement the
+ virtual boundingRectFor() function, and call updateBoundingRect() to notify
+ the framework whenever this rectangle changes. The virtual
+ sourceBoundingRectChanged() function is called to notify the effects that
+ the source's bounding rectangle has changed (e.g., if the source is a
+ QGraphicsRectItem, then if the rectangle parameters have changed).
+
+ \sa QGraphicsItem::setGraphicsEffect()
+*/
+
+#include "qgraphicseffect_p.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include <QtGui/qimage.h>
+#include <QtGui/qpainter.h>
+#include <QtCore/qrect.h>
+
+/*
+
+ List of known drawbacks which are being discussed:
+
+ * No d-pointer yet.
+
+ * No auto test yet.
+
+ * No API documentation yet.
+
+ * The API is far from being finalized.
+
+ * Most of the effect implementation is not efficient,
+ as this is still a proof of concept only.
+
+ * Painting artifacts occasionally occur when e.g. moving
+ an item over another item that has a large effective
+ bounding rect.
+
+ * Item transformation is not taken into account.
+ For example, the effective bounding rect is calculated at
+ item coordinate (fast), but the painting is mostly
+ done at device coordinate.
+
+ * Coordinate mode: item vs device. Most effects make sense only
+ in device coordinate. Should we keep both options open?
+ See also above transformation issue.
+
+ * Right now the pixmap for effect drawing is stored in each item.
+ There can be problems with coordinates, see above.
+
+ * There is a lot of duplication in drawItems() for each effect.
+
+ * Port to use the new layer feature in QGraphicsView.
+ This should solve the above pixmap problem.
+
+ * Frame effect is likely useless. However it is very useful
+ to check than the effective bounding rect is handled properly.
+
+ * Proper exposed region and rect for style option are missing.
+
+ * Pixelize effect is using raster only, because there is no
+ pixmap filter for it. We need to implement the missing pixmap filter.
+
+ * Blur effect is using raster only, with exponential blur algorithm.
+ Perhaps use stack blur (better approximate Gaussian blur) instead?
+ QPixmapConvolutionFilter is too slow for this simple blur effect.
+
+ * Bloom and shadow effect are also raster only. Same reason as above.
+
+ * Make it work with widgets (QGraphicsWidget).
+
+*/
+
+QGraphicsEffectSource::QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{}
+
+QGraphicsEffectSource::~QGraphicsEffectSource()
+{}
+
+QRect QGraphicsEffectSource::deviceRect() const
+{
+ return d_func()->deviceRect();
+}
+
+QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const
+{
+ return d_func()->boundingRect(system);
+}
+
+const QGraphicsItem *QGraphicsEffectSource::graphicsItem() const
+{
+ return d_func()->graphicsItem();
+}
+
+const QStyleOption *QGraphicsEffectSource::styleOption() const
+{
+ return d_func()->styleOption();
+}
+
+void QGraphicsEffectSource::draw(QPainter *painter)
+{
+ d_func()->draw(painter);
+}
+
+void QGraphicsEffectSource::update()
+{
+ d_func()->update();
+}
+
+bool QGraphicsEffectSource::isPixmap() const
+{
+ return d_func()->isPixmap();
+}
+
+QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset) const
+{
+ return d_func()->pixmap(system, offset);
+}
+
+/*!
+ Constructs a new QGraphicsEffect instance.
+*/
+QGraphicsEffect::QGraphicsEffect()
+ : QObject(*new QGraphicsEffectPrivate, 0)
+{
+ // ### parent?
+}
+
+/*!
+ \internal
+*/
+QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd)
+ : QObject(dd, 0)
+{
+}
+
+/*!
+ Removes the effect from the source, and destroys the graphics effect.
+*/
+QGraphicsEffect::~QGraphicsEffect()
+{
+ Q_D(QGraphicsEffect);
+ d->setGraphicsEffectSource(0);
+}
+
+/*!
+ Returns the bounding rectangle for this effect (i.e., the bounding
+ rectangle of the source, adjusted by any margins applied by the effect
+ itself).
+
+ \sa boundingRectFor(), updateBoundingRect()
+*/
+QRectF QGraphicsEffect::boundingRect() const
+{
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ return boundingRectFor(d->source->boundingRect());
+ return QRectF();
+}
+
+/*!
+ Returns the bounding rectangle for this effect, given the provided source
+ \a rect. When writing you own custom effect, you must call
+ updateBoundingRect() whenever any parameters are changed that may cause
+ this this function to return a different value.
+
+ \sa boundingRect()
+*/
+QRectF QGraphicsEffect::boundingRectFor(const QRectF &rect) const
+{
+ return rect;
+}
+
+/*!
+ \property QGraphicsEffect::enabled
+ \brief whether the effect is enabled or not.
+
+ If an effect is disabled, the source will be rendered with as normal, with
+ no interference from the effect. If the effect is enabled (default), the
+ source will be rendered with the effect applied.
+
+ This property is provided so that you can disable certain effects on slow
+ platforms, in order to ensure that the user interface is responsive.
+*/
+bool QGraphicsEffect::isEnabled() const
+{
+ Q_D(const QGraphicsEffect);
+ return d->isEnabled;
+}
+void QGraphicsEffect::setEnabled(bool enable)
+{
+ Q_D(QGraphicsEffect);
+ if (d->isEnabled == enable)
+ return;
+
+ d->isEnabled = enable;
+
+ if (d->source)
+ d->source->update();
+}
+
+/*!
+ Returns a pointer to the source, which provides extra context information
+ that can be useful for the effect.
+
+ \sa draw()
+*/
+QGraphicsEffectSource *QGraphicsEffect::source() const
+{
+ Q_D(const QGraphicsEffect);
+ return d->source;
+}
+
+/*!
+ This function notifies the effect framework that the effect's bounding
+ rectangle has changed. As a custom effect author, you must call this
+ function whenever you change any parameters that will cause the virtual
+ boundingRectFor() function to return a different value.
+
+ \sa boundingRectFor(), boundingRect()
+*/
+void QGraphicsEffect::updateBoundingRect()
+{
+ Q_D(QGraphicsEffect);
+ if (d->source)
+ d->source->update();
+}
+
+/*!
+ This virtual function is called by QGraphicsEffect to notify the effect
+ that the source has changed. If the effect applies any cache, then this
+ cache must be purged in order to reflect the new appearance of the source.
+
+ The \a flags describes what has changed.
+*/
+void QGraphicsEffect::sourceChanged(ChangeFlags flags)
+{
+ Q_UNUSED(flags);
+}
+
+QGraphicsGrayscaleEffect::QGraphicsGrayscaleEffect()
+ : QGraphicsEffect(*new QGraphicsGrayscaleEffectPrivate)
+{
+}
+
+QGraphicsGrayscaleEffect::~QGraphicsGrayscaleEffect()
+{
+}
+
+void QGraphicsGrayscaleEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsGrayscaleEffect);
+ QPoint offset;
+ if (source->isPixmap()) {
+ // No point in drawing in device coordinates (pixmap will be scaled anyways).
+ const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
+ d->filter->draw(painter, offset, pixmap);
+ return;
+ }
+
+ // Draw pixmap in device coordinates to avoid pixmap scaling;
+ const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ d->filter->draw(painter, offset, pixmap);
+ painter->setWorldTransform(restoreTransform);
+
+}
+
+QGraphicsColorizeEffect::QGraphicsColorizeEffect()
+ : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate)
+{}
+
+QGraphicsColorizeEffect::~QGraphicsColorizeEffect()
+{}
+
+QColor QGraphicsColorizeEffect::color() const
+{
+ Q_D(const QGraphicsColorizeEffect);
+ return d->filter->color();
+}
+
+void QGraphicsColorizeEffect::setColor(const QColor &c)
+{
+ Q_D(QGraphicsColorizeEffect);
+ d->filter->setColor(c);
+}
+
+void QGraphicsColorizeEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsColorizeEffect);
+ QPoint offset;
+ if (source->isPixmap()) {
+ // No point in drawing in device coordinates (pixmap will be scaled anyways).
+ const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
+ d->filter->draw(painter, offset, pixmap);
+ return;
+ }
+
+ // Draw pixmap in deviceCoordinates to avoid pixmap scaling.
+ const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ d->filter->draw(painter, offset, pixmap);
+ painter->setWorldTransform(restoreTransform);
+}
+
+QGraphicsPixelizeEffect::QGraphicsPixelizeEffect()
+ : QGraphicsEffect(*new QGraphicsPixelizeEffectPrivate)
+{
+}
+
+QGraphicsPixelizeEffect::~QGraphicsPixelizeEffect()
+{
+}
+
+int QGraphicsPixelizeEffect::pixelSize() const
+{
+ Q_D(const QGraphicsPixelizeEffect);
+ return d->pixelSize;
+}
+
+void QGraphicsPixelizeEffect::setPixelSize(int size)
+{
+ Q_D(QGraphicsPixelizeEffect);
+ d->pixelSize = size;
+}
+
+static inline void pixelize(QImage *image, int pixelSize)
+{
+ Q_ASSERT(pixelSize > 0);
+ Q_ASSERT(image);
+ int width = image->width();
+ int height = image->height();
+ for (int y = 0; y < height; y += pixelSize) {
+ int ys = qMin(height - 1, y + pixelSize / 2);
+ QRgb *sbuf = reinterpret_cast<QRgb*>(image->scanLine(ys));
+ for (int x = 0; x < width; x += pixelSize) {
+ int xs = qMin(width - 1, x + pixelSize / 2);
+ QRgb color = sbuf[xs];
+ for (int yi = 0; yi < qMin(pixelSize, height - y); ++yi) {
+ QRgb *buf = reinterpret_cast<QRgb*>(image->scanLine(y + yi));
+ for (int xi = 0; xi < qMin(pixelSize, width - x); ++xi)
+ buf[x + xi] = color;
+ }
+ }
+ }
+}
+
+void QGraphicsPixelizeEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsPixelizeEffect);
+ if (d->pixelSize <= 0) {
+ source->draw(painter);
+ return;
+ }
+
+ QPoint offset;
+ if (source->isPixmap()) {
+ const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
+ QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ pixelize(&image, d->pixelSize);
+ painter->drawImage(offset, image);
+ return;
+ }
+
+ // Draw pixmap in device coordinates to avoid pixmap scaling.
+ const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+
+ // pixelize routine
+ QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ pixelize(&image, d->pixelSize);
+
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ painter->drawImage(offset, image);
+ painter->setWorldTransform(restoreTransform);
+}
+
+QGraphicsBlurEffect::QGraphicsBlurEffect()
+ : QGraphicsEffect(*new QGraphicsBlurEffectPrivate)
+{
+}
+
+QGraphicsBlurEffect::~QGraphicsBlurEffect()
+{
+}
+
+// Blur the image according to the blur radius
+// Based on exponential blur algorithm by Jani Huhtanen
+// (maximum radius is set to 16)
+static QImage blurred(const QImage& image, const QRect& rect, int radius)
+{
+ int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
+ int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
+
+ QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ int r1 = rect.top();
+ int r2 = rect.bottom();
+ int c1 = rect.left();
+ int c2 = rect.right();
+
+ int bpl = result.bytesPerLine();
+ int rgba[4];
+ unsigned char* p;
+
+ for (int col = c1; col <= c2; col++) {
+ p = result.scanLine(r1) + col * 4;
+ for (int i = 0; i < 4; i++)
+ rgba[i] = p[i] << 4;
+
+ p += bpl;
+ for (int j = r1; j < r2; j++, p += bpl)
+ for (int i = 0; i < 4; i++)
+ p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ }
+
+ for (int row = r1; row <= r2; row++) {
+ p = result.scanLine(row) + c1 * 4;
+ for (int i = 0; i < 4; i++)
+ rgba[i] = p[i] << 4;
+
+ p += 4;
+ for (int j = c1; j < c2; j++, p += 4)
+ for (int i = 0; i < 4; i++)
+ p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ }
+
+ for (int col = c1; col <= c2; col++) {
+ p = result.scanLine(r2) + col * 4;
+ for (int i = 0; i < 4; i++)
+ rgba[i] = p[i] << 4;
+
+ p -= bpl;
+ for (int j = r1; j < r2; j++, p -= bpl)
+ for (int i = 0; i < 4; i++)
+ p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ }
+
+ for (int row = r1; row <= r2; row++) {
+ p = result.scanLine(row) + c2 * 4;
+ for (int i = 0; i < 4; i++)
+ rgba[i] = p[i] << 4;
+
+ p -= 4;
+ for (int j = c1; j < c2; j++, p -= 4)
+ for (int i = 0; i < 4; i++)
+ p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ }
+
+ return result;
+}
+
+int QGraphicsBlurEffect::blurRadius() const
+{
+ Q_D(const QGraphicsBlurEffect);
+ return d->filter->radius();
+}
+
+void QGraphicsBlurEffect::setBlurRadius(int radius)
+{
+ Q_D(QGraphicsBlurEffect);
+ d->filter->setRadius(radius);
+ updateBoundingRect();
+}
+
+QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsBlurEffect);
+ return d->filter->boundingRectFor(rect);
+}
+
+void QGraphicsBlurEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsBlurEffect);
+ if (d->filter->radius() <= 0) {
+ source->draw(painter);
+ return;
+ }
+
+ QPoint offset;
+ if (source->isPixmap()) {
+ // No point in drawing in device coordinates (pixmap will be scaled anyways).
+ const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
+ d->filter->draw(painter, offset, pixmap);
+ return;
+ }
+
+ // Draw pixmap in device coordinates to avoid pixmap scaling.
+ const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ d->filter->draw(painter, offset, pixmap);
+ painter->setWorldTransform(restoreTransform);
+}
+
+QGraphicsBloomEffect::QGraphicsBloomEffect()
+ : QGraphicsEffect(*new QGraphicsBloomEffectPrivate)
+{
+}
+
+QGraphicsBloomEffect::~QGraphicsBloomEffect()
+{
+}
+
+int QGraphicsBloomEffect::blurRadius() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->blurRadius;
+}
+
+void QGraphicsBloomEffect::setBlurRadius(int radius)
+{
+ Q_D(QGraphicsBloomEffect);
+ d->blurRadius = radius;
+ updateBoundingRect();
+}
+
+qreal QGraphicsBloomEffect::opacity() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->opacity;
+}
+
+void QGraphicsBloomEffect::setOpacity(qreal alpha)
+{
+ Q_D(QGraphicsBloomEffect);
+ d->opacity = alpha;
+}
+
+QRectF QGraphicsBloomEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsBloomEffect);
+ const qreal delta = d->blurRadius * 3;
+ return rect.adjusted(-delta, -delta, delta, delta);
+}
+
+// Change brightness (positive integer) of each pixel
+static QImage brightened(const QImage& image, int brightness)
+{
+ int tab[ 256 ];
+ for (int i = 0; i < 256; ++i)
+ tab[i] = qMin(i + brightness, 255);
+
+ QImage img = image.convertToFormat(QImage::Format_ARGB32);
+ for (int y = 0; y < img.height(); y++) {
+ QRgb* line = (QRgb*)(img.scanLine(y));
+ for (int x = 0; x < img.width(); x++) {
+ QRgb c = line[x];
+ line[x] = qRgba(tab[qRed(c)], tab[qGreen(c)], tab[qBlue(c)], qAlpha(c));
+ }
+ }
+
+ return img;
+}
+
+// Composite two QImages using given composition mode and opacity
+static QImage composited(const QImage& img1, const QImage& img2, qreal opacity, QPainter::CompositionMode mode)
+{
+ QImage result = img1.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ QPainter painter(&result);
+ painter.setCompositionMode(mode);
+ painter.setOpacity(opacity);
+ painter.drawImage(0, 0, img2);
+ painter.end();
+ return result;
+}
+
+void QGraphicsBloomEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsBloomEffect);
+ if (d->blurRadius <= 0) {
+ source->draw(painter);
+ return;
+ }
+
+ QPoint offset;
+ const int radius = d->blurRadius;
+
+ if (source->isPixmap()) {
+ // No point in drawing in device coordinates (pixmap will be scaled anyways).
+ const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
+
+ // bloom routine
+ 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);
+
+ painter->drawImage(offset, img);
+ return;
+ }
+
+ // Draw pixmap in device coordinates to avoid pixmap scaling.
+ const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+
+ // bloom routine
+ 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);
+
+ // Draw using an untransformed painter.
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ painter->drawImage(offset, img);
+ painter->setWorldTransform(restoreTransform);
+}
+
+QGraphicsFrameEffect::QGraphicsFrameEffect()
+ : QGraphicsEffect(*new QGraphicsFrameEffectPrivate)
+{
+}
+
+QGraphicsFrameEffect::~QGraphicsFrameEffect()
+{
+}
+
+QColor QGraphicsFrameEffect::frameColor() const
+{
+ Q_D(const QGraphicsFrameEffect);
+ return d->color;
+}
+
+void QGraphicsFrameEffect::setFrameColor(const QColor &c)
+{
+ Q_D(QGraphicsFrameEffect);
+ d->color = c;
+}
+
+qreal QGraphicsFrameEffect::frameWidth() const
+{
+ Q_D(const QGraphicsFrameEffect);
+ return d->width;
+}
+
+void QGraphicsFrameEffect::setFrameWidth(qreal frameWidth)
+{
+ Q_D(QGraphicsFrameEffect);
+ d->width = frameWidth;
+ updateBoundingRect();
+}
+
+qreal QGraphicsFrameEffect::frameOpacity() const
+{
+ Q_D(const QGraphicsFrameEffect);
+ return d->alpha;
+}
+
+void QGraphicsFrameEffect::setFrameOpacity(qreal opacity)
+{
+ Q_D(QGraphicsFrameEffect);
+ d->alpha = opacity;
+}
+
+QRectF QGraphicsFrameEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsFrameEffect);
+ return rect.adjusted(-d->width, -d->width, d->width, d->width);
+}
+
+void QGraphicsFrameEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsFrameEffect);
+ painter->save();
+ painter->setOpacity(painter->opacity() * d->alpha);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(d->color);
+ painter->drawRoundedRect(boundingRect(), 20, 20, Qt::RelativeSize);
+ painter->restore();
+
+ source->draw(painter);
+}
+
+QGraphicsShadowEffect::QGraphicsShadowEffect()
+ : QGraphicsEffect(*new QGraphicsShadowEffectPrivate)
+{
+}
+
+QGraphicsShadowEffect::~QGraphicsShadowEffect()
+{
+}
+
+QPointF QGraphicsShadowEffect::shadowOffset() const
+{
+ Q_D(const QGraphicsShadowEffect);
+ return d->offset;
+}
+
+void QGraphicsShadowEffect::setShadowOffset(const QPointF &ofs)
+{
+ Q_D(QGraphicsShadowEffect);
+ d->offset = ofs;
+ updateBoundingRect();
+}
+
+int QGraphicsShadowEffect::blurRadius() const
+{
+ Q_D(const QGraphicsShadowEffect);
+ return d->radius;
+}
+
+void QGraphicsShadowEffect::setBlurRadius(int blurRadius)
+{
+ Q_D(QGraphicsShadowEffect);
+ d->radius = blurRadius;
+ updateBoundingRect();
+}
+
+qreal QGraphicsShadowEffect::opacity() const
+{
+ Q_D(const QGraphicsShadowEffect);
+ return d->alpha;
+}
+
+void QGraphicsShadowEffect::setOpacity(qreal opacity)
+{
+ Q_D(QGraphicsShadowEffect);
+ d->alpha = opacity;
+}
+
+QRectF QGraphicsShadowEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsShadowEffect);
+ QRectF shadowRect = rect.translated(d->offset);
+ QRectF blurRect = shadowRect;
+ qreal delta = d->radius * 3;
+ blurRect.adjust(-delta, -delta, delta, delta);
+ blurRect |= rect;
+ return blurRect;
+}
+
+void QGraphicsShadowEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsShadowEffect);
+ if (d->radius <= 0 && d->offset.isNull()) {
+ source->draw(painter);
+ return;
+ }
+
+ const QTransform &transform = painter->worldTransform();
+ const QPointF offset(d->offset.x() * transform.m11(), d->offset.y() * transform.m22());
+ const QPoint shadowOffset = offset.toPoint();
+ const QRectF sourceRect = source->boundingRect(Qt::DeviceCoordinates);
+ const QRectF shadowRect = sourceRect.translated(offset);
+
+ QRectF blurRect = shadowRect;
+ qreal delta = d->radius * 3;
+ blurRect.adjust(-delta, -delta, delta, delta);
+ blurRect |= sourceRect;
+
+ QRect effectRect = blurRect.toAlignedRect();
+ const QRect deviceRect = source->deviceRect();
+ const bool fullyInsideDeviceRect = effectRect.x() >= deviceRect.x()
+ && effectRect.right() <= deviceRect.right()
+ && effectRect.y() >= deviceRect.y()
+ && effectRect.bottom() <= deviceRect.bottom();
+ if (!fullyInsideDeviceRect) {
+ // Clip to device rect to avoid huge pixmaps.
+ effectRect &= source->deviceRect();
+ effectRect |= effectRect.translated(-shadowOffset);
+ if (effectRect.isEmpty())
+ return; // nothing to paint;
+ }
+
+ QPixmap pixmap(effectRect.size());
+ pixmap.fill(Qt::transparent);
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ pixmapPainter.setWorldTransform(painter->worldTransform());
+ if (effectRect.x() != 0 || effectRect.y() != 0)
+ pixmapPainter.translate(-effectRect.topLeft());
+ source->draw(&pixmapPainter);
+ pixmapPainter.end();
+
+ QImage img = pixmap.toImage();
+ QImage shadowImage(img.size(), QImage::Format_ARGB32);
+ shadowImage.fill(qRgba(0, 0, 0, d->alpha * 255));
+ shadowImage.setAlphaChannel(img.alphaChannel());
+ shadowImage = blurred(shadowImage, shadowImage.rect(), d->radius);
+
+ // Draw using an untransformed painter.
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ painter->drawImage(effectRect.topLeft() + shadowOffset, shadowImage);
+ painter->drawPixmap(effectRect.topLeft(), pixmap);
+ painter->setWorldTransform(restoreTransform);
+}
+
+#endif
diff --git a/src/gui/effects/qgraphicseffect.h b/src/gui/effects/qgraphicseffect.h
new file mode 100644
index 0000000..d171b1b
--- /dev/null
+++ b/src/gui/effects/qgraphicseffect.h
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSEFFECT_H
+#define QGRAPHICSEFFECT_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsItem;
+class QStyleOption;
+class QColor;
+class QPainter;
+class QRectF;
+class QRect;
+class QPixmap;
+
+class QGraphicsEffectSourcePrivate;
+class Q_GUI_EXPORT QGraphicsEffectSource : public QObject
+{
+ Q_OBJECT
+public:
+ ~QGraphicsEffectSource();
+ const QGraphicsItem *graphicsItem() const;
+ const QStyleOption *styleOption() const;
+
+ bool isPixmap() const;
+ void draw(QPainter *painter);
+ void update();
+
+ QRectF boundingRect(Qt::CoordinateSystem coordinateSystem = Qt::LogicalCoordinates) const;
+ QRect deviceRect() const;
+ QPixmap pixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates, QPoint *offset = 0) const;
+
+protected:
+ QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent = 0);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsEffectSource);
+ Q_DISABLE_COPY(QGraphicsEffectSource);
+ friend class QGraphicsEffect;
+ friend class QGraphicsEffectPrivate;
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsItem;
+};
+
+class QGraphicsEffectPrivate;
+class Q_GUI_EXPORT QGraphicsEffect : public QObject
+{
+ Q_OBJECT
+ Q_FLAGS(ChangeFlags)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+public:
+ enum ChangeFlag {
+ SourceAttached = 0x1,
+ SourceDetached = 0x2,
+ SourceBoundingRectChanged = 0x4,
+ SourceInvalidated = 0x8
+ };
+ Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag);
+
+ QGraphicsEffect();
+ virtual ~QGraphicsEffect();
+
+ // ### make protected?
+ virtual QRectF boundingRectFor(const QRectF &rect) const;
+ QRectF boundingRect() const;
+
+ QGraphicsEffectSource *source() const;
+
+ bool isEnabled() const;
+
+public Q_SLOTS:
+ void setEnabled(bool enable);
+ // ### add update() slot
+
+protected:
+ QGraphicsEffect(QGraphicsEffectPrivate &d);
+ virtual void draw(QPainter *painter, QGraphicsEffectSource *source) = 0;
+ virtual void sourceChanged(ChangeFlags flags);
+ void updateBoundingRect();
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsEffect)
+ Q_DISABLE_COPY(QGraphicsEffect)
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+ friend class QGraphicsScenePrivate;
+};
+
+class QGraphicsGrayscaleEffectPrivate;
+class Q_GUI_EXPORT QGraphicsGrayscaleEffect: public QGraphicsEffect
+{
+ Q_OBJECT
+public:
+ QGraphicsGrayscaleEffect();
+ ~QGraphicsGrayscaleEffect();
+
+protected:
+ void draw(QPainter *painter, QGraphicsEffectSource *source);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsGrayscaleEffect)
+ Q_DISABLE_COPY(QGraphicsGrayscaleEffect)
+};
+
+class QGraphicsColorizeEffectPrivate;
+class Q_GUI_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect {
+ Q_OBJECT
+public:
+ QGraphicsColorizeEffect();
+ ~QGraphicsColorizeEffect();
+
+ QColor color() const;
+ void setColor(const QColor &c);
+
+protected:
+ void draw(QPainter *painter, QGraphicsEffectSource *source);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsColorizeEffect)
+ Q_DISABLE_COPY(QGraphicsColorizeEffect)
+};
+
+class QGraphicsPixelizeEffectPrivate;
+class Q_GUI_EXPORT QGraphicsPixelizeEffect: public QGraphicsEffect {
+ Q_OBJECT
+public:
+ QGraphicsPixelizeEffect();
+ ~QGraphicsPixelizeEffect();
+
+ int pixelSize() const;
+ void setPixelSize(int pixelSize);
+
+protected:
+ void draw(QPainter *painter, QGraphicsEffectSource *source);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsPixelizeEffect)
+ Q_DISABLE_COPY(QGraphicsPixelizeEffect)
+};
+
+class QGraphicsBlurEffectPrivate;
+class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect {
+ Q_OBJECT
+public:
+ QGraphicsBlurEffect();
+ ~QGraphicsBlurEffect();
+
+ int blurRadius() const;
+ void setBlurRadius(int blurRadius);
+
+protected:
+ QRectF boundingRectFor(const QRectF &rect) const;
+ void draw(QPainter *painter, QGraphicsEffectSource *source);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsBlurEffect)
+ Q_DISABLE_COPY(QGraphicsBlurEffect)
+};
+
+class QGraphicsBloomEffectPrivate;
+class Q_GUI_EXPORT QGraphicsBloomEffect: public QGraphicsEffect {
+ Q_OBJECT
+public:
+ QGraphicsBloomEffect();
+ ~QGraphicsBloomEffect();
+
+ int blurRadius() const;
+ void setBlurRadius(int blurRadius);
+
+ qreal opacity() const;
+ void setOpacity(qreal opacity);
+
+protected:
+ QRectF boundingRectFor(const QRectF &rect) const;
+ void draw(QPainter *painter, QGraphicsEffectSource *source);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsBloomEffect)
+ Q_DISABLE_COPY(QGraphicsBloomEffect)
+};
+
+class QGraphicsFrameEffectPrivate;
+class Q_GUI_EXPORT QGraphicsFrameEffect: public QGraphicsEffect {
+ Q_OBJECT
+public:
+ QGraphicsFrameEffect();
+ ~QGraphicsFrameEffect();
+
+ QColor frameColor() const;
+ void setFrameColor(const QColor &c);
+
+ qreal frameWidth() const;
+ void setFrameWidth(qreal frameWidth);
+
+ qreal frameOpacity() const;
+ void setFrameOpacity(qreal opacity);
+
+protected:
+ QRectF boundingRectFor(const QRectF &rect) const;
+ void draw(QPainter *painter, QGraphicsEffectSource *source);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsFrameEffect)
+ Q_DISABLE_COPY(QGraphicsFrameEffect)
+};
+
+class QGraphicsShadowEffectPrivate;
+class Q_GUI_EXPORT QGraphicsShadowEffect: public QGraphicsEffect {
+ Q_OBJECT
+public:
+ QGraphicsShadowEffect();
+ ~QGraphicsShadowEffect();
+
+ QPointF shadowOffset() const;
+ void setShadowOffset(const QPointF &ofs);
+ inline void setShadowOffset(qreal dx, qreal dy)
+ { setShadowOffset(QPointF(dx, dy)); }
+ inline void setShadowOffset(qreal d)
+ { setShadowOffset(QPointF(d, d)); }
+
+ int blurRadius() const;
+ void setBlurRadius(int blurRadius);
+
+ qreal opacity() const;
+ void setOpacity(qreal opacity);
+
+protected:
+ QRectF boundingRectFor(const QRectF &rect) const;
+ void draw(QPainter *painter, QGraphicsEffectSource *source);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsShadowEffect)
+ Q_DISABLE_COPY(QGraphicsShadowEffect)
+};
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QGRAPHICSEFFECT_H
diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h
new file mode 100644
index 0000000..6d546cc
--- /dev/null
+++ b/src/gui/effects/qgraphicseffect_p.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** 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"
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+#include <private/qobject_p.h>
+#include <private/qpixmapfilter_p.h>
+
+#include <QtCore/qrect.h>
+#include <QtCore/qpoint.h>
+#include <QtGui/qcolor.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsEffectSourcePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsEffectSource)
+public:
+ QGraphicsEffectSourcePrivate() : QObjectPrivate() {}
+ virtual ~QGraphicsEffectSourcePrivate() {}
+ virtual void detach() = 0;
+ virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
+ virtual QRect deviceRect() const = 0;
+ virtual const QGraphicsItem *graphicsItem() const = 0;
+ virtual const QStyleOption *styleOption() const = 0;
+ virtual void draw(QPainter *p) = 0;
+ virtual void update() = 0;
+ virtual bool isPixmap() const = 0;
+ virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0) const = 0;
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+};
+
+class Q_GUI_EXPORT QGraphicsEffectPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsEffect)
+public:
+ QGraphicsEffectPrivate() : source(0), isEnabled(1) {}
+
+ inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource)
+ {
+ QGraphicsEffect::ChangeFlags flags;
+ if (source) {
+ flags |= QGraphicsEffect::SourceDetached;
+ source->d_func()->detach();
+ delete source;
+ }
+ source = newSource;
+ if (newSource)
+ flags |= QGraphicsEffect::SourceAttached;
+ q_func()->sourceChanged(flags);
+ }
+
+ QGraphicsEffectSource *source;
+ QRectF boundingRect;
+ quint32 isEnabled : 1;
+ quint32 padding : 31; // feel free to use
+};
+
+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