util/src/gui/effects/qgraphicseffect.cpp
changeset 7 f7bc934e204c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/src/gui/effects/qgraphicseffect.cpp	Wed Mar 31 11:06:36 2010 +0300
@@ -0,0 +1,1238 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 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
+    \endlist
+
+    \table
+    \row
+    \o{2,1} \img graphicseffect-plain.png
+    \row
+    \o \img graphicseffect-blur.png
+    \o \img graphicseffect-colorize.png
+    \row
+    \o \img graphicseffect-opacity.png
+    \o \img graphicseffect-drop-shadow.png
+    \endtable
+
+    \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 takes the painter with which to draw as an argument. For more
+    information, refer to the documenation for draw(). In the draw() function
+    you can call sourcePixmap() to get a pixmap of the graphics effect source
+    which you can then process.
+
+    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
+    sourceChanged() function is called to notify the effects that
+    the source has changed in some way - e.g., if the source is a
+    QGraphicsRectItem and its rectangle parameters have changed.
+
+    \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect()
+*/
+
+#include "qgraphicseffect_p.h"
+#include "private/qgraphicsitem_p.h"
+
+#include <QtGui/qgraphicsitem.h>
+
+#include <QtGui/qimage.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpaintengine.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qdebug.h>
+#include <private/qdrawhelper_p.h>
+
+#ifndef QT_NO_GRAPHICSEFFECT
+QT_BEGIN_NAMESPACE
+
+/*!
+    \internal
+    \class QGraphicsEffectSource
+    \brief The QGraphicsEffectSource class represents the source on which a
+           QGraphicsEffect is installed on.
+
+    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 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 the bounding rectangle of the source mapped to the given \a system.
+
+    Calling this function with Qt::DeviceCoordinates outside of
+    QGraphicsEffect::draw() will give undefined results, as there is no device
+    context available.
+
+    \sa draw()
+*/
+QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const
+{
+    Q_D(const QGraphicsEffect);
+    if (d->source)
+        return d->source->boundingRect(system);
+    return QRectF();
+}
+
+/*!
+    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().
+
+    \sa QGraphicsEffect::draw()
+*/
+void QGraphicsEffectSource::draw(QPainter *painter)
+{
+    Q_D(const QGraphicsEffectSource);
+
+    QPixmap pm;
+    if (QPixmapCache::find(d->m_cacheKey, &pm)) {
+        QTransform restoreTransform;
+        if (d->m_cachedSystem == Qt::DeviceCoordinates) {
+            restoreTransform = painter->worldTransform();
+            painter->setWorldTransform(QTransform());
+        }
+
+        painter->drawPixmap(d->m_cachedOffset, pm);
+
+        if (d->m_cachedSystem == Qt::DeviceCoordinates)
+            painter->setWorldTransform(restoreTransform);
+    } else {
+        d_func()->draw(painter);
+    }
+}
+
+/*!
+    Draws the source directly 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 QGraphicsEffect::drawSource(QPainter *painter)
+{
+    Q_D(const QGraphicsEffect);
+    if (d->source)
+        d->source->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 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 QGraphicsEffect::sourceIsPixmap() const
+{
+    return source() ? source()->isPixmap() : false;
+}
+
+/*!
+    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 \a mode determines how much of the effect the pixmap will contain.
+    By default, the pixmap will contain the whole effect.
+
+    The returned pixmap is bound to the current painter's device rectangle when
+    \a system is Qt::DeviceCoordinates.
+
+    \sa QGraphicsEffect::draw(), boundingRect()
+*/
+QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
+{
+    Q_D(const QGraphicsEffectSource);
+
+    // Shortcut, no cache for childless pixmap items...
+    const QGraphicsItem *item = graphicsItem();
+    if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
+        const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item);
+        if (offset)
+            *offset = pixmapItem->offset().toPoint();
+        return pixmapItem->pixmap();
+    }
+
+    if (system == Qt::DeviceCoordinates && item
+        && !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info) {
+        qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
+        return QPixmap();
+    }
+
+    QPixmap pm;
+    if (d->m_cachedSystem == system && d->m_cachedMode == mode)
+        QPixmapCache::find(d->m_cacheKey, &pm);
+
+    if (pm.isNull()) {
+        pm = d->pixmap(system, &d->m_cachedOffset, mode);
+        d->m_cachedSystem = system;
+        d->m_cachedMode = mode;
+
+        d->invalidateCache();
+        d->m_cacheKey = QPixmapCache::insert(pm);
+    }
+
+    if (offset)
+        *offset = d->m_cachedOffset;
+
+    return pm;
+}
+
+/*!
+    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. For control on how the pixmap is
+    padded use the \a mode parameter.
+
+    The returned pixmap is clipped to the current painter's device rectangle when
+    \a system is Qt::DeviceCoordinates.
+
+    Calling this function with Qt::DeviceCoordinates outside of
+    QGraphicsEffect::draw() will give undefined results, as there is no device
+    context available.
+
+    \sa draw(), boundingRect()
+*/
+QPixmap QGraphicsEffect::sourcePixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
+{
+    Q_D(const QGraphicsEffect);
+    if (d->source)
+        return d->source->pixmap(system, offset, mode);
+    return QPixmap();
+}
+
+QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate()
+{
+    invalidateCache();
+}
+
+void QGraphicsEffectSourcePrivate::setCachedOffset(const QPoint &offset)
+{
+    m_cachedOffset = offset;
+}
+
+void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) const
+{
+    if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect
+        && (reason == EffectRectChanged
+            || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) {
+        return;
+    }
+
+    QPixmapCache::remove(m_cacheKey);
+}
+
+/*!
+    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 effective bounding rectangle for this effect, i.e., the
+    bounding rectangle of the source in device coordinates, 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 effective bounding rectangle for this effect, given the
+    provided \a rect in the device coordinates. 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 sourceBoundingRect()
+*/
+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();
+        d->source->d_func()->invalidateCache();
+    }
+    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();
+}
+
+/*!
+    \internal
+
+    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(), sourceBoundingRect()
+*/
+void QGraphicsEffect::updateBoundingRect()
+{
+    Q_D(QGraphicsEffect);
+    if (d->source) {
+        d->source->d_func()->effectBoundingRectChanged();
+        d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged);
+    }
+}
+
+/*!
+    \fn virtual void QGraphicsEffect::draw(QPainter *painter) = 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.
+
+    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.
+*/
+
+/*!
+    \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.
+*/
+
+/*!
+    \enum QGraphicsEffect::PixmapPadMode
+
+    This enum describes how the pixmap returned from sourcePixmap should be
+    padded.
+
+    \value NoPad The pixmap should not receive any additional
+           padding.
+    \value PadToTransparentBorder The pixmap should be padded
+           to ensure it has a completely transparent border.
+    \value PadToEffectiveBoundingRect The pixmap should be padded to
+           match the effective bounding rectangle of the effect.
+*/
+
+/*!
+    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 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, 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)
+{
+    Q_D(QGraphicsColorizeEffect);
+
+    if (!d->opaque) {
+        drawSource(painter);
+        return;
+    }
+
+    QPoint offset;
+    if (sourceIsPixmap()) {
+        // No point in drawing in device coordinates (pixmap will be scaled anyways).
+        const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, NoPad);
+        if (!pixmap.isNull())
+            d->filter->draw(painter, offset, pixmap);
+
+        return;
+    }
+
+    // Draw pixmap in deviceCoordinates to avoid pixmap scaling.
+    const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);
+    if (pixmap.isNull())
+        return;
+
+    QTransform restoreTransform = painter->worldTransform();
+    painter->setWorldTransform(QTransform());
+    d->filter->draw(painter, offset, pixmap);
+    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 setBlurHints() to choose the blur hints.
+
+    By default, the blur radius is 5 pixels. The blur radius is specified in
+    device coordinates.
+
+    \img graphicseffect-blur.png
+
+    \sa QGraphicsDropShadowEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+    \enum QGraphicsBlurEffect::BlurHint
+    \since 4.6
+
+    This enum describes the possible hints that can be used to control how
+    blur effects are applied. The hints might not have an effect in all the
+    paint engines.
+
+    \value PerformanceHint Indicates that rendering performance is the most important factor,
+    at the potential cost of lower quality.
+
+    \value QualityHint Indicates that rendering quality is the most important factor,
+    at the potential cost of lower performance.
+
+    \value AnimationHint Indicates that the blur radius is going to be animated, hinting
+    that the implementation can keep a cache of blurred verisons of the source.
+    Do not use this hint if the source is going to be dynamically changing.
+
+    \sa blurHints(), setBlurHints()
+*/
+
+
+/*!
+    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->setBlurHints(QGraphicsBlurEffect::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.
+
+    The radius is given in device coordinates, meaning it is
+    unaffected by scale.
+*/
+qreal QGraphicsBlurEffect::blurRadius() const
+{
+    Q_D(const QGraphicsBlurEffect);
+    return d->filter->radius();
+}
+
+void QGraphicsBlurEffect::setBlurRadius(qreal radius)
+{
+    Q_D(QGraphicsBlurEffect);
+    if (qFuzzyCompare(d->filter->radius(), radius))
+        return;
+
+    d->filter->setRadius(radius);
+    updateBoundingRect();
+    emit blurRadiusChanged(radius);
+}
+
+/*!
+    \fn void QGraphicsBlurEffect::blurRadiusChanged(qreal 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::blurHints
+    \brief the blur hint of the effect.
+
+    Use the PerformanceHint hint to say that you want a faster blur,
+    the QualityHint hint to say that you prefer a higher quality blur,
+    or the AnimationHint when you want to animate the blur radius.
+
+    By default, the blur hint is PerformanceHint.
+*/
+QGraphicsBlurEffect::BlurHints QGraphicsBlurEffect::blurHints() const
+{
+    Q_D(const QGraphicsBlurEffect);
+    return d->filter->blurHints();
+}
+
+void QGraphicsBlurEffect::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
+{
+    Q_D(QGraphicsBlurEffect);
+    if (d->filter->blurHints() == hints)
+        return;
+
+    d->filter->setBlurHints(hints);
+    emit blurHintsChanged(hints);
+}
+
+/*!
+    \fn void QGraphicsBlurEffect::blurHintsChanged(QGraphicsBlurEffect::BlurHints hints)
+
+    This signal is emitted whenever the effect's blur hints changes.
+    The \a hints parameter holds the effect's new blur hints.
+*/
+
+/*!
+    \reimp
+*/
+QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
+{
+    Q_D(const QGraphicsBlurEffect);
+    return d->filter->boundingRectFor(rect);
+}
+
+/*!
+    \reimp
+*/
+void QGraphicsBlurEffect::draw(QPainter *painter)
+{
+    Q_D(QGraphicsBlurEffect);
+    if (d->filter->radius() < 1) {
+        drawSource(painter);
+        return;
+    }
+
+    PixmapPadMode mode = PadToEffectiveBoundingRect;
+    if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
+        mode = NoPad;
+
+    QPoint offset;
+    QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode);
+    if (pixmap.isNull())
+        return;
+
+    d->filter->draw(painter, offset, pixmap);
+}
+
+/*!
+    \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. The drop shadow offset is specified
+    in device coordinates.
+
+    \img graphicseffect-drop-shadow.png
+
+    \sa QGraphicsBlurEffect, 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.
+
+    The offset is given in device coordinates, which means it is
+    unaffected by scale.
+
+    \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().
+*/
+qreal QGraphicsDropShadowEffect::blurRadius() const
+{
+    Q_D(const QGraphicsDropShadowEffect);
+    return d->filter->blurRadius();
+}
+
+void QGraphicsDropShadowEffect::setBlurRadius(qreal blurRadius)
+{
+    Q_D(QGraphicsDropShadowEffect);
+    if (qFuzzyCompare(d->filter->blurRadius(), blurRadius))
+        return;
+
+    d->filter->setBlurRadius(blurRadius);
+    updateBoundingRect();
+    emit blurRadiusChanged(blurRadius);
+}
+
+/*!
+    \fn void QGraphicsDropShadowEffect::blurRadiusChanged(qreal 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)
+{
+    Q_D(QGraphicsDropShadowEffect);
+    if (d->filter->blurRadius() <= 0 && d->filter->offset().isNull()) {
+        drawSource(painter);
+        return;
+    }
+
+    PixmapPadMode mode = PadToEffectiveBoundingRect;
+    if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
+        mode = NoPad;
+
+    // Draw pixmap in device coordinates to avoid pixmap scaling.
+    QPoint offset;
+    const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
+    if (pixmap.isNull())
+        return;
+
+    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, 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)
+{
+    Q_D(QGraphicsOpacityEffect);
+
+    // Transparent; nothing to draw.
+    if (d->isFullyTransparent)
+        return;
+
+    // Opaque; draw directly without going through a pixmap.
+    if (d->isFullyOpaque && !d->hasOpacityMask) {
+        drawSource(painter);
+        return;
+    }
+
+    QPoint offset;
+    Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
+    QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad);
+    if (pixmap.isNull())
+        return;
+
+    painter->save();
+    painter->setOpacity(d->opacity);
+
+    if (d->hasOpacityMask) {
+        QPainter pixmapPainter(&pixmap);
+        pixmapPainter.setRenderHints(painter->renderHints());
+        pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+        if (system == Qt::DeviceCoordinates) {
+            QTransform worldTransform = painter->worldTransform();
+            worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
+            pixmapPainter.setWorldTransform(worldTransform);
+            pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask);
+        } else {
+            pixmapPainter.translate(-offset);
+            pixmapPainter.fillRect(pixmap.rect(), d->opacityMask);
+        }
+    }
+
+    if (system == Qt::DeviceCoordinates)
+        painter->setWorldTransform(QTransform());
+
+    painter->drawPixmap(offset, pixmap);
+    painter->restore();
+}
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSEFFECT