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