source: trunk/src/gui/image/qpixmap_raster.cpp@ 67

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

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

File size: 11.7 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 "qpixmap.h"
43
44#include "qpixmap_raster_p.h"
45#include "qnativeimage_p.h"
46#include "qimage_p.h"
47
48#include "qbitmap.h"
49#include "qimage.h"
50#include <private/qwidget_p.h>
51#include <private/qdrawhelper_p.h>
52
53#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)
54#include <private/qpaintengine_d3d_p.h>
55#include <d3d9.h>
56extern QDirect3DPaintEngine *qt_d3dEngine();
57#endif
58
59QT_BEGIN_NAMESPACE
60
61const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
62 0x10, 0x20, 0x40, 0x80 };
63
64QRasterPixmapData::QRasterPixmapData(PixelType type)
65 : QPixmapData(type, RasterClass)
66#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECT3D)
67 , texture(0)
68#endif
69{
70}
71
72QRasterPixmapData::~QRasterPixmapData()
73{
74}
75
76void QRasterPixmapData::resize(int width, int height)
77{
78 QImage::Format format;
79#ifdef Q_WS_QWS
80 if (pixelType() == BitmapType) {
81 format = QImage::Format_Mono;
82 } else {
83 format = QScreen::instance()->pixelFormat();
84 if (format == QImage::Format_Invalid)
85 format = QImage::Format_ARGB32_Premultiplied;
86 else if (format == QImage::Format_Indexed8) // currently not supported
87 format = QImage::Format_RGB444;
88 }
89#else
90 if (pixelType() == BitmapType)
91 format = QImage::Format_MonoLSB;
92 else
93 format = QNativeImage::systemFormat();
94#endif
95
96 image = QImage(width, height, format);
97
98 if (pixelType() == BitmapType && !image.isNull()) {
99 image.setNumColors(2);
100 image.setColor(0, QColor(Qt::color0).rgba());
101 image.setColor(1, QColor(Qt::color1).rgba());
102 }
103
104 setSerialNumber(image.serialNumber());
105}
106
107void QRasterPixmapData::fromImage(const QImage &sourceImage,
108 Qt::ImageConversionFlags flags)
109{
110 Q_UNUSED(flags);
111
112#ifdef Q_WS_QWS
113 QImage::Format format;
114 if (pixelType() == BitmapType) {
115 format = QImage::Format_Mono;
116 } else {
117 format = QScreen::instance()->pixelFormat();
118 if (format == QImage::Format_Invalid)
119 format = QImage::Format_ARGB32_Premultiplied;
120 else if (format == QImage::Format_Indexed8) // currently not supported
121 format = QImage::Format_RGB444;
122 }
123
124 if (sourceImage.hasAlphaChannel()
125 && ((flags & Qt::NoOpaqueDetection)
126 || const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) {
127 switch (format) {
128 case QImage::Format_RGB16:
129 format = QImage::Format_ARGB8565_Premultiplied;
130 break;
131 case QImage::Format_RGB666:
132 format = QImage::Format_ARGB6666_Premultiplied;
133 break;
134 case QImage::Format_RGB555:
135 format = QImage::Format_ARGB8555_Premultiplied;
136 break;
137 case QImage::Format_RGB444:
138 format = QImage::Format_ARGB4444_Premultiplied;
139 break;
140 default:
141 format = QImage::Format_ARGB32_Premultiplied;
142 break;
143 }
144 } else if (format == QImage::Format_Invalid) {
145 format = QImage::Format_ARGB32_Premultiplied;
146 }
147
148 image = sourceImage.convertToFormat(format);
149#else
150 if (pixelType() == BitmapType) {
151 image = sourceImage.convertToFormat(QImage::Format_MonoLSB);
152 } else {
153 if (sourceImage.depth() == 1) {
154 image = sourceImage.hasAlphaChannel()
155 ? sourceImage.convertToFormat(QImage::Format_ARGB32_Premultiplied)
156 : sourceImage.convertToFormat(QImage::Format_RGB32);
157 } else {
158
159 QImage::Format opaqueFormat = QNativeImage::systemFormat();
160 QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
161
162 switch (opaqueFormat) {
163 case QImage::Format_RGB16:
164 alphaFormat = QImage::Format_ARGB8565_Premultiplied;
165 break;
166 default: // We don't care about the others...
167 break;
168 }
169
170 if (!sourceImage.hasAlphaChannel()
171 || ((flags & Qt::NoOpaqueDetection) == 0
172 && !const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) {
173 image = sourceImage.convertToFormat(opaqueFormat);
174 } else {
175 image = sourceImage.convertToFormat(alphaFormat);
176 }
177 }
178 }
179#endif
180
181 setSerialNumber(image.serialNumber());
182}
183
184void QRasterPixmapData::fill(const QColor &color)
185{
186 uint pixel;
187
188 if (image.depth() == 1) {
189 int gray = qGray(color.rgba());
190 // Pick the best approximate color in the image's colortable.
191 if (qAbs(qGray(image.color(0)) - gray) < qAbs(qGray(image.color(1)) - gray))
192 pixel = 0;
193 else
194 pixel = 1;
195 } else if (image.depth() >= 15) {
196 int alpha = color.alpha();
197 if (alpha != 255) {
198 if (!image.hasAlphaChannel()) {
199 QImage::Format toFormat;
200 if (image.format() == QImage::Format_RGB16)
201 toFormat = QImage::Format_ARGB8565_Premultiplied;
202 else if (image.format() == QImage::Format_RGB666)
203 toFormat = QImage::Format_ARGB6666_Premultiplied;
204 else if (image.format() == QImage::Format_RGB555)
205 toFormat = QImage::Format_ARGB8555_Premultiplied;
206 else if (image.format() == QImage::Format_RGB444)
207 toFormat = QImage::Format_ARGB4444_Premultiplied;
208 else
209 toFormat = QImage::Format_ARGB32_Premultiplied;
210 image = QImage(image.width(), image.height(), toFormat);
211 }
212
213 switch (image.format()) {
214 case QImage::Format_ARGB8565_Premultiplied:
215 pixel = qargb8565(color.rgba()).rawValue();
216 break;
217 case QImage::Format_ARGB8555_Premultiplied:
218 pixel = qargb8555(color.rgba()).rawValue();
219 break;
220 case QImage::Format_ARGB6666_Premultiplied:
221 pixel = qargb6666(color.rgba()).rawValue();
222 break;
223 case QImage::Format_ARGB4444_Premultiplied:
224 pixel = qargb4444(color.rgba()).rawValue();
225 break;
226 default:
227 pixel = PREMUL(color.rgba());
228 break;
229 }
230 } else {
231 switch (image.format()) {
232 case QImage::Format_RGB16:
233 pixel = qt_colorConvert<quint16, quint32>(color.rgba(), 0);
234 break;
235 case QImage::Format_RGB444:
236 pixel = qrgb444(color.rgba()).rawValue();
237 break;
238 case QImage::Format_RGB555:
239 pixel = qrgb555(color.rgba()).rawValue();
240 break;
241 case QImage::Format_RGB666:
242 pixel = qrgb666(color.rgba()).rawValue();
243 break;
244 case QImage::Format_RGB888:
245 pixel = qrgb888(color.rgba()).rawValue();
246 break;
247 default:
248 pixel = color.rgba();
249 break;
250 }
251 }
252 } else {
253 pixel = 0;
254 // ### what about 8 bits
255 }
256
257 image.fill(pixel);
258}
259
260void QRasterPixmapData::setMask(const QBitmap &mask)
261{
262 if (mask.size().isEmpty()) {
263 if (image.depth() != 1) { // hw: ????
264 image = image.convertToFormat(QImage::Format_RGB32);
265 }
266 } else {
267 const int w = image.width();
268 const int h = image.height();
269
270 switch (image.depth()) {
271 case 1: {
272 const QImage imageMask = mask.toImage().convertToFormat(image.format());
273 for (int y = 0; y < h; ++y) {
274 const uchar *mscan = imageMask.scanLine(y);
275 uchar *tscan = image.scanLine(y);
276 int bytesPerLine = image.bytesPerLine();
277 for (int i = 0; i < bytesPerLine; ++i)
278 tscan[i] &= mscan[i];
279 }
280 break;
281 }
282 default: {
283 const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
284 image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
285 for (int y = 0; y < h; ++y) {
286 const uchar *mscan = imageMask.scanLine(y);
287 QRgb *tscan = (QRgb *)image.scanLine(y);
288 for (int x = 0; x < w; ++x) {
289 if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7]))
290 tscan[x] = 0;
291 }
292 }
293 break;
294 }
295 }
296 }
297}
298
299bool QRasterPixmapData::hasAlphaChannel() const
300{
301 return image.hasAlphaChannel();
302}
303
304QImage QRasterPixmapData::toImage() const
305{
306 return image;
307}
308
309void QRasterPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
310{
311 image.setAlphaChannel(alphaChannel.toImage());
312}
313
314QPaintEngine* QRasterPixmapData::paintEngine() const
315{
316 return image.paintEngine();
317}
318
319extern int qt_defaultDpiX();
320extern int qt_defaultDpiY();
321
322int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
323{
324 // override the image dpi with the screen dpi when rendering to a pixmap
325 const int dpmX = qRound(qt_defaultDpiX() * 100 / qreal(2.54));
326 const int dpmY = qRound(qt_defaultDpiY() * 100 / qreal(2.54));
327 switch (metric) {
328 case QPaintDevice::PdmWidthMM:
329 return qRound(image.width() * 1000 / dpmX);
330 case QPaintDevice::PdmHeightMM:
331 return qRound(image.height() * 1000 / dpmY);
332 case QPaintDevice::PdmDpiX:
333 return qRound(dpmX * qreal(0.0254));
334 case QPaintDevice::PdmDpiY:
335 return qRound(dpmY * qreal(0.0254));
336 case QPaintDevice::PdmPhysicalDpiX:
337 return qRound(dpmX * qreal(0.0254));
338 case QPaintDevice::PdmPhysicalDpiY:
339 return qRound(dpmY * qreal(0.0254));
340 default:
341 return image.metric(metric);
342 }
343}
344
345QImage* QRasterPixmapData::buffer()
346{
347 return &image;
348}
349
350QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.