source: trunk/src/gui/image/qbitmap.cpp@ 642

Last change on this file since 642 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 11.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qbitmap.h"
43#include "qpixmapdata_p.h"
44#include "qimage.h"
45#include "qvariant.h"
46#include <qpainter.h>
47#include <private/qgraphicssystem_p.h>
48#include <private/qapplication_p.h>
49
50QT_BEGIN_NAMESPACE
51
52/*!
53 \class QBitmap
54 \brief The QBitmap class provides monochrome (1-bit depth) pixmaps.
55
56 \ingroup painting
57 \ingroup shared
58
59 The QBitmap class is a monochrome off-screen paint device used
60 mainly for creating custom QCursor and QBrush objects,
61 constructing QRegion objects, and for setting masks for pixmaps
62 and widgets.
63
64 QBitmap is a QPixmap subclass ensuring a depth of 1, except for
65 null objects which have a depth of 0. If a pixmap with a depth
66 greater than 1 is assigned to a bitmap, the bitmap will be
67 dithered automatically.
68
69 Use the QColor objects Qt::color0 and Qt::color1 when drawing on a
70 QBitmap object (or a QPixmap object with depth 1).
71
72 Painting with Qt::color0 sets the bitmap bits to 0, and painting
73 with Qt::color1 sets the bits to 1. For a bitmap, 0-bits indicate
74 background (or transparent pixels) and 1-bits indicate foreground
75 (or opaque pixels). Use the clear() function to set all the bits
76 to Qt::color0. Note that using the Qt::black and Qt::white colors
77 make no sense because the QColor::pixel() value is not necessarily
78 0 for black and 1 for white.
79
80 The QBitmap class provides the transformed() function returning a
81 transformed copy of the bitmap; use the QTransform argument to
82 translate, scale, shear, and rotate the bitmap. In addition,
83 QBitmap provides the static fromData() function which returns a
84 bitmap constructed from the given \c uchar data, and the static
85 fromImage() function returning a converted copy of a QImage
86 object.
87
88 Just like the QPixmap class, QBitmap is optimized by the use of
89 implicit data sharing. For more information, see the \l {Implicit
90 Data Sharing} documentation.
91
92 \sa QPixmap, QImage, QImageReader, QImageWriter
93*/
94
95/*! \typedef QBitmap::DataPtr
96 \internal
97 */
98
99/*!
100 Constructs a null bitmap.
101
102 \sa QPixmap::isNull()
103*/
104QBitmap::QBitmap()
105 : QPixmap(QSize(0, 0), QPixmapData::BitmapType)
106{
107}
108
109/*!
110 \fn QBitmap::QBitmap(int width, int height)
111
112 Constructs a bitmap with the given \a width and \a height. The pixels
113 inside are uninitialized.
114
115 \sa clear()
116*/
117
118QBitmap::QBitmap(int w, int h)
119 : QPixmap(QSize(w, h), QPixmapData::BitmapType)
120{
121}
122
123/*!
124 Constructs a bitmap with the given \a size. The pixels in the
125 bitmap are uninitialized.
126
127 \sa clear()
128*/
129
130QBitmap::QBitmap(const QSize &size)
131 : QPixmap(size, QPixmapData::BitmapType)
132{
133}
134
135/*!
136 \fn QBitmap::clear()
137
138 Clears the bitmap, setting all its bits to Qt::color0.
139*/
140
141/*!
142 Constructs a bitmap that is a copy of the given \a pixmap.
143
144 If the pixmap has a depth greater than 1, the resulting bitmap
145 will be dithered automatically.
146
147 \sa QPixmap::depth(), fromImage(), fromData()
148*/
149
150QBitmap::QBitmap(const QPixmap &pixmap)
151{
152 QBitmap::operator=(pixmap);
153}
154
155/*!
156 \fn QBitmap::QBitmap(const QImage &image)
157
158 Constructs a bitmap that is a copy of the given \a image.
159
160 Use the static fromImage() function instead.
161*/
162
163/*!
164 Constructs a bitmap from the file specified by the given \a
165 fileName. If the file does not exist, or has an unknown format,
166 the bitmap becomes a null bitmap.
167
168 The \a fileName and \a format parameters are passed on to the
169 QPixmap::load() function. If the file format uses more than 1 bit
170 per pixel, the resulting bitmap will be dithered automatically.
171
172 \sa QPixmap::isNull(), QImageReader::imageFormat()
173*/
174
175QBitmap::QBitmap(const QString& fileName, const char *format)
176 : QPixmap(QSize(0, 0), QPixmapData::BitmapType)
177{
178 load(fileName, format, Qt::MonoOnly);
179}
180
181/*!
182 \overload
183
184 Assigns the given \a pixmap to this bitmap and returns a reference
185 to this bitmap.
186
187 If the pixmap has a depth greater than 1, the resulting bitmap
188 will be dithered automatically.
189
190 \sa QPixmap::depth()
191 */
192
193QBitmap &QBitmap::operator=(const QPixmap &pixmap)
194{
195 if (pixmap.isNull()) { // a null pixmap
196 QBitmap bm(0, 0);
197 QBitmap::operator=(bm);
198 } else if (pixmap.depth() == 1) { // 1-bit pixmap
199 QPixmap::operator=(pixmap); // shallow assignment
200 } else { // n-bit depth pixmap
201 QImage image;
202 image = pixmap.toImage(); // convert pixmap to image
203 *this = fromImage(image); // will dither image
204 }
205 return *this;
206}
207
208
209#ifdef QT3_SUPPORT
210QBitmap::QBitmap(int w, int h, const uchar *bits, bool isXbitmap)
211{
212 *this = fromData(QSize(w, h), bits, isXbitmap ? QImage::Format_MonoLSB : QImage::Format_Mono);
213}
214
215
216QBitmap::QBitmap(const QSize &size, const uchar *bits, bool isXbitmap)
217{
218 *this = fromData(size, bits, isXbitmap ? QImage::Format_MonoLSB : QImage::Format_Mono);
219}
220#endif
221
222/*!
223 Destroys the bitmap.
224*/
225QBitmap::~QBitmap()
226{
227}
228
229/*!
230 Returns the bitmap as a QVariant.
231*/
232QBitmap::operator QVariant() const
233{
234 return QVariant(QVariant::Bitmap, this);
235}
236
237/*!
238 \fn QBitmap &QBitmap::operator=(const QImage &image)
239 \overload
240
241 Converts the given \a image to a bitmap, and assigns the result to
242 this bitmap. Returns a reference to the bitmap.
243
244 Use the static fromImage() function instead.
245*/
246
247/*!
248 Returns a copy of the given \a image converted to a bitmap using
249 the specified image conversion \a flags.
250
251 \sa fromData()
252*/
253QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
254{
255 if (image.isNull())
256 return QBitmap();
257
258 QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags);
259
260 // make sure image.color(0) == Qt::color0 (white)
261 // and image.color(1) == Qt::color1 (black)
262 const QRgb c0 = QColor(Qt::black).rgb();
263 const QRgb c1 = QColor(Qt::white).rgb();
264 if (img.color(0) == c0 && img.color(1) == c1) {
265 img.invertPixels();
266 img.setColor(0, c1);
267 img.setColor(1, c0);
268 }
269
270 QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
271 QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::BitmapType)
272 : QGraphicsSystem::createDefaultPixmapData(QPixmapData::BitmapType));
273
274 data->fromImage(img, flags | Qt::MonoOnly);
275 return QPixmap(data.take());
276}
277
278/*!
279 Constructs a bitmap with the given \a size, and sets the contents to
280 the \a bits supplied.
281
282 The bitmap data has to be byte aligned and provided in in the bit
283 order specified by \a monoFormat. The mono format must be either
284 QImage::Format_Mono or QImage::Format_MonoLSB. Use
285 QImage::Format_Mono to specify data on the XBM format.
286
287 \sa fromImage()
288
289*/
290QBitmap QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat)
291{
292 Q_ASSERT(monoFormat == QImage::Format_Mono || monoFormat == QImage::Format_MonoLSB);
293
294 QImage image(size, monoFormat);
295 image.setColor(0, QColor(Qt::color0).rgb());
296 image.setColor(1, QColor(Qt::color1).rgb());
297
298 // Need to memcpy each line separatly since QImage is 32bit aligned and
299 // this data is only byte aligned...
300 int bytesPerLine = (size.width() + 7) / 8;
301 for (int y = 0; y < size.height(); ++y)
302 memcpy(image.scanLine(y), bits + bytesPerLine * y, bytesPerLine);
303 return QBitmap::fromImage(image);
304}
305
306/*!