1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
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.
16**
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.
24**
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.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qbitmap.h"
41#include <qpa/qplatformpixmap.h>
42#include <qpa/qplatformintegration.h>
43#include "qimage.h"
44#include "qscreen.h"
45#include "qvariant.h"
46#include <qpainter.h>
47#include <private/qguiapplication_p.h>
48
49QT_BEGIN_NAMESPACE
50
51/*!
52 \class QBitmap
53 \inmodule QtGui
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), QPlatformPixmap::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), QPlatformPixmap::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, QPlatformPixmap::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 Constructs a bitmap from the file specified by the given \a
157 fileName. If the file does not exist, or has an unknown format,
158 the bitmap becomes a null bitmap.
159
160 The \a fileName and \a format parameters are passed on to the
161 QPixmap::load() function. If the file format uses more than 1 bit
162 per pixel, the resulting bitmap will be dithered automatically.
163
164 \sa QPixmap::isNull(), QImageReader::imageFormat()
165*/
166
167QBitmap::QBitmap(const QString& fileName, const char *format)
168 : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType)
169{
170 load(fileName, format, flags: Qt::MonoOnly);
171}
172
173/*!
174 \overload
175
176 Assigns the given \a pixmap to this bitmap and returns a reference
177 to this bitmap.
178
179 If the pixmap has a depth greater than 1, the resulting bitmap
180 will be dithered automatically.
181
182 \sa QPixmap::depth()
183 */
184
185QBitmap &QBitmap::operator=(const QPixmap &pixmap)
186{
187 if (pixmap.isNull()) { // a null pixmap
188 QBitmap(0, 0).swap(other&: *this);
189 } else if (pixmap.depth() == 1) { // 1-bit pixmap
190 QPixmap::operator=(pixmap); // shallow assignment
191 } else { // n-bit depth pixmap
192 *this = fromImage(image: pixmap.toImage()); // will dither image
193 }
194 return *this;
195}
196
197#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
198
199/*!
200 Destroys the bitmap.
201*/
202QBitmap::~QBitmap()
203{
204}
205
206#endif
207
208/*!
209 \fn void QBitmap::swap(QBitmap &other)
210 \since 4.8
211
212 Swaps bitmap \a other with this bitmap. This operation is very
213 fast and never fails.
214*/
215
216/*!
217 Returns the bitmap as a QVariant.
218*/
219QBitmap::operator QVariant() const
220{
221 return QVariant(QMetaType::QBitmap, this);
222}
223
224static QBitmap makeBitmap(QImage &&image, Qt::ImageConversionFlags flags)
225{
226 // make sure image.color(0) == Qt::color0 (white)
227 // and image.color(1) == Qt::color1 (black)
228 const QRgb c0 = QColor(Qt::black).rgb();
229 const QRgb c1 = QColor(Qt::white).rgb();
230 if (image.color(i: 0) == c0 && image.color(i: 1) == c1) {
231 image.invertPixels();
232 image.setColor(i: 0, c: c1);
233 image.setColor(i: 1, c: c0);
234 }
235
236 QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::BitmapType));
237
238 data->fromImageInPlace(image, flags: flags | Qt::MonoOnly);
239 return QPixmap(data.take());
240}
241
242/*!
243 Returns a copy of the given \a image converted to a bitmap using
244 the specified image conversion \a flags.
245
246 \sa fromData()
247*/
248QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
249{
250 if (image.isNull())
251 return QBitmap();
252
253 return makeBitmap(image: image.convertToFormat(f: QImage::Format_MonoLSB, flags), flags);
254}
255
256/*!
257 \since 5.12
258 \overload
259
260 Returns a copy of the given \a image converted to a bitmap using
261 the specified image conversion \a flags.
262
263 \sa fromData()
264*/
265QBitmap QBitmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
266{
267 if (image.isNull())
268 return QBitmap();
269
270 return makeBitmap(image: std::move(image).convertToFormat(f: QImage::Format_MonoLSB, flags), flags);
271}
272
273/*!
274 Constructs a bitmap with the given \a size, and sets the contents to
275 the \a bits supplied.
276
277 The bitmap data has to be byte aligned and provided in in the bit
278 order specified by \a monoFormat. The mono format must be either
279 QImage::Format_Mono or QImage::Format_MonoLSB. Use
280 QImage::Format_Mono to specify data on the XBM format.
281
282 \sa fromImage()
283
284*/
285QBitmap QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat)
286{
287 Q_ASSERT(monoFormat == QImage::Format_Mono || monoFormat == QImage::Format_MonoLSB);
288
289 QImage image(size, monoFormat);
290 image.setColor(i: 0, c: QColor(Qt::color0).rgb());
291 image.setColor(i: 1, c: QColor(Qt::color1).rgb());
292
293 // Need to memcpy each line separatly since QImage is 32bit aligned and
294 // this data is only byte aligned...
295 int bytesPerLine = (size.width() + 7) / 8;
296 for (int y = 0; y < size.height(); ++y)
297 memcpy(dest: image.scanLine(y), src: bits + bytesPerLine * y, n: bytesPerLine);
298 return QBitmap::fromImage(image: std::move(image));
299}
300
301/*!
302 Returns a copy of this bitmap, transformed according to the given
303 \a matrix.
304
305 \sa QPixmap::transformed()
306 */
307QBitmap QBitmap::transformed(const QTransform &matrix) const
308{
309 QBitmap bm = QPixmap::transformed(matrix);
310 return bm;
311}
312
313#if QT_DEPRECATED_SINCE(5, 13)
314/*!
315 \overload
316 \obsolete
317
318 This convenience function converts the \a matrix to a QTransform
319 and calls the overloaded function.
320*/
321QBitmap QBitmap::transformed(const QMatrix &matrix) const
322{
323 return transformed(matrix: QTransform(matrix));
324}
325#endif
326
327QT_END_NAMESPACE
328

source code of qtbase/src/gui/image/qbitmap.cpp