200 Q_D(HbVgChainedEffect); |
201 Q_D(HbVgChainedEffect); |
201 // If some effect wants to be the source then have it rendered |
202 // If some effect wants to be the source then have it rendered |
202 // into a pixmap first (works only for sw-based effects). |
203 // into a pixmap first (works only for sw-based effects). |
203 QPixmap src = d->srcPixmap; |
204 QPixmap src = d->srcPixmap; |
204 QVariant srcVgImage = vgImage; |
205 QVariant srcVgImage = vgImage; |
205 QSize srcVgImageSize = vgImageSize; |
|
206 QPointF srcOffset = offset; |
|
207 foreach(HbVgEffect * effect, d->effects) { |
206 foreach(HbVgEffect * effect, d->effects) { |
208 if (effect->chainBehavior() == ChainBehavAsSource) { |
207 if (effect->chainBehavior() == ChainBehavAsSource) { |
209 // Restore the world transform temporarily because the sw |
208 // Restore the world transform temporarily because the sw |
210 // version has slightly different semantics. |
209 // version has slightly different semantics. |
211 painter->setWorldTransform(d->worldTransform); |
210 painter->setWorldTransform(d->worldTransform); |
212 effect->performEffectSw(painter, &src, &srcOffset); |
211 QPixmap modSrc = src; |
|
212 QPointF modOffset; |
|
213 // This can be nothing but a mask effect and it can produce smaller output if |
|
214 // the source is based on a scroll area (or anything that clips its children, |
|
215 // as long as the source pixmaps are not restricted to obey the clipping). So |
|
216 // have its output in a temporary pixmap and copy it into the original source |
|
217 // pixmap to the (hopefully) appropriate position afterwards. |
|
218 effect->performEffectSw(painter, &modSrc, &modOffset); |
|
219 qreal dx = modOffset.x() - offset.x(); |
|
220 qreal dy = modOffset.y() - offset.y(); |
213 painter->setWorldTransform(QTransform()); |
221 painter->setWorldTransform(QTransform()); |
214 srcVgImage = QVariant::fromValue<VGImage>(qPixmapToVGImage(src)); |
222 if (dx >= 0 && dy >= 0) { |
215 srcVgImageSize = src.size(); |
223 src.fill(Qt::transparent); |
|
224 QPainter p(&src); |
|
225 p.drawPixmap(QPointF(dx, dy), modSrc); |
|
226 p.end(); |
|
227 srcVgImage = QVariant::fromValue<VGImage>(qPixmapToVGImage(src)); |
|
228 } |
216 break; |
229 break; |
217 } |
230 } |
218 } |
231 } |
219 bool hadNormalEffects = false; |
232 bool hadNormalEffects = false; |
220 foreach(HbVgEffect * effect, d->effects) { |
233 foreach(HbVgEffect * effect, d->effects) { |
226 // contained ones. |
239 // contained ones. |
227 HbVgEffectPrivate *effD = HbVgEffectPrivate::d_ptr(effect); |
240 HbVgEffectPrivate *effD = HbVgEffectPrivate::d_ptr(effect); |
228 effD->srcPixmap = src; |
241 effD->srcPixmap = src; |
229 effD->worldTransform = d->worldTransform; |
242 effD->worldTransform = d->worldTransform; |
230 // Draw. |
243 // Draw. |
231 effect->performEffect(painter, srcOffset, srcVgImage, srcVgImageSize); |
244 effect->performEffect(painter, offset, srcVgImage, vgImageSize); |
232 // The flags must be cleared manually for the contained effects. |
245 // The flags must be cleared manually for the contained effects. |
233 effD->paramsChanged = effD->cacheInvalidated = false; |
246 effD->paramsChanged = effD->cacheInvalidated = false; |
|
247 if (effD->alwaysClearPixmaps || HbInstancePrivate::d_ptr()->mDropHiddenIconData) { |
|
248 effD->clearPixmaps(); |
|
249 } |
234 hadNormalEffects = true; |
250 hadNormalEffects = true; |
235 } |
251 } |
236 // If there are no effects in the chain then just draw the source. |
252 // If there are no effects in the chain then just draw the source. |
237 if (d->effects.isEmpty() || !hadNormalEffects) { |
253 if (d->effects.isEmpty() || !hadNormalEffects) { |
238 painter->drawPixmap(srcOffset, src); |
254 painter->drawPixmap(offset, src); |
239 } |
255 } |
240 |
256 |
241 #else |
257 #else |
242 Q_UNUSED(painter); |
258 Q_UNUSED(painter); |
243 Q_UNUSED(offset); |
259 Q_UNUSED(offset); |