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
71 QT_BEGIN_NAMESPACE
72
qt_pixmap_thread_test()73 static bool qt_pixmap_thread_test()
74 {
75 if (Q_UNLIKELY(!QCoreApplication::instance())) {
76 qFatal("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(QPlatformIntegration::ThreadedPixmaps)) {
83 printf("Platform plugin does not support threaded pixmaps!\n");
84 fail = true;
85 }
86 if (fail) {
87 qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread");
88 return false;
89 }
90 }
91 return true;
92 }
93
doInit(int w,int h,int type)94 void QPixmap::doInit(int w, int h, int type)
95 {
96 if ((w > 0 && h > 0) || type == QPlatformPixmap::BitmapType)
97 data = QPlatformPixmap::create(w, h, (QPlatformPixmap::PixelType) type);
98 else
99 data = nullptr;
100 }
101
102 /*!
103 Constructs a null pixmap.
104
105 \sa isNull()
106 */
107
QPixmap()108 QPixmap::QPixmap()
109 : QPaintDevice()
110 {
111 (void) qt_pixmap_thread_test();
112 doInit(0, 0, 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
QPixmap(int w,int h)129 QPixmap::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
QPixmap(const QSize & size)144 QPixmap::QPixmap(const QSize &size)
145 : QPixmap(size, QPlatformPixmap::PixmapType)
146 {
147 }
148
149 /*!
150 \internal
151 */
QPixmap(const QSize & s,int type)152 QPixmap::QPixmap(const QSize &s, int type)
153 {
154 if (!qt_pixmap_thread_test())
155 doInit(0, 0, static_cast<QPlatformPixmap::PixelType>(type));
156 else
157 doInit(s.width(), s.height(), static_cast<QPlatformPixmap::PixelType>(type));
158 }
159
160 /*!
161 \internal
162 */
QPixmap(QPlatformPixmap * d)163 QPixmap::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
QPixmap(const QString & fileName,const char * format,Qt::ImageConversionFlags flags)197 QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags)
198 : QPaintDevice()
199 {
200 doInit(0, 0, 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
QPixmap(const QPixmap & pixmap)213 QPixmap::QPixmap(const QPixmap &pixmap)
214 : QPaintDevice()
215 {
216 if (!qt_pixmap_thread_test()) {
217 doInit(0, 0, QPlatformPixmap::PixmapType);
218 return;
219 }
220 if (pixmap.paintingActive()) { // make a deep copy
221 pixmap.copy().swap(*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
QPixmap(const char * const xpm[])243 QPixmap::QPixmap(const char * const xpm[])
244 : QPaintDevice()
245 {
246 doInit(0, 0, 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(std::move(image));
254 else
255 *this = fromImage(std::move(image));
256 }
257 }
258 #endif
259
260
261 /*!
262 Destroys the pixmap.
263 */
264
~QPixmap()265 QPixmap::~QPixmap()
266 {
267 Q_ASSERT(!data || data->ref.loadRelaxed() >= 1); // Catch if ref-counting changes again
268 }
269
270 /*!
271 \internal
272 */
devType() const273 int 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 */
copy(const QRect & rect) const298 QPixmap 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(rect);
306
307 QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
308 d->copy(data.data(), 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 */
scroll(int dx,int dy,const QRect & rect,QRegion * exposed)335 void 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, -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, src)) {
350 // Fallback
351 QPixmap pix = *this;
352 QPainter painter(&pix);
353 painter.setCompositionMode(QPainter::CompositionMode_Source);
354 painter.drawPixmap(src.translated(dx, dy), *this, 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
operator =(const QPixmap & pixmap)372 QPixmap &QPixmap::operator=(const QPixmap &pixmap)
373 {
374 if (paintingActive()) {
375 qWarning("QPixmap::operator=: Cannot assign to pixmap during painting");
376 return *this;
377 }
378 if (pixmap.paintingActive()) { // make a deep copy
379 pixmap.copy().swap(*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 */
operator QVariant() const405 QPixmap::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 */
toImage() const434 QImage 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 */
trueMatrix(const QTransform & m,int w,int h)458 QTransform 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 */
trueMatrix(const QMatrix & m,int w,int h)474 QMatrix QPixmap::trueMatrix(const QMatrix &m, int w, int h)
475 {
476 return trueMatrix(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
isQBitmap() const487 bool 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 */
isNull() const500 bool 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 */
width() const512 int 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 */
height() const524 int 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 */
size() const537 QSize 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 */
rect() const549 QRect 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 */
depth() const565 int 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 */
setMask(const QBitmap & mask)587 void QPixmap::setMask(const QBitmap &mask)
588 {
589 if (paintingActive()) {
590 qWarning("QPixmap::setMask: Cannot set mask while pixmap is being painted on");
591 return;
592 }
593
594 if (!mask.isNull() && mask.size() != size()) {
595 qWarning("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 */
devicePixelRatio() const620 qreal 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 */
setDevicePixelRatio(qreal scaleFactor)648 void 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 */
createHeuristicMask(bool clipTight) const680 QBitmap QPixmap::createHeuristicMask(bool clipTight) const
681 {
682 QBitmap m = QBitmap::fromImage(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 */
createMaskFromColor(const QColor & maskColor,Qt::MaskMode mode) const698 QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
699 {
700 QImage image = toImage().convertToFormat(QImage::Format_ARGB32);
701 return QBitmap::fromImage(std::move(image).createMaskFromColor(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
load(const QString & fileName,const char * format,Qt::ImageConversionFlags flags)731 bool 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, this))
748 return true;
749
750 data = QPlatformPixmap::create(0, 0, data ? data->pixelType() : QPlatformPixmap::PixmapType);
751
752 if (data->fromFile(fileName, format, flags)) {
753 if (inGuiThread)
754 QPixmapCache::insert(key, *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
loadFromData(const uchar * buf,uint len,const char * format,Qt::ImageConversionFlags flags)788 bool 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(0, 0, QPlatformPixmap::PixmapType);
796
797 if (data->fromData(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
save(const QString & fileName,const char * format,int quality) const830 bool 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(&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
save(QIODevice * device,const char * format,int quality) const848 bool 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(&writer, quality);
854 }
855
856 /*! \internal
857 */
doImageIO(QImageWriter * writer,int quality) const858 bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
859 {
860 if (quality > 100 || quality < -1)
861 qWarning("QPixmap::save: quality out of range [-1,100]");
862 if (quality >= 0)
863 writer->setQuality(qMin(quality,100));
864 return writer->write(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
fill(const QPaintDevice * device,const QPoint & p)875 void QPixmap::fill(const QPaintDevice *device, const QPoint &p)
876 {
877 Q_UNUSED(device)
878 Q_UNUSED(p)
879 qWarning("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 */
fill(const QPaintDevice * device,int xofs,int yofs)889 void QPixmap::fill(const QPaintDevice *device, int xofs, int yofs)
890 {
891 Q_UNUSED(device)
892 Q_UNUSED(xofs)
893 Q_UNUSED(yofs)
894 qWarning("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
fill(const QColor & color)908 void 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("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(data->width(), data->height());
929 data = d;
930 }
931 data->fill(color);
932 }
933
934 /*! \fn int QPixmap::serialNumber() const
935 \obsolete
936 Returns a number that identifies the contents of this QPixmap
937 object. Distinct QPixmap objects can only have the same serial
938 number if they refer to the same contents (but they don't have
939 to).
940
941 Use cacheKey() instead.
942
943 \warning The serial number doesn't necessarily change when
944 the pixmap is altered. This means that it may be dangerous to use
945 it as a cache key. For caching pixmaps, we recommend using the
946 QPixmapCache class whenever possible.
947 */
948
949 /*!
950 Returns a number that identifies this QPixmap. Distinct QPixmap
951 objects can only have the same cache key if they refer to the same
952 contents.
953
954 The cacheKey() will change when the pixmap is altered.
955 */
cacheKey() const956 qint64 QPixmap::cacheKey() const
957 {
958 if (isNull())
959 return 0;
960
961 Q_ASSERT(data);
962 return data->cacheKey();
963 }
964
965 #if 0
966 static void sendResizeEvents(QWidget *target)
967 {
968 QResizeEvent e(target->size(), QSize());
969 QApplication::sendEvent(target, &e);
970
971 const QObjectList children = target->children();
972 for (int i = 0; i < children.size(); ++i) {
973 QWidget *child = static_cast<QWidget*>(children.at(i));
974 if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
975 sendResizeEvents(child);
976 }
977 }
978 #endif
979
980 #if QT_DEPRECATED_SINCE(5, 13)
981 /*!
982 \obsolete
983
984 Use QWidget::grab() instead.
985 */
grabWidget(QObject * widget,const QRect & rectangle)986 QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle)
987 {
988 QPixmap pixmap;
989 qWarning("QPixmap::grabWidget is deprecated, use QWidget::grab() instead");
990 if (!widget)
991 return pixmap;
992 QMetaObject::invokeMethod(widget, "grab", Qt::DirectConnection,
993 Q_RETURN_ARG(QPixmap, pixmap),
994 Q_ARG(QRect, rectangle));
995 return pixmap;
996 }
997
998 /*!
999 \fn QPixmap QPixmap::grabWidget(QObject *widget, int x, int y, int w, int h)
1000 \obsolete
1001
1002 Use QWidget::grab() instead.
1003 */
grabWidget(QObject * widget,int x,int y,int w,int h)1004 QPixmap QPixmap::grabWidget(QObject *widget, int x, int y, int w, int h)
1005 {
1006 QT_WARNING_PUSH
1007 QT_WARNING_DISABLE_DEPRECATED
1008 return grabWidget(widget, QRect(x, y, w, h));
1009 QT_WARNING_POP
1010 }
1011 #endif
1012
1013 /*****************************************************************************
1014 QPixmap stream functions
1015 *****************************************************************************/
1016 #if !defined(QT_NO_DATASTREAM)
1017 /*!
1018 \relates QPixmap
1019
1020 Writes the given \a pixmap to the given \a stream as a PNG
1021 image. Note that writing the stream to a file will not produce a
1022 valid image file.
1023
1024 \sa QPixmap::save(), {Serializing Qt Data Types}
1025 */
1026
operator <<(QDataStream & stream,const QPixmap & pixmap)1027 QDataStream &operator<<(QDataStream &stream, const QPixmap &pixmap)
1028 {
1029 return stream << pixmap.toImage();
1030 }
1031
1032 /*!
1033 \relates QPixmap
1034
1035 Reads an image from the given \a stream into the given \a pixmap.
1036
1037 \sa QPixmap::load(), {Serializing Qt Data Types}
1038 */
1039
operator >>(QDataStream & stream,QPixmap & pixmap)1040 QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
1041 {
1042 QImage image;
1043 stream >> image;
1044
1045 if (image.isNull()) {
1046 pixmap = QPixmap();
1047 } else if (image.depth() == 1) {
1048 pixmap = QBitmap::fromImage(std::move(image));
1049 } else {
1050 pixmap = QPixmap::fromImage(std::move(image));
1051 }
1052 return stream;
1053 }
1054
1055 #endif // QT_NO_DATASTREAM
1056
1057 /*!
1058 \internal
1059 */
1060
isDetached() const1061 bool QPixmap::isDetached() const
1062 {
1063 return data && data->ref.loadRelaxed() == 1;
1064 }
1065
1066 /*!
1067 Replaces this pixmap's data with the given \a image using the
1068 specified \a flags to control the conversion. The \a flags
1069 argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
1070 Passing 0 for \a flags sets all the default options. Returns \c true
1071 if the result is that this pixmap is not null.
1072
1073 Note: this function was part of Qt 3 support in Qt 4.6 and earlier.
1074 It has been promoted to official API status in 4.7 to support updating
1075 the pixmap's image without creating a new QPixmap as fromImage() would.
1076
1077 \sa fromImage()
1078 \since 4.7
1079 */
convertFromImage(const QImage & image,Qt::ImageConversionFlags flags)1080 bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
1081 {
1082 detach();
1083 if (image.isNull() || !data)
1084 *this = QPixmap::fromImage(image, flags);
1085 else
1086 data->fromImage(image, flags);
1087 return !isNull();
1088 }
1089
1090 /*!
1091 \fn QPixmap QPixmap::scaled(int width, int height,
1092 Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode
1093 transformMode) const
1094
1095 \overload
1096
1097 Returns a copy of the pixmap scaled to a rectangle with the given
1098 \a width and \a height according to the given \a aspectRatioMode and
1099 \a transformMode.
1100
1101 If either the \a width or the \a height is zero or negative, this
1102 function returns a null pixmap.
1103 */
1104
1105 /*!
1106 \fn QPixmap QPixmap::scaled(const QSize &size, Qt::AspectRatioMode
1107 aspectRatioMode, Qt::TransformationMode transformMode) const
1108
1109 Scales the pixmap to the given \a size, using the aspect ratio and
1110 transformation modes specified by \a aspectRatioMode and \a
1111 transformMode.
1112
1113 \image qimage-scaling.png
1114
1115 \list
1116 \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
1117 is scaled to \a size.
1118 \li If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
1119 scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
1120 \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
1121 the pixmap is scaled to a rectangle as small as possible
1122 outside \a size, preserving the aspect ratio.
1123 \endlist
1124
1125 If the given \a size is empty, this function returns a null
1126 pixmap.
1127
1128
1129 In some cases it can be more beneficial to draw the pixmap to a
1130 painter with a scale set rather than scaling the pixmap. This is
1131 the case when the painter is for instance based on OpenGL or when
1132 the scale factor changes rapidly.
1133
1134 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1135 Transformations}
1136
1137 */
scaled(const QSize & s,Qt::AspectRatioMode aspectMode,Qt::TransformationMode mode) const1138 QPixmap QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
1139 {
1140 if (isNull()) {
1141 qWarning("QPixmap::scaled: Pixmap is a null pixmap");
1142 return QPixmap();
1143 }
1144 if (s.isEmpty())
1145 return QPixmap();
1146
1147 QSize newSize = size();
1148 newSize.scale(s, aspectMode);
1149 newSize.rwidth() = qMax(newSize.width(), 1);
1150 newSize.rheight() = qMax(newSize.height(), 1);
1151 if (newSize == size())
1152 return *this;
1153
1154 Q_TRACE_SCOPE(QPixmap_scaled, s, aspectMode, mode);
1155
1156 QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(),
1157 (qreal)newSize.height() / height());
1158 QPixmap pix = transformed(wm, mode);
1159 return pix;
1160 }
1161
1162 /*!
1163 \fn QPixmap QPixmap::scaledToWidth(int width, Qt::TransformationMode
1164 mode) const
1165
1166 Returns a scaled copy of the image. The returned image is scaled
1167 to the given \a width using the specified transformation \a mode.
1168 The height of the pixmap is automatically calculated so that the
1169 aspect ratio of the pixmap is preserved.
1170
1171 If \a width is 0 or negative, a null pixmap is returned.
1172
1173 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1174 Transformations}
1175 */
scaledToWidth(int w,Qt::TransformationMode mode) const1176 QPixmap QPixmap::scaledToWidth(int w, Qt::TransformationMode mode) const
1177 {
1178 if (isNull()) {
1179 qWarning("QPixmap::scaleWidth: Pixmap is a null pixmap");
1180 return copy();
1181 }
1182 if (w <= 0)
1183 return QPixmap();
1184
1185 Q_TRACE_SCOPE(QPixmap_scaledToWidth, w, mode);
1186
1187 qreal factor = (qreal) w / width();
1188 QTransform wm = QTransform::fromScale(factor, factor);
1189 return transformed(wm, mode);
1190 }
1191
1192 /*!
1193 \fn QPixmap QPixmap::scaledToHeight(int height,
1194 Qt::TransformationMode mode) const
1195
1196 Returns a scaled copy of the image. The returned image is scaled
1197 to the given \a height using the specified transformation \a mode.
1198 The width of the pixmap is automatically calculated so that the
1199 aspect ratio of the pixmap is preserved.
1200
1201 If \a height is 0 or negative, a null pixmap is returned.
1202
1203 \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1204 Transformations}
1205 */
scaledToHeight(int h,Qt::TransformationMode mode) const1206 QPixmap QPixmap::scaledToHeight(int h, Qt::TransformationMode mode) const
1207 {
1208 if (isNull()) {
1209 qWarning("QPixmap::scaleHeight: Pixmap is a null pixmap");
1210 return copy();
1211 }
1212 if (h <= 0)
1213 return QPixmap();
1214
1215 Q_TRACE_SCOPE(QPixmap_scaledToHeight, h, mode);
1216
1217 qreal factor = (qreal) h / height();
1218 QTransform wm = QTransform::fromScale(factor, factor);
1219 return transformed(wm, mode);
1220 }
1221
1222 /*!
1223 Returns a copy of the pixmap that is transformed using the given
1224 transformation \a transform and transformation \a mode. The original
1225 pixmap is not changed.
1226
1227 The transformation \a transform is internally adjusted to compensate
1228 for unwanted translation; i.e. the pixmap produced is the smallest
1229 pixmap that contains all the transformed points of the original
1230 pixmap. Use the trueMatrix() function to retrieve the actual
1231 matrix used for transforming the pixmap.
1232
1233 This function is slow because it involves transformation to a
1234 QImage, non-trivial computations and a transformation back to a
1235 QPixmap.
1236
1237 \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
1238 Transformations}
1239 */
transformed(const QTransform & transform,Qt::TransformationMode mode) const1240 QPixmap QPixmap::transformed(const QTransform &transform,
1241 Qt::TransformationMode mode) const
1242 {
1243 if (isNull() || transform.type() <= QTransform::TxTranslate)
1244 return *this;
1245
1246 return data->transformed(transform, mode);
1247 }
1248
1249 #if QT_DEPRECATED_SINCE(5, 15)
1250 /*!
1251 \overload
1252 \obsolete
1253
1254 Use transformed(const QTransform &transform, Qt::TransformationMode mode)() instead.
1255
1256 This convenience function loads the \a matrix into a
1257 QTransform and calls the overloaded function.
1258 */
transformed(const QMatrix & matrix,Qt::TransformationMode mode) const1259 QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) const
1260 {
1261 return transformed(QTransform(matrix), mode);
1262 }
1263 #endif // QT_DEPRECATED_SINCE(5, 15)
1264
1265
1266
1267
1268
1269
1270
1271
1272 /*!
1273 \class QPixmap
1274 \inmodule QtGui
1275
1276 \brief The QPixmap class is an off-screen image representation
1277 that can be used as a paint device.
1278
1279 \ingroup painting
1280 \ingroup shared
1281
1282
1283 Qt provides four classes for handling image data: QImage, QPixmap,
1284 QBitmap and QPicture. QImage is designed and optimized for I/O,
1285 and for direct pixel access and manipulation, while QPixmap is
1286 designed and optimized for showing images on screen. QBitmap is
1287 only a convenience class that inherits QPixmap, ensuring a depth
1288 of 1. The isQBitmap() function returns \c true if a QPixmap object is
1289 really a bitmap, otherwise returns \c false. Finally, the QPicture class
1290 is a paint device that records and replays QPainter commands.
1291
1292 A QPixmap can easily be displayed on the screen using QLabel or
1293 one of QAbstractButton's subclasses (such as QPushButton and
1294 QToolButton). QLabel has a pixmap property, whereas
1295 QAbstractButton has an icon property.
1296
1297 QPixmap objects can be passed around by value since the QPixmap
1298 class uses implicit data sharing. For more information, see the \l
1299 {Implicit Data Sharing} documentation. QPixmap objects can also be
1300 streamed.
1301
1302 Note that the pixel data in a pixmap is internal and is managed by
1303 the underlying window system. Because QPixmap is a QPaintDevice
1304 subclass, QPainter can be used to draw directly onto pixmaps.
1305 Pixels can only be accessed through QPainter functions or by
1306 converting the QPixmap to a QImage. However, the fill() function
1307 is available for initializing the entire pixmap with a given color.
1308
1309 There are functions to convert between QImage and
1310 QPixmap. Typically, the QImage class is used to load an image
1311 file, optionally manipulating the image data, before the QImage
1312 object is converted into a QPixmap to be shown on
1313 screen. Alternatively, if no manipulation is desired, the image
1314 file can be loaded directly into a QPixmap.
1315
1316 QPixmap provides a collection of functions that can be used to
1317 obtain a variety of information about the pixmap. In addition,
1318 there are several functions that enables transformation of the
1319 pixmap.
1320
1321 \tableofcontents
1322
1323 \section1 Reading and Writing Image Files
1324
1325 QPixmap provides several ways of reading an image file: The file
1326 can be loaded when constructing the QPixmap object, or by using
1327 the load() or loadFromData() functions later on. When loading an
1328 image, the file name can either refer to an actual file on disk or
1329 to one of the application's embedded resources. See \l{The Qt
1330 Resource System} overview for details on how to embed images and
1331 other resource files in the application's executable.
1332
1333 Simply call the save() function to save a QPixmap object.
1334
1335 The complete list of supported file formats are available through
1336 the QImageReader::supportedImageFormats() and
1337 QImageWriter::supportedImageFormats() functions. New file formats
1338 can be added as plugins. By default, Qt supports the following
1339 formats:
1340
1341 \table
1342 \header \li Format \li Description \li Qt's support
1343 \row \li BMP \li Windows Bitmap \li Read/write
1344 \row \li GIF \li Graphic Interchange Format (optional) \li Read
1345 \row \li JPG \li Joint Photographic Experts Group \li Read/write
1346 \row \li JPEG \li Joint Photographic Experts Group \li Read/write
1347 \row \li PNG \li Portable Network Graphics \li Read/write
1348 \row \li PBM \li Portable Bitmap \li Read
1349 \row \li PGM \li Portable Graymap \li Read
1350 \row \li PPM \li Portable Pixmap \li Read/write
1351 \row \li XBM \li X11 Bitmap \li Read/write
1352 \row \li XPM \li X11 Pixmap \li Read/write
1353 \endtable
1354
1355 \section1 Pixmap Information
1356
1357 QPixmap provides a collection of functions that can be used to
1358 obtain a variety of information about the pixmap:
1359
1360 \table
1361 \header
1362 \li \li Available Functions
1363 \row
1364 \li Geometry
1365 \li
1366 The size(), width() and height() functions provide information
1367 about the pixmap's size. The rect() function returns the image's
1368 enclosing rectangle.
1369
1370 \row
1371 \li Alpha component
1372 \li
1373
1374 The hasAlphaChannel() returns \c true if the pixmap has a format that
1375 respects the alpha channel, otherwise returns \c false. The hasAlpha(),
1376 setMask() and mask() functions are legacy and should not be used.
1377 They are potentially very slow.
1378
1379 The createHeuristicMask() function creates and returns a 1-bpp
1380 heuristic mask (i.e. a QBitmap) for this pixmap. It works by
1381 selecting a color from one of the corners and then chipping away
1382 pixels of that color, starting at all the edges. The
1383 createMaskFromColor() function creates and returns a mask (i.e. a
1384 QBitmap) for the pixmap based on a given color.
1385
1386 \row
1387 \li Low-level information
1388 \li
1389
1390 The depth() function returns the depth of the pixmap. The
1391 defaultDepth() function returns the default depth, i.e. the depth
1392 used by the application on the given screen.
1393
1394 The cacheKey() function returns a number that uniquely
1395 identifies the contents of the QPixmap object.
1396
1397 \endtable
1398
1399 \section1 Pixmap Conversion
1400
1401 A QPixmap object can be converted into a QImage using the
1402 toImage() function. Likewise, a QImage can be converted into a
1403 QPixmap using the fromImage(). If this is too expensive an
1404 operation, you can use QBitmap::fromImage() instead.
1405
1406 To convert a QPixmap to and from HICON you can use the QtWinExtras
1407 functions QtWin::toHICON() and QtWin::fromHICON() respectively.
1408
1409 \section1 Pixmap Transformations
1410
1411 QPixmap supports a number of functions for creating a new pixmap
1412 that is a transformed version of the original:
1413
1414 The scaled(), scaledToWidth() and scaledToHeight() functions
1415 return scaled copies of the pixmap, while the copy() function
1416 creates a QPixmap that is a plain copy of the original one.
1417
1418 The transformed() function returns a copy of the pixmap that is
1419 transformed with the given transformation matrix and
1420 transformation mode: Internally, the transformation matrix is
1421 adjusted to compensate for unwanted translation,
1422 i.e. transformed() returns the smallest pixmap containing all
1423 transformed points of the original pixmap. The static trueMatrix()
1424 function returns the actual matrix used for transforming the
1425 pixmap.
1426
1427 \sa QBitmap, QImage, QImageReader, QImageWriter
1428 */
1429
1430
1431 /*!
1432 \typedef QPixmap::DataPtr
1433 \internal
1434 */
1435
1436 /*!
1437 \fn DataPtr &QPixmap::data_ptr()
1438 \internal
1439 */
1440
1441 /*!
1442 Returns \c true if this pixmap has an alpha channel, \e or has a
1443 mask, otherwise returns \c false.
1444
1445 \sa hasAlphaChannel(), mask()
1446 */
hasAlpha() const1447 bool QPixmap::hasAlpha() const
1448 {
1449 return data && data->hasAlphaChannel();
1450 }
1451
1452 /*!
1453 Returns \c true if the pixmap has a format that respects the alpha
1454 channel, otherwise returns \c false.
1455
1456 \sa hasAlpha()
1457 */
hasAlphaChannel() const1458 bool QPixmap::hasAlphaChannel() const
1459 {
1460 return data && data->hasAlphaChannel();
1461 }
1462
1463 /*!
1464 \internal
1465 */
metric(PaintDeviceMetric metric) const1466 int QPixmap::metric(PaintDeviceMetric metric) const
1467 {
1468 return data ? data->metric(metric) : 0;
1469 }
1470
1471 /*!
1472 \internal
1473 */
paintEngine() const1474 QPaintEngine *QPixmap::paintEngine() const
1475 {
1476 return data ? data->paintEngine() : nullptr;
1477 }
1478
1479 /*!
1480 \fn QBitmap QPixmap::mask() const
1481
1482 Extracts a bitmap mask from the pixmap's alpha channel.
1483
1484 \warning This is potentially an expensive operation. The mask of
1485 the pixmap is extracted dynamically from the pixeldata.
1486
1487 \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
1488 */
mask() const1489 QBitmap QPixmap::mask() const
1490 {
1491 return data ? data->mask() : QBitmap();
1492 }
1493
1494 /*!
1495 Returns the default pixmap depth used by the application.
1496
1497 On all platforms the depth of the primary screen will be returned.
1498
1499 \note QGuiApplication must be created before calling this function.
1500
1501 \sa depth(), QColormap::depth(), {QPixmap#Pixmap Information}{Pixmap Information}
1502
1503 */
defaultDepth()1504 int QPixmap::defaultDepth()
1505 {
1506 QScreen *primary = QGuiApplication::primaryScreen();
1507 if (Q_LIKELY(primary))
1508 return primary->depth();
1509 qWarning("QPixmap: QGuiApplication must be created before calling defaultDepth().");
1510 return 0;
1511 }
1512
1513 /*!
1514 Detaches the pixmap from shared pixmap data.
1515
1516 A pixmap is automatically detached by Qt whenever its contents are
1517 about to change. This is done in almost all QPixmap member
1518 functions that modify the pixmap (fill(), fromImage(),
1519 load(), etc.), and in QPainter::begin() on a pixmap.
1520
1521 There are two exceptions in which detach() must be called
1522 explicitly, that is when calling the handle() or the
1523 x11PictureHandle() function (only available on X11). Otherwise,
1524 any modifications done using system calls, will be performed on
1525 the shared data.
1526
1527 The detach() function returns immediately if there is just a
1528 single reference or if the pixmap has not been initialized yet.
1529 */
detach()1530 void QPixmap::detach()
1531 {
1532 if (!data)
1533 return;
1534
1535 // QPixmap.data member may be QRuntimePlatformPixmap so use handle() function to get
1536 // the actual underlaying runtime pixmap data.
1537 QPlatformPixmap *pd = handle();
1538 QPlatformPixmap::ClassId id = pd->classId();
1539 if (id == QPlatformPixmap::RasterClass) {
1540 QRasterPlatformPixmap *rasterData = static_cast<QRasterPlatformPixmap*>(pd);
1541 rasterData->image.detach();
1542 }
1543
1544 if (data->is_cached && data->ref.loadRelaxed() == 1)
1545 QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(data.data());
1546
1547 if (data->ref.loadRelaxed() != 1) {
1548 *this = copy();
1549 }
1550 ++data->detach_no;
1551 }
1552
1553 /*!
1554 \fn QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1555
1556 Converts the given \a image to a pixmap using the specified \a
1557 flags to control the conversion. The \a flags argument is a
1558 bitwise-OR of the \l{Qt::ImageConversionFlags}. Passing 0 for \a
1559 flags sets all the default options.
1560
1561 In case of monochrome and 8-bit images, the image is first
1562 converted to a 32-bit pixmap and then filled with the colors in
1563 the color table. If this is too expensive an operation, you can
1564 use QBitmap::fromImage() instead.
1565
1566 \sa fromImageReader(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1567 */
fromImage(const QImage & image,Qt::ImageConversionFlags flags)1568 QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1569 {
1570 if (image.isNull())
1571 return QPixmap();
1572
1573 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1574 qWarning("QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
1575 return QPixmap();
1576 }
1577
1578 QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
1579 data->fromImage(image, flags);
1580 return QPixmap(data.take());
1581 }
1582
1583 /*!
1584 \fn QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
1585 \since 5.3
1586 \overload
1587
1588 Converts the given \a image to a pixmap without copying if possible.
1589 */
1590
1591
1592 /*!
1593 \internal
1594 */
fromImageInPlace(QImage & image,Qt::ImageConversionFlags flags)1595 QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
1596 {
1597 if (image.isNull())
1598 return QPixmap();
1599
1600 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1601 qWarning("QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
1602 return QPixmap();
1603 }
1604
1605 QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
1606 data->fromImageInPlace(image, flags);
1607 return QPixmap(data.take());
1608 }
1609
1610 /*!
1611 \fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1612
1613 Create a QPixmap from an image read directly from an \a imageReader.
1614 The \a flags argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
1615 Passing 0 for \a flags sets all the default options.
1616
1617 On some systems, reading an image directly to QPixmap can use less memory than
1618 reading a QImage to convert it to QPixmap.
1619
1620 \sa fromImage(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1621 */
fromImageReader(QImageReader * imageReader,Qt::ImageConversionFlags flags)1622 QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1623 {
1624 if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1625 qWarning("QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
1626 return QPixmap();
1627 }
1628
1629 QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
1630 data->fromImageReader(imageReader, flags);
1631 return QPixmap(data.take());
1632 }
1633
1634 #if QT_DEPRECATED_SINCE(5, 13)
1635 /*!
1636 \fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int
1637 width, int height)
1638
1639 Creates and returns a pixmap constructed by grabbing the contents
1640 of the given \a window restricted by QRect(\a x, \a y, \a width,
1641 \a height).
1642
1643 The arguments (\a{x}, \a{y}) specify the offset in the window,
1644 whereas (\a{width}, \a{height}) specify the area to be copied. If
1645 \a width is negative, the function copies everything to the right
1646 border of the window. If \a height is negative, the function
1647 copies everything to the bottom of the window.
1648
1649 The window system identifier (\c WId) can be retrieved using the
1650 QWidget::winId() function. The rationale for using a window
1651 identifier and not a QWidget, is to enable grabbing of windows
1652 that are not part of the application, window system frames, and so
1653 on.
1654
1655 The grabWindow() function grabs pixels from the screen, not from
1656 the window, i.e. if there is another window partially or entirely
1657 over the one you grab, you get pixels from the overlying window,
1658 too. The mouse cursor is generally not grabbed.
1659
1660 Note on X11 that if the given \a window doesn't have the same depth
1661 as the root window, and another window partially or entirely
1662 obscures the one you grab, you will \e not get pixels from the
1663 overlying window. The contents of the obscured areas in the
1664 pixmap will be undefined and uninitialized.
1665
1666 On Windows Vista and above grabbing a layered window, which is
1667 created by setting the Qt::WA_TranslucentBackground attribute, will
1668 not work. Instead grabbing the desktop widget should work.
1669
1670 \warning In general, grabbing an area outside the screen is not
1671 safe. This depends on the underlying window system.
1672
1673 \warning The function is deprecated in Qt 5.0 since there might be
1674 platform plugins in which window system identifiers (\c WId)
1675 are local to a screen. Use QScreen::grabWindow() instead.
1676
1677 \sa grabWidget(), {Screenshot Example}
1678 \sa QScreen
1679 \deprecated
1680 */
1681
grabWindow(WId window,int x,int y,int w,int h)1682 QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
1683 {
1684 qWarning("this function is deprecated, use QScreen::grabWindow() instead."
1685 " Defaulting to primary screen.");
1686 return QGuiApplication::primaryScreen()->grabWindow(window, x, y, w, h);
1687 }
1688 #endif
1689
1690 /*!
1691 \internal
1692 */
handle() const1693 QPlatformPixmap* QPixmap::handle() const
1694 {
1695 return data.data();
1696 }
1697
1698 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QPixmap & r)1699 QDebug operator<<(QDebug dbg, const QPixmap &r)
1700 {
1701 QDebugStateSaver saver(dbg);
1702 dbg.resetFormat();
1703 dbg.nospace();
1704 dbg << "QPixmap(";
1705 if (r.isNull()) {
1706 dbg << "null";
1707 } else {
1708 dbg << r.size() << ",depth=" << r.depth()
1709 << ",devicePixelRatio=" << r.devicePixelRatio()
1710 << ",cacheKey=" << Qt::showbase << Qt::hex << r.cacheKey() << Qt::dec << Qt::noshowbase;
1711 }
1712 dbg << ')';
1713 return dbg;
1714 }
1715 #endif
1716
1717 /*!
1718 \fn QPixmap QPixmap::alphaChannel() const
1719
1720 Most use cases for this can be achieved using a QPainter and QPainter::CompositionMode instead.
1721 */
1722
1723 /*!
1724 \fn void QPixmap::setAlphaChannel(const QPixmap &p)
1725
1726 Most use cases for this can be achieved using \a p with QPainter and QPainter::CompositionMode instead.
1727 */
1728
1729 QT_END_NAMESPACE
1730