src/hbcore/ovgeffects/hbvgchainedeffect.cpp
changeset 21 4633027730f5
parent 7 923ff622b8b9
child 30 80e4d18b72f5
equal deleted inserted replaced
7:923ff622b8b9 21:4633027730f5
    47  * something else.
    47  * something else.
    48  *
    48  *
    49  * For the sake of simplicity the opacity and caching properties of
    49  * For the sake of simplicity the opacity and caching properties of
    50  * ChainedEffect instances is ignored, use the property of the
    50  * ChainedEffect instances is ignored, use the property of the
    51  * individual effects instead.
    51  * individual effects instead.
       
    52  *
       
    53  * Software-based mask effects in the chain are handled specially. If
       
    54  * such an effect is present at any position, it will be applied first
       
    55  * and the other effects will get its output as their source pixmap.
       
    56  * (this works only in hw mode)
    52  */
    57  */
    53 
    58 
    54 /*!
    59 /*!
    55  * Constructs a new chained effect instance.
    60  * Constructs a new chained effect instance.
    56  */
    61  */
   137     Q_D(HbVgChainedEffect);
   142     Q_D(HbVgChainedEffect);
   138     return d->effects.at(index);
   143     return d->effects.at(index);
   139 }
   144 }
   140 
   145 
   141 /*!
   146 /*!
       
   147  * Returns all effects in a list and removes them from the chain
       
   148  * without destroying them.
       
   149  */
       
   150 QList<HbVgEffect *> HbVgChainedEffect::takeAll()
       
   151 {
       
   152     Q_D(HbVgChainedEffect);
       
   153     QList<HbVgEffect *> result = d->effects.toList();
       
   154     d->effects.clear();
       
   155     return result;
       
   156 }
       
   157 
       
   158 /*!
   142  * \reimp
   159  * \reimp
   143  */
   160  */
   144 QRectF HbVgChainedEffect::boundingRectFor(const QRectF &rect) const
   161 QRectF HbVgChainedEffect::boundingRectFor(const QRectF &rect) const
   145 {
   162 {
   146     Q_D(const HbVgChainedEffect);
   163     Q_D(const HbVgChainedEffect);
   179                                       const QVariant &vgImage,
   196                                       const QVariant &vgImage,
   180                                       const QSize &vgImageSize)
   197                                       const QSize &vgImageSize)
   181 {
   198 {
   182 #ifdef HB_EFFECTS_OPENVG
   199 #ifdef HB_EFFECTS_OPENVG
   183     Q_D(HbVgChainedEffect);
   200     Q_D(HbVgChainedEffect);
   184     foreach(HbVgEffect * effect, d->effects) {
   201     // If some effect wants to be the source then have it rendered
       
   202     // into a pixmap first (works only for sw-based effects).
       
   203     QPixmap src = d->srcPixmap;
       
   204     QVariant srcVgImage = vgImage;
       
   205     QSize srcVgImageSize = vgImageSize;
       
   206     QPointF srcOffset = offset;
       
   207     foreach(HbVgEffect * effect, d->effects) {
       
   208         if (effect->chainBehavior() == ChainBehavAsSource) {
       
   209             // Restore the world transform temporarily because the sw
       
   210             // version has slightly different semantics.
       
   211             painter->setWorldTransform(d->worldTransform);
       
   212             effect->performEffectSw(painter, &src, &srcOffset);
       
   213             painter->setWorldTransform(QTransform());
       
   214             srcVgImage = QVariant::fromValue<VGImage>(qPixmapToVGImage(src));
       
   215             srcVgImageSize = src.size();
       
   216             break;
       
   217         }
       
   218     }
       
   219     bool hadNormalEffects = false;
       
   220     foreach(HbVgEffect * effect, d->effects) {
       
   221         if (effect->chainBehavior() == ChainBehavAsSource) {
       
   222             continue;
       
   223         }
   185         // Set up srcPixmap and others for the individual effects
   224         // Set up srcPixmap and others for the individual effects
   186         // because the base class does it only for us, not for the
   225         // because the base class does it only for us, not for the
   187         // contained ones.
   226         // contained ones.
   188         HbVgEffectPrivate *effD = HbVgEffectPrivate::d_ptr(effect);
   227         HbVgEffectPrivate *effD = HbVgEffectPrivate::d_ptr(effect);
   189         effD->srcPixmap = d->srcPixmap;
   228         effD->srcPixmap = src;
   190         effD->worldTransform = d->worldTransform;
   229         effD->worldTransform = d->worldTransform;
   191         // Draw.
   230         // Draw.
   192         effect->performEffect(painter, offset, vgImage, vgImageSize);
   231         effect->performEffect(painter, srcOffset, srcVgImage, srcVgImageSize);
   193         // The flags must be cleared manually for the contained effects.
   232         // The flags must be cleared manually for the contained effects.
   194         effD->paramsChanged = effD->cacheInvalidated = false;
   233         effD->paramsChanged = effD->cacheInvalidated = false;
       
   234         hadNormalEffects = true;
   195     }
   235     }
   196     // If there are no effects in the chain then just draw the source.
   236     // If there are no effects in the chain then just draw the source.
   197     if (d->effects.isEmpty()) {
   237     if (d->effects.isEmpty() || !hadNormalEffects) {
   198         painter->drawPixmap(offset, d->srcPixmap);
   238         painter->drawPixmap(srcOffset, src);
   199     }
   239     }
   200 
   240 
   201 #else
   241 #else
   202     Q_UNUSED(painter);
   242     Q_UNUSED(painter);
   203     Q_UNUSED(offset);
   243     Q_UNUSED(offset);
   206 #endif
   246 #endif
   207 }
   247 }
   208 
   248 
   209 /*!
   249 /*!
   210  * \reimp
   250  * \reimp
   211  */
   251  *
   212 void HbVgChainedEffect::performEffectSw(QPainter *painter)
   252  * Sw-mode for a chained effect does not make much sense and will
   213 {
   253  * usually not have any good results because typically the only
   214     Q_D(HbVgChainedEffect);
   254  * sw-based effect is the mask effect and that would need special
   215     foreach(HbVgEffect * effect, d->effects) {
   255  * handling which is impossible to provide here.
   216         effect->performEffectSw(painter);
   256  */
       
   257 void HbVgChainedEffect::performEffectSw(QPainter *devicePainter,
       
   258                                         QPixmap *result,
       
   259                                         QPointF *resultPos)
       
   260 {
       
   261     Q_D(HbVgChainedEffect);
       
   262     foreach(HbVgEffect * effect, d->effects) {
       
   263         effect->performEffectSw(devicePainter, result, resultPos);
   217         HbVgEffectPrivate *effD = HbVgEffectPrivate::d_ptr(effect);
   264         HbVgEffectPrivate *effD = HbVgEffectPrivate::d_ptr(effect);
   218         effD->paramsChanged = effD->cacheInvalidated = false;
   265         effD->paramsChanged = effD->cacheInvalidated = false;
   219     }
   266     }
   220     if (d->effects.isEmpty()) {
   267     if (d->effects.isEmpty()) {
   221         drawSource(painter);
   268         drawSource(devicePainter);
   222     }
   269     }
   223 }
   270 }
   224 
   271 
   225 /*!
   272 /*!
   226   \reimp
   273   \reimp