Coverage Report

Created: 2026-02-10 07:39

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