util/src/gui/effects/qgraphicseffect.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     \class QGraphicsEffect
       
    44     \brief The QGraphicsEffect class is the base class for all graphics
       
    45            effects.
       
    46     \since 4.6
       
    47     \ingroup multimedia
       
    48     \ingroup graphicsview-api
       
    49 
       
    50     Effects alter the appearance of elements by hooking into the rendering
       
    51     pipeline and operating between the source (e.g., a QGraphicsPixmapItem)
       
    52     and the destination device (e.g., QGraphicsView's viewport). Effects can be
       
    53     disabled by calling setEnabled(false). If effects are disabled, the source
       
    54     is rendered directly.
       
    55 
       
    56     To add a visual effect to a QGraphicsItem, for example, you can use one of
       
    57     the standard effects, or alternately, create your own effect by creating a
       
    58     subclass of QGraphicsEffect. The effect can then be installed on the item
       
    59     using QGraphicsItem::setGraphicsEffect().
       
    60 
       
    61     Qt provides the following standard effects:
       
    62 
       
    63     \list
       
    64     \o QGraphicsBlurEffect - blurs the item by a given radius
       
    65     \o QGraphicsDropShadowEffect - renders a dropshadow behind the item
       
    66     \o QGraphicsColorizeEffect - renders the item in shades of any given color
       
    67     \o QGraphicsOpacityEffect - renders the item with an opacity
       
    68     \endlist
       
    69 
       
    70     \table
       
    71     \row
       
    72     \o{2,1} \img graphicseffect-plain.png
       
    73     \row
       
    74     \o \img graphicseffect-blur.png
       
    75     \o \img graphicseffect-colorize.png
       
    76     \row
       
    77     \o \img graphicseffect-opacity.png
       
    78     \o \img graphicseffect-drop-shadow.png
       
    79     \endtable
       
    80 
       
    81     \img graphicseffect-widget.png
       
    82 
       
    83     For more information on how to use each effect, refer to the specific
       
    84     effect's documentation.
       
    85 
       
    86     To create your own custom effect, create a subclass of QGraphicsEffect (or
       
    87     any other existing effects) and reimplement the virtual function draw().
       
    88     This function is called whenever the effect needs to redraw. The draw()
       
    89     function takes the painter with which to draw as an argument. For more
       
    90     information, refer to the documenation for draw(). In the draw() function
       
    91     you can call sourcePixmap() to get a pixmap of the graphics effect source
       
    92     which you can then process.
       
    93 
       
    94     If your effect changes, use update() to request for a redraw. If your
       
    95     custom effect changes the bounding rectangle of the source, e.g., a radial
       
    96     glow effect may need to apply an extra margin, you can reimplement the
       
    97     virtual boundingRectFor() function, and call updateBoundingRect()
       
    98     to notify the framework whenever this rectangle changes. The virtual
       
    99     sourceChanged() function is called to notify the effects that
       
   100     the source has changed in some way - e.g., if the source is a
       
   101     QGraphicsRectItem and its rectangle parameters have changed.
       
   102 
       
   103     \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect()
       
   104 */
       
   105 
       
   106 #include "qgraphicseffect_p.h"
       
   107 #include "private/qgraphicsitem_p.h"
       
   108 
       
   109 #include <QtGui/qgraphicsitem.h>
       
   110 
       
   111 #include <QtGui/qimage.h>
       
   112 #include <QtGui/qpainter.h>
       
   113 #include <QtGui/qpaintengine.h>
       
   114 #include <QtCore/qrect.h>
       
   115 #include <QtCore/qdebug.h>
       
   116 #include <private/qdrawhelper_p.h>
       
   117 
       
   118 #ifndef QT_NO_GRAPHICSEFFECT
       
   119 QT_BEGIN_NAMESPACE
       
   120 
       
   121 /*!
       
   122     \internal
       
   123     \class QGraphicsEffectSource
       
   124     \brief The QGraphicsEffectSource class represents the source on which a
       
   125            QGraphicsEffect is installed on.
       
   126 
       
   127     When a QGraphicsEffect is installed on a QGraphicsItem, for example, this
       
   128     class will act as a wrapper around QGraphicsItem. Then, calling update() is
       
   129     effectively the same as calling QGraphicsItem::update().
       
   130 
       
   131     QGraphicsEffectSource also provides a pixmap() function which creates a
       
   132     pixmap with the source painted into it.
       
   133 
       
   134     \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect().
       
   135 */
       
   136 
       
   137 /*!
       
   138     \internal
       
   139 */
       
   140 QGraphicsEffectSource::QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent)
       
   141     : QObject(dd, parent)
       
   142 {}
       
   143 
       
   144 /*!
       
   145     Destroys the effect source.
       
   146 */
       
   147 QGraphicsEffectSource::~QGraphicsEffectSource()
       
   148 {}
       
   149 
       
   150 /*!
       
   151     Returns the bounding rectangle of the source mapped to the given \a system.
       
   152 
       
   153     \sa draw()
       
   154 */
       
   155 QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const
       
   156 {
       
   157     return d_func()->boundingRect(system);
       
   158 }
       
   159 
       
   160 /*!
       
   161     Returns the bounding rectangle of the source mapped to the given \a system.
       
   162 
       
   163     Calling this function with Qt::DeviceCoordinates outside of
       
   164     QGraphicsEffect::draw() will give undefined results, as there is no device
       
   165     context available.
       
   166 
       
   167     \sa draw()
       
   168 */
       
   169 QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const
       
   170 {
       
   171     Q_D(const QGraphicsEffect);
       
   172     if (d->source)
       
   173         return d->source->boundingRect(system);
       
   174     return QRectF();
       
   175 }
       
   176 
       
   177 /*!
       
   178     Returns a pointer to the item if this source is a QGraphicsItem; otherwise
       
   179     returns 0.
       
   180 
       
   181     \sa widget()
       
   182 */
       
   183 const QGraphicsItem *QGraphicsEffectSource::graphicsItem() const
       
   184 {
       
   185     return d_func()->graphicsItem();
       
   186 }
       
   187 
       
   188 /*!
       
   189     Returns a pointer to the widget if this source is a QWidget; otherwise
       
   190     returns 0.
       
   191 
       
   192     \sa graphicsItem()
       
   193 */
       
   194 const QWidget *QGraphicsEffectSource::widget() const
       
   195 {
       
   196     return d_func()->widget();
       
   197 }
       
   198 
       
   199 /*!
       
   200     Returns a pointer to the style options (used when drawing the source) if
       
   201     available; otherwise returns 0.
       
   202 
       
   203     \sa graphicsItem(), widget()
       
   204 */
       
   205 const QStyleOption *QGraphicsEffectSource::styleOption() const
       
   206 {
       
   207     return d_func()->styleOption();
       
   208 }
       
   209 
       
   210 /*!
       
   211     Draws the source using the given \a painter.
       
   212 
       
   213     This function should only be called from QGraphicsEffect::draw().
       
   214 
       
   215     \sa QGraphicsEffect::draw()
       
   216 */
       
   217 void QGraphicsEffectSource::draw(QPainter *painter)
       
   218 {
       
   219     Q_D(const QGraphicsEffectSource);
       
   220 
       
   221     QPixmap pm;
       
   222     if (QPixmapCache::find(d->m_cacheKey, &pm)) {
       
   223         QTransform restoreTransform;
       
   224         if (d->m_cachedSystem == Qt::DeviceCoordinates) {
       
   225             restoreTransform = painter->worldTransform();
       
   226             painter->setWorldTransform(QTransform());
       
   227         }
       
   228 
       
   229         painter->drawPixmap(d->m_cachedOffset, pm);
       
   230 
       
   231         if (d->m_cachedSystem == Qt::DeviceCoordinates)
       
   232             painter->setWorldTransform(restoreTransform);
       
   233     } else {
       
   234         d_func()->draw(painter);
       
   235     }
       
   236 }
       
   237 
       
   238 /*!
       
   239     Draws the source directly using the given \a painter.
       
   240 
       
   241     This function should only be called from QGraphicsEffect::draw().
       
   242 
       
   243     For example:
       
   244 
       
   245     \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 0
       
   246 
       
   247     \sa QGraphicsEffect::draw()
       
   248 */
       
   249 void QGraphicsEffect::drawSource(QPainter *painter)
       
   250 {
       
   251     Q_D(const QGraphicsEffect);
       
   252     if (d->source)
       
   253         d->source->draw(painter);
       
   254 }
       
   255 
       
   256 /*!
       
   257     Schedules a redraw of the source. Call this function whenever the source
       
   258     needs to be redrawn.
       
   259 
       
   260     \sa QGraphicsEffect::updateBoundingRect(), QWidget::update(),
       
   261         QGraphicsItem::update(),
       
   262 */
       
   263 void QGraphicsEffectSource::update()
       
   264 {
       
   265     d_func()->update();
       
   266 }
       
   267 
       
   268 /*!
       
   269     Returns true if the source effectively is a pixmap, e.g., a
       
   270     QGraphicsPixmapItem.
       
   271 
       
   272     This function is useful for optimization purposes. For instance, there's no
       
   273     point in drawing the source in device coordinates to avoid pixmap scaling
       
   274     if this function returns true - the source pixmap will be scaled anyways.
       
   275 */
       
   276 bool QGraphicsEffectSource::isPixmap() const
       
   277 {
       
   278     return d_func()->isPixmap();
       
   279 }
       
   280 
       
   281 /*!
       
   282     Returns true if the source effectively is a pixmap, e.g., a
       
   283     QGraphicsPixmapItem.
       
   284 
       
   285     This function is useful for optimization purposes. For instance, there's no
       
   286     point in drawing the source in device coordinates to avoid pixmap scaling
       
   287     if this function returns true - the source pixmap will be scaled anyways.
       
   288 */
       
   289 bool QGraphicsEffect::sourceIsPixmap() const
       
   290 {
       
   291     return source() ? source()->isPixmap() : false;
       
   292 }
       
   293 
       
   294 /*!
       
   295     Returns a pixmap with the source painted into it.
       
   296 
       
   297     The \a system specifies which coordinate system to be used for the source.
       
   298     The optional \a offset parameter returns the offset where the pixmap should
       
   299     be painted at using the current painter.
       
   300 
       
   301     The \a mode determines how much of the effect the pixmap will contain.
       
   302     By default, the pixmap will contain the whole effect.
       
   303 
       
   304     The returned pixmap is bound to the current painter's device rectangle when
       
   305     \a system is Qt::DeviceCoordinates.
       
   306 
       
   307     \sa QGraphicsEffect::draw(), boundingRect()
       
   308 */
       
   309 QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
       
   310 {
       
   311     Q_D(const QGraphicsEffectSource);
       
   312 
       
   313     // Shortcut, no cache for childless pixmap items...
       
   314     const QGraphicsItem *item = graphicsItem();
       
   315     if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
       
   316         const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item);
       
   317         if (offset)
       
   318             *offset = pixmapItem->offset().toPoint();
       
   319         return pixmapItem->pixmap();
       
   320     }
       
   321 
       
   322     if (system == Qt::DeviceCoordinates && item
       
   323         && !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info) {
       
   324         qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
       
   325         return QPixmap();
       
   326     }
       
   327 
       
   328     QPixmap pm;
       
   329     if (d->m_cachedSystem == system && d->m_cachedMode == mode)
       
   330         QPixmapCache::find(d->m_cacheKey, &pm);
       
   331 
       
   332     if (pm.isNull()) {
       
   333         pm = d->pixmap(system, &d->m_cachedOffset, mode);
       
   334         d->m_cachedSystem = system;
       
   335         d->m_cachedMode = mode;
       
   336 
       
   337         d->invalidateCache();
       
   338         d->m_cacheKey = QPixmapCache::insert(pm);
       
   339     }
       
   340 
       
   341     if (offset)
       
   342         *offset = d->m_cachedOffset;
       
   343 
       
   344     return pm;
       
   345 }
       
   346 
       
   347 /*!
       
   348     Returns a pixmap with the source painted into it.
       
   349 
       
   350     The \a system specifies which coordinate system to be used for the source.
       
   351     The optional \a offset parameter returns the offset where the pixmap should
       
   352     be painted at using the current painter. For control on how the pixmap is
       
   353     padded use the \a mode parameter.
       
   354 
       
   355     The returned pixmap is clipped to the current painter's device rectangle when
       
   356     \a system is Qt::DeviceCoordinates.
       
   357 
       
   358     Calling this function with Qt::DeviceCoordinates outside of
       
   359     QGraphicsEffect::draw() will give undefined results, as there is no device
       
   360     context available.
       
   361 
       
   362     \sa draw(), boundingRect()
       
   363 */
       
   364 QPixmap QGraphicsEffect::sourcePixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
       
   365 {
       
   366     Q_D(const QGraphicsEffect);
       
   367     if (d->source)
       
   368         return d->source->pixmap(system, offset, mode);
       
   369     return QPixmap();
       
   370 }
       
   371 
       
   372 QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate()
       
   373 {
       
   374     invalidateCache();
       
   375 }
       
   376 
       
   377 void QGraphicsEffectSourcePrivate::setCachedOffset(const QPoint &offset)
       
   378 {
       
   379     m_cachedOffset = offset;
       
   380 }
       
   381 
       
   382 void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) const
       
   383 {
       
   384     if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect
       
   385         && (reason == EffectRectChanged
       
   386             || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) {
       
   387         return;
       
   388     }
       
   389 
       
   390     QPixmapCache::remove(m_cacheKey);
       
   391 }
       
   392 
       
   393 /*!
       
   394     Constructs a new QGraphicsEffect instance having the
       
   395     specified \a parent.
       
   396 */
       
   397 QGraphicsEffect::QGraphicsEffect(QObject *parent)
       
   398     : QObject(*new QGraphicsEffectPrivate, parent)
       
   399 {
       
   400 }
       
   401 
       
   402 /*!
       
   403     \internal
       
   404 */
       
   405 QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd, QObject *parent)
       
   406     : QObject(dd, parent)
       
   407 {
       
   408 }
       
   409 
       
   410 /*!
       
   411     Removes the effect from the source, and destroys the graphics effect.
       
   412 */
       
   413 QGraphicsEffect::~QGraphicsEffect()
       
   414 {
       
   415     Q_D(QGraphicsEffect);
       
   416     d->setGraphicsEffectSource(0);
       
   417 }
       
   418 
       
   419 /*!
       
   420     Returns the effective bounding rectangle for this effect, i.e., the
       
   421     bounding rectangle of the source in device coordinates, adjusted by
       
   422     any margins applied by the effect itself.
       
   423 
       
   424     \sa boundingRectFor(), updateBoundingRect()
       
   425 */
       
   426 QRectF QGraphicsEffect::boundingRect() const
       
   427 {
       
   428     Q_D(const QGraphicsEffect);
       
   429     if (d->source)
       
   430         return boundingRectFor(d->source->boundingRect());
       
   431     return QRectF();
       
   432 }
       
   433 
       
   434 /*!
       
   435     Returns the effective bounding rectangle for this effect, given the
       
   436     provided \a rect in the device coordinates. When writing
       
   437     you own custom effect, you must call updateBoundingRect() whenever any
       
   438     parameters are changed that may cause this this function to return a
       
   439     different value.
       
   440 
       
   441     \sa sourceBoundingRect()
       
   442 */
       
   443 QRectF QGraphicsEffect::boundingRectFor(const QRectF &rect) const
       
   444 {
       
   445     return rect;
       
   446 }
       
   447 
       
   448 /*!
       
   449     \property QGraphicsEffect::enabled
       
   450     \brief whether the effect is enabled or not.
       
   451 
       
   452     If an effect is disabled, the source will be rendered with as normal, with
       
   453     no interference from the effect. If the effect is enabled, the source will
       
   454     be rendered with the effect applied.
       
   455 
       
   456     This property is enabled by default.
       
   457 
       
   458     Using this property, you can disable certain effects on slow platforms, in
       
   459     order to ensure that the user interface is responsive.
       
   460 */
       
   461 bool QGraphicsEffect::isEnabled() const
       
   462 {
       
   463     Q_D(const QGraphicsEffect);
       
   464     return d->isEnabled;
       
   465 }
       
   466 
       
   467 void QGraphicsEffect::setEnabled(bool enable)
       
   468 {
       
   469     Q_D(QGraphicsEffect);
       
   470     if (d->isEnabled == enable)
       
   471         return;
       
   472 
       
   473     d->isEnabled = enable;
       
   474     if (d->source) {
       
   475         d->source->d_func()->effectBoundingRectChanged();
       
   476         d->source->d_func()->invalidateCache();
       
   477     }
       
   478     emit enabledChanged(enable);
       
   479 }
       
   480 
       
   481 /*!
       
   482     \fn void QGraphicsEffect::enabledChanged(bool enabled)
       
   483 
       
   484     This signal is emitted whenever the effect is enabled or disabled.
       
   485     The \a enabled parameter holds the effects's new enabled state.
       
   486 
       
   487     \sa isEnabled()
       
   488 */
       
   489 
       
   490 /*!
       
   491     Schedules a redraw of the source. Call this function whenever the source
       
   492     needs to be redrawn.
       
   493 
       
   494     This convenience function is equivalent to calling
       
   495     QGraphicsEffectSource::update().
       
   496 
       
   497     \sa updateBoundingRect(), QGraphicsEffectSource::update()
       
   498 */
       
   499 void QGraphicsEffect::update()
       
   500 {
       
   501     Q_D(QGraphicsEffect);
       
   502     if (d->source)
       
   503         d->source->update();
       
   504 }
       
   505 
       
   506 /*!
       
   507     \internal
       
   508 
       
   509     Returns a pointer to the source, which provides extra context information
       
   510     that can be useful for the effect.
       
   511 
       
   512     \sa draw()
       
   513 */
       
   514 QGraphicsEffectSource *QGraphicsEffect::source() const
       
   515 {
       
   516     Q_D(const QGraphicsEffect);
       
   517     return d->source;
       
   518 }
       
   519 
       
   520 /*!
       
   521     This function notifies the effect framework when the effect's bounding
       
   522     rectangle has changed. As a custom effect author, you must call this
       
   523     function whenever you change any parameters that will cause the virtual
       
   524     boundingRectFor() function to return a different value.
       
   525 
       
   526     This function will call update() if this is necessary.
       
   527 
       
   528     \sa boundingRectFor(), boundingRect(), sourceBoundingRect()
       
   529 */
       
   530 void QGraphicsEffect::updateBoundingRect()
       
   531 {
       
   532     Q_D(QGraphicsEffect);
       
   533     if (d->source) {
       
   534         d->source->d_func()->effectBoundingRectChanged();
       
   535         d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged);
       
   536     }
       
   537 }
       
   538 
       
   539 /*!
       
   540     \fn virtual void QGraphicsEffect::draw(QPainter *painter) = 0
       
   541 
       
   542     This pure virtual function draws the effect and is called whenever the
       
   543     source needs to be drawn.
       
   544 
       
   545     Reimplement this function in a QGraphicsEffect subclass to provide the
       
   546     effect's drawing implementation, using \a painter.
       
   547 
       
   548     For example:
       
   549 
       
   550     \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 1
       
   551 
       
   552     This function should not be called explicitly by the user, since it is
       
   553     meant for reimplementation purposes only.
       
   554 */
       
   555 
       
   556 /*!
       
   557     \enum QGraphicsEffect::ChangeFlag
       
   558 
       
   559     This enum describes what has changed in QGraphicsEffectSource.
       
   560 
       
   561     \value SourceAttached The effect is installed on a source.
       
   562     \value SourceDetached The effect is uninstalled on a source.
       
   563     \value SourceBoundingRectChanged The bounding rect of the source has
       
   564            changed.
       
   565     \value SourceInvalidated The visual appearance of the source has changed.
       
   566 */
       
   567 
       
   568 /*!
       
   569     \enum QGraphicsEffect::PixmapPadMode
       
   570 
       
   571     This enum describes how the pixmap returned from sourcePixmap should be
       
   572     padded.
       
   573 
       
   574     \value NoPad The pixmap should not receive any additional
       
   575            padding.
       
   576     \value PadToTransparentBorder The pixmap should be padded
       
   577            to ensure it has a completely transparent border.
       
   578     \value PadToEffectiveBoundingRect The pixmap should be padded to
       
   579            match the effective bounding rectangle of the effect.
       
   580 */
       
   581 
       
   582 /*!
       
   583     This virtual function is called by QGraphicsEffect to notify the effect
       
   584     that the source has changed. If the effect applies any cache, then this
       
   585     cache must be purged in order to reflect the new appearance of the source.
       
   586 
       
   587     The \a flags describes what has changed.
       
   588 */
       
   589 void QGraphicsEffect::sourceChanged(ChangeFlags flags)
       
   590 {
       
   591     Q_UNUSED(flags);
       
   592 }
       
   593 
       
   594 /*!
       
   595     \class QGraphicsColorizeEffect
       
   596     \brief The QGraphicsColorizeEffect class provides a colorize effect.
       
   597     \since 4.6
       
   598 
       
   599     A colorize effect renders the source with a tint of its color(). The color
       
   600     can be modified using the setColor() function.
       
   601 
       
   602     By default, the color is light blue (QColor(0, 0, 192)).
       
   603 
       
   604     \img graphicseffect-colorize.png
       
   605 
       
   606     \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsOpacityEffect
       
   607 */
       
   608 
       
   609 /*!
       
   610     Constructs a new QGraphicsColorizeEffect instance.
       
   611     The \a parent parameter is passed to QGraphicsEffect's constructor.
       
   612 */
       
   613 QGraphicsColorizeEffect::QGraphicsColorizeEffect(QObject *parent)
       
   614     : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate, parent)
       
   615 {
       
   616 }
       
   617 
       
   618 /*!
       
   619     Destroys the effect.
       
   620 */
       
   621 QGraphicsColorizeEffect::~QGraphicsColorizeEffect()
       
   622 {
       
   623 }
       
   624 
       
   625 /*!
       
   626     \property QGraphicsColorizeEffect::color
       
   627     \brief the color of the effect.
       
   628 
       
   629     By default, the color is light blue (QColor(0, 0, 192)).
       
   630 */
       
   631 QColor QGraphicsColorizeEffect::color() const
       
   632 {
       
   633     Q_D(const QGraphicsColorizeEffect);
       
   634     return d->filter->color();
       
   635 }
       
   636 
       
   637 void QGraphicsColorizeEffect::setColor(const QColor &color)
       
   638 {
       
   639     Q_D(QGraphicsColorizeEffect);
       
   640     if (d->filter->color() == color)
       
   641         return;
       
   642 
       
   643     d->filter->setColor(color);
       
   644     update();
       
   645     emit colorChanged(color);
       
   646 }
       
   647 
       
   648 /*!
       
   649     \property QGraphicsColorizeEffect::strength
       
   650     \brief the strength of the effect.
       
   651 
       
   652     By default, the strength is 1.0.
       
   653     A strength 0.0 equals to no effect, while 1.0 means full colorization.
       
   654 */
       
   655 qreal QGraphicsColorizeEffect::strength() const
       
   656 {
       
   657     Q_D(const QGraphicsColorizeEffect);
       
   658     return d->filter->strength();
       
   659 }
       
   660 
       
   661 void QGraphicsColorizeEffect::setStrength(qreal strength)
       
   662 {
       
   663     Q_D(QGraphicsColorizeEffect);
       
   664     if (qFuzzyCompare(d->filter->strength(), strength))
       
   665         return;
       
   666 
       
   667     d->filter->setStrength(strength);
       
   668     d->opaque = !qFuzzyIsNull(strength);
       
   669     update();
       
   670     emit strengthChanged(strength);
       
   671 }
       
   672 
       
   673 /*! \fn void QGraphicsColorizeEffect::strengthChanged(qreal strength)
       
   674   This signal is emitted whenever setStrength() changes the colorize
       
   675   strength property. \a strength contains the new strength value of
       
   676   the colorize effect.
       
   677  */
       
   678 
       
   679 /*!
       
   680     \fn void QGraphicsColorizeEffect::colorChanged(const QColor &color)
       
   681 
       
   682     This signal is emitted whenever the effect's color changes.
       
   683     The \a color parameter holds the effect's new color.
       
   684 */
       
   685 
       
   686 /*!
       
   687     \reimp
       
   688 */
       
   689 void QGraphicsColorizeEffect::draw(QPainter *painter)
       
   690 {
       
   691     Q_D(QGraphicsColorizeEffect);
       
   692 
       
   693     if (!d->opaque) {
       
   694         drawSource(painter);
       
   695         return;
       
   696     }
       
   697 
       
   698     QPoint offset;
       
   699     if (sourceIsPixmap()) {
       
   700         // No point in drawing in device coordinates (pixmap will be scaled anyways).
       
   701         const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, NoPad);
       
   702         if (!pixmap.isNull())
       
   703             d->filter->draw(painter, offset, pixmap);
       
   704 
       
   705         return;
       
   706     }
       
   707 
       
   708     // Draw pixmap in deviceCoordinates to avoid pixmap scaling.
       
   709     const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);
       
   710     if (pixmap.isNull())
       
   711         return;
       
   712 
       
   713     QTransform restoreTransform = painter->worldTransform();
       
   714     painter->setWorldTransform(QTransform());
       
   715     d->filter->draw(painter, offset, pixmap);
       
   716     painter->setWorldTransform(restoreTransform);
       
   717 }
       
   718 
       
   719 /*!
       
   720     \class QGraphicsBlurEffect
       
   721     \brief The QGraphicsBlurEffect class provides a blur effect.
       
   722     \since 4.6
       
   723 
       
   724     A blur effect blurs the source. This effect is useful for reducing details,
       
   725     such as when the source loses focus and you want to draw attention to other
       
   726     elements. The level of detail can be modified using the setBlurRadius()
       
   727     function. Use setBlurHints() to choose the blur hints.
       
   728 
       
   729     By default, the blur radius is 5 pixels. The blur radius is specified in
       
   730     device coordinates.
       
   731 
       
   732     \img graphicseffect-blur.png
       
   733 
       
   734     \sa QGraphicsDropShadowEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
       
   735 */
       
   736 
       
   737 /*!
       
   738     \enum QGraphicsBlurEffect::BlurHint
       
   739     \since 4.6
       
   740 
       
   741     This enum describes the possible hints that can be used to control how
       
   742     blur effects are applied. The hints might not have an effect in all the
       
   743     paint engines.
       
   744 
       
   745     \value PerformanceHint Indicates that rendering performance is the most important factor,
       
   746     at the potential cost of lower quality.
       
   747 
       
   748     \value QualityHint Indicates that rendering quality is the most important factor,
       
   749     at the potential cost of lower performance.
       
   750 
       
   751     \value AnimationHint Indicates that the blur radius is going to be animated, hinting
       
   752     that the implementation can keep a cache of blurred verisons of the source.
       
   753     Do not use this hint if the source is going to be dynamically changing.
       
   754 
       
   755     \sa blurHints(), setBlurHints()
       
   756 */
       
   757 
       
   758 
       
   759 /*!
       
   760     Constructs a new QGraphicsBlurEffect instance.
       
   761     The \a parent parameter is passed to QGraphicsEffect's constructor.
       
   762 */
       
   763 QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
       
   764     : QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
       
   765 {
       
   766     Q_D(QGraphicsBlurEffect);
       
   767     d->filter->setBlurHints(QGraphicsBlurEffect::PerformanceHint);
       
   768 }
       
   769 
       
   770 /*!
       
   771     Destroys the effect.
       
   772 */
       
   773 QGraphicsBlurEffect::~QGraphicsBlurEffect()
       
   774 {
       
   775 }
       
   776 
       
   777 /*!
       
   778     \property QGraphicsBlurEffect::blurRadius
       
   779     \brief the blur radius of the effect.
       
   780 
       
   781     Using a smaller radius results in a sharper appearance, whereas a bigger
       
   782     radius results in a more blurred appearance.
       
   783 
       
   784     By default, the blur radius is 5 pixels.
       
   785 
       
   786     The radius is given in device coordinates, meaning it is
       
   787     unaffected by scale.
       
   788 */
       
   789 qreal QGraphicsBlurEffect::blurRadius() const
       
   790 {
       
   791     Q_D(const QGraphicsBlurEffect);
       
   792     return d->filter->radius();
       
   793 }
       
   794 
       
   795 void QGraphicsBlurEffect::setBlurRadius(qreal radius)
       
   796 {
       
   797     Q_D(QGraphicsBlurEffect);
       
   798     if (qFuzzyCompare(d->filter->radius(), radius))
       
   799         return;
       
   800 
       
   801     d->filter->setRadius(radius);
       
   802     updateBoundingRect();
       
   803     emit blurRadiusChanged(radius);
       
   804 }
       
   805 
       
   806 /*!
       
   807     \fn void QGraphicsBlurEffect::blurRadiusChanged(qreal radius)
       
   808 
       
   809     This signal is emitted whenever the effect's blur radius changes.
       
   810     The \a radius parameter holds the effect's new blur radius.
       
   811 */
       
   812 
       
   813 /*!
       
   814     \property QGraphicsBlurEffect::blurHints
       
   815     \brief the blur hint of the effect.
       
   816 
       
   817     Use the PerformanceHint hint to say that you want a faster blur,
       
   818     the QualityHint hint to say that you prefer a higher quality blur,
       
   819     or the AnimationHint when you want to animate the blur radius.
       
   820 
       
   821     By default, the blur hint is PerformanceHint.
       
   822 */
       
   823 QGraphicsBlurEffect::BlurHints QGraphicsBlurEffect::blurHints() const
       
   824 {
       
   825     Q_D(const QGraphicsBlurEffect);
       
   826     return d->filter->blurHints();
       
   827 }
       
   828 
       
   829 void QGraphicsBlurEffect::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
       
   830 {
       
   831     Q_D(QGraphicsBlurEffect);
       
   832     if (d->filter->blurHints() == hints)
       
   833         return;
       
   834 
       
   835     d->filter->setBlurHints(hints);
       
   836     emit blurHintsChanged(hints);
       
   837 }
       
   838 
       
   839 /*!
       
   840     \fn void QGraphicsBlurEffect::blurHintsChanged(QGraphicsBlurEffect::BlurHints hints)
       
   841 
       
   842     This signal is emitted whenever the effect's blur hints changes.
       
   843     The \a hints parameter holds the effect's new blur hints.
       
   844 */
       
   845 
       
   846 /*!
       
   847     \reimp
       
   848 */
       
   849 QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
       
   850 {
       
   851     Q_D(const QGraphicsBlurEffect);
       
   852     return d->filter->boundingRectFor(rect);
       
   853 }
       
   854 
       
   855 /*!
       
   856     \reimp
       
   857 */
       
   858 void QGraphicsBlurEffect::draw(QPainter *painter)
       
   859 {
       
   860     Q_D(QGraphicsBlurEffect);
       
   861     if (d->filter->radius() < 1) {
       
   862         drawSource(painter);
       
   863         return;
       
   864     }
       
   865 
       
   866     PixmapPadMode mode = PadToEffectiveBoundingRect;
       
   867     if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
       
   868         mode = NoPad;
       
   869 
       
   870     QPoint offset;
       
   871     QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode);
       
   872     if (pixmap.isNull())
       
   873         return;
       
   874 
       
   875     d->filter->draw(painter, offset, pixmap);
       
   876 }
       
   877 
       
   878 /*!
       
   879     \class QGraphicsDropShadowEffect
       
   880     \brief The QGraphicsDropShadowEffect class provides a drop shadow effect.
       
   881     \since 4.6
       
   882 
       
   883     A drop shadow effect renders the source with a drop shadow. The color of
       
   884     the drop shadow can be modified using the setColor() function. The drop
       
   885     shadow offset can be modified using the setOffset() function and the blur
       
   886     radius of the drop shadow can be changed with the setBlurRadius()
       
   887     function.
       
   888 
       
   889     By default, the drop shadow is a semi-transparent dark gray
       
   890     (QColor(63, 63, 63, 180)) shadow, blurred with a radius of 1 at an offset
       
   891     of 8 pixels towards the lower right. The drop shadow offset is specified
       
   892     in device coordinates.
       
   893 
       
   894     \img graphicseffect-drop-shadow.png
       
   895 
       
   896     \sa QGraphicsBlurEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
       
   897 */
       
   898 
       
   899 /*!
       
   900     Constructs a new QGraphicsDropShadowEffect instance.
       
   901     The \a parent parameter is passed to QGraphicsEffect's constructor.
       
   902 */
       
   903 QGraphicsDropShadowEffect::QGraphicsDropShadowEffect(QObject *parent)
       
   904     : QGraphicsEffect(*new QGraphicsDropShadowEffectPrivate, parent)
       
   905 {
       
   906 }
       
   907 
       
   908 /*!
       
   909     Destroys the effect.
       
   910 */
       
   911 QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect()
       
   912 {
       
   913 }
       
   914 
       
   915 /*!
       
   916     \property QGraphicsDropShadowEffect::offset
       
   917     \brief the shadow offset in pixels.
       
   918 
       
   919     By default, the offset is 8 pixels towards the lower right.
       
   920 
       
   921     The offset is given in device coordinates, which means it is
       
   922     unaffected by scale.
       
   923 
       
   924     \sa xOffset(), yOffset(), blurRadius(), color()
       
   925 */
       
   926 QPointF QGraphicsDropShadowEffect::offset() const
       
   927 {
       
   928     Q_D(const QGraphicsDropShadowEffect);
       
   929     return d->filter->offset();
       
   930 }
       
   931 
       
   932 void QGraphicsDropShadowEffect::setOffset(const QPointF &offset)
       
   933 {
       
   934     Q_D(QGraphicsDropShadowEffect);
       
   935     if (d->filter->offset() == offset)
       
   936         return;
       
   937 
       
   938     d->filter->setOffset(offset);
       
   939     updateBoundingRect();
       
   940     emit offsetChanged(offset);
       
   941 }
       
   942 
       
   943 /*!
       
   944     \property QGraphicsDropShadowEffect::xOffset
       
   945     \brief the horizontal shadow offset in pixels.
       
   946 
       
   947     By default, the horizontal shadow offset is 8 pixels.
       
   948 
       
   949 
       
   950 
       
   951     \sa yOffset(), offset()
       
   952 */
       
   953 
       
   954 /*!
       
   955     \property QGraphicsDropShadowEffect::yOffset
       
   956     \brief the vertical shadow offset in pixels.
       
   957 
       
   958     By default, the vertical shadow offset is 8 pixels.
       
   959 
       
   960     \sa xOffset(), offset()
       
   961 */
       
   962 
       
   963 /*!
       
   964     \fn void QGraphicsDropShadowEffect::offsetChanged(const QPointF &offset)
       
   965 
       
   966     This signal is emitted whenever the effect's shadow offset changes.
       
   967     The \a offset parameter holds the effect's new shadow offset.
       
   968 */
       
   969 
       
   970 /*!
       
   971     \property QGraphicsDropShadowEffect::blurRadius
       
   972     \brief the blur radius in pixels of the drop shadow.
       
   973 
       
   974     Using a smaller radius results in a sharper shadow, whereas using a bigger
       
   975     radius results in a more blurred shadow.
       
   976 
       
   977     By default, the blur radius is 1 pixel.
       
   978 
       
   979     \sa color(), offset().
       
   980 */
       
   981 qreal QGraphicsDropShadowEffect::blurRadius() const
       
   982 {
       
   983     Q_D(const QGraphicsDropShadowEffect);
       
   984     return d->filter->blurRadius();
       
   985 }
       
   986 
       
   987 void QGraphicsDropShadowEffect::setBlurRadius(qreal blurRadius)
       
   988 {
       
   989     Q_D(QGraphicsDropShadowEffect);
       
   990     if (qFuzzyCompare(d->filter->blurRadius(), blurRadius))
       
   991         return;
       
   992 
       
   993     d->filter->setBlurRadius(blurRadius);
       
   994     updateBoundingRect();
       
   995     emit blurRadiusChanged(blurRadius);
       
   996 }
       
   997 
       
   998 /*!
       
   999     \fn void QGraphicsDropShadowEffect::blurRadiusChanged(qreal blurRadius)
       
  1000 
       
  1001     This signal is emitted whenever the effect's blur radius changes.
       
  1002     The \a blurRadius parameter holds the effect's new blur radius.
       
  1003 */
       
  1004 
       
  1005 /*!
       
  1006     \property QGraphicsDropShadowEffect::color
       
  1007     \brief the color of the drop shadow.
       
  1008 
       
  1009     By default, the drop color is a semi-transparent dark gray
       
  1010     (QColor(63, 63, 63, 180)).
       
  1011 
       
  1012     \sa offset(), blurRadius()
       
  1013 */
       
  1014 QColor QGraphicsDropShadowEffect::color() const
       
  1015 {
       
  1016     Q_D(const QGraphicsDropShadowEffect);
       
  1017     return d->filter->color();
       
  1018 }
       
  1019 
       
  1020 void QGraphicsDropShadowEffect::setColor(const QColor &color)
       
  1021 {
       
  1022     Q_D(QGraphicsDropShadowEffect);
       
  1023     if (d->filter->color() == color)
       
  1024         return;
       
  1025 
       
  1026     d->filter->setColor(color);
       
  1027     update();
       
  1028     emit colorChanged(color);
       
  1029 }
       
  1030 
       
  1031 /*!
       
  1032     \fn void QGraphicsDropShadowEffect::colorChanged(const QColor &color)
       
  1033 
       
  1034     This signal is emitted whenever the effect's color changes.
       
  1035     The \a color parameter holds the effect's new color.
       
  1036 */
       
  1037 
       
  1038 /*!
       
  1039     \reimp
       
  1040 */
       
  1041 QRectF QGraphicsDropShadowEffect::boundingRectFor(const QRectF &rect) const
       
  1042 {
       
  1043     Q_D(const QGraphicsDropShadowEffect);
       
  1044     return d->filter->boundingRectFor(rect);
       
  1045 }
       
  1046 
       
  1047 /*!
       
  1048     \reimp
       
  1049 */
       
  1050 void QGraphicsDropShadowEffect::draw(QPainter *painter)
       
  1051 {
       
  1052     Q_D(QGraphicsDropShadowEffect);
       
  1053     if (d->filter->blurRadius() <= 0 && d->filter->offset().isNull()) {
       
  1054         drawSource(painter);
       
  1055         return;
       
  1056     }
       
  1057 
       
  1058     PixmapPadMode mode = PadToEffectiveBoundingRect;
       
  1059     if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
       
  1060         mode = NoPad;
       
  1061 
       
  1062     // Draw pixmap in device coordinates to avoid pixmap scaling.
       
  1063     QPoint offset;
       
  1064     const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
       
  1065     if (pixmap.isNull())
       
  1066         return;
       
  1067 
       
  1068     QTransform restoreTransform = painter->worldTransform();
       
  1069     painter->setWorldTransform(QTransform());
       
  1070     d->filter->draw(painter, offset, pixmap);
       
  1071     painter->setWorldTransform(restoreTransform);
       
  1072 }
       
  1073 
       
  1074 /*!
       
  1075     \class QGraphicsOpacityEffect
       
  1076     \brief The QGraphicsOpacityEffect class provides an opacity effect.
       
  1077     \since 4.6
       
  1078 
       
  1079     An opacity effect renders the source with an opacity. This effect is useful
       
  1080     for making the source semi-transparent, similar to a fade-in/fade-out
       
  1081     sequence. The opacity can be modified using the setOpacity() function.
       
  1082 
       
  1083     By default, the opacity is 0.7.
       
  1084 
       
  1085     \img graphicseffect-opacity.png
       
  1086 
       
  1087     \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsColorizeEffect
       
  1088 */
       
  1089 
       
  1090 /*!
       
  1091     Constructs a new QGraphicsOpacityEffect instance.
       
  1092     The \a parent parameter is passed to QGraphicsEffect's constructor.
       
  1093 */
       
  1094 QGraphicsOpacityEffect::QGraphicsOpacityEffect(QObject *parent)
       
  1095     : QGraphicsEffect(*new QGraphicsOpacityEffectPrivate, parent)
       
  1096 {
       
  1097 }
       
  1098 
       
  1099 /*!
       
  1100     Destroys the effect.
       
  1101 */
       
  1102 QGraphicsOpacityEffect::~QGraphicsOpacityEffect()
       
  1103 {
       
  1104 }
       
  1105 
       
  1106 /*!
       
  1107     \property QGraphicsOpacityEffect::opacity
       
  1108     \brief the opacity of the effect.
       
  1109 
       
  1110     The value should be in the range of 0.0 to 1.0, where 0.0 is
       
  1111     fully transparent and 1.0 is fully opaque.
       
  1112 
       
  1113     By default, the opacity is 0.7.
       
  1114 
       
  1115     \sa setOpacityMask()
       
  1116 */
       
  1117 qreal QGraphicsOpacityEffect::opacity() const
       
  1118 {
       
  1119     Q_D(const QGraphicsOpacityEffect);
       
  1120     return d->opacity;
       
  1121 }
       
  1122 
       
  1123 void QGraphicsOpacityEffect::setOpacity(qreal opacity)
       
  1124 {
       
  1125     Q_D(QGraphicsOpacityEffect);
       
  1126     opacity = qBound(qreal(0.0), opacity, qreal(1.0));
       
  1127 
       
  1128     if (qFuzzyCompare(d->opacity, opacity))
       
  1129         return;
       
  1130 
       
  1131     d->opacity = opacity;
       
  1132     if ((d->isFullyTransparent = qFuzzyIsNull(d->opacity)))
       
  1133         d->isFullyOpaque = 0;
       
  1134     else
       
  1135         d->isFullyOpaque = qFuzzyIsNull(d->opacity - 1);
       
  1136     update();
       
  1137     emit opacityChanged(opacity);
       
  1138 }
       
  1139 
       
  1140 /*!
       
  1141     \fn void QGraphicsOpacityEffect::opacityChanged(qreal opacity)
       
  1142 
       
  1143     This signal is emitted whenever the effect's opacity changes.
       
  1144     The \a opacity parameter holds the effect's new opacity.
       
  1145 */
       
  1146 
       
  1147 /*!
       
  1148     \property QGraphicsOpacityEffect::opacityMask
       
  1149     \brief the opacity mask of the effect.
       
  1150 
       
  1151     An opacity mask allows you apply opacity to portions of an element.
       
  1152 
       
  1153     For example:
       
  1154 
       
  1155     \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 2
       
  1156 
       
  1157     There is no opacity mask by default.
       
  1158 
       
  1159     \sa setOpacity()
       
  1160 */
       
  1161 QBrush QGraphicsOpacityEffect::opacityMask() const
       
  1162 {
       
  1163     Q_D(const QGraphicsOpacityEffect);
       
  1164     return d->opacityMask;
       
  1165 }
       
  1166 
       
  1167 void QGraphicsOpacityEffect::setOpacityMask(const QBrush &mask)
       
  1168 {
       
  1169     Q_D(QGraphicsOpacityEffect);
       
  1170     if (d->opacityMask == mask)
       
  1171         return;
       
  1172 
       
  1173     d->opacityMask = mask;
       
  1174     d->hasOpacityMask = (mask.style() != Qt::NoBrush);
       
  1175     update();
       
  1176 
       
  1177     emit opacityMaskChanged(mask);
       
  1178 }
       
  1179 
       
  1180 /*!
       
  1181     \fn void QGraphicsOpacityEffect::opacityMaskChanged(const QBrush &mask)
       
  1182 
       
  1183     This signal is emitted whenever the effect's opacity mask changes.
       
  1184     The \a mask parameter holds the effect's new opacity mask.
       
  1185 */
       
  1186 
       
  1187 /*!
       
  1188     \reimp
       
  1189 */
       
  1190 void QGraphicsOpacityEffect::draw(QPainter *painter)
       
  1191 {
       
  1192     Q_D(QGraphicsOpacityEffect);
       
  1193 
       
  1194     // Transparent; nothing to draw.
       
  1195     if (d->isFullyTransparent)
       
  1196         return;
       
  1197 
       
  1198     // Opaque; draw directly without going through a pixmap.
       
  1199     if (d->isFullyOpaque && !d->hasOpacityMask) {
       
  1200         drawSource(painter);
       
  1201         return;
       
  1202     }
       
  1203 
       
  1204     QPoint offset;
       
  1205     Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
       
  1206     QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad);
       
  1207     if (pixmap.isNull())
       
  1208         return;
       
  1209 
       
  1210     painter->save();
       
  1211     painter->setOpacity(d->opacity);
       
  1212 
       
  1213     if (d->hasOpacityMask) {
       
  1214         QPainter pixmapPainter(&pixmap);
       
  1215         pixmapPainter.setRenderHints(painter->renderHints());
       
  1216         pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
       
  1217         if (system == Qt::DeviceCoordinates) {
       
  1218             QTransform worldTransform = painter->worldTransform();
       
  1219             worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
       
  1220             pixmapPainter.setWorldTransform(worldTransform);
       
  1221             pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask);
       
  1222         } else {
       
  1223             pixmapPainter.translate(-offset);
       
  1224             pixmapPainter.fillRect(pixmap.rect(), d->opacityMask);
       
  1225         }
       
  1226     }
       
  1227 
       
  1228     if (system == Qt::DeviceCoordinates)
       
  1229         painter->setWorldTransform(QTransform());
       
  1230 
       
  1231     painter->drawPixmap(offset, pixmap);
       
  1232     painter->restore();
       
  1233 }
       
  1234 
       
  1235 
       
  1236 QT_END_NAMESPACE
       
  1237 
       
  1238 #endif //QT_NO_GRAPHICSEFFECT