Replace 'i < len-1 && func(i+1)' by 'i+1 < len && func(i+1)'
[profile/ivi/qtbase.git] / src / gui / painting / qpaintengine_blitter.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "private/qpaintengine_blitter_p.h"
43
44 #include "private/qblittable_p.h"
45 #include "private/qpaintengine_raster_p.h"
46 #include "private/qpainter_p.h"
47 #include "private/qapplication_p.h"
48 #include "private/qpixmap_blitter_p.h"
49
50 #ifndef QT_NO_BLITTABLE
51 QT_BEGIN_NAMESPACE
52
53 #define STATE_XFORM_SCALE       0x00000001
54 #define STATE_XFORM_COMPLEX     0x00000002
55
56 #define STATE_BRUSH_PATTERN     0x00000010
57 #define STATE_BRUSH_ALPHA       0x00000020
58
59 #define STATE_PEN_ENABLED       0x00000100
60
61 #define STATE_ANTIALIASING      0x00001000
62 #define STATE_ALPHA             0x00002000
63 #define STATE_BLENDING_COMPLEX  0x00004000
64
65 #define STATE_CLIPSYS_COMPLEX   0x00010000
66 #define STATE_CLIP_COMPLEX      0x00020000
67
68
69 static inline void updateStateBits(uint *state, uint mask, bool on)
70 {
71     *state = on ? (*state | mask) : (*state & ~mask);
72 }
73
74 static inline bool checkStateAgainstMask(uint state, uint mask)
75 {
76     return !state || (state & mask && !(state & ~mask));
77 }
78
79 class CapabilitiesToStateMask
80 {
81 public:
82     CapabilitiesToStateMask(QBlittable::Capabilities capabilities)
83             : m_capabilities(capabilities),
84               fillRectMask(0),
85               drawRectMask(0),
86               drawPixmapMask(0),
87               capabillitiesState(0)
88     {
89         if (capabilities & QBlittable::SolidRectCapability) {
90             setFillRectMask();
91         }
92         if (capabilities & QBlittable::SourcePixmapCapability) {
93            setSourcePixmapMask();
94         }
95         if (capabilities & QBlittable::SourceOverPixmapCapability) {
96            setSourceOverPixmapMask();
97         }
98         if (capabilities & QBlittable::SourceOverScaledPixmapCapability) {
99             setSourceOverScaledPixmapMask();
100         }
101     }
102
103     inline bool canBlitterFillRect() const
104     {
105         return checkStateAgainstMask(capabillitiesState,fillRectMask);
106     }
107
108     inline bool canBlitterDrawRectMask() const
109     {
110         return checkStateAgainstMask(capabillitiesState,drawRectMask);
111     }
112
113     bool canBlitterDrawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) const
114     {
115         if (pm.pixmapData()->classId() != QPixmapData::BlitterClass)
116             return false;
117         if (checkStateAgainstMask(capabillitiesState,drawPixmapMask)) {
118             if (m_capabilities & (QBlittable::SourceOverPixmapCapability
119                                   | QBlittable::SourceOverScaledPixmapCapability)) {
120                 if (r.size() != sr.size()) {
121                     return m_capabilities & QBlittable::SourceOverScaledPixmapCapability;
122                 } else {
123                     return m_capabilities & QBlittable::SourceOverPixmapCapability;
124                 }
125             }
126             if ((m_capabilities & QBlittable::SourcePixmapCapability) && r.size() == sr.size() && !pm.hasAlphaChannel()) {
127                 return m_capabilities & QBlittable::SourcePixmapCapability;
128             }
129         }
130         return false;
131     }
132
133     inline void updateState(uint mask, bool on) {
134         updateStateBits(&capabillitiesState,mask,on);
135     }
136
137 public:
138
139     void setFillRectMask() {
140         updateStateBits(&fillRectMask, STATE_XFORM_SCALE, false);
141         updateStateBits(&fillRectMask, STATE_XFORM_COMPLEX, false);
142
143         updateStateBits(&fillRectMask, STATE_BRUSH_PATTERN, false);
144         updateStateBits(&fillRectMask, STATE_BRUSH_ALPHA, false);
145
146         updateStateBits(&fillRectMask, STATE_PEN_ENABLED, true);
147
148         //Sub-pixel aliasing should not be sent to the blitter
149         updateStateBits(&fillRectMask, STATE_ANTIALIASING, true);
150         updateStateBits(&fillRectMask, STATE_ALPHA, false);
151         updateStateBits(&fillRectMask, STATE_BLENDING_COMPLEX, false);
152
153         updateStateBits(&fillRectMask, STATE_CLIPSYS_COMPLEX, false);
154         updateStateBits(&fillRectMask, STATE_CLIP_COMPLEX, false);
155     }
156
157     void setSourcePixmapMask() {
158         updateStateBits(&drawPixmapMask, STATE_XFORM_SCALE, true);
159         updateStateBits(&drawPixmapMask, STATE_XFORM_COMPLEX, false);
160
161         updateStateBits(&drawPixmapMask, STATE_BRUSH_PATTERN, true);
162         updateStateBits(&drawPixmapMask, STATE_BRUSH_ALPHA, false);
163
164         updateStateBits(&drawPixmapMask, STATE_PEN_ENABLED, true);
165
166         updateStateBits(&drawPixmapMask, STATE_ANTIALIASING, true);
167         updateStateBits(&drawPixmapMask, STATE_ALPHA, false);
168         updateStateBits(&drawPixmapMask, STATE_BLENDING_COMPLEX, false);
169
170         updateStateBits(&drawPixmapMask, STATE_CLIPSYS_COMPLEX, false);
171         updateStateBits(&drawPixmapMask, STATE_CLIP_COMPLEX, false);
172     }
173
174     void setSourceOverPixmapMask() {
175         setSourcePixmapMask();
176     }
177
178     void setSourceOverScaledPixmapMask() {
179         setSourceOverPixmapMask();
180         updateStateBits(&drawRectMask, STATE_XFORM_SCALE, true);
181     }
182
183     QBlittable::Capabilities m_capabilities;
184     uint fillRectMask;
185     uint drawRectMask;
186     uint drawPixmapMask;
187     uint capabillitiesState;
188 };
189
190 class QBlitterPaintEnginePrivate : public QPaintEngineExPrivate
191 {
192     Q_DECLARE_PUBLIC(QBlitterPaintEngine);
193 public:
194     QBlitterPaintEnginePrivate(QBlittablePixmapData *p)
195             : QPaintEngineExPrivate(),
196               pmData(p),
197               isBlitterLocked(false),
198               hasXForm(false)
199
200     {
201         raster = new QRasterPaintEngine(p->buffer());
202         capabillities = new CapabilitiesToStateMask(pmData->blittable()->capabilities());
203     }
204
205     inline void lock() {
206         if (!isBlitterLocked) {
207             raster->d_func()->rasterBuffer->prepare(pmData->blittable()->lock());
208             isBlitterLocked = true;
209         }
210     }
211
212     inline void unlock() {
213         if (isBlitterLocked) {
214             pmData->blittable()->unlock();
215             isBlitterLocked = false;
216         }
217     }
218
219     void fillRect(const QRectF &rect, const QColor &color) {
220         Q_Q(QBlitterPaintEngine);
221         pmData->unmarkRasterOverlay(rect);
222         QRectF targetRect = rect;
223         if (hasXForm) {
224             targetRect = q->state()->matrix.mapRect(rect);
225         }
226         const QClipData *clipData = q->clip();
227         if (clipData) {
228             if (clipData->hasRectClip) {
229                 unlock();
230                 pmData->blittable()->fillRect(targetRect & clipData->clipRect, color);
231             } else if (clipData->hasRegionClip) {
232                 QVector<QRect> rects = clipData->clipRegion.rects();
233                 for ( int i = 0; i < rects.size(); i++ ) {
234                     QRect intersectRect = rects.at(i).intersected(targetRect.toRect());
235                     if (!intersectRect.isEmpty()) {
236                         unlock();
237                         pmData->blittable()->fillRect(intersectRect,color);
238                     }
239                 }
240             }
241         } else {
242             if (targetRect.x() >= 0 && targetRect.y() >= 0
243                 && targetRect.width() <= raster->paintDevice()->width()
244                 && targetRect.height() <= raster->paintDevice()->height()) {
245                 unlock();
246                 pmData->blittable()->fillRect(targetRect,color);
247             } else {
248                 QRectF deviceRect(0,0,raster->paintDevice()->width(), raster->paintDevice()->height());
249                 unlock();
250                 pmData->blittable()->fillRect(deviceRect&targetRect,color);
251             }
252         }
253     }
254
255     void clipAndDrawPixmap(const QRectF &clip, const QRectF &target, const QPixmap &pm, const QRectF &sr) {
256         QRectF intersectedRect = clip.intersected(target);
257         if (intersectedRect.isEmpty())
258             return;
259         QRectF source = sr;
260         if(intersectedRect.size() != target.size()) {
261             qreal deltaTop = target.top() - intersectedRect.top();
262             qreal deltaLeft = target.left() - intersectedRect.left();
263             qreal deltaBottom = target.bottom() - intersectedRect.bottom();
264             qreal deltaRight = target.right() - intersectedRect.right();
265             source.adjust(-deltaLeft,-deltaTop,-deltaRight,-deltaBottom);
266         }
267         pmData->unmarkRasterOverlay(intersectedRect);
268         pmData->blittable()->drawPixmap(intersectedRect, pm, source);
269     }
270
271     void updateClip() {
272         Q_Q(QBlitterPaintEngine);
273         const QClipData *clip = q->clip();
274         bool complex = clip && !(clip->hasRectClip || clip->hasRegionClip);
275         capabillities->updateState(STATE_CLIP_COMPLEX, complex);
276     }
277
278     void systemStateChanged() {
279         raster->d_func()->systemStateChanged();
280     }
281
282     QRasterPaintEngine *raster;
283
284     QBlittablePixmapData *pmData;
285     bool isBlitterLocked;
286
287     CapabilitiesToStateMask *capabillities;
288
289     uint hasXForm;
290 };
291
292 QBlitterPaintEngine::QBlitterPaintEngine(QBlittablePixmapData *p)
293     : QPaintEngineEx(*(new QBlitterPaintEnginePrivate(p)))
294 {
295 }
296
297 QBlitterPaintEngine::~QBlitterPaintEngine()
298 {
299 }
300
301 QPainterState *QBlitterPaintEngine::createState(QPainterState *orig) const
302 {
303     Q_D(const QBlitterPaintEngine);
304     return d->raster->createState(orig);
305 }
306
307 bool QBlitterPaintEngine::begin(QPaintDevice *pdev)
308 {
309     Q_D(QBlitterPaintEngine);
310
311     setActive(true);
312     bool ok = d->raster->begin(pdev);
313 #ifdef QT_BLITTER_RASTEROVERLAY
314     d->pmData->unmergeOverlay();
315 #endif
316     return ok;
317 }
318
319
320 bool QBlitterPaintEngine::end()
321 {
322     Q_D(QBlitterPaintEngine);
323
324     setActive(false);
325 #ifdef QT_BLITTER_RASTEROVERLAY
326     d->pmData->mergeOverlay();
327 #endif
328     return d->raster->end();
329 }
330
331
332 void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
333 {
334     Q_D(QBlitterPaintEngine);
335     if (path.shape() == QVectorPath::RectangleHint) {
336         QRectF rect(((QPointF *) path.points())[0], ((QPointF *) path.points())[2]);
337         fillRect(rect, brush);
338     } else {
339         d->lock();
340         d->pmData->markRasterOverlay(path);
341         d->raster->fill(path, brush);
342     }
343 }
344
345 void QBlitterPaintEngine::fillRect(const QRectF &rect, const QColor &color)
346 {
347     Q_D(QBlitterPaintEngine);
348     if (d->capabillities->canBlitterFillRect() && color.alpha() == 0xff) {
349         d->fillRect(rect, color);
350     } else {
351         d->lock();
352         d->pmData->markRasterOverlay(rect);
353         d->raster->fillRect(rect, color);
354     }
355 }
356
357 void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
358 {
359     if(rect.size().isEmpty())
360         return;
361
362     Q_D(QBlitterPaintEngine);
363
364     if (qbrush_style(brush) == Qt::SolidPattern
365         && qbrush_color(brush).alpha() == 0xff
366         && d->capabillities->canBlitterFillRect())
367     {
368         d->fillRect(rect, qbrush_color(brush));
369     }else if (brush.style() == Qt::TexturePattern
370               && d->capabillities->canBlitterDrawPixmap(rect,brush.texture(),rect))
371     {
372         bool rectIsFilled = false;
373         QRectF transformedRect = state()->matrix.mapRect(rect);
374         qreal x = transformedRect.x();
375         qreal y = transformedRect.y();
376         QPixmap pm = brush.texture();
377         d->unlock();
378         int srcX = int(rect.x() - state()->brushOrigin.x()) % pm.width();
379         if (srcX < 0)
380             srcX = pm.width() + srcX;
381         const int startX = srcX;
382         int srcY = int(rect.y() - state()->brushOrigin.y()) % pm.height();
383         if (srcY < 0)
384             srcY = pm.height() + srcY;
385         while (!rectIsFilled) {
386             qreal blitWidth = (pm.width() ) - srcX;
387             qreal blitHeight = (pm.height() ) - srcY;
388             if (x + blitWidth > transformedRect.right())
389                 blitWidth = transformedRect.right() -x;
390             if (y + blitHeight > transformedRect.bottom())
391                 blitHeight = transformedRect.bottom() - y;
392             const QClipData *clipData = clip();
393             if (clipData->hasRectClip) {
394                 QRect targetRect = QRect(x,y,blitWidth,blitHeight).intersected(clipData->clipRect);
395                 if (targetRect.isValid()) {
396                     int tmpSrcX  = srcX + (targetRect.x() - x);
397                     int tmpSrcY = srcY + (targetRect.y() - y);
398                     QRect srcRect(tmpSrcX,tmpSrcY,targetRect.width(),targetRect.height());
399                     d->pmData->blittable()->drawPixmap(targetRect,pm,srcRect);
400                 }
401             } else if (clipData->hasRegionClip) {
402                 QVector<QRect> clipRects = clipData->clipRegion.rects();
403                 QRect unclippedTargetRect(x,y,blitWidth,blitHeight);
404                 QRegion intersectedRects = clipData->clipRegion.intersected(unclippedTargetRect);
405
406                 for ( int i = 0; i < intersectedRects.rects().size(); i++ ) {
407                     QRect targetRect = intersectedRects.rects().at(i);
408                     if (!targetRect.isValid() || targetRect.isEmpty())
409                         continue;
410                     int tmpSrcX = srcX + (targetRect.x() - x);
411                     int tmpSrcY = srcY + (targetRect.y() - y);
412                     QRect srcRect(tmpSrcX,tmpSrcY,targetRect.width(),targetRect.height());
413                     d->pmData->blittable()->drawPixmap(targetRect,pm,srcRect);
414                 }
415             }
416             x+=blitWidth;
417             if (x>=transformedRect.right()) {
418                 x = transformedRect.x();
419                 srcX = startX;
420                 srcY = 0;
421                 y+=blitHeight;
422                 if (y>=transformedRect.bottom())
423                     rectIsFilled = true;
424             } else
425                 srcX = 0;
426         }
427     } else {
428         d->lock();
429         d->pmData->markRasterOverlay(rect);
430         d->raster->fillRect(rect, brush);
431     }
432
433 }
434
435 void QBlitterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
436 {
437     Q_D(QBlitterPaintEngine);
438     d->lock();
439     d->pmData->markRasterOverlay(path);
440     d->raster->stroke(path, pen);
441 }
442
443 void QBlitterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
444 {
445     Q_D(QBlitterPaintEngine);
446     d->lock();
447     d->raster->clip(path, op);
448     d->updateClip();
449 }
450 void QBlitterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op){
451     Q_D(QBlitterPaintEngine);
452     d->lock();
453     d->raster->clip(rect,op);
454     d->updateClip();
455 }
456 void QBlitterPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
457 {
458     Q_D(QBlitterPaintEngine);
459     d->lock();
460     d->raster->clip(region,op);
461     d->updateClip();
462 }
463
464 void QBlitterPaintEngine::clipEnabledChanged()
465 {
466     Q_D(QBlitterPaintEngine);
467     d->lock();
468     d->raster->clipEnabledChanged();
469 }
470
471 void QBlitterPaintEngine::penChanged()
472 {
473     Q_D(QBlitterPaintEngine);
474     d->lock();
475     d->raster->penChanged();
476     d->capabillities->updateState(STATE_PEN_ENABLED,qpen_style(state()->pen) != Qt::NoPen);
477 }
478
479 void QBlitterPaintEngine::brushChanged()
480 {
481     Q_D(QBlitterPaintEngine);
482     d->raster->brushChanged();
483
484     bool solid = qbrush_style(state()->brush) == Qt::SolidPattern;
485
486     d->capabillities->updateState(STATE_BRUSH_PATTERN, !solid);
487     d->capabillities->updateState(STATE_BRUSH_ALPHA,
488                                         qbrush_color(state()->brush).alpha() < 255);
489 }
490
491 void QBlitterPaintEngine::brushOriginChanged()
492 {
493     Q_D(QBlitterPaintEngine);
494     d->raster->brushOriginChanged();
495 }
496
497 void QBlitterPaintEngine::opacityChanged()
498 {
499     Q_D(QBlitterPaintEngine);
500     d->raster->opacityChanged();
501
502     bool translucent = state()->opacity < 1;
503     d->capabillities->updateState(STATE_ALPHA,translucent);
504 }
505
506 void QBlitterPaintEngine::compositionModeChanged()
507 {
508     Q_D(QBlitterPaintEngine);
509     d->raster->compositionModeChanged();
510
511     bool nonTrivial = state()->composition_mode != QPainter::CompositionMode_SourceOver
512                       && state()->composition_mode != QPainter::CompositionMode_Source;
513
514     d->capabillities->updateState(STATE_BLENDING_COMPLEX,nonTrivial);
515 }
516
517 void QBlitterPaintEngine::renderHintsChanged()
518 {
519     Q_D(QBlitterPaintEngine);
520     d->raster->renderHintsChanged();
521
522     bool aa = state()->renderHints & QPainter::Antialiasing;
523     d->capabillities->updateState(STATE_ANTIALIASING, aa);
524
525 }
526
527 void QBlitterPaintEngine::transformChanged()
528 {
529     Q_D(QBlitterPaintEngine);
530     d->raster->transformChanged();
531
532     QTransform::TransformationType type = state()->matrix.type();
533
534     d->capabillities->updateState(STATE_XFORM_COMPLEX, type > QTransform::TxScale);
535     d->capabillities->updateState(STATE_XFORM_SCALE, type > QTransform::TxTranslate);
536
537     d->hasXForm = type >= QTransform::TxTranslate;
538
539 }
540
541 void QBlitterPaintEngine::drawRects(const QRect *rects, int rectCount)
542 {
543     Q_D(QBlitterPaintEngine);
544     if (d->capabillities->canBlitterDrawRectMask()) {
545         for (int i=0; i<rectCount; ++i) {
546             d->fillRect(rects[i], qbrush_color(state()->brush));
547         }
548     } else {
549         d->pmData->markRasterOverlay(rects,rectCount);
550         QPaintEngineEx::drawRects(rects, rectCount);
551     }
552 }
553
554 void QBlitterPaintEngine::drawRects(const QRectF *rects, int rectCount)
555 {
556     Q_D(QBlitterPaintEngine);
557     if (d->capabillities->canBlitterDrawRectMask()) {
558         for (int i=0; i<rectCount; ++i) {
559             d->fillRect(rects[i], qbrush_color(state()->brush));
560         }
561     } else {
562         d->pmData->markRasterOverlay(rects,rectCount);
563         QPaintEngineEx::drawRects(rects, rectCount);
564     }
565 }
566
567 void QBlitterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
568 {
569     Q_D(QBlitterPaintEngine);
570     if (d->capabillities->canBlitterDrawPixmap(r,pm,sr)) {
571
572         d->unlock();
573         QRectF targetRect = r;
574         if (d->hasXForm) {
575             targetRect = state()->matrix.mapRect(r);
576         }
577         const QClipData *clipData = clip();
578         if (clipData) {
579             if (clipData->hasRectClip) {
580                 d->clipAndDrawPixmap(clipData->clipRect,targetRect,pm,sr);
581             }else if (clipData->hasRegionClip) {
582                 QVector<QRect>rects = clipData->clipRegion.rects();
583                 for (int i = 0; i<rects.size(); i++) {
584                     d->clipAndDrawPixmap(rects.at(i),targetRect,pm,sr);
585                 }
586             }
587         } else {
588             QRectF deviceRect(0,0,d->raster->paintDevice()->width(), d->raster->paintDevice()->height());
589             d->clipAndDrawPixmap(deviceRect,targetRect,pm,sr);
590         }
591     }else {
592         d->lock();
593         d->pmData->markRasterOverlay(r);
594         d->raster->drawPixmap(r, pm, sr);
595     }
596 }
597
598 void QBlitterPaintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
599                                     Qt::ImageConversionFlags flags)
600 {
601     Q_D(QBlitterPaintEngine);
602     d->lock();
603     d->pmData->markRasterOverlay(r);
604     d->raster->drawImage(r, pm, sr, flags);
605 }
606
607
608 void QBlitterPaintEngine::drawTextItem(const QPointF &pos, const QTextItem &ti)
609 {
610     Q_D(QBlitterPaintEngine);
611     d->lock();
612     d->raster->drawTextItem(pos, ti);
613     d->pmData->markRasterOverlay(pos,ti);
614 }
615
616 void QBlitterPaintEngine::drawStaticTextItem(QStaticTextItem *sti)
617 {
618     Q_D(QBlitterPaintEngine);
619     d->lock();
620     d->raster->drawStaticTextItem(sti);
621
622 //#### d->pmData->markRasterOverlay(sti);
623     qWarning("not implemented: markRasterOverlay for QStaticTextItem");
624
625 }
626
627
628 void QBlitterPaintEngine::drawEllipse(const QRectF &r)
629 {
630     Q_D(QBlitterPaintEngine);
631     d->lock();
632     d->pmData->markRasterOverlay(r);
633     d->raster->drawEllipse(r);
634 }
635
636 void QBlitterPaintEngine::setState(QPainterState *s)
637 {
638     Q_D(QBlitterPaintEngine);
639     d->lock();
640     QPaintEngineEx::setState(s);
641     d->raster->setState(s);
642
643     clipEnabledChanged();
644     penChanged();
645     brushChanged();
646     brushOriginChanged();
647     opacityChanged();
648     compositionModeChanged();
649     renderHintsChanged();
650     transformChanged();
651
652     d->updateClip();
653 }
654
655 inline QRasterPaintEngine *QBlitterPaintEngine::raster() const
656 {
657     Q_D(const QBlitterPaintEngine);
658     return d->raster;
659 }
660
661 QT_END_NAMESPACE
662 #endif //QT_NO_BLITTABLE
663