Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qbitmap.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qbitmap.h"
5#include <qpa/qplatformpixmap.h>
6#include <qpa/qplatformintegration.h>
7#include "qimage.h"
8#include "qscreen.h"
9#include "qvariant.h"
10#include <qpainter.h>
11#include <private/qguiapplication_p.h>
12
13#include <memory>
14
16
17/*!
18 \class QBitmap
19 \inmodule QtGui
20 \brief The QBitmap class provides monochrome (1-bit depth) pixmaps.
21
22 \ingroup painting
23 \ingroup shared
24
25 The QBitmap class is a monochrome off-screen paint device used
26 mainly for creating custom QCursor and QBrush objects,
27 constructing QRegion objects, and for setting masks for pixmaps
28 and widgets.
29
30 QBitmap is a QPixmap subclass ensuring a depth of 1, except for
31 null objects which have a depth of 0. If a pixmap with a depth
32 greater than 1 is assigned to a bitmap, the bitmap will be
33 dithered automatically.
34
35 Use the QColor objects Qt::color0 and Qt::color1 when drawing on a
36 QBitmap object (or a QPixmap object with depth 1).
37
38 Painting with Qt::color0 sets the bitmap bits to 0, and painting
39 with Qt::color1 sets the bits to 1. For a bitmap, 0-bits indicate
40 background (or transparent pixels) and 1-bits indicate foreground
41 (or opaque pixels). Use the clear() function to set all the bits
42 to Qt::color0. Note that using the Qt::black and Qt::white colors
43 make no sense because the QColor::pixel() value is not necessarily
44 0 for black and 1 for white.
45
46 The QBitmap class provides the transformed() function returning a
47 transformed copy of the bitmap; use the QTransform argument to
48 translate, scale, shear, and rotate the bitmap. In addition,
49 QBitmap provides the static fromData() function which returns a
50 bitmap constructed from the given \c uchar data, and the static
51 fromImage() function returning a converted copy of a QImage
52 object.
53
54 Just like the QPixmap class, QBitmap is optimized by the use of
55 implicit data sharing. For more information, see the \l {Implicit
56 Data Sharing} documentation.
57
58 \sa QPixmap, QImage, QImageReader, QImageWriter
59*/
60
61/*! \typedef QBitmap::DataPtr
62 \internal
63 */
64
65/*!
66 Constructs a null bitmap.
67
68 \sa QPixmap::isNull()
69*/
70QBitmap::QBitmap()
71 : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType)
72{
73}
74
75/*!
76 \fn QBitmap::QBitmap(int width, int height)
77
78 Constructs a bitmap with the given \a width and \a height. The pixels
79 inside are uninitialized.
80
81 \sa clear()
82*/
83QBitmap::QBitmap(int w, int h)
84 : QPixmap(QSize(w, h), QPlatformPixmap::BitmapType)
85{
86}
87
88/*!
89 Constructs a bitmap with the given \a size. The pixels in the
90 bitmap are uninitialized.
91
92 \sa clear()
93*/
94QBitmap::QBitmap(const QSize &size)
95 : QPixmap(size, QPlatformPixmap::BitmapType)
96{
97}
98
99/*!
100 \internal
101 This dtor must stay empty until Qt 7 (was inline until 6.2).
102*/
103QBitmap::~QBitmap() = default;
104
105/*!
106 \fn QBitmap::clear()
107
108 Clears the bitmap, setting all its bits to Qt::color0.
109*/
110
111/*!
112 Constructs a bitmap from the file specified by the given \a
113 fileName. If the file does not exist, or has an unknown format,
114 the bitmap becomes a null bitmap.
115
116 The \a fileName and \a format parameters are passed on to the
117 QPixmap::load() function. If the file format uses more than 1 bit
118 per pixel, the resulting bitmap will be dithered automatically.
119
120 \sa QPixmap::isNull(), QImageReader::imageFormat()
121*/
122QBitmap::QBitmap(const QString& fileName, const char *format)
123 : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType)
124{
125 load(fileName, format, Qt::MonoOnly);
126}
127
128/*!
129 \fn void QBitmap::swap(QBitmap &other)
130 \memberswap{bitmap}
131*/
132
133/*!
134 Returns the bitmap as a QVariant.
135*/
136QBitmap::operator QVariant() const
137{
138 return QVariant::fromValue(*this);
139}
140
141static QBitmap makeBitmap(QImage &&image, Qt::ImageConversionFlags flags)
142{
143 // make sure image.color(0) == Qt::color0 (white)
144 // and image.color(1) == Qt::color1 (black)
145 const QRgb c0 = QColor(Qt::black).rgb();
146 const QRgb c1 = QColor(Qt::white).rgb();
147 if (image.color(0) == c0 && image.color(1) == c1) {
148 image.invertPixels();
149 image.setColor(0, c1);
150 image.setColor(1, c0);
151 }
152
153 std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType));
154
155 data->fromImageInPlace(image, flags | Qt::MonoOnly);
156 return QBitmap::fromPixmap(QPixmap(data.release()));
157}
158
159/*!
160 Returns a copy of the given \a image converted to a bitmap using
161 the specified image conversion \a flags.
162
163 \sa fromData()
164*/
165QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
166{
167 if (image.isNull())
168 return QBitmap();
169
170 return makeBitmap(image.convertToFormat(QImage::Format_MonoLSB, flags), flags);
171}
172
173/*!
174 \since 5.12
175 \overload
176
177 Returns a copy of the given \a image converted to a bitmap using
178 the specified image conversion \a flags.
179
180 \sa fromData()
181*/
182QBitmap QBitmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
183{
184 if (image.isNull())
185 return QBitmap();
186
187 return makeBitmap(std::move(image).convertToFormat(QImage::Format_MonoLSB, flags), flags);
188}
189
190/*!
191 Constructs a bitmap with the given \a size, and sets the contents to
192 the \a bits supplied.
193
194 The bitmap data has to be byte aligned and provided in the bit
195 order specified by \a monoFormat. The mono format must be either
196 QImage::Format_Mono or QImage::Format_MonoLSB. Use
197 QImage::Format_Mono to specify data on the XBM format.
198
199 \sa fromImage()
200
201*/
202QBitmap QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat)
203{
204 Q_ASSERT(monoFormat == QImage::Format_Mono || monoFormat == QImage::Format_MonoLSB);
205
206 QImage image(size, monoFormat);
207 image.setColor(0, QColor(Qt::color0).rgb());
208 image.setColor(1, QColor(Qt::color1).rgb());
209
210 // Need to memcpy each line separately since QImage is 32bit aligned and
211 // this data is only byte aligned...
212 int bytesPerLine = (size.width() + 7) / 8;
213 for (int y = 0; y < size.height(); ++y)
214 memcpy(image.scanLine(y), bits + bytesPerLine * y, bytesPerLine);
215 return QBitmap::fromImage(std::move(image));
216}
217
218/*!
219 Returns a copy of the given \a pixmap converted to a bitmap.
220
221 If the pixmap has a depth greater than 1, the resulting bitmap
222 will be dithered automatically.
223
224 \since 6.0
225
226 \sa QPixmap::depth()
227*/
228
229QBitmap QBitmap::fromPixmap(const QPixmap &pixmap)
230{
231 if (pixmap.isNull()) { // a null pixmap
232 return QBitmap(0, 0);
233 } else if (pixmap.depth() == 1) { // 1-bit pixmap
234 QBitmap bm;
235 if (pixmap.paintingActive()) { // make a deep copy
236 pixmap.copy().swap(bm);
237 } else {
238 bm.data = pixmap.data; // shallow assignment
239 }
240 return bm;
241 }
242 // n-bit depth pixmap, will dither image
243 return fromImage(pixmap.toImage());
244}
245
246#if QT_DEPRECATED_SINCE(6, 0)
247/*!
248 \deprecated [6.0] Use fromPixmap instead.
249 Constructs a bitmap that is a copy of the given \a pixmap.
250
251 If the pixmap has a depth greater than 1, the resulting bitmap
252 will be dithered automatically.
253
254 \sa QPixmap::depth(), fromImage(), fromData()
255*/
256QBitmap::QBitmap(const QPixmap &pixmap)
257{
258 *this = QBitmap::fromPixmap(pixmap);
259}
260
261/*!
262 \deprecated [6.0] Use fromPixmap instead.
263 \overload
264
265 Assigns the given \a pixmap to this bitmap and returns a reference
266 to this bitmap.
267
268 If the pixmap has a depth greater than 1, the resulting bitmap
269 will be dithered automatically.
270
271 \sa QPixmap::depth()
272 */
273QBitmap &QBitmap::operator=(const QPixmap &pixmap)
274{
275 *this = QBitmap::fromPixmap(pixmap);
276 return *this;
277}
278#endif
279
280/*!
281 Returns a copy of this bitmap, transformed according to the given
282 \a matrix.
283
284 \sa QPixmap::transformed()
285 */
286QBitmap QBitmap::transformed(const QTransform &matrix) const
287{
288 return QBitmap::fromPixmap(QPixmap::transformed(matrix));
289}
290
291QT_END_NAMESPACE
Combined button and popup list for selecting options.
static QBitmap makeBitmap(QImage &&image, Qt::ImageConversionFlags flags)
Definition qbitmap.cpp:141