source: trunk/src/gui/painting/qpaintengine_alpha.cpp@ 139

Last change on this file since 139 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 14.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <qglobal.h>
43
44#ifndef QT_NO_PRINTER
45#include <qdebug.h>
46#include "private/qpaintengine_alpha_p.h"
47
48#include "private/qpicture_p.h"
49#include "QtGui/qpicture.h"
50
51QT_BEGIN_NAMESPACE
52
53QAlphaPaintEngine::QAlphaPaintEngine(QAlphaPaintEnginePrivate &data, PaintEngineFeatures devcaps)
54 : QPaintEngine(data, devcaps)
55{
56
57}
58
59QAlphaPaintEngine::~QAlphaPaintEngine()
60{
61
62}
63
64bool QAlphaPaintEngine::begin(QPaintDevice *pdev)
65{
66 Q_D(QAlphaPaintEngine);
67
68 d->m_continueCall = true;
69 if (d->m_pass != 0) {
70 return true;
71 }
72
73 d->m_savedcaps = gccaps;
74 d->m_pdev = pdev;
75
76 d->m_alphaPen = false;
77 d->m_alphaBrush = false;
78 d->m_alphaOpacity = false;
79 d->m_hasalpha = false;
80 d->m_advancedPen = false;
81 d->m_advancedBrush = false;
82 d->m_complexTransform = false;
83 d->m_emulateProjectiveTransforms = false;
84
85 // clear alpha region
86 d->m_alphargn = QRegion();
87 d->m_cliprgn = QRegion();
88 d->m_pen = QPen();
89 d->m_transform = QTransform();
90
91 flushAndInit();
92
93 return true;
94}
95
96extern int qt_defaultDpiX();
97extern int qt_defaultDpiY();
98
99bool QAlphaPaintEngine::end()
100{
101 Q_D(QAlphaPaintEngine);
102
103 d->m_continueCall = true;
104 if (d->m_pass != 0) {
105 return true;
106 }
107
108 flushAndInit(false);
109 return true;
110}
111
112void QAlphaPaintEngine::updateState(const QPaintEngineState &state)
113{
114 Q_D(QAlphaPaintEngine);
115
116 DirtyFlags flags = state.state();
117 if (flags & QPaintEngine::DirtyTransform) {
118 d->m_transform = state.transform();
119 d->m_complexTransform = (d->m_transform.type() > QTransform::TxScale);
120 d->m_emulateProjectiveTransforms = !(d->m_savedcaps & QPaintEngine::PerspectiveTransform)
121 && !(d->m_savedcaps & QPaintEngine::AlphaBlend)
122 && (d->m_transform.type() >= QTransform::TxProject);
123 }
124 if (flags & QPaintEngine::DirtyPen) {
125 d->m_pen = state.pen();
126 if (d->m_pen.style() == Qt::NoPen) {
127 d->m_advancedPen = false;
128 d->m_alphaPen = false;
129 } else {
130 d->m_advancedPen = (d->m_pen.brush().style() != Qt::SolidPattern);
131 d->m_alphaPen = !d->m_pen.brush().isOpaque();
132 }
133 }
134
135 if (d->m_pass != 0) {
136 d->m_continueCall = true;
137 return;
138 }
139 d->m_continueCall = false;
140
141 if (flags & QPaintEngine::DirtyOpacity) {
142 d->m_alphaOpacity = (state.opacity() != 1.0f);
143 }
144
145 if (flags & QPaintEngine::DirtyBrush) {
146 if (state.brush().style() == Qt::NoBrush) {
147 d->m_advancedBrush = false;
148 d->m_alphaBrush = false;
149 } else {
150 d->m_advancedBrush = (state.brush().style() != Qt::SolidPattern);
151 d->m_alphaBrush = !state.brush().isOpaque();
152 }
153 }
154
155
156 d->m_hasalpha = d->m_alphaOpacity || d->m_alphaBrush || d->m_alphaPen;
157
158 if (d->m_picengine)
159 d->m_picengine->updateState(state);
160}
161
162void QAlphaPaintEngine::drawPath(const QPainterPath &path)
163{
164 Q_D(QAlphaPaintEngine);
165
166 QRectF tr = d->addPenWidth(path);
167
168 if (d->m_pass == 0) {
169 d->m_continueCall = false;
170 if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
171 || d->m_emulateProjectiveTransforms)
172 {
173 d->addAlphaRect(tr);
174 }
175 if (d->m_picengine)
176 d->m_picengine->drawPath(path);
177 } else {
178 d->m_continueCall = !d->fullyContained(tr);
179 }
180}
181
182void QAlphaPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
183{
184 Q_D(QAlphaPaintEngine);
185
186 QPolygonF poly;
187 for (int i=0; i<pointCount; ++i)
188 poly.append(points[i]);
189
190 QPainterPath path;
191 path.addPolygon(poly);
192 QRectF tr = d->addPenWidth(path);
193
194 if (d->m_pass == 0) {
195 d->m_continueCall = false;
196 if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
197 || d->m_emulateProjectiveTransforms)
198 {
199 d->addAlphaRect(tr);
200 }
201
202 if (d->m_picengine)
203 d->m_picengine->drawPolygon(points, pointCount, mode);
204 } else {
205 d->m_continueCall = !d->fullyContained(tr);
206 }
207}
208
209void QAlphaPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
210{
211 Q_D(QAlphaPaintEngine);
212
213 QRectF tr = d->m_transform.mapRect(r);
214 if (d->m_pass == 0) {
215 d->m_continueCall = false;
216 if (pm.hasAlpha() || d->m_alphaOpacity || d->m_complexTransform || pm.isQBitmap()) {
217 d->addAlphaRect(tr);
218 }
219
220 if (d->m_picengine)
221 d->m_picengine->drawPixmap(r, pm, sr);
222
223 } else {
224 d->m_continueCall = !d->fullyContained(tr);
225 }
226}
227
228void QAlphaPaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr)
229{
230 Q_D(QAlphaPaintEngine);
231
232 QRectF tr = d->m_transform.mapRect(r);
233 if (d->m_pass == 0) {
234 d->m_continueCall = false;
235 if (image.hasAlphaChannel() || d->m_alphaOpacity || d->m_complexTransform) {
236 d->addAlphaRect(tr);
237 }
238
239 if (d->m_picengine)
240 d->m_picengine->drawImage(r, image, sr);
241
242 } else {
243 d->m_continueCall = !d->fullyContained(tr);
244 }
245}
246
247void QAlphaPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
248{
249 Q_D(QAlphaPaintEngine);
250
251 QRectF tr(p.x(), p.y() - textItem.ascent(), textItem.width() + 5, textItem.ascent() + textItem.descent() + 5);
252 tr = d->m_transform.mapRect(tr);
253
254 if (d->m_pass == 0) {
255 d->m_continueCall = false;
256 if (d->m_alphaPen || d->m_alphaOpacity || d->m_advancedPen) {
257 d->addAlphaRect(tr);
258 }
259 if (d->m_picengine) {
260 d->m_picengine->drawTextItem(p, textItem);
261 }
262 } else {
263 d->m_continueCall = !d->fullyContained(tr);
264 }
265}
266
267void QAlphaPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
268{
269 Q_D(QAlphaPaintEngine);
270
271 QRectF brect = d->m_transform.mapRect(r);
272
273 if (d->m_pass == 0) {
274 d->m_continueCall = false;
275 if (pixmap.hasAlpha() || d->m_alphaOpacity || d->m_complexTransform || pixmap.isQBitmap()) {
276 d->addAlphaRect(brect);
277 }
278 if (d->m_picengine)
279 d->m_picengine->drawTiledPixmap(r, pixmap, s);
280 } else {
281 d->m_continueCall = !d->fullyContained(brect);
282 }
283}
284
285QRegion QAlphaPaintEngine::alphaClipping() const
286{
287 Q_D(const QAlphaPaintEngine);
288 return d->m_cliprgn;
289}
290
291bool QAlphaPaintEngine::continueCall() const
292{
293 Q_D(const QAlphaPaintEngine);
294 return d->m_continueCall;
295}
296
297void QAlphaPaintEngine::flushAndInit(bool init)
298{
299 Q_D(QAlphaPaintEngine);
300 Q_ASSERT(d->m_pass == 0);
301
302 if (d->m_pic) {
303 d->m_picpainter->end();
304
305 // set clip region
306 d->m_alphargn = d->m_alphargn.intersected(QRect(0, 0, d->m_pdev->width(), d->m_pdev->height()));
307
308 // just use the bounding rect if it's a complex region..
309 QVector<QRect> rects = d->m_alphargn.rects();
310 if (rects.size() > 10) {
311 QRect br = d->m_alphargn.boundingRect();
312 d->m_alphargn = QRegion(br);