summaryrefslogtreecommitdiffstats
path: root/src/gui/effects/qgraphicseffect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/effects/qgraphicseffect.cpp')
-rw-r--r--src/gui/effects/qgraphicseffect.cpp1528
1 files changed, 1528 insertions, 0 deletions
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
new file mode 100644
index 0000000..ee01fdc
--- /dev/null
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -0,0 +1,1528 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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(false). If effects are disabled, the source
+ is rendered directly.
+
+ To add a visual effect to a QGraphicsItem, for example, you can use one of
+ the standard effects, or alternately, create your own effect by creating a
+ subclass of QGraphicsEffect. The effect can then be installed on the item
+ using QGraphicsItem::setGraphicsEffect().
+
+ Qt provides the following standard effects:
+
+ \list
+ \o QGraphicsBlurEffect - blurs the item by a given radius
+ \o QGraphicsDropShadowEffect - renders a dropshadow behind the item
+ \o QGraphicsColorizeEffect - renders the item in shades of any given color
+ \o QGraphicsOpacityEffect - renders the item with an opacity
+ \o QGraphicsPixelizeEffect - pixelizes the item with any pixel size
+ \o QGraphicsGrayscaleEffect - renders the item in shades of gray
+ \o QGraphicsBloomEffect - applies a blooming / glowing effect
+ \endlist
+
+ \img graphicseffect-effects.png
+ \img graphicseffect-widget.png
+
+ For more information on how to use each effect, refer to the specific
+ effect's documentation.
+
+ To create your own custom effect, create a subclass of QGraphicsEffect (or
+ any other existing effects) and reimplement the virtual function draw().
+ This function is called whenever the effect needs to redraw. The draw()
+ function accepts 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, or the device rectangle bounds. For more information, refer to
+ the documenation for draw(). To obtain a pointer to the current source,
+ simply call source().
+
+ If your effect changes, use update() to request for 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 and its rectangle parameters have changed.
+
+ \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect(),
+ QGraphicsEffectSource
+*/
+
+#include "qgraphicseffect_p.h"
+
+#include <QtGui/qimage.h>
+#include <QtGui/qpainter.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGraphicsEffectSource
+ \brief The QGraphicsEffectSource class represents the source on which a
+ QGraphicsEffect is installed on.
+ \since 4.6
+
+ When a QGraphicsEffect is installed on a QGraphicsItem, for example, this
+ class will act as a wrapper around QGraphicsItem. Then, calling update() is
+ effectively the same as calling QGraphicsItem::update().
+
+ QGraphicsEffectSource also provides a pixmap() function which creates a
+ pixmap with the source painted into it.
+
+ \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect().
+*/
+
+/*!
+ \internal
+*/
+QGraphicsEffectSource::QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{}
+
+/*!
+ Destroys the effect source.
+*/
+QGraphicsEffectSource::~QGraphicsEffectSource()
+{}
+
+/*!
+ Returns the bounds of the current painter's device.
+
+ This function is useful when you want to draw something in device
+ coordinates and ensure the size of the pixmap is not bigger than the size
+ of the device.
+
+ Calling QGraphicsEffectSource::pixmap(Qt::DeviceCoordinates) always returns
+ a pixmap which is bound to the device's size.
+
+ \sa pixmap()
+*/
+QRect QGraphicsEffectSource::deviceRect() const
+{
+ return d_func()->deviceRect();
+}
+
+/*!
+ Returns the bounding rectangle of the source mapped to the given \a system.
+
+ \sa draw()
+*/
+QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const
+{
+ return d_func()->boundingRect(system);
+}
+
+/*!
+ Returns a pointer to the item if this source is a QGraphicsItem; otherwise
+ returns 0.
+
+ \sa widget()
+*/
+const QGraphicsItem *QGraphicsEffectSource::graphicsItem() const
+{
+ return d_func()->graphicsItem();
+}
+
+/*!
+ Returns a pointer to the widget if this source is a QWidget; otherwise
+ returns 0.
+
+ \sa graphicsItem()
+*/
+const QWidget *QGraphicsEffectSource::widget() const
+{
+ return d_func()->widget();
+}
+
+/*!
+ Returns a pointer to the style options (used when drawing the source) if
+ available; otherwise returns 0.
+
+ \sa graphicsItem(), widget()
+*/
+const QStyleOption *QGraphicsEffectSource::styleOption() const
+{
+ return d_func()->styleOption();
+}
+
+/*!
+ Draws the source using the given \a painter.
+
+ This function should only be called from QGraphicsEffect::draw().
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 0
+
+ \sa QGraphicsEffect::draw()
+*/
+void QGraphicsEffectSource::draw(QPainter *painter)
+{
+ d_func()->draw(painter);
+}
+
+/*!
+ Schedules a redraw of the source. Call this function whenever the source
+ needs to be redrawn.
+
+ \sa QGraphicsEffect::updateBoundingRect(), QWidget::update(),
+ QGraphicsItem::update(),
+*/
+void QGraphicsEffectSource::update()
+{
+ d_func()->update();
+}
+
+/*!
+ Returns true if the source effectively is a pixmap, e.g., a
+ QGraphicsPixmapItem.
+
+ This function is useful for optimization purposes. For instance, there's no
+ point in drawing the source in device coordinates to avoid pixmap scaling
+ if this function returns true - the source pixmap will be scaled anyways.
+*/
+bool QGraphicsEffectSource::isPixmap() const
+{
+ return d_func()->isPixmap();
+}
+
+/*!
+ Returns a pixmap with the source painted into it.
+
+ The \a system specifies which coordinate system to be used for the source.
+ The optional \a offset parameter returns the offset where the pixmap should
+ be painted at using the current painter.
+
+ The returned pixmap is bound to the current painter's device rectangle when
+ \a system is Qt::DeviceCoordinates.
+
+ \sa QGraphicsEffect::draw(), boundingRect(), deviceRect()
+*/
+QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset) const
+{
+ return d_func()->pixmap(system, offset);
+}
+
+/*!
+ Constructs a new QGraphicsEffect instance having the
+ specified \a parent.
+*/
+QGraphicsEffect::QGraphicsEffect(QObject *parent)
+ : QObject(*new QGraphicsEffectPrivate, parent)
+{
+}
+
+/*!
+ \internal
+*/
+QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
+
+/*!
+ 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, the source will
+ be rendered with the effect applied.
+
+ This property is enabled by default.
+
+ Using this property, 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->d_func()->effectBoundingRectChanged();
+ emit enabledChanged(enable);
+}
+
+/*!
+ \fn void QGraphicsEffect::enabledChanged(bool enabled)
+
+ This signal is emitted whenever the effect is enabled or disabled.
+ The \a enabled parameter holds the effects's new enabled state.
+
+ \sa isEnabled()
+*/
+
+/*!
+ Schedules a redraw of the source. Call this function whenever the source
+ needs to be redrawn.
+
+ This convenience function is equivalent to calling
+ QGraphicsEffectSource::update().
+
+ \sa updateBoundingRect(), QGraphicsEffectSource::update()
+*/
+void QGraphicsEffect::update()
+{
+ Q_D(QGraphicsEffect);
+ 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 when 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.
+
+ This function will call update() if this is necessary.
+
+ \sa boundingRectFor(), boundingRect()
+*/
+void QGraphicsEffect::updateBoundingRect()
+{
+ Q_D(QGraphicsEffect);
+ if (d->source)
+ d->source->d_func()->effectBoundingRectChanged();
+}
+
+/*!
+ \fn virtual void QGraphicsEffect::draw(QPainter *painter,
+ QGraphicsEffectSource *source) = 0
+
+ This pure virtual function draws the effect and is called whenever the
+ source() needs to be drawn.
+
+ Reimplement this function in a QGraphicsEffect subclass to provide the
+ effect's drawing implementation, using \a painter. The \a source parameter
+ is provided for convenience; its value is the same as source().
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 1
+
+ This function should not be called explicitly by the user, since it is
+ meant for reimplementation purposes only.
+
+ \sa QGraphicsEffectSource
+*/
+
+/*!
+ \enum QGraphicsEffect::ChangeFlag
+
+ This enum describes what has changed in QGraphicsEffectSource.
+
+ \value SourceAttached The effect is installed on a source.
+ \value SourceDetached The effect is uninstalled on a source.
+ \value SourceBoundingRectChanged The bounding rect of the source has
+ changed.
+ \value SourceInvalidated The visual appearance of the source has changed.
+*/
+
+/*!
+ 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);
+}
+
+/*!
+ \class QGraphicsGrayscaleEffect
+ \brief The QGraphicsGrayscaleEffect class provides a grayscale effect.
+ \since 4.6
+
+ A grayscale effect renders the source in shades of gray.
+
+ \img graphicseffect-grayscale.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
+ QGraphicsColorizeEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+ Constructs a new QGraphicsGrayscale instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsGrayscaleEffect::QGraphicsGrayscaleEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsGrayscaleEffectPrivate, parent)
+{
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsGrayscaleEffect::~QGraphicsGrayscaleEffect()
+{
+}
+
+
+/*!
+ \property QGraphicsGrayscaleEffect::strength
+ \brief the strength of the effect.
+
+ By default, the strength is 1.0.
+ A strength 0.0 equals to no effect, while 1.0 means full grayscale.
+*/
+qreal QGraphicsGrayscaleEffect::strength() const
+{
+ Q_D(const QGraphicsGrayscaleEffect);
+ return d->filter->strength();
+}
+
+void QGraphicsGrayscaleEffect::setStrength(qreal strength)
+{
+ Q_D(QGraphicsGrayscaleEffect);
+ if (qFuzzyCompare(d->filter->strength(), strength))
+ return;
+
+ d->filter->setStrength(strength);
+ d->opaque = !qFuzzyIsNull(strength);
+ update();
+ emit strengthChanged(strength);
+}
+
+/*! \fn void QGraphicsGrayscaleEffect::strengthChanged(qreal strength)
+ This signal is emitted whenever setStrength() changes the grayscale
+ strength property. \a strength contains the new strength value of
+ the grayscale effect.
+ */
+
+/*!
+ \reimp
+*/
+void QGraphicsGrayscaleEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsGrayscaleEffect);
+
+ if (!d->opaque) {
+ 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);
+
+}
+
+/*!
+ \class QGraphicsColorizeEffect
+ \brief The QGraphicsColorizeEffect class provides a colorize effect.
+ \since 4.6
+
+ A colorize effect renders the source with a tint of its color(). The color
+ can be modified using the setColor() function.
+
+ By default, the color is light blue (QColor(0, 0, 192)).
+
+ \img graphicseffect-colorize.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
+ QGraphicsGrayscaleEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+ Constructs a new QGraphicsColorizeEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsColorizeEffect::QGraphicsColorizeEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate, parent)
+{
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsColorizeEffect::~QGraphicsColorizeEffect()
+{
+}
+
+/*!
+ \property QGraphicsColorizeEffect::color
+ \brief the color of the effect.
+
+ By default, the color is light blue (QColor(0, 0, 192)).
+*/
+QColor QGraphicsColorizeEffect::color() const
+{
+ Q_D(const QGraphicsColorizeEffect);
+ return d->filter->color();
+}
+
+void QGraphicsColorizeEffect::setColor(const QColor &color)
+{
+ Q_D(QGraphicsColorizeEffect);
+ if (d->filter->color() == color)
+ return;
+
+ d->filter->setColor(color);
+ update();
+ emit colorChanged(color);
+}
+
+/*!
+ \property QGraphicsColorizeEffect::strength
+ \brief the strength of the effect.
+
+ By default, the strength is 1.0.
+ A strength 0.0 equals to no effect, while 1.0 means full colorization.
+*/
+qreal QGraphicsColorizeEffect::strength() const
+{
+ Q_D(const QGraphicsColorizeEffect);
+ return d->filter->strength();
+}
+
+void QGraphicsColorizeEffect::setStrength(qreal strength)
+{
+ Q_D(QGraphicsColorizeEffect);
+ if (qFuzzyCompare(d->filter->strength(), strength))
+ return;
+
+ d->filter->setStrength(strength);
+ d->opaque = !qFuzzyIsNull(strength);
+ update();
+ emit strengthChanged(strength);
+}
+
+/*! \fn void QGraphicsColorizeEffect::strengthChanged(qreal strength)
+ This signal is emitted whenever setStrength() changes the colorize
+ strength property. \a strength contains the new strength value of
+ the colorize effect.
+ */
+
+/*!
+ \fn void QGraphicsColorizeEffect::colorChanged(const QColor &color)
+
+ This signal is emitted whenever the effect's color changes.
+ The \a color parameter holds the effect's new color.
+*/
+
+/*!
+ \reimp
+*/
+void QGraphicsColorizeEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsColorizeEffect);
+
+ if (!d->opaque) {
+ 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 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);
+}
+
+/*!
+ \class QGraphicsPixelizeEffect
+ \brief The QGraphicsPixelizeEffect class provides a pixelize effect.
+ \since 4.6
+
+ A pixelize effect renders the source in lower resolution. This effect is
+ useful for reducing details, like censorship. The resolution can be
+ modified using the setPixelSize() function.
+
+ By default, the pixel size is 3.
+
+ \img graphicseffect-pixelize.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsGrayscaleEffect,
+ QGraphicsColorizeEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+ Constructs a new QGraphicsPixelizeEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsPixelizeEffect::QGraphicsPixelizeEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsPixelizeEffectPrivate, parent)
+{
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsPixelizeEffect::~QGraphicsPixelizeEffect()
+{
+}
+
+/*!
+ \property QGraphicsPixelizeEffect::pixelSize
+ \brief the size of a pixel in the effect.
+
+ Setting the pixel size to 2 means two pixels in the source will be used to
+ represent one pixel. Using a bigger size results in lower resolution.
+
+ By default, the pixel size is 3.
+*/
+int QGraphicsPixelizeEffect::pixelSize() const
+{
+ Q_D(const QGraphicsPixelizeEffect);
+ return d->pixelSize;
+}
+
+void QGraphicsPixelizeEffect::setPixelSize(int size)
+{
+ Q_D(QGraphicsPixelizeEffect);
+ if (d->pixelSize == size)
+ return;
+
+ d->pixelSize = size;
+ update();
+ emit pixelSizeChanged(size);
+}
+
+/*!
+ \fn void QGraphicsPixelizeEffect::pixelSizeChanged(int size)
+
+ This signal is emitted whenever the effect's pixel size changes.
+ The \a size parameter holds the effect's new pixel 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;
+ }
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+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);
+}
+
+/*!
+ \class QGraphicsBlurEffect
+ \brief The QGraphicsBlurEffect class provides a blur effect.
+ \since 4.6
+
+ A blur effect blurs the source. This effect is useful for reducing details,
+ such as when the source loses focus and you want to draw attention to other
+ elements. The level of detail can be modified using the setBlurRadius()
+ function. Use setBlurHint() to choose the quality or performance blur hints.
+
+ By default, the blur radius is 5 pixels.
+
+ \img graphicseffect-blur.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsPixelizeEffect, QGraphicsGrayscaleEffect,
+ QGraphicsColorizeEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+ Constructs a new QGraphicsBlurEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
+{
+ Q_D(QGraphicsBlurEffect);
+ d->filter->setBlurHint(Qt::PerformanceHint);
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsBlurEffect::~QGraphicsBlurEffect()
+{
+}
+
+/*!
+ \property QGraphicsBlurEffect::blurRadius
+ \brief the blur radius of the effect.
+
+ Using a smaller radius results in a sharper appearance, whereas a bigger
+ radius results in a more blurred appearance.
+
+ By default, the blur radius is 5 pixels.
+*/
+int QGraphicsBlurEffect::blurRadius() const
+{
+ Q_D(const QGraphicsBlurEffect);
+ return d->filter->radius();
+}
+
+void QGraphicsBlurEffect::setBlurRadius(int radius)
+{
+ Q_D(QGraphicsBlurEffect);
+ if (d->filter->radius() == radius)
+ return;
+
+ d->filter->setRadius(radius);
+ updateBoundingRect();
+ emit blurRadiusChanged(radius);
+}
+
+/*!
+ \fn void QGraphicsBlurEffect::blurRadiusChanged(int radius)
+
+ This signal is emitted whenever the effect's blur radius changes.
+ The \a radius parameter holds the effect's new blur radius.
+*/
+
+/*!
+ \property QGraphicsBlurEffect::blurHint
+ \brief the blur hint of the effect.
+
+ Use the Qt::PerformanceHint hint to say that you want a faster blur,
+ and the Qt::QualityHint hint to say that you prefer a higher quality blur.
+
+ When animating the blur radius it's recommended to use Qt::PerformanceHint.
+
+ By default, the blur hint is Qt::PerformanceHint.
+*/
+Qt::RenderHint QGraphicsBlurEffect::blurHint() const
+{
+ Q_D(const QGraphicsBlurEffect);
+ return d->filter->blurHint();
+}
+
+void QGraphicsBlurEffect::setBlurHint(Qt::RenderHint hint)
+{
+ Q_D(QGraphicsBlurEffect);
+ if (d->filter->blurHint() == hint)
+ return;
+
+ d->filter->setBlurHint(hint);
+ emit blurHintChanged(hint);
+}
+
+/*!
+ \fn void QGraphicsBlurEffect::blurHintChanged(Qt::RenderHint hint)
+
+ This signal is emitted whenever the effect's blur hint changes.
+ The \a hint parameter holds the effect's new blur hint.
+*/
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsBlurEffect);
+ return d->filter->boundingRectFor(rect);
+}
+
+/*!
+ \reimp
+*/
+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);
+}
+
+/*!
+ \class QGraphicsDropShadowEffect
+ \brief The QGraphicsDropShadowEffect class provides a drop shadow effect.
+ \since 4.6
+
+ A drop shadow effect renders the source with a drop shadow. The color of
+ the drop shadow can be modified using the setColor() function. The drop
+ shadow offset can be modified using the setOffset() function and the blur
+ radius of the drop shadow can be changed with the setBlurRadius()
+ function.
+
+ By default, the drop shadow is a semi-transparent dark gray
+ (QColor(63, 63, 63, 180)) shadow, blurred with a radius of 1 at an offset
+ of 8 pixels towards the lower right.
+
+ \img graphicseffect-drop-shadow.png
+
+ \sa QGraphicsBlurEffect, QGraphicsPixelizeEffect, QGraphicsGrayscaleEffect,
+ QGraphicsColorizeEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+ Constructs a new QGraphicsDropShadowEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsDropShadowEffect::QGraphicsDropShadowEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsDropShadowEffectPrivate, parent)
+{
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect()
+{
+}
+
+/*!
+ \property QGraphicsDropShadowEffect::offset
+ \brief the shadow offset in pixels.
+
+ By default, the offset is 8 pixels towards the lower right.
+
+ \sa xOffset(), yOffset(), blurRadius(), color()
+*/
+QPointF QGraphicsDropShadowEffect::offset() const
+{
+ Q_D(const QGraphicsDropShadowEffect);
+ return d->filter->offset();
+}
+
+void QGraphicsDropShadowEffect::setOffset(const QPointF &offset)
+{
+ Q_D(QGraphicsDropShadowEffect);
+ if (d->filter->offset() == offset)
+ return;
+
+ d->filter->setOffset(offset);
+ updateBoundingRect();
+ emit offsetChanged(offset);
+}
+
+/*!
+ \property QGraphicsDropShadowEffect::xOffset
+ \brief the horizontal shadow offset in pixels.
+
+ By default, the horizontal shadow offset is 8 pixels.
+
+ \sa yOffset(), offset()
+*/
+
+/*!
+ \property QGraphicsDropShadowEffect::yOffset
+ \brief the vertical shadow offset in pixels.
+
+ By default, the vertical shadow offset is 8 pixels.
+
+ \sa xOffset(), offset()
+*/
+
+/*!
+ \fn void QGraphicsDropShadowEffect::offsetChanged(const QPointF &offset)
+
+ This signal is emitted whenever the effect's shadow offset changes.
+ The \a offset parameter holds the effect's new shadow offset.
+*/
+
+/*!
+ \property QGraphicsDropShadowEffect::blurRadius
+ \brief the blur radius in pixels of the drop shadow.
+
+ Using a smaller radius results in a sharper shadow, whereas using a bigger
+ radius results in a more blurred shadow.
+
+ By default, the blur radius is 1 pixel.
+
+ \sa color(), offset().
+*/
+int QGraphicsDropShadowEffect::blurRadius() const
+{
+ Q_D(const QGraphicsDropShadowEffect);
+ return d->filter->blurRadius();
+}
+
+void QGraphicsDropShadowEffect::setBlurRadius(int blurRadius)
+{
+ Q_D(QGraphicsDropShadowEffect);
+ if (d->filter->blurRadius() == blurRadius)
+ return;
+
+ d->filter->setBlurRadius(blurRadius);
+ updateBoundingRect();
+ emit blurRadiusChanged(blurRadius);
+}
+
+/*!
+ \fn void QGraphicsDropShadowEffect::blurRadiusChanged(int blurRadius)
+
+ This signal is emitted whenever the effect's blur radius changes.
+ The \a blurRadius parameter holds the effect's new blur radius.
+*/
+
+/*!
+ \property QGraphicsDropShadowEffect::color
+ \brief the color of the drop shadow.
+
+ By default, the drop color is a semi-transparent dark gray
+ (QColor(63, 63, 63, 180)).
+
+ \sa offset(), blurRadius()
+*/
+QColor QGraphicsDropShadowEffect::color() const
+{
+ Q_D(const QGraphicsDropShadowEffect);
+ return d->filter->color();
+}
+
+void QGraphicsDropShadowEffect::setColor(const QColor &color)
+{
+ Q_D(QGraphicsDropShadowEffect);
+ if (d->filter->color() == color)
+ return;
+
+ d->filter->setColor(color);
+ update();
+ emit colorChanged(color);
+}
+
+/*!
+ \fn void QGraphicsDropShadowEffect::colorChanged(const QColor &color)
+
+ This signal is emitted whenever the effect's color changes.
+ The \a color parameter holds the effect's new color.
+*/
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsDropShadowEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsDropShadowEffect);
+ return d->filter->boundingRectFor(rect);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsDropShadowEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsDropShadowEffect);
+ if (d->filter->blurRadius() <= 0 && d->filter->offset().isNull()) {
+ 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);
+}
+
+/*!
+ \class QGraphicsOpacityEffect
+ \brief The QGraphicsOpacityEffect class provides an opacity effect.
+ \since 4.6
+
+ An opacity effect renders the source with an opacity. This effect is useful
+ for making the source semi-transparent, similar to a fade-in/fade-out
+ sequence. The opacity can be modified using the setOpacity() function.
+
+ By default, the opacity is 0.7.
+
+ \img graphicseffect-opacity.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
+ QGraphicsGrayscaleEffect, QGraphicsColorizeEffect
+*/
+
+/*!
+ Constructs a new QGraphicsOpacityEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsOpacityEffect::QGraphicsOpacityEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsOpacityEffectPrivate, parent)
+{
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsOpacityEffect::~QGraphicsOpacityEffect()
+{
+}
+
+/*!
+ \property QGraphicsOpacityEffect::opacity
+ \brief the opacity of the effect.
+
+ The value should be in the range of 0.0 to 1.0, where 0.0 is
+ fully transparent and 1.0 is fully opaque.
+
+ By default, the opacity is 0.7.
+
+ \sa setOpacityMask()
+*/
+qreal QGraphicsOpacityEffect::opacity() const
+{
+ Q_D(const QGraphicsOpacityEffect);
+ return d->opacity;
+}
+
+void QGraphicsOpacityEffect::setOpacity(qreal opacity)
+{
+ Q_D(QGraphicsOpacityEffect);
+ opacity = qBound(qreal(0.0), opacity, qreal(1.0));
+
+ if (qFuzzyCompare(d->opacity, opacity))
+ return;
+
+ d->opacity = opacity;
+ if ((d->isFullyTransparent = qFuzzyIsNull(d->opacity)))
+ d->isFullyOpaque = 0;
+ else
+ d->isFullyOpaque = qFuzzyIsNull(d->opacity - 1);
+ update();
+ emit opacityChanged(opacity);
+}
+
+/*!
+ \fn void QGraphicsOpacityEffect::opacityChanged(qreal opacity)
+
+ This signal is emitted whenever the effect's opacity changes.
+ The \a opacity parameter holds the effect's new opacity.
+*/
+
+/*!
+ \property QGraphicsOpacityEffect::opacityMask
+ \brief the opacity mask of the effect.
+
+ An opacity mask allows you apply opacity to portions of an element.
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 2
+
+ There is no opacity mask by default.
+
+ \sa setOpacity()
+*/
+QBrush QGraphicsOpacityEffect::opacityMask() const
+{
+ Q_D(const QGraphicsOpacityEffect);
+ return d->opacityMask;
+}
+
+void QGraphicsOpacityEffect::setOpacityMask(const QBrush &mask)
+{
+ Q_D(QGraphicsOpacityEffect);
+ if (d->opacityMask == mask)
+ return;
+
+ d->opacityMask = mask;
+ d->hasOpacityMask = (mask.style() != Qt::NoBrush);
+ update();
+
+ emit opacityMaskChanged(mask);
+}
+
+/*!
+ \fn void QGraphicsOpacityEffect::opacityMaskChanged(const QBrush &mask)
+
+ This signal is emitted whenever the effect's opacity mask changes.
+ The \a mask parameter holds the effect's new opacity mask.
+*/
+
+/*!
+ \reimp
+*/
+void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsOpacityEffect);
+
+ // Transparent; nothing to draw.
+ if (d->isFullyTransparent)
+ return;
+
+ // Opaque; draw directly without going through a pixmap.
+ if (d->isFullyOpaque && !d->hasOpacityMask) {
+ source->draw(painter);
+ return;
+ }
+
+ painter->save();
+ painter->setOpacity(d->opacity);
+
+ QPoint offset;
+ if (source->isPixmap()) {
+ // No point in drawing in device coordinates (pixmap will be scaled anyways).
+ if (!d->hasOpacityMask) {
+ const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
+ painter->drawPixmap(offset, pixmap);
+ } else {
+ QRect srcBrect = source->boundingRect().toAlignedRect();
+ offset = srcBrect.topLeft();
+ QPixmap pixmap(srcBrect.size());
+ pixmap.fill(Qt::transparent);
+
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ pixmapPainter.translate(-offset);
+ source->draw(&pixmapPainter);
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ pixmapPainter.fillRect(srcBrect, d->opacityMask);
+ pixmapPainter.end();
+
+ painter->drawPixmap(offset, pixmap);
+ }
+ } else {
+ // Draw pixmap in device coordinates to avoid pixmap scaling;
+ if (!d->hasOpacityMask) {
+ const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+ painter->setWorldTransform(QTransform());
+ painter->drawPixmap(offset, pixmap);
+ } else {
+ QTransform worldTransform = painter->worldTransform();
+
+ // Calculate source bounding rect in logical and device coordinates.
+ QRectF srcBrect = source->boundingRect();
+ QRect srcDeviceBrect = worldTransform.mapRect(srcBrect).toAlignedRect();
+ srcDeviceBrect &= source->deviceRect();
+
+ offset = srcDeviceBrect.topLeft();
+ worldTransform *= QTransform::fromTranslate(-srcDeviceBrect.x(), -srcDeviceBrect.y());
+
+ QPixmap pixmap(srcDeviceBrect.size());
+ pixmap.fill(Qt::transparent);
+
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ pixmapPainter.setWorldTransform(worldTransform);
+ source->draw(&pixmapPainter);
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ pixmapPainter.fillRect(srcBrect, d->opacityMask);
+ pixmapPainter.end();
+
+ painter->setWorldTransform(QTransform());
+ painter->drawPixmap(offset, pixmap);
+ }
+ }
+
+ painter->restore();
+}
+
+/*!
+ \class QGraphicsBloomEffect
+ \brief The QGraphicsBloomEffect class provides a bloom/glow effect.
+ \since 4.6
+
+ A bloom/glow effect adds fringes of light around bright areas in the source.
+
+ \img graphicseffect-bloom.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
+ QGraphicsGrayscaleEffect, QGraphicsColorizeEffect
+*/
+
+/*!
+ Constructs a new QGraphicsBloomEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsBloomEffect::QGraphicsBloomEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsBloomEffectPrivate, parent)
+{
+ Q_D(QGraphicsBloomEffect);
+ for (int i = 0; i < 256; ++i)
+ d->colorTable[i] = qMin(i + d->brightness, 255);
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsBloomEffect::~QGraphicsBloomEffect()
+{
+}
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsBloomEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsBloomEffect);
+ const qreal delta = d->blurFilter.radius() * 2;
+ return rect.adjusted(-delta, -delta, delta, delta);
+}
+
+/*!
+ \property QGraphicsBloomEffect::blurRadius
+ \brief the blur radius in pixels of the effect.
+
+ Using a smaller radius results in a sharper appearance, whereas a bigger
+ radius results in a more blurred appearance.
+
+ By default, the blur radius is 5 pixels.
+
+ \sa strength(), brightness()
+*/
+int QGraphicsBloomEffect::blurRadius() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->blurFilter.radius();
+}
+
+void QGraphicsBloomEffect::setBlurRadius(int radius)
+{
+ Q_D(QGraphicsBloomEffect);
+ if (d->blurFilter.radius() == radius)
+ return;
+
+ d->blurFilter.setRadius(radius);
+ updateBoundingRect();
+ emit blurRadiusChanged(radius);
+}
+
+/*!
+ \fn void QGraphicsBloomEffect::blurRadiusChanged(int blurRadius)
+
+ This signal is emitted whenever the effect's blur radius changes.
+ The \a blurRadius parameter holds the effect's new blur radius.
+*/
+
+/*!
+ \property QGraphicsBloomEffect::blurHint
+ \brief the blur hint of the effect.
+
+ Use the Qt::PerformanceHint hint to say that you want a faster blur,
+ and the Qt::QualityHint hint to say that you prefer a higher quality blur.
+
+ When animating the blur radius it's recommended to use Qt::PerformanceHint.
+
+ By default, the blur hint is Qt::PerformanceHint.
+*/
+Qt::RenderHint QGraphicsBloomEffect::blurHint() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->blurFilter.blurHint();
+}
+
+void QGraphicsBloomEffect::setBlurHint(Qt::RenderHint hint)
+{
+ Q_D(QGraphicsBloomEffect);
+ if (d->blurFilter.blurHint() == hint)
+ return;
+
+ d->blurFilter.setBlurHint(hint);
+ emit blurHintChanged(hint);
+}
+
+/*!
+ \fn void QGraphicsBloomEffect::blurHintChanged(Qt::RenderHint hint)
+
+ This signal is emitted whenever the effect's blur hint changes.
+ The \a hint parameter holds the effect's new blur hint.
+*/
+
+/*!
+ \property QGraphicsBloomEffect::brightness
+ \brief the brightness of the glow.
+
+ The value should be in the range of 0 to 255, where 0 is dark
+ and 255 is bright.
+
+ By default, the brightness is 70.
+
+ \sa strength(), blurRadius()
+*/
+int QGraphicsBloomEffect::brightness() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->brightness;
+}
+
+void QGraphicsBloomEffect::setBrightness(int brightness)
+{
+ Q_D(QGraphicsBloomEffect);
+ brightness = qBound(0, brightness, 255);
+ if (d->brightness == brightness)
+ return;
+
+ d->brightness = brightness;
+ for (int i = 0; i < 256; ++i)
+ d->colorTable[i] = qMin(i + brightness, 255);
+
+ update();
+ emit brightnessChanged(brightness);
+}
+
+/*!
+ \fn void QGraphicsBloomEffect::brightnessChanged(int brightness)
+
+ This signal is emitted whenever the effect's brightness changes.
+ The \a brightness parameter holds the effect's new brightness.
+*/
+
+/*!
+ \property QGraphicsBloomEffect::strength
+ \brief the strength of the effect.
+
+ A strength 0.0 equals to no effect, while 1.0 means maximum glow.
+
+ By default, the strength is 0.7.
+*/
+qreal QGraphicsBloomEffect::strength() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->strength;
+}
+
+void QGraphicsBloomEffect::setStrength(qreal strength)
+{
+ Q_D(QGraphicsBloomEffect);
+ strength = qBound(qreal(0.0), strength, qreal(1.0));
+ if (qFuzzyCompare(d->strength, strength))
+ return;
+
+ d->strength = strength;
+ update();
+ emit strengthChanged(strength);
+}
+
+/*!
+ \fn void QGraphicsBloomEffect::strengthChanged(qreal strength)
+
+ This signal is emitted whenever the effect's strength changes.
+ The \a strength parameter holds the effect's new strength.
+*/
+
+/*!
+ \reimp
+*/
+void QGraphicsBloomEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsBloomEffect);
+ if (d->strength < 0.001) {
+ source->draw(painter);
+ return;
+ }
+
+ const Qt::CoordinateSystem system = source->isPixmap()
+ ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
+ QPoint offset;
+ QPixmap pixmap = source->pixmap(system, &offset);
+ QImage result = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
+ // Blur.
+ QPainter blurPainter(&pixmap);
+ d->blurFilter.draw(&blurPainter, QPointF(), pixmap);
+ blurPainter.end();
+
+ // Brighten.
+ QImage overlay = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ const int numBits = overlay.width() * overlay.height();
+ QRgb *bits = reinterpret_cast<QRgb *>(overlay.bits());
+ for (int i = 0; i < numBits; ++i) {
+ const QRgb bit = bits[i];
+ bits[i] = qRgba(d->colorTable[qRed(bit)], d->colorTable[qGreen(bit)],
+ d->colorTable[qBlue(bit)], qAlpha(bit));
+ }
+
+ // Composite.
+ QPainter compPainter(&result);
+ compPainter.setCompositionMode(QPainter::CompositionMode_Overlay);
+ compPainter.setOpacity(d->strength);
+ compPainter.drawImage(0, 0, overlay);
+ compPainter.end();
+
+ if (system == Qt::DeviceCoordinates) {
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ painter->drawImage(offset, result);
+ painter->setWorldTransform(restoreTransform);
+ } else {
+ painter->drawImage(offset, result);
+ }
+}
+
+QT_END_NAMESPACE
+