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 <qglobal.h>
41
42#include "qpixmap.h"
43#include <qpa/qplatformpixmap.h>
44#include "qimagepixmapcleanuphooks_p.h"
45
46#include "qbitmap.h"
47#include "qimage.h"
48#include "qpainter.h"
49#include "qdatastream.h"
50#include "qbuffer.h"
51#include <private/qguiapplication_p.h>
52#include "qevent.h"
53#include "qfile.h"
54#include "qfileinfo.h"
55#include "qpixmapcache.h"
56#include "qdatetime.h"
57#include "qimagereader.h"
58#include "qimagewriter.h"
59#include "qpaintengine.h"
60#include "qscreen.h"
61#include "qthread.h"
62#include "qdebug.h"
63
64#include <qpa/qplatformintegration.h>
65
66#include "qpixmap_raster_p.h"
67#include "private/qhexstring_p.h"
68
69#include <qtgui_tracepoints_p.h>
70
71QT_BEGIN_NAMESPACE
72
73static bool qt_pixmap_thread_test()
74{
75 if (Q_UNLIKELY(!QCoreApplication::instance())) {
76 qFatal(msg: "QPixmap: Must construct a QGuiApplication before a QPixmap");
77 return false;
78 }
79
80 if (qApp->thread() != QThread::currentThread()) {
81 bool fail = false;
82 if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(cap: QPlatformIntegration::ThreadedPixmaps)) {
83 printf(format: "Platform plugin does not support threaded pixmaps!\n");
84 fail = true;
85 }
86 if (fail) {
87 qWarning(msg: "QPixmap: It is not safe to use pixmaps outside the GUI thread");
88 return false;
89 }
90 }
91 return true;
92}
93
94void QPixmap::doInit(int w, int h, int type)
95{
96 if ((w > 0 && h > 0) || type == QPlatformPixmap::BitmapType)
97 data = QPlatformPixmap::create(w, h, type: (QPlatformPixmap::PixelType) type);
98 else
99 data = nullptr;
100}
101
102/*!
103 Constructs a null pixmap.
104
105 \sa isNull()
106*/
107
108QPixmap::QPixmap()
109 : QPaintDevice()
110{
111 (void) qt_pixmap_thread_test();
112 doInit(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
113}
114
115/*!
116 \fn QPixmap::QPixmap(int width, int height)
117
118 Constructs a pixmap with the given \a width and \a height. If
119 either \a width or \a height is zero, a null pixmap is
120 constructed.
121
122 \warning This will create a QPixmap with uninitialized data. Call
123 fill() to fill the pixmap with an appropriate color before drawing
124 onto it with QPainter.
125
126 \sa isNull()
127*/
128
129QPixmap::QPixmap(int w, int h)
130 : QPixmap(QSize(w, h))
131{
132}
133
134/*!
135 \overload
136
137 Constructs a pixmap of the given \a size.
138
139 \warning This will create a QPixmap with uninitialized data. Call
140 fill() to fill the pixmap with an appropriate color before drawing
141 onto it with QPainter.
142*/
143
144QPixmap::QPixmap(const QSize &size)
145 : QPixmap(size, QPlatformPixmap::PixmapType)
146{
147}
148
149/*!
150 \internal
151*/
152QPixmap::QPixmap(const QSize &s, int type)
153{
154 if (!qt_pixmap_thread_test())
155 doInit(w: 0, h: 0, type: static_cast<QPlatformPixmap::PixelType>(type));
156 else
157 doInit(w: s.width(), h: s.height(), type: static_cast<QPlatformPixmap::PixelType>(type));
158}
159
160/*!
161 \internal
162*/
163QPixmap::QPixmap(QPlatformPixmap *d)
164 : QPaintDevice(), data(d)
165{
166}
167
168/*!
169 Constructs a pixmap from the file with the given \a fileName. If the
170 file does not exist or is of an unknown format, the pixmap becomes a
171 null pixmap.
172
173 The loader attempts to read the pixmap using the specified \a
174 format. If the \a format is not specified (which is the default),
175 the loader probes the file for a header to guess the file format.
176
177 The file name can either refer to an actual file on disk or to
178 one of the application's embedded resources. See the
179 \l{resources.html}{Resource System} overview for details on how
180 to embed images and other resource files in the application's
181 executable.
182
183 If the image needs to be modified to fit in a lower-resolution
184 result (e.g. converting from 32-bit to 8-bit), use the \a
185 flags to control the conversion.
186
187 The \a fileName, \a format and \a flags parameters are
188 passed on to load(). This means that the data in \a fileName is
189 not compiled into the binary. If \a fileName contains a relative
190 path (e.g. the filename only) the relevant file must be found
191 relative to the runtime working directory.
192
193 \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
194 Image Files}
195*/
196
197QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags)
198 : QPaintDevice()
199{
200 doInit(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
201 if (!qt_pixmap_thread_test())
202 return;
203
204 load(fileName, format, flags);
205}
206
207/*!
208 Constructs a pixmap that is a copy of the given \a pixmap.
209
210 \sa copy()
211*/
212
213QPixmap::QPixmap(const QPixmap &pixmap)
214 : QPaintDevice()
215{
216 if (!qt_pixmap_thread_test()) {
217 doInit(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
218 return;
219 }
220 if (pixmap.paintingActive()) { // make a deep copy
221 pixmap.copy().swap(other&: *this);
222 } else {
223 data = pixmap.data;
224 }
225}
226
227/*!
228 Constructs a pixmap from the given \a xpm data, which must be a
229 valid XPM image.
230
231 Errors are silently ignored.
232
233 Note that it's possible to squeeze the XPM variable a little bit
234 by using an unusual declaration:
235
236 \snippet code/src_gui_image_qpixmap.cpp 0
237
238 The extra \c const makes the entire definition read-only, which is
239 slightly more efficient (for example, when the code is in a shared
240 library) and ROMable when the application is to be stored in ROM.
241*/
242#ifndef QT_NO_IMAGEFORMAT_XPM
243QPixmap::QPixmap(const char * const xpm[])
244 : QPaintDevice()
245{
246 doInit(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
247 if (!xpm)
248 return;
249
250 QImage image(xpm);
251 if (!image.isNull()) {
252 if (data && data->pixelType() == QPlatformPixmap::BitmapType)
253 *this = QBitmap::fromImage(image: std::move(image));
254 else
255 *this = fromImage(image: std::move(image));
256 }
257}
258#endif
259
260
261/*!
262 Destroys the pixmap.
263*/
264
265QPixmap::~QPixmap()
266{
267 Q_ASSERT(!data || data->ref.loadRelaxed() >= 1); // Catch if ref-counting changes again
268}
269
270/*!
271 \internal
272*/
273int QPixmap::devType() const
274{
275 return QInternal::Pixmap;
276}
277
278/*!
279 \fn QPixmap QPixmap::copy(int x, int y, int width, int height) const
280 \overload
281
282 Returns a deep copy of the subset of the pixmap that is specified
283 by the rectangle QRect( \a x, \a y, \a width, \a height).
284*/
285
286/*!
287 \fn QPixmap QPixmap::copy(const QRect &rectangle) const
288
289 Returns a deep copy of the subset of the pixmap that is specified
290 by the given \a rectangle. For more information on deep copies,
291 see the \l {Implicit Data Sharing} documentation.
292
293 If the given \a rectangle is empty, the whole image is copied.
294
295 \sa operator=(), QPixmap(), {QPixmap#Pixmap
296 Transformations}{Pixmap Transformations}
297*/
298QPixmap QPixmap::copy(const QRect &rect) const
299{
300 if (isNull())
301 return QPixmap();
302
303 QRect r(0, 0, width(), height());
304 if (!rect.isEmpty())
305 r = r.intersected(other: rect);
306
307 QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
308 d->copy(data: data.data(), rect: r);
309 return QPixmap(d);
310}
311
312/*!
313 \fn QPixmap::scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed)
314 \since 4.6
315
316 This convenience function is equivalent to calling QPixmap::scroll(\a dx,
317 \a dy, QRect(\a x, \a y, \a width, \a height), \a exposed).
318
319 \sa QWidget::scroll(), QGraphicsItem::scroll()
320*/
321
322/*!
323 \since 4.6
324
325 Scrolls the area \a rect of this pixmap by (\a dx, \a dy). The exposed
326 region is left unchanged. You can optionally pass a pointer to an empty
327 QRegion to get the region that is \a exposed by the scroll operation.
328
329 \snippet code/src_gui_image_qpixmap.cpp 2
330
331 You cannot scroll while there is an active painter on the pixmap.
332
333 \sa QWidget::scroll(), QGraphicsItem::scroll()
334*/
335void QPixmap::scroll(int dx, int dy, const QRect &rect, QRegion *exposed)
336{
337 if (isNull() || (dx == 0 && dy == 0))
338 return;
339 QRect dest = rect & this->rect();
340 QRect src = dest.translated(dx: -dx, dy: -dy) & dest;
341 if (src.isEmpty()) {
342 if (exposed)
343 *exposed += dest;
344 return;
345 }
346
347 detach();
348
349 if (!data->scroll(dx, dy, rect: src)) {
350 // Fallback
351 QPixmap pix = *this;
352 QPainter painter(&pix);
353 painter.setCompositionMode(QPainter::CompositionMode_Source);
354 painter.drawPixmap(targetRect: src.translated(dx, dy), pixmap: *this, sourceRect: src);
355 painter.end();
356 *this = pix;
357 }
358
359 if (exposed) {
360 *exposed += dest;
361 *exposed -= src.translated(dx, dy);
362 }
363}
364
365/*!
366 Assigns the given \a pixmap to this pixmap and returns a reference
367 to this pixmap.
368
369 \sa copy(), QPixmap()
370*/
371
372QPixmap &QPixmap::operator=(const QPixmap &pixmap)
373{
374 if (paintingActive()) {
375 qWarning(msg: "QPixmap::operator=: Cannot assign to pixmap during painting");
376 return *this;
377 }
378 if (pixmap.paintingActive()) { // make a deep copy
379 pixmap.copy().swap(other&: *this);
380 } else {
381 data = pixmap.data;
382 }
383 return *this;
384}
385
386/*!
387 \fn QPixmap &QPixmap::operator=(QPixmap &&other)
388
389 Move-assigns \a other to this QPixmap instance.
390
391 \since 5.2
392*/
393
394/*!
395 \fn void QPixmap::swap(QPixmap &other)
396 \since 4.8
397
398 Swaps pixmap \a other with this pixmap. This operation is very
399 fast and never fails.
400*/
401
402/*!
403 Returns the pixmap as a QVariant.
404*/
405QPixmap::operator QVariant() const
406{
407 return QVariant(QMetaType::QPixmap, this);
408}
409
410/*!
411 \fn bool QPixmap::operator!() const
412
413 Returns \c true if this is a null pixmap; otherwise returns \c false.
414
415 \sa isNull()
416*/
417
418/*!
419 Converts the pixmap to a QImage. Returns a null image if the
420 conversion fails.
421
422 If the pixmap has 1-bit depth, the returned image will also be 1
423 bit deep. Images with more bits will be returned in a format
424 closely represents the underlying system. Usually this will be
425 QImage::Format_ARGB32_Premultiplied for pixmaps with an alpha and
426 QImage::Format_RGB32 or QImage::Format_RGB16 for pixmaps without
427 alpha.
428
429 Note that for the moment, alpha masks on monochrome images are
430 ignored.
431
432 \sa fromImage(), {QImage#Image Formats}{Image Formats}
433*/
434QImage QPixmap::toImage() const
435{
436 if (isNull())
437 return QImage();
438
439 return data->toImage();
440}
441
442/*!
443 \fn QTransform QPixmap::trueMatrix(const QTransform &matrix, int width, int height)
444
445 Returns the actual matrix used for transforming a pixmap with the
446 given \a width, \a height and \a matrix.
447
448 When transforming a pixmap using the transformed() function, the
449 transformation matrix is internally adjusted to compensate for
450 unwanted translation, i.e. transformed() returns the smallest
451 pixmap containing all transformed points of the original
452 pixmap. This function returns the modified matrix, which maps
453 points correctly from the original pixmap into the new pixmap.
454
455 \sa transformed(), {QPixmap#Pixmap Transformations}{Pixmap
456 Transformations}
457*/
458QTransform QPixmap::trueMatrix(const QTransform &m, int w, int h)
459{
460 return QImage::trueMatrix(m, w, h);
461}
462
463#if QT_DEPRECATED_SINCE(5, 15)
464/*!
465 \overload
466 \obsolete
467
468 Use trueMatrix(const QTransform &m, int w, int h) instead.
469
470 This convenience function loads the matrix \a m into a
471 QTransform and calls the overloaded function with the
472 QTransform and the width \a w and the height \a h.
473 */
474QMatrix QPixmap::trueMatrix(const QMatrix &m, int w, int h)
475{
476 return trueMatrix(m: QTransform(m), w, h).toAffine();
477}
478#endif // QT_DEPRECATED_SINCE(5, 15)
479
480
481/*!
482 \fn bool QPixmap::isQBitmap() const
483
484 Returns \c true if this is a QBitmap; otherwise returns \c false.
485*/
486
487bool QPixmap::isQBitmap() const
488{
489 return data && data->type == QPlatformPixmap::BitmapType;
490}
491
492/*!
493 \fn bool QPixmap::isNull() const
494
495 Returns \c true if this is a null pixmap; otherwise returns \c false.
496
497 A null pixmap has zero width, zero height and no contents. You
498 cannot draw in a null pixmap.
499*/
500bool QPixmap::isNull() const
501{
502 return !data || data->isNull();
503}
504
505/*!
506 \fn int QPixmap::width() const
507
508 Returns the width of the pixmap.
509
510 \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
511*/
512int QPixmap::width() const
513{
514 return data ? data->width() : 0;
515}
516
517/*!
518 \fn int QPixmap::height() const
519
520 Returns the height of the pixmap.
521
522 \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
523*/
524int QPixmap::height() const
525{
526 return data ? data->height() : 0;
527}
528
529/*!
530 \fn QSize QPixmap::size() const
531
532 Returns the size of the pixmap.
533
534 \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
535 Information}
536*/
537QSize QPixmap::size() const
538{
539 return data ? QSize(data->width(), data->height()) : QSize(0, 0);
540}
541
542/*!
543 \fn QRect QPixmap::rect() const
544
545 Returns the pixmap's enclosing rectangle.
546
547 \sa {QPixmap#Pixmap Information}{Pixmap Information}
548*/
549QRect QPixmap::rect() const
550{
551 return data ? QRect(0, 0, data->width(), data->height()) : QRect();
552}
553
554/*!
555 \fn int QPixmap::depth() const
556
557 Returns the depth of the pixmap.
558
559 The pixmap depth is also called bits per pixel (bpp) or bit planes
560 of a pixmap. A null pixmap has depth 0.
561
562 \sa defaultDepth(), {QPixmap#Pixmap Information}{Pixmap
563 Information}
564*/
565int QPixmap::depth() const
566{
567 return data ? data->depth() : 0;
568}
569
570/*!
571 Sets a mask bitmap.
572
573 This function merges the \a mask with the pixmap's alpha channel. A pixel
574 value of 1 on the mask means the pixmap's pixel is unchanged; a value of 0
575 means the pixel is transparent. The mask must have the same size as this
576 pixmap.
577
578 Setting a null mask resets the mask, leaving the previously transparent
579 pixels black. The effect of this function is undefined when the pixmap is
580 being painted on.
581
582 \warning This is potentially an expensive operation.
583
584 \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations},
585 QBitmap
586*/
587void QPixmap::setMask(const QBitmap &mask)
588{
589 if (paintingActive()) {
590 qWarning(msg: "QPixmap::setMask: Cannot set mask while pixmap is being painted on");
591 return;
592 }
593
594 if (!mask.isNull() && mask.size() != size()) {
595 qWarning(msg: "QPixmap::setMask() mask size differs from pixmap size");
596 return;
597 }
598
599 if (isNull())
600 return;
601
602 if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
603 return;
604
605 detach();
606 data->setMask(mask);
607}
608
609/*!
610 Returns the device pixel ratio for the pixmap. This is the
611 ratio between \e{device pixels} and \e{device independent pixels}.
612
613 Use this function when calculating layout geometry based on
614 the pixmap size: QSize layoutSize = image.size() / image.devicePixelRatio()
615
616 The default value is 1.0.
617
618 \sa setDevicePixelRatio(), QImageReader
619*/
620qreal QPixmap::devicePixelRatio() const
621{
622 if (!data)
623 return qreal(1.0);
624 return data->devicePixelRatio();
625}
626
627/*!
628 Sets the device pixel ratio for the pixmap. This is the
629 ratio between image pixels and device-independent pixels.
630
631 The default \a scaleFactor is 1.0. Setting it to something else has
632 two effects:
633
634 QPainters that are opened on the pixmap will be scaled. For
635 example, painting on a 200x200 image if with a ratio of 2.0
636 will result in effective (device-independent) painting bounds
637 of 100x100.
638
639 Code paths in Qt that calculate layout geometry based on the
640 pixmap size will take the ratio into account:
641 QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio()
642 The net effect of this is that the pixmap is displayed as
643 high-DPI pixmap rather than a large pixmap
644 (see \l{Drawing High Resolution Versions of Pixmaps and Images}).
645
646 \sa devicePixelRatio()
647*/
648void QPixmap::setDevicePixelRatio(qreal scaleFactor)
649{
650 if (isNull())
651 return;
652
653 if (scaleFactor == data->devicePixelRatio())
654 return;
655
656 detach();
657 data->setDevicePixelRatio(scaleFactor);
658}
659
660#ifndef QT_NO_IMAGE_HEURISTIC_MASK
661/*!
662 Creates and returns a heuristic mask for this pixmap.
663
664 The function works by selecting a color from one of the corners
665 and then chipping away pixels of that color, starting at all the
666 edges. If \a clipTight is true (the default) the mask is just
667 large enough to cover the pixels; otherwise, the mask is larger
668 than the data pixels.
669
670 The mask may not be perfect but it should be reasonable, so you
671 can do things such as the following:
672
673 \snippet code/src_gui_image_qpixmap.cpp 1
674
675 This function is slow because it involves converting to/from a
676 QImage, and non-trivial computations.
677
678 \sa QImage::createHeuristicMask(), createMaskFromColor()
679*/
680QBitmap QPixmap::createHeuristicMask(bool clipTight) const
681{
682 QBitmap m = QBitmap::fromImage(image: toImage().createHeuristicMask(clipTight));
683 return m;
684}
685#endif
686
687/*!
688 Creates and returns a mask for this pixmap based on the given \a
689 maskColor. If the \a mode is Qt::MaskInColor, all pixels matching the
690 maskColor will be transparent. If \a mode is Qt::MaskOutColor, all pixels
691 matching the maskColor will be opaque.
692
693 This function is slow because it involves converting to/from a
694 QImage.
695
696 \sa createHeuristicMask(), QImage::createMaskFromColor()
697*/
698QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
699{
700 QImage image = toImage().convertToFormat(f: QImage::Format_ARGB32);
701 return QBitmap::fromImage(image: std::move(image).createMaskFromColor(color: maskColor.rgba(), mode));
702}
703
704/*!
705 Loads a pixmap from the file with the given \a fileName. Returns
706 true if the pixmap was successfully loaded; otherwise invalidates
707 the pixmap and returns \c false.
708
709 The loader attempts to read the pixmap using the specified \a
710 format. If the \a format is not specified (which is the default),
711 the loader probes the file for a header to guess the file format.
712
713 The file name can either refer to an actual file on disk or to one
714 of the application's embedded resources. See the
715 \l{resources.html}{Resource System} overview for details on how to
716 embed pixmaps and other resource files in the application's
717 executable.
718
719 If the data needs to be modified to fit in a lower-resolution
720 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
721 control the conversion.
722
723 Note that QPixmaps are automatically added to the QPixmapCache
724 when loaded from a file in main thread; the key used is internal
725 and cannot be acquired.
726
727 \sa loadFromData(), {QPixmap#Reading and Writing Image
728 Files}{Reading and Writing Image Files}
729*/
730
731bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
732{
733 if (!fileName.isEmpty()) {
734
735 QFileInfo info(fileName);
736 // Note: If no extension is provided, we try to match the
737 // file against known plugin extensions
738 if (info.completeSuffix().isEmpty() || info.exists()) {
739 const bool inGuiThread = qApp->thread() == QThread::currentThread();
740
741 QString key = QLatin1String("qt_pixmap")
742 % info.absoluteFilePath()
743 % HexString<uint>(info.lastModified().toSecsSinceEpoch())
744 % HexString<quint64>(info.size())
745 % HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);
746
747 if (inGuiThread && QPixmapCache::find(key, pixmap: this))
748 return true;
749
750 data = QPlatformPixmap::create(w: 0, h: 0, type: data ? data->pixelType() : QPlatformPixmap::PixmapType);
751
752 if (data->fromFile(filename: fileName, format, flags)) {
753 if (inGuiThread)
754 QPixmapCache::insert(key, pixmap: *this);
755 return true;
756 }
757 }
758 }
759
760 if (!isNull()) {
761 if (isQBitmap())
762 *this = QBitmap();
763 else
764 data.reset();
765 }
766 return false;
767}
768
769/*!
770 \fn bool QPixmap::loadFromData(const uchar *data, uint len, const char *format, Qt::ImageConversionFlags flags)
771
772 Loads a pixmap from the \a len first bytes of the given binary \a
773 data. Returns \c true if the pixmap was loaded successfully;
774 otherwise invalidates the pixmap and returns \c false.
775
776 The loader attempts to read the pixmap using the specified \a
777 format. If the \a format is not specified (which is the default),
778 the loader probes the file for a header to guess the file format.
779
780 If the data needs to be modified to fit in a lower-resolution
781 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
782 control the conversion.
783
784 \sa load(), {QPixmap#Reading and Writing Image Files}{Reading and
785 Writing Image Files}
786*/
787
788bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
789{
790 if (len == 0 || buf == nullptr) {
791 data.reset();
792 return false;
793 }
794
795 data = QPlatformPixmap::create(w: 0, h: 0, type: QPlatformPixmap::PixmapType);
796
797 if (data->fromData(buffer: buf, len, format, flags))
798 return true;
799
800 data.reset();
801 return false;
802}
803
804/*!
805 \fn bool QPixmap::loadFromData(const QByteArray &data, const char *format, Qt::ImageConversionFlags flags)
806
807 \overload
808
809 Loads a pixmap from the binary \a data using the specified \a
810 format and conversion \a flags.
811*/
812
813
814/*!
815 Saves the pixmap to the file with the given \a fileName using the
816 specified image file \a format and \a quality factor. Returns \c true
817 if successful; otherwise returns \c false.
818
819 The \a quality factor must be in the range [0,100] or -1. Specify
820 0 to obtain small compressed files, 100 for large uncompressed
821 files, and -1 to use the default settings.
822
823 If \a format is \nullptr, an image format will be chosen from
824 \a fileName's suffix.
825
826 \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
827 Image Files}
828*/
829
830bool QPixmap::save(const QString &fileName, const char *format, int quality) const
831{
832 if (isNull())
833 return false; // nothing to save
834 QImageWriter writer(fileName, format);
835 return doImageIO(io: &writer, quality);
836}
837
838/*!
839 \overload
840
841 This function writes a QPixmap to the given \a device using the
842 specified image file \a format and \a quality factor. This can be
843 used, for example, to save a pixmap directly into a QByteArray:
844
845 \snippet image/image.cpp 1
846*/
847
848bool QPixmap::save(QIODevice* device, const char* format, int quality) const
849{
850 if (isNull())
851 return false; // nothing to save
852 QImageWriter writer(device, format);
853 return doImageIO(io: &writer, quality);
854}
855
856/*! \internal
857*/
858bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
859{
860 if (quality > 100 || quality < -1)
861 qWarning(msg: "QPixmap::save: quality out of range [-1,100]");
862 if (quality >= 0)
863 writer->setQuality(qMin(a: quality,b: 100));
864 return writer->write(image: toImage());
865}
866
867
868#if QT_DEPRECATED_SINCE(5, 13)
869/*!
870 \obsolete
871
872 Use QPainter or the fill(QColor) overload instead.
873*/
874
875void QPixmap::fill(const QPaintDevice *device, const QPoint &p)
876{
877 Q_UNUSED(device)
878 Q_UNUSED(p)
879 qWarning(msg: "this function is deprecated, ignored");
880}
881
882
883/*!
884 \fn void QPixmap::fill(const QPaintDevice *device, int x, int y)
885 \obsolete
886
887 Use QPainter or the fill(QColor) overload instead.
888*/
889void QPixmap::fill(const QPaintDevice *device, int xofs, int yofs)
890{
891 Q_UNUSED(device)
892 Q_UNUSED(xofs)
893 Q_UNUSED(yofs)
894 qWarning(msg: "this function is deprecated, ignored");
895}
896#endif
897
898
899/*!
900 Fills the pixmap with the given \a color.
901
902 The effect of this function is undefined when the pixmap is
903 being painted on.
904
905 \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}
906*/
907
908void QPixmap::fill(const QColor &color)
909{
910 if (isNull())
911 return;
912
913 // Some people are probably already calling fill while a painter is active, so to not break
914 // their programs, only print a warning and return when the fill operation could cause a crash.
915 if (paintingActive() && (color.alpha() != 255) && !hasAlphaChannel()) {
916 qWarning(msg: "QPixmap::fill: Cannot fill while pixmap is being painted on");
917 return;
918 }
919
920 if (data->ref.loadRelaxed() == 1) {
921 // detach() will also remove this pixmap from caches, so
922 // it has to be called even when ref == 1.
923 detach();
924 } else {
925 // Don't bother to make a copy of the data object, since
926 // it will be filled with new pixel data anyway.
927 QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
928 d->resize(width: data->width(), height: data->height());
929 d->setDevicePixelRatio(data->devicePixelRatio());
930 data = d;
931 }
932 data->fill(color);
933}
934
935/*! \fn int QPixmap::serialNumber() const
936 \obsolete
937 Returns a number that identifies the contents of this QPixmap
938 object. Distinct QPixmap objects can only have the same serial
939 number if they refer to the same contents (but they don't have
940 to).
941
942 Use cacheKey() instead.
943
944 \warning The serial number doesn't necessarily change when
945 the pixmap is altered. This means that it may be dangerous to use
946 it as a cache key. For caching pixmaps, we recommend using the
947 QPixmapCache class whenever possible.
948*/
949
950/*!
951 Returns a number that identifies this QPixmap. Distinct QPixmap
952 objects can only have the same cache key if they refer to the same
953 contents.
954
955 The cacheKey() will change when the pixmap is altered.
956*/
957qint64 QPixmap::cacheKey() const
958{
959 if (isNull())
960 return 0;
961
962 Q_ASSERT(data);
963 return data->cacheKey();
964}
965
966#if 0
967static void sendResizeEvents(QWidget *target)
968{
969 QResizeEvent e(target->size(), QSize());
970 QApplication::sendEvent(target, &e);
971
972 const QObjectList children = target->children();
973 for (int i = 0; i < children.size(); ++i) {
974 QWidget *child = static_cast<QWidget*>(children.at(i));
975 if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
976 sendResizeEvents(child);
977 }
978}
979#endif
980
981#if QT_DEPRECATED_SINCE(5, 13)
982/*!
983 \obsolete
984
985 Use QWidget::grab() instead.
986*/
987QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle)
988{
989 QPixmap pixmap;
990 qWarning(msg: "QPixmap::grabWidget is deprecated, use QWidget::grab() instead");
991 if (!widget)
992 return pixmap;
993 QMetaObject::invokeMethod(obj: widget, member: "grab", Qt::DirectConnection,
994 Q_RETURN_ARG(QPixmap, pixmap),
995 Q_ARG(QRect, rectangle));
996 return pixmap;
997}
998
999/*!
1000 \fn QPixmap QPixmap::grabWidget(QObject *widget, int x, int y, int w, int h)
1001 \obsolete
1002
1003 Use QWidget::grab() instead.
1004*/
1005QPixmap QPixmap::grabWidget(QObject *widget, int x, int y, int w, int h)
1006{
1007QT_WARNING_PUSH
1008QT_WARNING_DISABLE_DEPRECATED
1009 return grabWidget(widget, rectangle: QRect(x, y, w, h));
1010QT_WARNING_POP
1011}
1012#endif
1013
1014/*****************************************************************************
1015 QPixmap stream functions
1016 *****************************************************************************/
1017#if !defined(QT_NO_DATASTREAM)
1018/*!
1019 \relates QPixmap
1020
1021 Writes the given \a pixmap to the given \a stream as a PNG
1022 image. Note that writing the stream to a file will not produce a
1023 valid image file.
1024
1025 \sa QPixmap::save(), {Serializing Qt Data Types}
1026*/
1027
1028QDataStream &operator<<(QDataStream &stream, const QPixmap &pixmap)
1029{
1030 return stream << pixmap.toImage();
1031}
1032
1033/*!
1034 \relates QPixmap
1035
1036 Reads an image from the given \a stream into the given \a pixmap.
1037
1038 \sa QPixmap::load(), {Serializing Qt Data Types}
1039*/
1040
1041QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
1042{
1043 QImage image;
1044 stream >> image;
1045
1046 if (image.isNull()) {
1047 pixmap = QPixmap();
1048 } else if (image.depth() == 1) {
1049 pixmap = QBitmap::fromImage(image: std::move(image));
1050 } else {
1051 pixmap = QPixmap::fromImage(image: std::move(image));
1052 }
1053 return stream;
1054}
1055
1056#endif // QT_NO_DATASTREAM
1057
1058/*!
1059 \internal
1060*/
1061
1062bool QPixmap::isDetached() const
1063{
1064 return data && data->ref.loadRelaxed() == 1;
1065}
1066
1067/*!
1068 Replaces this pixmap's data with the given \a image using the
1069 specified \a flags to control the conversion. The \a flags
1070 argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
1071 Passing 0 for \a flags sets all the default options. Returns \c true
1072 if the result is that this pixmap is not null.
1073
1074 Note: this function was part of Qt 3 support in Qt 4.6 and earlier.
1075 It has been promoted to official API status in 4.7 to support updating
1076 the pixmap's image without creating a new QPixmap as fromImage() would.
1077
1078 \sa fromImage()
1079 \since 4.7
1080*/
1081bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
1082{
1083 detach();
1084 if (image.isNull() || !data)
1085 *this = QPixmap::fromImage(image, flags);
1086 else
1087 data->fromImage(image, flags);
1088 return !isNull();
1089}
1090
1091/*!
1092 \fn QPixmap QPixmap::scaled(int width, int height,
1093 Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode
1094 transformMode) const
1095
1096 \overload
1097
1098 Returns a copy of the pixmap scaled to a rectangle with the given
1099 \a width and \a height according to the given \a aspectRatioMode and
1100 \a transformMode.
1101
1102 If either the \a width or the \a height is zero or negative, this
1103 function returns a null pixmap.
1104*/
1105
1106/*!
1107 \fn QPixmap QPixmap::scaled(const QSize &size, Qt::AspectRatioMode
1108 aspectRatioMode, Qt::TransformationMode transformMode) const
1109
1110 Scales the pixmap to the given \a size, using the aspect ratio and
1111 transformation modes specified by \a aspectRatioMode and \a
1112 transformMode.
1113
1114 \image qimage-scaling.png
1115
1116 \list
1117 \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
1118 is scaled to \a size.
1119 \li If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
1120 scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
1121 \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
1122 the pixmap is scaled to a rectangle as small as possible
1123 outside \a size, preserving the aspect ratio.
1124 \endlist
1125
1126 If the given \a size is empty, this function returns a null
1127 pixmap.
1128
1129
1130 In some cases it can be more beneficial to draw the pixmap to a
1131 painter with a scale set rather than scaling the pixmap. This is
1132 the case when the painter is for instance based on OpenGL or when
1133 the scale factor changes rapidly.
1134
1135 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1136 Transformations}
1137
1138*/
1139QPixmap QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
1140{
1141 if (isNull()) {
1142 qWarning(msg: "QPixmap::scaled: Pixmap is a null pixmap");
1143 return QPixmap();
1144 }
1145 if (s.isEmpty())
1146 return QPixmap();
1147
1148 QSize newSize = size();
1149 newSize.scale(s, mode: aspectMode);
1150 newSize.rwidth() = qMax(a: newSize.width(), b: 1);
1151 newSize.rheight() = qMax(a: newSize.height(), b: 1);
1152 if (newSize == size())
1153 return *this;
1154
1155 Q_TRACE_SCOPE(QPixmap_scaled, s, aspectMode, mode);
1156
1157 QTransform wm = QTransform::fromScale(dx: (qreal)newSize.width() / width(),
1158 dy: (qreal)newSize.height() / height());
1159 QPixmap pix = transformed(wm, mode);
1160 return pix;
1161}
1162
1163/*!
1164 \fn QPixmap QPixmap::scaledToWidth(int width, Qt::TransformationMode
1165 mode) const
1166
1167 Returns a scaled copy of the image. The returned image is scaled
1168 to the given \a width using the specified transformation \a mode.
1169 The height of the pixmap is automatically calculated so that the
1170 aspect ratio of the pixmap is preserved.
1171
1172 If \a width is 0 or negative, a null pixmap is returned.
1173
1174 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1175 Transformations}
1176*/
1177QPixmap QPixmap::scaledToWidth(int w, Qt::TransformationMode mode) const
1178{
1179 if (isNull()) {
1180 qWarning(msg: "QPixmap::scaleWidth: Pixmap is a null pixmap");
1181 return copy();
1182 }
1183 if (w <= 0)
1184 return QPixmap();
1185
1186 Q_TRACE_SCOPE(QPixmap_scaledToWidth, w, mode);
1187
1188 qreal factor = (qreal) w / width();
1189 QTransform wm = QTransform::fromScale(dx: factor, dy: factor);
1190 return transformed(wm, mode);
1191}
1192
1193/*!
1194 \fn QPixmap QPixmap::scaledToHeight(int height,
1195 Qt::TransformationMode mode) const
1196
1197 Returns a scaled copy of the image. The returned image is scaled
1198 to the given \a height using the specified transformation \a mode.
1199 The width of the pixmap is automatically calculated so that the
1200 aspect ratio of the pixmap is preserved.
1201
1202 If \a height is 0 or negative, a null pixmap is returned.
1203
1204 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1205 Transformations}
1206*/
1207QPixmap QPixmap::scaledToHeight(int h, Qt::TransformationMode mode) const
1208{
1209 if (isNull()) {
1210 qWarning(msg: "QPixmap::scaleHeight: Pixmap is a null pixmap");
1211 return copy();
1212 }
1213 if (h <= 0)
1214 return QPixmap();
1215
1216 Q_TRACE_SCOPE(QPixmap_scaledToHeight, h, mode);
1217
1218 qreal factor = (qreal) h / height();
1219 QTransform wm = QTransform::fromScale(dx: factor, dy: factor);
1220 return transformed(wm, mode);
1221}
1222
1223/*!
1224 Returns a copy of the pixmap that is transformed using the given
1225 transformation \a transform and transformation \a mode. The original
1226 pixmap is not changed.
1227
1228 The transformation \a transform is internally adjusted to compensate
1229 for unwanted translation; i.e. the pixmap produced is the smallest
1230 pixmap that contains all the transformed points of the original
1231 pixmap. Use the trueMatrix() function to retrieve the actual
1232 matrix used for transforming the pixmap.
1233
1234 This function is slow because it involves transformation to a
1235 QImage, non-trivial computations and a transformation back to a
1236 QPixmap.
1237
1238 \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
1239 Transformations}
1240*/
1241QPixmap QPixmap::transformed(const QTransform &transform,
1242 Qt::TransformationMode mode) const
1243{
1244 if (isNull() || transform.type() <= QTransform::TxTranslate)
1245 return *this;
1246
1247 return data->transformed(matrix: transform, mode);
1248}
1249
1250#if QT_DEPRECATED_SINCE(5, 15)
1251/*!
1252 \overload
1253 \obsolete
1254
1255 Use transformed(const QTransform &transform, Qt::TransformationMode mode)() instead.
1256
1257 This convenience function loads the \a matrix into a
1258 QTransform and calls the overloaded function.
1259 */
1260QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) const
1261{
1262 return transformed(transform: QTransform(matrix), mode);
1263}
1264#endif // QT_DEPRECATED_SINCE(5, 15)
1265
1266
1267
1268
1269
1270
1271
1272
1273/*!
1274 \class QPixmap
1275 \inmodule QtGui
1276
1277 \brief The QPixmap class is an off-screen image representation
1278 that can be used as a paint device.
1279
1280 \ingroup painting
1281 \ingroup shared
1282
1283
1284 Qt provides four classes for handling image data: QImage, QPixmap,
1285 QBitmap and QPicture. QImage is designed and optimized for I/O,
1286 and for direct pixel access and manipulation, while QPixmap is
1287 designed and optimized for showing images on screen. QBitmap is
1288 only a convenience class that inherits QPixmap, ensuring a depth
1289 of 1. The isQBitmap() function returns \c true if a QPixmap object is
1290 really a bitmap, otherwise returns \c false. Finally, the QPicture class
1291 is a paint device that records and replays QPainter commands.
1292
1293 A QPixmap can easily be displayed on the screen using QLabel or
1294 one of QAbstractButton's subclasses (such as QPushButton and
1295 QToolButton). QLabel has a pixmap property, whereas
1296 QAbstractButton has an icon property.
1297
1298 QPixmap objects can be passed around by value since the QPixmap
1299 class uses implicit data sharing. For more information, see the \l
1300 {Implicit Data Sharing} documentation. QPixmap objects can also be
1301 streamed.
1302
1303 Note that the pixel data in a pixmap is internal and is managed by
1304 the underlying window system. Because QPixmap is a QPaintDevice
1305 subclass, QPainter can be used to draw directly onto pixmaps.
1306 Pixels can only be accessed through QPainter functions or by
1307 converting the QPixmap to a QImage. However, the fill() function
1308 is available for initializing the entire pixmap with a given color.
1309
1310 There are functions to convert between QImage and
1311 QPixmap. Typically, the QImage class is used to load an image
1312 file, optionally manipulating the image data, before the QImage
1313 object is converted into a QPixmap to be shown on
1314 screen. Alternatively, if no manipulation is desired, the image
1315 file can be loaded directly into a QPixmap.
1316
1317 QPixmap provides a collection of functions that can be used to
1318 obtain a variety of information about the pixmap. In addition,
1319 there are several functions that enables transformation of the
1320 pixmap.
1321
1322 \tableofcontents
1323
1324 \section1 Reading and Writing Image Files
1325
1326 QPixmap provides several ways of reading an image file: The file
1327 can be loaded when constructing the QPixmap object, or by using
1328 the load() or loadFromData() functions later on. When loading an
1329 image, the file name can either refer to an actual file on disk or
1330 to one of the application's embedded resources. See \l{The Qt
1331 Resource System} overview for details on how to embed images and
1332 other resource files in the application's executable.
1333
1334 Simply call the save() function to save a QPixmap object.
1335
1336 The complete list of supported file formats are available through
1337 the QImageReader::supportedImageFormats() and
1338 QImageWriter::supportedImageFormats() functions. New file formats
1339 can be added as plugins. By default, Qt supports the following
1340 formats:
1341
1342 \table
1343 \header \li Format \li Description \li Qt's support
1344 \row \li BMP \li Windows Bitmap \li Read/write
1345 \row \li GIF \li Graphic Interchange Format (optional) \li Read
1346 \row \li JPG \li Joint Photographic Experts Group \li Read/write
1347 \row \li JPEG \li Joint Photographic Experts Group \li Read/write
1348 \row \li PNG \li Portable Network Graphics \li Read/write
1349 \row \li PBM \li Portable Bitmap \li Read
1350 \row \li PGM \li Portable Graymap \li Read
1351 \row \li PPM \li Portable Pixmap \li Read/write
1352 \row \li XBM \li X11 Bitmap \li Read/write
1353 \row \li XPM \li X11 Pixmap \li Read/write
1354 \endtable
1355
1356 \section1 Pixmap Information
1357
1358 QPixmap provides a collection of functions that can be used to
1359 obtain a variety of information about the pixmap:
1360
1361 \table
1362 \header
1363 \li \li Available Functions
1364 \row
1365 \li Geometry
1366 \li
1367 The size(), width() and height() functions provide information
1368 about the pixmap's size. The rect() function returns the image's
1369 enclosing rectangle.
1370
1371 \row
1372 \li Alpha component
1373 \li
1374
1375 The hasAlphaChannel() returns \c true if the pixmap has a format that
1376 respects the alpha channel, otherwise returns \c false. The hasAlpha(),
1377 setMask() and mask() functions are legacy and should not be used.
1378 They are potentially very slow.
1379
1380 The createHeuristicMask() function creates and returns a 1-bpp
1381 heuristic mask (i.e. a QBitmap) for this pixmap. It works by
1382 selecting a color from one of the corners and then chipping away
1383 pixels of that color, starting at all the edges. The
1384 createMaskFromColor() function creates and returns a mask (i.e. a
1385 QBitmap) for the pixmap based on a given color.
1386
1387 \row
1388 \li Low-level information
1389 \li
1390
1391 The depth() function returns the depth of the pixmap. The
1392 defaultDepth() function returns the default depth, i.e. the depth
1393 used by the application on the given screen.
1394
1395 The cacheKey() function returns a number that uniquely
1396 identifies the contents of the QPixmap object.
1397
1398 \endtable
1399
1400 \section1 Pixmap Conversion
1401
1402 A QPixmap object can be converted into a QImage using the
1403 toImage() function. Likewise, a QImage can be converted into a
1404 QPixmap using the fromImage(). If this is too expensive an
1405 operation, you can use QBitmap::fromImage() instead.
1406
1407 To convert a QPixmap to and from HICON you can use the QtWinExtras
1408 functions QtWin::toHICON() and QtWin::fromHICON() respectively.
1409
1410 \section1 Pixmap Transformations
1411
1412 QPixmap supports a number of functions for creating a new pixmap
1413 that is a transformed version of the original:
1414
1415 The scaled(), scaledToWidth() and scaledToHeight() functions
1416 return scaled copies of the pixmap, while the copy() function
1417 creates a QPixmap that is a plain copy of the original one.
1418
1419 The transformed() function returns a copy of the pixmap that is
1420 transformed with the given transformation matrix and
1421 transformation mode: Internally, the transformation matrix is
1422 adjusted to compensate for unwanted translation,
1423 i.e. transformed() returns the smallest pixmap containing all
1424 transformed points of the original pixmap. The static trueMatrix()
1425 function returns the actual matrix used for transforming the
1426 pixmap.
1427
1428 \sa QBitmap, QImage, QImageReader, QImageWriter
1429*/
1430
1431
1432/*!
1433 \typedef QPixmap::DataPtr
1434 \internal
1435*/
1436
1437/*!
1438 \fn DataPtr &QPixmap::data_ptr()
1439 \internal
1440*/
1441
1442/*!
1443 Returns \c true if this pixmap has an alpha channel, \e or has a
1444 mask, otherwise returns \c false.
1445
1446 \sa hasAlphaChannel(), mask()
1447*/
1448bool QPixmap::hasAlpha() const
1449{
1450 return data && data->hasAlphaChannel();
1451}
1452
1453/*!
1454 Returns \c true if the pixmap has a format that respects the alpha
1455 channel, otherwise returns \c false.
1456
1457 \sa hasAlpha()
1458*/
1459bool QPixmap::hasAlphaChannel() const
1460{
1461 return data && data->hasAlphaChannel();
1462}
1463
1464/*!
1465 \internal
1466*/
1467int QPixmap::metric(PaintDeviceMetric metric) const
1468{
1469 return data ? data->metric(metric) : 0;
1470}
1471
1472/*!
1473 \internal
1474*/
1475QPaintEngine *QPixmap::paintEngine() const
1476{
1477 return data ? data->paintEngine() : nullptr;
1478}
1479
1480/*!
1481 \fn QBitmap QPixmap::mask() const
1482
1483 Extracts a bitmap mask from the pixmap's alpha channel.
1484
1485 \warning This is potentially an expensive operation. The mask of
1486 the pixmap is extracted dynamically from the pixeldata.
1487
1488 \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
1489*/
1490QBitmap QPixmap::mask() const
1491{
1492 return data ? data->mask() : QBitmap();
1493}
1494
1495/*!
1496 Returns the default pixmap depth used by the application.
1497
1498 On all platforms the depth of the primary screen will be returned.
1499
1500 \note QGuiApplication must be created before calling this function.
1501
1502 \sa depth(), QColormap::depth(), {QPixmap#Pixmap Information}{Pixmap Information}
1503
1504*/
1505int QPixmap::defaultDepth()
1506{
1507 QScreen *primary = QGuiApplication::primaryScreen();
1508 if (Q_LIKELY(primary))
1509 return primary->depth();
1510 qWarning(msg: "QPixmap: QGuiApplication must be created before calling defaultDepth().");
1511 return 0;
1512}
1513
1514/*!
1515 Detaches the pixmap from shared pixmap data.
1516
1517 A pixmap is automatically detached by Qt whenever its contents are
1518 about to change. This is done in almost all QPixmap member
1519 functions that modify the pixmap (fill(), fromImage(),
1520 load(), etc.), and in QPainter::begin() on a pixmap.
1521
1522 There are two exceptions in which detach() must be called
1523 explicitly, that is when calling the handle() or the
1524 x11PictureHandle() function (only available on X11). Otherwise,
1525 any modifications done using system calls, will be performed on
1526 the shared data.
1527
1528 The detach() function returns immediately if there is just a
1529 single reference or if the pixmap has not been initialized yet.
1530*/
1531void QPixmap::detach()
1532{
1533 if (!data)
1534 return;
1535
1536 // QPixmap.data member may be QRuntimePlatformPixmap so use handle() function to get
1537 // the actual underlaying runtime pixmap data.
1538 QPlatformPixmap *pd = handle();
1539 QPlatformPixmap::ClassId id = pd->classId();
1540 if (id == QPlatformPixmap::RasterClass) {
1541 QRasterPlatformPixmap *rasterData = static_cast<QRasterPlatformPixmap*>(pd);
1542 rasterData->image.detach();
1543 }
1544
1545 if (data->is_cached && data->ref.loadRelaxed() == 1)
1546 QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(data.data());
1547
1548 if (data->ref.loadRelaxed() != 1) {
1549 *this = copy();
1550 }
1551 ++data->detach_no;
1552}
1553
1554/*!
1555 \fn QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1556
1557 Converts the given \a image to a pixmap using the specified \a
1558 flags to control the conversion. The \a flags argument is a
1559 bitwise-OR of the \l{Qt::ImageConversionFlags}. Passing 0 for \a
1560 flags sets all the default options.
1561
1562 In case of monochrome and 8-bit images, the image is first
1563 converted to a 32-bit pixmap and then filled with the colors in
1564 the color table. If this is too expensive an operation, you can
1565 use QBitmap::fromImage() instead.
1566
1567 \sa fromImageReader(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1568*/
1569QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1570{
1571 if (image.isNull())
1572 return QPixmap();
1573
1574 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1575 qWarning(msg: "QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
1576 return QPixmap();
1577 }
1578
1579 QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1580 data->fromImage(image, flags);
1581 return QPixmap(data.take());
1582}
1583
1584/*!
1585 \fn QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
1586 \since 5.3
1587 \overload
1588
1589 Converts the given \a image to a pixmap without copying if possible.
1590*/
1591
1592
1593/*!
1594 \internal
1595*/
1596QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
1597{
1598 if (image.isNull())
1599 return QPixmap();
1600
1601 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1602 qWarning(msg: "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
1603 return QPixmap();
1604 }
1605
1606 QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1607 data->fromImageInPlace(image, flags);
1608 return QPixmap(data.take());
1609}
1610
1611/*!
1612 \fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1613
1614 Create a QPixmap from an image read directly from an \a imageReader.
1615 The \a flags argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
1616 Passing 0 for \a flags sets all the default options.
1617
1618 On some systems, reading an image directly to QPixmap can use less memory than
1619 reading a QImage to convert it to QPixmap.
1620
1621 \sa fromImage(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1622*/
1623QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1624{
1625 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1626 qWarning(msg: "QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
1627 return QPixmap();
1628 }
1629
1630 QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(type: QPlatformPixmap::PixmapType));
1631 data->fromImageReader(imageReader, flags);
1632 return QPixmap(data.take());
1633}
1634
1635#if QT_DEPRECATED_SINCE(5, 13)
1636/*!
1637 \fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int
1638 width, int height)
1639
1640 Creates and returns a pixmap constructed by grabbing the contents
1641 of the given \a window restricted by QRect(\a x, \a y, \a width,
1642 \a height).
1643
1644 The arguments (\a{x}, \a{y}) specify the offset in the window,
1645 whereas (\a{width}, \a{height}) specify the area to be copied. If
1646 \a width is negative, the function copies everything to the right
1647 border of the window. If \a height is negative, the function
1648 copies everything to the bottom of the window.
1649
1650 The window system identifier (\c WId) can be retrieved using the
1651 QWidget::winId() function. The rationale for using a window
1652 identifier and not a QWidget, is to enable grabbing of windows
1653 that are not part of the application, window system frames, and so
1654 on.
1655
1656 The grabWindow() function grabs pixels from the screen, not from
1657 the window, i.e. if there is another window partially or entirely
1658 over the one you grab, you get pixels from the overlying window,
1659 too. The mouse cursor is generally not grabbed.
1660
1661 Note on X11 that if the given \a window doesn't have the same depth
1662 as the root window, and another window partially or entirely
1663 obscures the one you grab, you will \e not get pixels from the
1664 overlying window. The contents of the obscured areas in the
1665 pixmap will be undefined and uninitialized.
1666
1667 On Windows Vista and above grabbing a layered window, which is
1668 created by setting the Qt::WA_TranslucentBackground attribute, will
1669 not work. Instead grabbing the desktop widget should work.
1670
1671 \warning In general, grabbing an area outside the screen is not
1672 safe. This depends on the underlying window system.
1673
1674 \warning The function is deprecated in Qt 5.0 since there might be
1675 platform plugins in which window system identifiers (\c WId)
1676 are local to a screen. Use QScreen::grabWindow() instead.
1677
1678 \sa grabWidget(), {Screenshot Example}
1679 \sa QScreen
1680 \deprecated
1681*/
1682
1683QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
1684{
1685 qWarning(msg: "this function is deprecated, use QScreen::grabWindow() instead."
1686 " Defaulting to primary screen.");
1687 return QGuiApplication::primaryScreen()->grabWindow(window, x, y, w, h);
1688}
1689#endif
1690
1691/*!
1692 \internal
1693*/
1694QPlatformPixmap* QPixmap::handle() const
1695{
1696 return data.data();
1697}
1698
1699#ifndef QT_NO_DEBUG_STREAM
1700QDebug operator<<(QDebug dbg, const QPixmap &r)
1701{
1702 QDebugStateSaver saver(dbg);
1703 dbg.resetFormat();
1704 dbg.nospace();
1705 dbg << "QPixmap(";
1706 if (r.isNull()) {
1707 dbg << "null";
1708 } else {
1709 dbg << r.size() << ",depth=" << r.depth()
1710 << ",devicePixelRatio=" << r.devicePixelRatio()
1711 << ",cacheKey=" << Qt::showbase << Qt::hex << r.cacheKey() << Qt::dec << Qt::noshowbase;
1712 }
1713 dbg << ')';
1714 return dbg;
1715}
1716#endif
1717
1718/*!
1719 \fn QPixmap QPixmap::alphaChannel() const
1720
1721 Most use cases for this can be achieved using a QPainter and QPainter::CompositionMode instead.
1722*/
1723
1724/*!
1725 \fn void QPixmap::setAlphaChannel(const QPixmap &p)
1726
1727 Most use cases for this can be achieved using \a p with QPainter and QPainter::CompositionMode instead.
1728*/
1729
1730QT_END_NAMESPACE
1731

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