1
/****************************************************************************
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
6
** This file is part of the QtGui module of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
38
****************************************************************************/
40
#include "private/qpaintengine_blitter_p.h"
42
#include "private/qblittable_p.h"
43
#include "private/qpaintengine_raster_p.h"
44
#include "private/qpainter_p.h"
45
#include "private/qpixmap_blitter_p.h"
47
#ifndef QT_NO_BLITTABLE
50
#define STATE_XFORM_SCALE 0x00000001
51
#define STATE_XFORM_COMPLEX 0x00000002
53
#define STATE_BRUSH_PATTERN 0x00000010
54
#define STATE_BRUSH_ALPHA 0x00000020
56
#define STATE_PEN_ENABLED 0x00000100
58
#define STATE_ANTIALIASING 0x00001000
59
#define STATE_ALPHA 0x00002000
60
#define STATE_BLENDING_COMPLEX 0x00004000
62
#define STATE_CLIPSYS_COMPLEX 0x00010000
63
#define STATE_CLIP_COMPLEX 0x00020000
66
class CapabilitiesToStateMask
69
CapabilitiesToStateMask(QBlittable::Capabilities capabilities)
70
: m_capabilities(capabilities)
74
, alphaFillRectMask(0)
75
, opacityPixmapMask(0)
76
, capabillitiesState(0)
78
if (capabilities & QBlittable::SolidRectCapability)
80
if (capabilities & QBlittable::SourcePixmapCapability)
81
setSourcePixmapMask();
82
if (capabilities & QBlittable::SourceOverPixmapCapability)
83
setSourceOverPixmapMask();
84
if (capabilities & QBlittable::SourceOverScaledPixmapCapability)
85
setSourceOverScaledPixmapMask();
86
if (capabilities & QBlittable::AlphaFillRectCapability)
87
setAlphaFillRectMask();
88
if (capabilities & QBlittable::OpacityPixmapCapability)
89
setOpacityPixmapMask();
92
inline bool canBlitterFillRect() const
94
return checkStateAgainstMask(capabillitiesState, fillRectMask);
97
inline bool canBlitterAlphaFillRect() const
99
return checkStateAgainstMask(capabillitiesState, alphaFillRectMask);
102
inline bool canBlitterDrawRectMask() const
104
return checkStateAgainstMask(capabillitiesState, drawRectMask);
107
bool canBlitterDrawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) const
109
if (pm.handle()->classId() != QPlatformPixmap::BlitterClass)
111
if (checkStateAgainstMask(capabillitiesState, drawPixmapMask)) {
112
if (m_capabilities & (QBlittable::SourceOverPixmapCapability
113
| QBlittable::SourceOverScaledPixmapCapability)) {
114
if (r.size() != sr.size())
115
return m_capabilities & QBlittable::SourceOverScaledPixmapCapability;
117
return m_capabilities & QBlittable::SourceOverPixmapCapability;
119
if ((m_capabilities & QBlittable::SourcePixmapCapability) && r.size() == sr.size() && !pm.hasAlphaChannel())
120
return m_capabilities & QBlittable::SourcePixmapCapability;
125
bool canBlitterDrawPixmapOpacity(const QPixmap &pm) const
127
if (pm.handle()->classId() != QPlatformPixmap::BlitterClass)
130
return checkStateAgainstMask(capabillitiesState, opacityPixmapMask);
133
bool canBlitterDrawCachedGlyphs(const QTransform &transform, QFontEngine::GlyphFormat requestedGlyphFormat, bool complexClip) const
135
if (transform.type() > QTransform::TxScale)
137
if (!(m_capabilities & QBlittable::DrawScaledCachedGlyphsCapability))
139
if (requestedGlyphFormat == QFontEngine::Format_ARGB && !(m_capabilities & QBlittable::SubPixelGlyphsCapability))
141
if (complexClip && !(m_capabilities & QBlittable::ComplexClipCapability))
146
inline void updateState(uint mask, bool on) {
147
updateStateBits(&capabillitiesState, mask, on);
152
static inline void updateStateBits(uint *state, uint mask, bool on)
154
*state = on ? (*state | mask) : (*state & ~mask);
157
static inline bool checkStateAgainstMask(uint state, uint mask)
159
return !state || (state & mask && !(state & ~mask));
162
void setFillRectMask() {
163
updateStateBits(&fillRectMask, STATE_XFORM_SCALE, false);
164
updateStateBits(&fillRectMask, STATE_XFORM_COMPLEX, false);
166
updateStateBits(&fillRectMask, STATE_BRUSH_PATTERN, false);
167
updateStateBits(&fillRectMask, STATE_BRUSH_ALPHA, false);
169
updateStateBits(&fillRectMask, STATE_PEN_ENABLED, true);
171
//Sub-pixel aliasing should not be sent to the blitter
172
updateStateBits(&fillRectMask, STATE_ANTIALIASING, true);
173
updateStateBits(&fillRectMask, STATE_ALPHA, false);
174
updateStateBits(&fillRectMask, STATE_BLENDING_COMPLEX, false);
176
updateStateBits(&fillRectMask, STATE_CLIPSYS_COMPLEX, false);
177
updateStateBits(&fillRectMask, STATE_CLIP_COMPLEX, false);
180
void setAlphaFillRectMask() {
181
updateStateBits(&alphaFillRectMask, STATE_XFORM_SCALE, false);
182
updateStateBits(&alphaFillRectMask, STATE_XFORM_COMPLEX, false);
184
updateStateBits(&alphaFillRectMask, STATE_BRUSH_PATTERN, false);
185
updateStateBits(&alphaFillRectMask, STATE_BRUSH_ALPHA, true);
187
updateStateBits(&alphaFillRectMask, STATE_PEN_ENABLED, true);
189
//Sub-pixel aliasing should not be sent to the blitter
190
updateStateBits(&alphaFillRectMask, STATE_ANTIALIASING, true);
191
updateStateBits(&alphaFillRectMask, STATE_ALPHA, false);
192
updateStateBits(&alphaFillRectMask, STATE_BLENDING_COMPLEX, false);
194
updateStateBits(&alphaFillRectMask, STATE_CLIPSYS_COMPLEX, false);
195
updateStateBits(&alphaFillRectMask, STATE_CLIP_COMPLEX, false);
198
void setSourcePixmapMask() {
199
updateStateBits(&drawPixmapMask, STATE_XFORM_SCALE, false);
200
updateStateBits(&drawPixmapMask, STATE_XFORM_COMPLEX, false);
202
updateStateBits(&drawPixmapMask, STATE_BRUSH_PATTERN, true);
203
updateStateBits(&drawPixmapMask, STATE_BRUSH_ALPHA, false);
205
updateStateBits(&drawPixmapMask, STATE_PEN_ENABLED, true);
207
updateStateBits(&drawPixmapMask, STATE_ANTIALIASING, true);
208
updateStateBits(&drawPixmapMask, STATE_ALPHA, false);
209
updateStateBits(&drawPixmapMask, STATE_BLENDING_COMPLEX, false);
211
updateStateBits(&drawPixmapMask, STATE_CLIPSYS_COMPLEX, false);
212
updateStateBits(&drawPixmapMask, STATE_CLIP_COMPLEX, false);
215
void setSourceOverPixmapMask() {
216
setSourcePixmapMask();
219
void setSourceOverScaledPixmapMask() {
220
setSourceOverPixmapMask();
221
updateStateBits(&drawPixmapMask, STATE_XFORM_SCALE, true);
224
void setOpacityPixmapMask() {
225
updateStateBits(&opacityPixmapMask, STATE_XFORM_SCALE, true);
226
updateStateBits(&opacityPixmapMask, STATE_XFORM_COMPLEX, false);
228
updateStateBits(&opacityPixmapMask, STATE_BRUSH_PATTERN, true);
229
updateStateBits(&opacityPixmapMask, STATE_BRUSH_ALPHA, true);
231
updateStateBits(&opacityPixmapMask, STATE_PEN_ENABLED, true);
233
updateStateBits(&opacityPixmapMask, STATE_ANTIALIASING, true);
234
updateStateBits(&opacityPixmapMask, STATE_ALPHA, true);
235
updateStateBits(&opacityPixmapMask, STATE_BLENDING_COMPLEX, false);
237
updateStateBits(&opacityPixmapMask, STATE_CLIPSYS_COMPLEX, false);
238
updateStateBits(&opacityPixmapMask, STATE_CLIP_COMPLEX, false);
241
QBlittable::Capabilities m_capabilities;
245
uint alphaFillRectMask;
246
uint opacityPixmapMask;
247
uint capabillitiesState;
250
class QBlitterPaintEnginePrivate : public QRasterPaintEnginePrivate
252
Q_DECLARE_PUBLIC(QBlitterPaintEngine)
254
QBlitterPaintEnginePrivate(QBlittablePlatformPixmap *p)
255
: QRasterPaintEnginePrivate()
257
, caps(pmData->blittable()->capabilities())
264
void fillRect(const QRectF &rect, const QColor &color, bool alpha);
265
void clipAndDrawPixmap(const QRectF &clip, const QRectF &target, const QPixmap &pm, const QRectF &sr, bool opacity);
268
void updateCompleteState(QPainterState *s);
269
void updatePenState(QPainterState *s);
270
void updateBrushState(QPainterState *s);
271
void updateOpacityState(QPainterState *s);
272
void updateCompositionModeState(QPainterState *s);
273
void updateRenderHintsState(QPainterState *s);
274
void updateTransformState(QPainterState *s);
275
void updateClipState(QPainterState *s);
277
QBlittablePlatformPixmap *pmData;
278
CapabilitiesToStateMask caps;
283
inline void QBlitterPaintEnginePrivate::lock()
285
if (!pmData->blittable()->isLocked())
286
rasterBuffer->prepare(pmData->buffer());
289
inline void QBlitterPaintEnginePrivate::unlock()
291
pmData->blittable()->unlock();
294
// State tracking to make decisions
295
void QBlitterPaintEnginePrivate::updateCompleteState(QPainterState *s)
299
updateOpacityState(s);
300
updateCompositionModeState(s);
301
updateRenderHintsState(s);
302
updateTransformState(s);
306
void QBlitterPaintEnginePrivate::updatePenState(QPainterState *s)
308
caps.updateState(STATE_PEN_ENABLED, qpen_style(s->pen) != Qt::NoPen);
311
void QBlitterPaintEnginePrivate::updateBrushState(QPainterState *s)
313
Qt::BrushStyle style = qbrush_style(s->brush);
315
caps.updateState(STATE_BRUSH_PATTERN, style > Qt::SolidPattern);
316
caps.updateState(STATE_BRUSH_ALPHA,
317
qbrush_color(s->brush).alpha() < 255);
320
void QBlitterPaintEnginePrivate::updateOpacityState(QPainterState *s)
322
bool translucent = s->opacity < 1;
323
caps.updateState(STATE_ALPHA, translucent);
326
void QBlitterPaintEnginePrivate::updateCompositionModeState(QPainterState *s)
328
bool nonTrivial = s->composition_mode != QPainter::CompositionMode_SourceOver
329
&& s->composition_mode != QPainter::CompositionMode_Source;
331
caps.updateState(STATE_BLENDING_COMPLEX, nonTrivial);
334
void QBlitterPaintEnginePrivate::updateRenderHintsState(QPainterState *s)
336
bool aa = s->renderHints & QPainter::Antialiasing;
337
caps.updateState(STATE_ANTIALIASING, aa);
340
void QBlitterPaintEnginePrivate::updateTransformState(QPainterState *s)
342
QTransform::TransformationType type = s->matrix.type();
344
// consider scaling operations with a negative factor as "complex" for now.
345
// as some blitters could handle axisymmetrical operations, we should improve blitter
346
// paint engine to handle them as a capability
347
caps.updateState(STATE_XFORM_COMPLEX, (type > QTransform::TxScale) ||
348
((type == QTransform::TxScale) && ((s->matrix.m11() < 0.0) || (s->matrix.m22() < 0.0))));
349
caps.updateState(STATE_XFORM_SCALE, type > QTransform::TxTranslate);
351
hasXForm = type >= QTransform::TxTranslate;
354
void QBlitterPaintEnginePrivate::updateClipState(QPainterState *)
356
const QClipData *clipData = clip();
357
bool complexClip = clipData && !(clipData->hasRectClip || clipData->hasRegionClip);
358
caps.updateState(STATE_CLIP_COMPLEX, complexClip);
361
void QBlitterPaintEnginePrivate::fillRect(const QRectF &rect, const QColor &color, bool alpha)
363
Q_Q(QBlitterPaintEngine);
364
pmData->unmarkRasterOverlay(rect);
365
QRectF targetRect = rect;
367
targetRect = q->state()->matrix.mapRect(rect);
368
const QClipData *clipData = clip();
370
if (clipData->hasRectClip) {
373
pmData->blittable()->alphaFillRect(targetRect & clipData->clipRect, color, q->state()->compositionMode());
375
pmData->blittable()->fillRect(targetRect & clipData->clipRect, color);
376
} else if (clipData->hasRegionClip) {
377
QVector<QRect> rects = clipData->clipRegion.rects();
378
for (int i = 0; i < rects.size(); ++i) {
379
QRect intersectRect = rects.at(i).intersected(targetRect.toRect());
380
if (!intersectRect.isEmpty()) {
383
pmData->blittable()->alphaFillRect(intersectRect, color, q->state()->compositionMode());
385
pmData->blittable()->fillRect(intersectRect, color);
390
if (targetRect.x() >= 0 && targetRect.y() >= 0
391
&& targetRect.width() <= q->paintDevice()->width()
392
&& targetRect.height() <= q->paintDevice()->height()) {
395
pmData->blittable()->alphaFillRect(targetRect, color, q->state()->compositionMode());
397
pmData->blittable()->fillRect(targetRect, color);
399
QRectF deviceRect(0, 0, q->paintDevice()->width(), q->paintDevice()->height());
402
pmData->blittable()->alphaFillRect(deviceRect & targetRect, color, q->state()->compositionMode());
404
pmData->blittable()->fillRect(deviceRect & targetRect, color);
409
void QBlitterPaintEnginePrivate::clipAndDrawPixmap(const QRectF &clip,
410
const QRectF &target,
415
Q_Q(QBlitterPaintEngine);
416
QRectF intersectedRect = clip.intersected(target);
417
if (intersectedRect.isEmpty())
420
if (intersectedRect.size() != target.size()) {
421
if (sr.size() == target.size()) {
423
qreal deltaTop = target.top() - intersectedRect.top();
424
qreal deltaLeft = target.left() - intersectedRect.left();
425
qreal deltaBottom = target.bottom() - intersectedRect.bottom();
426
qreal deltaRight = target.right() - intersectedRect.right();
427
source.adjust(-deltaLeft, -deltaTop, -deltaRight, -deltaBottom);
430
qreal hFactor = sr.size().width() / target.size().width();
431
qreal vFactor = sr.size().height() / target.size().height();
432
qreal deltaTop = (target.top() - intersectedRect.top()) * vFactor;
433
qreal deltaLeft = (target.left() - intersectedRect.left()) * hFactor;
434
qreal deltaBottom = (target.bottom() - intersectedRect.bottom()) * vFactor;
435
qreal deltaRight = (target.right() - intersectedRect.right()) * hFactor;
436
source.adjust(-deltaLeft, -deltaTop, -deltaRight, -deltaBottom);
439
pmData->unmarkRasterOverlay(intersectedRect);
441
pmData->blittable()->drawPixmapOpacity(intersectedRect, pm, source, q->state()->compositionMode(), q->state()->opacity);
443
pmData->blittable()->drawPixmap(intersectedRect, pm, source);
446
QBlitterPaintEngine::QBlitterPaintEngine(QBlittablePlatformPixmap *p)
447
: QRasterPaintEngine(*(new QBlitterPaintEnginePrivate(p)), p->buffer())
451
void QBlitterPaintEngine::penChanged()
453
Q_D(QBlitterPaintEngine);
455
QRasterPaintEngine::penChanged();
456
d->updatePenState(state());
459
void QBlitterPaintEngine::brushChanged()
461
Q_D(QBlitterPaintEngine);
463
QRasterPaintEngine::brushChanged();
464
d->updateBrushState(state());
467
void QBlitterPaintEngine::opacityChanged()
469
Q_D(QBlitterPaintEngine);
471
QRasterPaintEngine::opacityChanged();
472
d->updateOpacityState(state());
475
void QBlitterPaintEngine::compositionModeChanged()
477
Q_D(QBlitterPaintEngine);
479
QRasterPaintEngine::compositionModeChanged();
480
d->updateCompositionModeState(state());
483
void QBlitterPaintEngine::renderHintsChanged()
485
Q_D(QBlitterPaintEngine);
487
QRasterPaintEngine::renderHintsChanged();
488
d->updateRenderHintsState(state());
491
void QBlitterPaintEngine::transformChanged()
493
Q_D(QBlitterPaintEngine);
495
QRasterPaintEngine::transformChanged();
496
d->updateTransformState(state());
499
void QBlitterPaintEngine::clipEnabledChanged()
501
Q_D(QBlitterPaintEngine);
502
QRasterPaintEngine::clipEnabledChanged();
503
d->updateClipState(state());
506
bool QBlitterPaintEngine::begin(QPaintDevice *pdev)
508
Q_D(QBlitterPaintEngine);
509
bool ok = QRasterPaintEngine::begin(pdev);
510
#ifdef QT_BLITTER_RASTEROVERLAY
511
d->pmData->unmergeOverlay();
517
bool QBlitterPaintEngine::end()
519
#ifdef QT_BLITTER_RASTEROVERLAY
520
Q_D(QBlitterPaintEngine);
521
d->pmData->mergeOverlay();
524
return QRasterPaintEngine::end();
527
void QBlitterPaintEngine::setState(QPainterState *s)
529
Q_D(QBlitterPaintEngine);
531
QRasterPaintEngine::setState(s);
532
d->updateCompleteState(s);
536
void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
538
Q_D(QBlitterPaintEngine);
539
if (path.shape() == QVectorPath::RectangleHint) {
540
QRectF rect(((const QPointF *) path.points())[0], ((const QPointF *) path.points())[2]);
541
fillRect(rect, brush);
544
d->pmData->markRasterOverlay(path);
545
QRasterPaintEngine::fill(path, brush);
549
void QBlitterPaintEngine::fillRect(const QRectF &rect, const QColor &color)
551
Q_D(QBlitterPaintEngine);
552
if (d->caps.canBlitterAlphaFillRect()) {
553
d->fillRect(rect, color, true);
554
} else if (d->caps.canBlitterFillRect() && color.alpha() == 0xff) {
555
d->fillRect(rect, color, false);
558
d->pmData->markRasterOverlay(rect);
559
QRasterPaintEngine::fillRect(rect, color);
563
void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
565
if (rect.size().isEmpty())
568
Q_D(QBlitterPaintEngine);
570
if (qbrush_style(brush) == Qt::SolidPattern
571
&& d->caps.canBlitterAlphaFillRect()) {
572
d->fillRect(rect, qbrush_color(brush), true);
573
} else if (qbrush_style(brush) == Qt::SolidPattern
574
&& qbrush_color(brush).alpha() == 0xff
575
&& d->caps.canBlitterFillRect()) {
576
d->fillRect(rect, qbrush_color(brush), false);
577
} else if ((brush.style() == Qt::TexturePattern) &&
578
(brush.transform().type() <= QTransform::TxTranslate) &&
579
((d->caps.canBlitterDrawPixmapOpacity(brush.texture())) ||
580
(d->caps.canBlitterDrawPixmap(rect, brush.texture(), rect)))) {
581
bool rectIsFilled = false;
582
QRectF transformedRect = state()->matrix.mapRect(rect);
583
qreal x = transformedRect.x();
584
qreal y = transformedRect.y();
585
QPixmap pm = brush.texture();
587
int srcX = int(rect.x() - state()->brushOrigin.x() - brush.transform().dx()) % pm.width();
589
srcX = pm.width() + srcX;
590
const int startX = srcX;
591
int srcY = int(rect.y() - state()->brushOrigin.y() - brush.transform().dy()) % pm.height();
593
srcY = pm.height() + srcY;
594
while (!rectIsFilled) {
595
qreal blitWidth = (pm.width() ) - srcX;
596
qreal blitHeight = (pm.height() ) - srcY;
597
if (x + blitWidth > transformedRect.right())
598
blitWidth = transformedRect.right() -x;
599
if (y + blitHeight > transformedRect.bottom())
600
blitHeight = transformedRect.bottom() - y;
601
const QClipData *clipData = d->clip();
602
if (clipData->hasRectClip) {
603
QRect targetRect = QRect(x, y, blitWidth, blitHeight).intersected(clipData->clipRect);
604
if (targetRect.isValid()) {
605
int tmpSrcX = srcX + (targetRect.x() - x);
606
int tmpSrcY = srcY + (targetRect.y() - y);
607
QRect srcRect(tmpSrcX, tmpSrcY, targetRect.width(), targetRect.height());
608
d->pmData->blittable()->drawPixmap(targetRect, pm, srcRect);
610
} else if (clipData->hasRegionClip) {
611
QRect unclippedTargetRect(x, y, blitWidth, blitHeight);
612
const QVector<QRect> intersectedRects = clipData->clipRegion.intersected(unclippedTargetRect).rects();
613
const int intersectedSize = intersectedRects.size();
614
for (int i = 0; i < intersectedSize; ++i) {
615
const QRect &targetRect = intersectedRects.at(i);
616
if (!targetRect.isValid() || targetRect.isEmpty())
618
int tmpSrcX = srcX + (targetRect.x() - x);
619
int tmpSrcY = srcY + (targetRect.y() - y);
620
QRect srcRect(tmpSrcX, tmpSrcY, targetRect.width(), targetRect.height());
621
d->pmData->blittable()->drawPixmap(targetRect, pm, srcRect);
625
if (qFuzzyCompare(x, transformedRect.right())) {
626
x = transformedRect.x();
630
if (qFuzzyCompare(y, transformedRect.bottom()))
637
d->pmData->markRasterOverlay(rect);
638
QRasterPaintEngine::fillRect(rect, brush);
643
void QBlitterPaintEngine::drawRects(const QRect *rects, int rectCount)
645
Q_D(QBlitterPaintEngine);
646
if (d->caps.canBlitterDrawRectMask()) {
647
for (int i=0; i<rectCount; ++i)
648
d->fillRect(rects[i], qbrush_color(state()->brush), false);
650
d->pmData->markRasterOverlay(rects, rectCount);
651
QRasterPaintEngine::drawRects(rects, rectCount);
655
void QBlitterPaintEngine::drawRects(const QRectF *rects, int rectCount)
657
Q_D(QBlitterPaintEngine);
658
if (d->caps.canBlitterDrawRectMask()) {
659
for (int i = 0; i < rectCount; ++i)
660
d->fillRect(rects[i], qbrush_color(state()->brush), false);
662
d->pmData->markRasterOverlay(rects, rectCount);
663
QRasterPaintEngine::drawRects(rects, rectCount);
667
void QBlitterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
669
drawPixmap(QRectF(pos, pm.size()), pm, pm.rect());
672
void QBlitterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
674
Q_D(QBlitterPaintEngine);
677
canDrawOpacity = d->caps.canBlitterDrawPixmapOpacity(pm);
678
if (canDrawOpacity || (d->caps.canBlitterDrawPixmap(r, pm, sr))) {
681
QRectF targetRect = r;
683
targetRect = state()->matrix.mapRect(r);
684
const QClipData *clipData = d->clip();
686
if (clipData->hasRectClip) {
687
d->clipAndDrawPixmap(clipData->clipRect, targetRect, pm, sr, canDrawOpacity);
688
} else if (clipData->hasRegionClip) {
689
QVector<QRect>rects = clipData->clipRegion.rects();
690
for (int i = 0; i<rects.size(); ++i)
691
d->clipAndDrawPixmap(rects.at(i), targetRect, pm, sr, canDrawOpacity);
694
QRectF deviceRect(0, 0, paintDevice()->width(), paintDevice()->height());
695
d->clipAndDrawPixmap(deviceRect, targetRect, pm, sr, canDrawOpacity);
699
d->pmData->markRasterOverlay(r);
700
QRasterPaintEngine::drawPixmap(r, pm, sr);
704
// Overridden methods to lock the graphics memory
705
void QBlitterPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
707
Q_D(QBlitterPaintEngine);
709
d->pmData->markRasterOverlay(points, pointCount);
710
QRasterPaintEngine::drawPolygon(points, pointCount, mode);
713
void QBlitterPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
715
Q_D(QBlitterPaintEngine);
717
d->pmData->markRasterOverlay(points, pointCount);
718
QRasterPaintEngine::drawPolygon(points, pointCount, mode);
721
void QBlitterPaintEngine::fillPath(const QPainterPath &path, QSpanData *fillData)
723
Q_D(QBlitterPaintEngine);
725
d->pmData->markRasterOverlay(path);
726
QRasterPaintEngine::fillPath(path, fillData);
729
void QBlitterPaintEngine::fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
731
Q_D(QBlitterPaintEngine);
733
d->pmData->markRasterOverlay(points, pointCount);
734
QRasterPaintEngine::fillPolygon(points, pointCount, mode);
737
void QBlitterPaintEngine::drawEllipse(const QRectF &r)
739
Q_D(QBlitterPaintEngine);
741
d->pmData->markRasterOverlay(r);
742
QRasterPaintEngine::drawEllipse(r);
745
void QBlitterPaintEngine::drawImage(const QPointF &pos, const QImage &image)
747
drawImage(QRectF(pos, image.size()), image, image.rect());
750
void QBlitterPaintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
751
Qt::ImageConversionFlags flags)
753
Q_D(QBlitterPaintEngine);
755
d->pmData->markRasterOverlay(r);
756
QRasterPaintEngine::drawImage(r, pm, sr, flags);
759
void QBlitterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr)
761
Q_D(QBlitterPaintEngine);
763
d->pmData->markRasterOverlay(r);
764
QRasterPaintEngine::drawTiledPixmap(r, pm, sr);
767
void QBlitterPaintEngine::drawTextItem(const QPointF &pos, const QTextItem &ti)
769
Q_D(QBlitterPaintEngine);
771
d->pmData->markRasterOverlay(pos, ti);
772
QRasterPaintEngine::drawTextItem(pos, ti);
775
void QBlitterPaintEngine::drawPoints(const QPointF *points, int pointCount)
777
Q_D(QBlitterPaintEngine);
779
d->pmData->markRasterOverlay(points, pointCount);
780
QRasterPaintEngine::drawPoints(points, pointCount);
783
void QBlitterPaintEngine::drawPoints(const QPoint *points, int pointCount)
785
Q_D(QBlitterPaintEngine);
787
d->pmData->markRasterOverlay(points, pointCount);
788
QRasterPaintEngine::drawPoints(points, pointCount);
791
void QBlitterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
793
Q_D(QBlitterPaintEngine);
795
d->pmData->markRasterOverlay(path);
796
QRasterPaintEngine::stroke(path, pen);
799
void QBlitterPaintEngine::drawStaticTextItem(QStaticTextItem *sti)
801
Q_D(QBlitterPaintEngine);
803
QRasterPaintEngine::drawStaticTextItem(sti);
805
#ifdef QT_BLITTER_RASTEROVERLAY
806
//#### d->pmData->markRasterOverlay(sti);
807
qWarning("not implemented: markRasterOverlay for QStaticTextItem");
811
bool QBlitterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, QFontEngine *fontEngine)
813
Q_D(QBlitterPaintEngine);
814
QFontEngine::GlyphFormat glyphFormat = d->glyphCacheFormat;
815
if (fontEngine->glyphFormat != QFontEngine::Format_None)
816
glyphFormat = fontEngine->glyphFormat;
818
const QClipData *clipData = d->clip();
819
const bool complexClip = clipData && !clipData->hasRectClip;
821
const QPainterState *s = state();
822
if (d->caps.canBlitterDrawCachedGlyphs(s->transform(), glyphFormat, complexClip)) {
824
const bool result = d->pmData->blittable()->drawCachedGlyphs(s, glyphFormat, numGlyphs, glyphs, positions, fontEngine);
825
// Lock again as the raster paint engine might draw decorations now.
829
return QRasterPaintEngine::drawCachedGlyphs(numGlyphs, glyphs, positions, fontEngine);
834
#endif //QT_NO_BLITTABLE