/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qglobal.h>

#include "qpixmap.h"
#include <qpa/qplatformpixmap.h>
#include "qimagepixmapcleanuphooks_p.h"

#include "qbitmap.h"
#include "qimage.h"
#include "qpainter.h"
#include "qdatastream.h"
#include "qbuffer.h"
#include <private/qguiapplication_p.h>
#include "qevent.h"
#include "qfile.h"
#include "qfileinfo.h"
#include "qpixmapcache.h"
#include "qdatetime.h"
#include "qimagereader.h"
#include "qimagewriter.h"
#include "qpaintengine.h"
#include "qscreen.h"
#include "qthread.h"
#include "qdebug.h"

#include <qpa/qplatformintegration.h>

#include "qpixmap_raster_p.h"
#include "private/qhexstring_p.h"

#include <qtgui_tracepoints_p.h>

QT_BEGIN_NAMESPACE

static bool qt_pixmap_thread_test()
{
    if (Q_UNLIKELY(!QCoreApplication::instance())) {
        qFatal("QPixmap: Must construct a QGuiApplication before a QPixmap");
        return false;
    }

    if (qApp->thread() != QThread::currentThread()) {
        bool fail = false;
        if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) {
            printf("Platform plugin does not support threaded pixmaps!\n");
            fail = true;
        }
        if (fail) {
            qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread");
            return false;
        }
    }
    return true;
}

void QPixmap::doInit(int w, int h, int type)
{
    if ((w > 0 && h > 0) || type == QPlatformPixmap::BitmapType)
        data = QPlatformPixmap::create(w, h, (QPlatformPixmap::PixelType) type);
    else
        data = nullptr;
}

/*!
    Constructs a null pixmap.

    \sa isNull()
*/

QPixmap::QPixmap()
    : QPaintDevice()
{
    (void) qt_pixmap_thread_test();
    doInit(0, 0, QPlatformPixmap::PixmapType);
}

/*!
    \fn QPixmap::QPixmap(int width, int height)

    Constructs a pixmap with the given \a width and \a height. If
    either \a width or \a height is zero, a null pixmap is
    constructed.

    \warning This will create a QPixmap with uninitialized data. Call
    fill() to fill the pixmap with an appropriate color before drawing
    onto it with QPainter.

    \sa isNull()
*/

QPixmap::QPixmap(int w, int h)
    : QPixmap(QSize(w, h))
{
}

/*!
    \overload

    Constructs a pixmap of the given \a size.

    \warning This will create a QPixmap with uninitialized data. Call
    fill() to fill the pixmap with an appropriate color before drawing
    onto it with QPainter.
*/

QPixmap::QPixmap(const QSize &size)
    : QPixmap(size, QPlatformPixmap::PixmapType)
{
}

/*!
  \internal
*/
QPixmap::QPixmap(const QSize &s, int type)
{
    if (!qt_pixmap_thread_test())
        doInit(0, 0, static_cast<QPlatformPixmap::PixelType>(type));
    else
        doInit(s.width(), s.height(), static_cast<QPlatformPixmap::PixelType>(type));
}

/*!
    \internal
*/
QPixmap::QPixmap(QPlatformPixmap *d)
    : QPaintDevice(), data(d)
{
}

/*!
    Constructs a pixmap from the file with the given \a fileName. If the
    file does not exist or is of an unknown format, the pixmap becomes a
    null pixmap.

    The loader attempts to read the pixmap using the specified \a
    format. If the \a format is not specified (which is the default),
    the loader probes the file for a header to guess the file format.

    The file name can either refer to an actual file on disk or to
    one of the application's embedded resources. See the
    \l{resources.html}{Resource System} overview for details on how
    to embed images and other resource files in the application's
    executable.

    If the image needs to be modified to fit in a lower-resolution
    result (e.g. converting from 32-bit to 8-bit), use the \a
    flags to control the conversion.

    The \a fileName, \a format and \a flags parameters are
    passed on to load(). This means that the data in \a fileName is
    not compiled into the binary. If \a fileName contains a relative
    path (e.g. the filename only) the relevant file must be found
    relative to the runtime working directory.

    \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
    Image Files}
*/

QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags)
    : QPaintDevice()
{
    doInit(0, 0, QPlatformPixmap::PixmapType);
    if (!qt_pixmap_thread_test())
        return;

    load(fileName, format, flags);
}

/*!
    Constructs a pixmap that is a copy of the given \a pixmap.

    \sa copy()
*/

QPixmap::QPixmap(const QPixmap &pixmap)
    : QPaintDevice()
{
    if (!qt_pixmap_thread_test()) {
        doInit(0, 0, QPlatformPixmap::PixmapType);
        return;
    }
    if (pixmap.paintingActive()) {                // make a deep copy
        pixmap.copy().swap(*this);
    } else {
        data = pixmap.data;
    }
}

/*!
    Constructs a pixmap from the given \a xpm data, which must be a
    valid XPM image.

    Errors are silently ignored.

    Note that it's possible to squeeze the XPM variable a little bit
    by using an unusual declaration:

    \snippet code/src_gui_image_qpixmap.cpp 0

    The extra \c const makes the entire definition read-only, which is
    slightly more efficient (for example, when the code is in a shared
    library) and ROMable when the application is to be stored in ROM.
*/
#ifndef QT_NO_IMAGEFORMAT_XPM
QPixmap::QPixmap(const char * const xpm[])
    : QPaintDevice()
{
    doInit(0, 0, QPlatformPixmap::PixmapType);
    if (!xpm)
        return;

    QImage image(xpm);
    if (!image.isNull()) {
        if (data && data->pixelType() == QPlatformPixmap::BitmapType)
            *this = QBitmap::fromImage(std::move(image));
        else
            *this = fromImage(std::move(image));
    }
}
#endif


/*!
    Destroys the pixmap.
*/

QPixmap::~QPixmap()
{
    Q_ASSERT(!data || data->ref.loadRelaxed() >= 1); // Catch if ref-counting changes again
}

/*!
  \internal
*/
int QPixmap::devType() const
{
    return QInternal::Pixmap;
}

/*!
    \fn QPixmap QPixmap::copy(int x, int y, int width, int height) const
    \overload

    Returns a deep copy of the subset of the pixmap that is specified
    by the rectangle QRect( \a x, \a y, \a width, \a height).
*/

/*!
    \fn QPixmap QPixmap::copy(const QRect &rectangle) const

    Returns a deep copy of the subset of the pixmap that is specified
    by the given \a rectangle. For more information on deep copies,
    see the \l {Implicit Data Sharing} documentation.

    If the given \a rectangle is empty, the whole image is copied.

    \sa operator=(), QPixmap(), {QPixmap#Pixmap
    Transformations}{Pixmap Transformations}
*/
QPixmap QPixmap::copy(const QRect &rect) const
{
    if (isNull())
        return QPixmap();

    QRect r(0, 0, width(), height());
    if (!rect.isEmpty())
        r = r.intersected(rect);

    QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
    d->copy(data.data(), r);
    return QPixmap(d);
}

/*!
    \fn QPixmap::scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed)
    \since 4.6

    This convenience function is equivalent to calling QPixmap::scroll(\a dx,
    \a dy, QRect(\a x, \a y, \a width, \a height), \a exposed).

    \sa QWidget::scroll(), QGraphicsItem::scroll()
*/

/*!
    \since 4.6

    Scrolls the area \a rect of this pixmap by (\a dx, \a dy). The exposed
    region is left unchanged. You can optionally pass a pointer to an empty
    QRegion to get the region that is \a exposed by the scroll operation.

    \snippet code/src_gui_image_qpixmap.cpp 2

    You cannot scroll while there is an active painter on the pixmap.

    \sa QWidget::scroll(), QGraphicsItem::scroll()
*/
void QPixmap::scroll(int dx, int dy, const QRect &rect, QRegion *exposed)
{
    if (isNull() || (dx == 0 && dy == 0))
        return;
    QRect dest = rect & this->rect();
    QRect src = dest.translated(-dx, -dy) & dest;
    if (src.isEmpty()) {
        if (exposed)
            *exposed += dest;
        return;
    }

    detach();

    if (!data->scroll(dx, dy, src)) {
        // Fallback
        QPixmap pix = *this;
        QPainter painter(&pix);
        painter.setCompositionMode(QPainter::CompositionMode_Source);
        painter.drawPixmap(src.translated(dx, dy), *this, src);
        painter.end();
        *this = pix;
    }

    if (exposed) {
        *exposed += dest;
        *exposed -= src.translated(dx, dy);
    }
}

/*!
    Assigns the given \a pixmap to this pixmap and returns a reference
    to this pixmap.

    \sa copy(), QPixmap()
*/

QPixmap &QPixmap::operator=(const QPixmap &pixmap)
{
    if (paintingActive()) {
        qWarning("QPixmap::operator=: Cannot assign to pixmap during painting");
        return *this;
    }
    if (pixmap.paintingActive()) {                // make a deep copy
        pixmap.copy().swap(*this);
    } else {
        data = pixmap.data;
    }
    return *this;
}

/*!
    \fn QPixmap &QPixmap::operator=(QPixmap &&other)

    Move-assigns \a other to this QPixmap instance.

    \since 5.2
*/

/*!
    \fn void QPixmap::swap(QPixmap &other)
    \since 4.8

    Swaps pixmap \a other with this pixmap. This operation is very
    fast and never fails.
*/

/*!
   Returns the pixmap as a QVariant.
*/
QPixmap::operator QVariant() const
{
    return QVariant(QMetaType::QPixmap, this);
}

/*!
    \fn bool QPixmap::operator!() const

    Returns \c true if this is a null pixmap; otherwise returns \c false.

    \sa isNull()
*/

/*!
    Converts the pixmap to a QImage. Returns a null image if the
    conversion fails.

    If the pixmap has 1-bit depth, the returned image will also be 1
    bit deep. Images with more bits will be returned in a format
    closely represents the underlying system. Usually this will be
    QImage::Format_ARGB32_Premultiplied for pixmaps with an alpha and
    QImage::Format_RGB32 or QImage::Format_RGB16 for pixmaps without
    alpha.

    Note that for the moment, alpha masks on monochrome images are
    ignored.

    \sa fromImage(), {QImage#Image Formats}{Image Formats}
*/
QImage QPixmap::toImage() const
{
    if (isNull())
        return QImage();

    return data->toImage();
}

/*!
    \fn QTransform QPixmap::trueMatrix(const QTransform &matrix, int width, int height)

    Returns the actual matrix used for transforming a pixmap with the
    given \a width, \a height and \a matrix.

    When transforming a pixmap using the transformed() function, the
    transformation matrix is internally adjusted to compensate for
    unwanted translation, i.e. transformed() returns the smallest
    pixmap containing all transformed points of the original
    pixmap. This function returns the modified matrix, which maps
    points correctly from the original pixmap into the new pixmap.

    \sa transformed(), {QPixmap#Pixmap Transformations}{Pixmap
    Transformations}
*/
QTransform QPixmap::trueMatrix(const QTransform &m, int w, int h)
{
    return QImage::trueMatrix(m, w, h);
}

#if QT_DEPRECATED_SINCE(5, 15)
/*!
  \overload
  \obsolete

  Use trueMatrix(const QTransform &m, int w, int h) instead.

  This convenience function loads the matrix \a m into a
  QTransform and calls the overloaded function with the
  QTransform and the width \a w and the height \a h.
 */
QMatrix QPixmap::trueMatrix(const QMatrix &m, int w, int h)
{
    return trueMatrix(QTransform(m), w, h).toAffine();
}
#endif // QT_DEPRECATED_SINCE(5, 15)


/*!
    \fn bool QPixmap::isQBitmap() const

    Returns \c true if this is a QBitmap; otherwise returns \c false.
*/

bool QPixmap::isQBitmap() const
{
    return data && data->type == QPlatformPixmap::BitmapType;
}

/*!
    \fn bool QPixmap::isNull() const

    Returns \c true if this is a null pixmap; otherwise returns \c false.

    A null pixmap has zero width, zero height and no contents. You
    cannot draw in a null pixmap.
*/
bool QPixmap::isNull() const
{
    return !data || data->isNull();
}

/*!
    \fn int QPixmap::width() const

    Returns the width of the pixmap.

    \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
*/
int QPixmap::width() const
{
    return data ? data->width() : 0;
}

/*!
    \fn int QPixmap::height() const

    Returns the height of the pixmap.

    \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
*/
int QPixmap::height() const
{
    return data ? data->height() : 0;
}

/*!
    \fn QSize QPixmap::size() const

    Returns the size of the pixmap.

    \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
    Information}
*/
QSize QPixmap::size() const
{
    return data ? QSize(data->width(), data->height()) : QSize(0, 0);
}

/*!
    \fn QRect QPixmap::rect() const

    Returns the pixmap's enclosing rectangle.

    \sa {QPixmap#Pixmap Information}{Pixmap Information}
*/
QRect QPixmap::rect() const
{
    return data ? QRect(0, 0, data->width(), data->height()) : QRect();
}

/*!
    \fn int QPixmap::depth() const

    Returns the depth of the pixmap.

    The pixmap depth is also called bits per pixel (bpp) or bit planes
    of a pixmap. A null pixmap has depth 0.

    \sa defaultDepth(), {QPixmap#Pixmap Information}{Pixmap
    Information}
*/
int QPixmap::depth() const
{
    return data ? data->depth() : 0;
}

/*!
    Sets a mask bitmap.

    This function merges the \a mask with the pixmap's alpha channel. A pixel
    value of 1 on the mask means the pixmap's pixel is unchanged; a value of 0
    means the pixel is transparent. The mask must have the same size as this
    pixmap.

    Setting a null mask resets the mask, leaving the previously transparent
    pixels black. The effect of this function is undefined when the pixmap is
    being painted on.

    \warning This is potentially an expensive operation.

    \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations},
    QBitmap
*/
void QPixmap::setMask(const QBitmap &mask)
{
    if (paintingActive()) {
        qWarning("QPixmap::setMask: Cannot set mask while pixmap is being painted on");
        return;
    }

    if (!mask.isNull() && mask.size() != size()) {
        qWarning("QPixmap::setMask() mask size differs from pixmap size");
        return;
    }

    if (isNull())
        return;

    if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
       return;

    detach();
    data->setMask(mask);
}

/*!
    Returns the device pixel ratio for the pixmap. This is the
    ratio between \e{device pixels} and \e{device independent pixels}.

    Use this function when calculating layout geometry based on
    the pixmap size: QSize layoutSize = image.size() / image.devicePixelRatio()

    The default value is 1.0.

    \sa setDevicePixelRatio(), QImageReader
*/
qreal QPixmap::devicePixelRatio() const
{
    if (!data)
        return qreal(1.0);
    return data->devicePixelRatio();
}

/*!
    Sets the device pixel ratio for the pixmap. This is the
    ratio between image pixels and device-independent pixels.

    The default \a scaleFactor is 1.0. Setting it to something else has
    two effects:

    QPainters that are opened on the pixmap will be scaled. For
    example, painting on a 200x200 image if with a ratio of 2.0
    will result in effective (device-independent) painting bounds
    of 100x100.

    Code paths in Qt that calculate layout geometry based on the
    pixmap size will take the ratio into account:
    QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio()
    The net effect of this is that the pixmap is displayed as
    high-DPI pixmap rather than a large pixmap
    (see \l{Drawing High Resolution Versions of Pixmaps and Images}).

    \sa devicePixelRatio()
*/
void QPixmap::setDevicePixelRatio(qreal scaleFactor)
{
    if (isNull())
        return;

    if (scaleFactor == data->devicePixelRatio())
        return;

    detach();
    data->setDevicePixelRatio(scaleFactor);
}

#ifndef QT_NO_IMAGE_HEURISTIC_MASK
/*!
    Creates and returns a heuristic mask for this pixmap.

    The function works by selecting a color from one of the corners
    and then chipping away pixels of that color, starting at all the
    edges.  If \a clipTight is true (the default) the mask is just
    large enough to cover the pixels; otherwise, the mask is larger
    than the data pixels.

    The mask may not be perfect but it should be reasonable, so you
    can do things such as the following:

    \snippet code/src_gui_image_qpixmap.cpp 1

    This function is slow because it involves converting to/from a
    QImage, and non-trivial computations.

    \sa QImage::createHeuristicMask(), createMaskFromColor()
*/
QBitmap QPixmap::createHeuristicMask(bool clipTight) const
{
    QBitmap m = QBitmap::fromImage(toImage().createHeuristicMask(clipTight));
    return m;
}
#endif

/*!
    Creates and returns a mask for this pixmap based on the given \a
    maskColor. If the \a mode is Qt::MaskInColor, all pixels matching the
    maskColor will be transparent. If \a mode is Qt::MaskOutColor, all pixels
    matching the maskColor will be opaque.

    This function is slow because it involves converting to/from a
    QImage.

    \sa createHeuristicMask(), QImage::createMaskFromColor()
*/
QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
{
    QImage image = toImage().convertToFormat(QImage::Format_ARGB32);
    return QBitmap::fromImage(std::move(image).createMaskFromColor(maskColor.rgba(), mode));
}

/*!
    Loads a pixmap from the file with the given \a fileName. Returns
    true if the pixmap was successfully loaded; otherwise invalidates
    the pixmap and returns \c false.

    The loader attempts to read the pixmap using the specified \a
    format. If the \a format is not specified (which is the default),
    the loader probes the file for a header to guess the file format.

    The file name can either refer to an actual file on disk or to one
    of the application's embedded resources. See the
    \l{resources.html}{Resource System} overview for details on how to
    embed pixmaps and other resource files in the application's
    executable.

    If the data needs to be modified to fit in a lower-resolution
    result (e.g. converting from 32-bit to 8-bit), use the \a flags to
    control the conversion.

    Note that QPixmaps are automatically added to the QPixmapCache
    when loaded from a file in main thread; the key used is internal
    and cannot be acquired.

    \sa loadFromData(), {QPixmap#Reading and Writing Image
    Files}{Reading and Writing Image Files}
*/

bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
{
    if (!fileName.isEmpty()) {

        QFileInfo info(fileName);
        // Note: If no extension is provided, we try to match the
        // file against known plugin extensions
        if (info.completeSuffix().isEmpty() || info.exists()) {
            const bool inGuiThread = qApp->thread() == QThread::currentThread();

            QString key = QLatin1String("qt_pixmap")
                    % info.absoluteFilePath()
                    % HexString<uint>(info.lastModified().toSecsSinceEpoch())
                    % HexString<quint64>(info.size())
                    % HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);

            if (inGuiThread && QPixmapCache::find(key, this))
                return true;

            data = QPlatformPixmap::create(0, 0, data ? data->pixelType() : QPlatformPixmap::PixmapType);

            if (data->fromFile(fileName, format, flags)) {
                if (inGuiThread)
                    QPixmapCache::insert(key, *this);
                return true;
            }
        }
    }

    if (!isNull()) {
        if (isQBitmap())
            *this = QBitmap();
        else
            data.reset();
    }
    return false;
}

/*!
    \fn bool QPixmap::loadFromData(const uchar *data, uint len, const char *format, Qt::ImageConversionFlags flags)

    Loads a pixmap from the \a len first bytes of the given binary \a
    data.  Returns \c true if the pixmap was loaded successfully;
    otherwise invalidates the pixmap and returns \c false.

    The loader attempts to read the pixmap using the specified \a
    format. If the \a format is not specified (which is the default),
    the loader probes the file for a header to guess the file format.

    If the data needs to be modified to fit in a lower-resolution
    result (e.g. converting from 32-bit to 8-bit), use the \a flags to
    control the conversion.

    \sa load(), {QPixmap#Reading and Writing Image Files}{Reading and
    Writing Image Files}
*/

bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
{
    if (len == 0 || buf == nullptr) {
        data.reset();
        return false;
    }

    data = QPlatformPixmap::create(0, 0, QPlatformPixmap::PixmapType);

    if (data->fromData(buf, len, format, flags))
        return true;

    data.reset();
    return false;
}

/*!
    \fn bool QPixmap::loadFromData(const QByteArray &data, const char *format, Qt::ImageConversionFlags flags)

    \overload

    Loads a pixmap from the binary \a data using the specified \a
    format and conversion \a flags.
*/


/*!
    Saves the pixmap to the file with the given \a fileName using the
    specified image file \a format and \a quality factor. Returns \c true
    if successful; otherwise returns \c false.

    The \a quality factor must be in the range [0,100] or -1. Specify
    0 to obtain small compressed files, 100 for large uncompressed
    files, and -1 to use the default settings.

    If \a format is \nullptr, an image format will be chosen from
    \a fileName's suffix.

    \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
    Image Files}
*/

bool QPixmap::save(const QString &fileName, const char *format, int quality) const
{
    if (isNull())
        return false;                                // nothing to save
    QImageWriter writer(fileName, format);
    return doImageIO(&writer, quality);
}

/*!
    \overload

    This function writes a QPixmap to the given \a device using the
    specified image file \a format and \a quality factor. This can be
    used, for example, to save a pixmap directly into a QByteArray:

    \snippet image/image.cpp 1
*/

bool QPixmap::save(QIODevice* device, const char* format, int quality) const
{
    if (isNull())
        return false;                                // nothing to save
    QImageWriter writer(device, format);
    return doImageIO(&writer, quality);
}

/*! \internal
*/
bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
{
    if (quality > 100  || quality < -1)
        qWarning("QPixmap::save: quality out of range [-1,100]");
    if (quality >= 0)
        writer->setQuality(qMin(quality,100));
    return writer->write(toImage());
}


#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \obsolete

    Use QPainter or the fill(QColor) overload instead.
*/

void QPixmap::fill(const QPaintDevice *device, const QPoint &p)
{
    Q_UNUSED(device)
    Q_UNUSED(p)
    qWarning("this function is deprecated, ignored");
}


/*!
    \fn void QPixmap::fill(const QPaintDevice *device, int x, int y)
    \obsolete

    Use QPainter or the fill(QColor) overload instead.
*/
void QPixmap::fill(const QPaintDevice *device, int xofs, int yofs)
{
    Q_UNUSED(device)
    Q_UNUSED(xofs)
    Q_UNUSED(yofs)
    qWarning("this function is deprecated, ignored");
}
#endif


/*!
    Fills the pixmap with the given \a color.

    The effect of this function is undefined when the pixmap is
    being painted on.

    \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}
*/

void QPixmap::fill(const QColor &color)
{
    if (isNull())
        return;

    // Some people are probably already calling fill while a painter is active, so to not break
    // their programs, only print a warning and return when the fill operation could cause a crash.
    if (paintingActive() && (color.alpha() != 255) && !hasAlphaChannel()) {
        qWarning("QPixmap::fill: Cannot fill while pixmap is being painted on");
        return;
    }

    if (data->ref.loadRelaxed() == 1) {
        // detach() will also remove this pixmap from caches, so
        // it has to be called even when ref == 1.
        detach();
    } else {
        // Don't bother to make a copy of the data object, since
        // it will be filled with new pixel data anyway.
        QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
        d->resize(data->width(), data->height());
        data = d;
    }
    data->fill(color);
}

/*! \fn int QPixmap::serialNumber() const
    \obsolete
    Returns a number that identifies the contents of this QPixmap
    object. Distinct QPixmap objects can only have the same serial
    number if they refer to the same contents (but they don't have
    to).

    Use cacheKey() instead.

    \warning The serial number doesn't necessarily change when
    the pixmap is altered. This means that it may be dangerous to use
    it as a cache key. For caching pixmaps, we recommend using the
    QPixmapCache class whenever possible.
*/

/*!
    Returns a number that identifies this QPixmap. Distinct QPixmap
    objects can only have the same cache key if they refer to the same
    contents.

    The cacheKey() will change when the pixmap is altered.
*/
qint64 QPixmap::cacheKey() const
{
    if (isNull())
        return 0;

    Q_ASSERT(data);
    return data->cacheKey();
}

#if 0
static void sendResizeEvents(QWidget *target)
{
    QResizeEvent e(target->size(), QSize());
    QApplication::sendEvent(target, &e);

    const QObjectList children = target->children();
    for (int i = 0; i < children.size(); ++i) {
        QWidget *child = static_cast<QWidget*>(children.at(i));
        if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
            sendResizeEvents(child);
    }
}
#endif

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \obsolete

    Use QWidget::grab() instead.
*/
QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle)
{
    QPixmap pixmap;
    qWarning("QPixmap::grabWidget is deprecated, use QWidget::grab() instead");
    if (!widget)
        return pixmap;
    QMetaObject::invokeMethod(widget, "grab", Qt::DirectConnection,
                              Q_RETURN_ARG(QPixmap, pixmap),
                              Q_ARG(QRect, rectangle));
    return pixmap;
}

/*!
    \fn QPixmap QPixmap::grabWidget(QObject *widget, int x, int y, int w, int h)
    \obsolete

    Use QWidget::grab() instead.
*/
QPixmap QPixmap::grabWidget(QObject *widget, int x, int y, int w, int h)
{
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
    return grabWidget(widget, QRect(x, y, w, h));
QT_WARNING_POP
}
#endif

/*****************************************************************************
  QPixmap stream functions
 *****************************************************************************/
#if !defined(QT_NO_DATASTREAM)
/*!
    \relates QPixmap

    Writes the given \a pixmap to the given \a stream as a PNG
    image. Note that writing the stream to a file will not produce a
    valid image file.

    \sa QPixmap::save(), {Serializing Qt Data Types}
*/

QDataStream &operator<<(QDataStream &stream, const QPixmap &pixmap)
{
    return stream << pixmap.toImage();
}

/*!
    \relates QPixmap

    Reads an image from the given \a stream into the given \a pixmap.

    \sa QPixmap::load(), {Serializing Qt Data Types}
*/

QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
{
    QImage image;
    stream >> image;

    if (image.isNull()) {
        pixmap = QPixmap();
    } else if (image.depth() == 1) {
        pixmap = QBitmap::fromImage(std::move(image));
    } else {
        pixmap = QPixmap::fromImage(std::move(image));
    }
    return stream;
}

#endif // QT_NO_DATASTREAM

/*!
    \internal
*/

bool QPixmap::isDetached() const
{
    return data && data->ref.loadRelaxed() == 1;
}

/*!
    Replaces this pixmap's data with the given \a image using the
    specified \a flags to control the conversion.  The \a flags
    argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
    Passing 0 for \a flags sets all the default options. Returns \c true
    if the result is that this pixmap is not null.

    Note: this function was part of Qt 3 support in Qt 4.6 and earlier.
    It has been promoted to official API status in 4.7 to support updating
    the pixmap's image without creating a new QPixmap as fromImage() would.

    \sa fromImage()
    \since 4.7
*/
bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
{
    detach();
    if (image.isNull() || !data)
        *this = QPixmap::fromImage(image, flags);
    else
        data->fromImage(image, flags);
    return !isNull();
}

/*!
    \fn QPixmap QPixmap::scaled(int width, int height,
    Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode
    transformMode) const

    \overload

    Returns a copy of the pixmap scaled to a rectangle with the given
    \a width and \a height according to the given \a aspectRatioMode and
    \a transformMode.

    If either the \a width or the \a height is zero or negative, this
    function returns a null pixmap.
*/

/*!
    \fn QPixmap QPixmap::scaled(const QSize &size, Qt::AspectRatioMode
    aspectRatioMode, Qt::TransformationMode transformMode) const

    Scales the pixmap to the given \a size, using the aspect ratio and
    transformation modes specified by \a aspectRatioMode and \a
    transformMode.

    \image qimage-scaling.png

    \list
    \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
       is scaled to \a size.
    \li If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
       scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
    \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
       the pixmap is scaled to a rectangle as small as possible
       outside \a size, preserving the aspect ratio.
    \endlist

    If the given \a size is empty, this function returns a null
    pixmap.


    In some cases it can be more beneficial to draw the pixmap to a
    painter with a scale set rather than scaling the pixmap. This is
    the case when the painter is for instance based on OpenGL or when
    the scale factor changes rapidly.

    \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
    Transformations}

*/
QPixmap QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
{
    if (isNull()) {
        qWarning("QPixmap::scaled: Pixmap is a null pixmap");
        return QPixmap();
    }
    if (s.isEmpty())
        return QPixmap();

    QSize newSize = size();
    newSize.scale(s, aspectMode);
    newSize.rwidth() = qMax(newSize.width(), 1);
    newSize.rheight() = qMax(newSize.height(), 1);
    if (newSize == size())
        return *this;

    Q_TRACE_SCOPE(QPixmap_scaled, s, aspectMode, mode);

    QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(),
                                          (qreal)newSize.height() / height());
    QPixmap pix = transformed(wm, mode);
    return pix;
}

/*!
    \fn QPixmap QPixmap::scaledToWidth(int width, Qt::TransformationMode
    mode) const

    Returns a scaled copy of the image. The returned image is scaled
    to the given \a width using the specified transformation \a mode.
    The height of the pixmap is automatically calculated so that the
    aspect ratio of the pixmap is preserved.

    If \a width is 0 or negative, a null pixmap is returned.

    \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
    Transformations}
*/
QPixmap QPixmap::scaledToWidth(int w, Qt::TransformationMode mode) const
{
    if (isNull()) {
        qWarning("QPixmap::scaleWidth: Pixmap is a null pixmap");
        return copy();
    }
    if (w <= 0)
        return QPixmap();

    Q_TRACE_SCOPE(QPixmap_scaledToWidth, w, mode);

    qreal factor = (qreal) w / width();
    QTransform wm = QTransform::fromScale(factor, factor);
    return transformed(wm, mode);
}

/*!
    \fn QPixmap QPixmap::scaledToHeight(int height,
    Qt::TransformationMode mode) const

    Returns a scaled copy of the image. The returned image is scaled
    to the given \a height using the specified transformation \a mode.
    The width of the pixmap is automatically calculated so that the
    aspect ratio of the pixmap is preserved.

    If \a height is 0 or negative, a null pixmap is returned.

    \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
    Transformations}
*/
QPixmap QPixmap::scaledToHeight(int h, Qt::TransformationMode mode) const
{
    if (isNull()) {
        qWarning("QPixmap::scaleHeight: Pixmap is a null pixmap");
        return copy();
    }
    if (h <= 0)
        return QPixmap();

    Q_TRACE_SCOPE(QPixmap_scaledToHeight, h, mode);

    qreal factor = (qreal) h / height();
    QTransform wm = QTransform::fromScale(factor, factor);
    return transformed(wm, mode);
}

/*!
    Returns a copy of the pixmap that is transformed using the given
    transformation \a transform and transformation \a mode. The original
    pixmap is not changed.

    The transformation \a transform is internally adjusted to compensate
    for unwanted translation; i.e. the pixmap produced is the smallest
    pixmap that contains all the transformed points of the original
    pixmap. Use the trueMatrix() function to retrieve the actual
    matrix used for transforming the pixmap.

    This function is slow because it involves transformation to a
    QImage, non-trivial computations and a transformation back to a
    QPixmap.

    \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
    Transformations}
*/
QPixmap QPixmap::transformed(const QTransform &transform,
                             Qt::TransformationMode mode) const
{
    if (isNull() || transform.type() <= QTransform::TxTranslate)
        return *this;

    return data->transformed(transform, mode);
}

#if QT_DEPRECATED_SINCE(5, 15)
/*!
  \overload
  \obsolete

  Use transformed(const QTransform &transform, Qt::TransformationMode mode)() instead.

  This convenience function loads the \a matrix into a
  QTransform and calls the overloaded function.
 */
QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) const
{
    return transformed(QTransform(matrix), mode);
}
#endif // QT_DEPRECATED_SINCE(5, 15)








/*!
    \class QPixmap
    \inmodule QtGui

    \brief The QPixmap class is an off-screen image representation
    that can be used as a paint device.

    \ingroup painting
    \ingroup shared


    Qt provides four classes for handling image data: QImage, QPixmap,
    QBitmap and QPicture. QImage is designed and optimized for I/O,
    and for direct pixel access and manipulation, while QPixmap is
    designed and optimized for showing images on screen. QBitmap is
    only a convenience class that inherits QPixmap, ensuring a depth
    of 1. The isQBitmap() function returns \c true if a QPixmap object is
    really a bitmap, otherwise returns \c false. Finally, the QPicture class
    is a paint device that records and replays QPainter commands.

    A QPixmap can easily be displayed on the screen using QLabel or
    one of QAbstractButton's subclasses (such as QPushButton and
    QToolButton). QLabel has a pixmap property, whereas
    QAbstractButton has an icon property.

    QPixmap objects can be passed around by value since the QPixmap
    class uses implicit data sharing. For more information, see the \l
    {Implicit Data Sharing} documentation. QPixmap objects can also be
    streamed.

    Note that the pixel data in a pixmap is internal and is managed by
    the underlying window system. Because QPixmap is a QPaintDevice
    subclass, QPainter can be used to draw directly onto pixmaps.
    Pixels can only be accessed through QPainter functions or by
    converting the QPixmap to a QImage. However, the fill() function
    is available for initializing the entire pixmap with a given color.

    There are functions to convert between QImage and
    QPixmap. Typically, the QImage class is used to load an image
    file, optionally manipulating the image data, before the QImage
    object is converted into a QPixmap to be shown on
    screen. Alternatively, if no manipulation is desired, the image
    file can be loaded directly into a QPixmap.

    QPixmap provides a collection of functions that can be used to
    obtain a variety of information about the pixmap. In addition,
    there are several functions that enables transformation of the
    pixmap.

    \tableofcontents

    \section1 Reading and Writing Image Files

    QPixmap provides several ways of reading an image file: The file
    can be loaded when constructing the QPixmap object, or by using
    the load() or loadFromData() functions later on. When loading an
    image, the file name can either refer to an actual file on disk or
    to one of the application's embedded resources. See \l{The Qt
    Resource System} overview for details on how to embed images and
    other resource files in the application's executable.

    Simply call the save() function to save a QPixmap object.

    The complete list of supported file formats are available through
    the QImageReader::supportedImageFormats() and
    QImageWriter::supportedImageFormats() functions. New file formats
    can be added as plugins. By default, Qt supports the following
    formats:

    \table
    \header \li Format \li Description                      \li Qt's support
    \row    \li BMP    \li Windows Bitmap                   \li Read/write
    \row    \li GIF    \li Graphic Interchange Format (optional) \li Read
    \row    \li JPG    \li Joint Photographic Experts Group \li Read/write
    \row    \li JPEG   \li Joint Photographic Experts Group \li Read/write
    \row    \li PNG    \li Portable Network Graphics        \li Read/write
    \row    \li PBM    \li Portable Bitmap                  \li Read
    \row    \li PGM    \li Portable Graymap                 \li Read
    \row    \li PPM    \li Portable Pixmap                  \li Read/write
    \row    \li XBM    \li X11 Bitmap                       \li Read/write
    \row    \li XPM    \li X11 Pixmap                       \li Read/write
    \endtable

    \section1 Pixmap Information

    QPixmap provides a collection of functions that can be used to
    obtain a variety of information about the pixmap:

    \table
    \header
    \li \li Available Functions
    \row
    \li Geometry
    \li
    The size(), width() and height() functions provide information
    about the pixmap's size. The rect() function returns the image's
    enclosing rectangle.

    \row
    \li Alpha component
    \li

    The hasAlphaChannel() returns \c true if the pixmap has a format that
    respects the alpha channel, otherwise returns \c false. The hasAlpha(),
    setMask() and mask() functions are legacy and should not be used.
    They are potentially very slow.

    The createHeuristicMask() function creates and returns a 1-bpp
    heuristic mask (i.e. a QBitmap) for this pixmap. It works by
    selecting a color from one of the corners and then chipping away
    pixels of that color, starting at all the edges. The
    createMaskFromColor() function creates and returns a mask (i.e. a
    QBitmap) for the pixmap based on a given color.

    \row
    \li Low-level information
    \li

    The depth() function returns the depth of the pixmap. The
    defaultDepth() function returns the default depth, i.e. the depth
    used by the application on the given screen.

    The cacheKey() function returns a number that uniquely
    identifies the contents of the QPixmap object.

    \endtable

    \section1 Pixmap Conversion

    A QPixmap object can be converted into a QImage using the
    toImage() function. Likewise, a QImage can be converted into a
    QPixmap using the fromImage(). If this is too expensive an
    operation, you can use QBitmap::fromImage() instead.

    To convert a QPixmap to and from HICON you can use the QtWinExtras
    functions QtWin::toHICON() and QtWin::fromHICON() respectively.

    \section1 Pixmap Transformations

    QPixmap supports a number of functions for creating a new pixmap
    that is a transformed version of the original:

    The scaled(), scaledToWidth() and scaledToHeight() functions
    return scaled copies of the pixmap, while the copy() function
    creates a QPixmap that is a plain copy of the original one.

    The transformed() function returns a copy of the pixmap that is
    transformed with the given transformation matrix and
    transformation mode: Internally, the transformation matrix is
    adjusted to compensate for unwanted translation,
    i.e. transformed() returns the smallest pixmap containing all
    transformed points of the original pixmap. The static trueMatrix()
    function returns the actual matrix used for transforming the
    pixmap.

    \sa QBitmap, QImage, QImageReader, QImageWriter
*/


/*!
    \typedef QPixmap::DataPtr
    \internal
*/

/*!
    \fn DataPtr &QPixmap::data_ptr()
    \internal
*/

/*!
    Returns \c true if this pixmap has an alpha channel, \e or has a
    mask, otherwise returns \c false.

    \sa hasAlphaChannel(), mask()
*/
bool QPixmap::hasAlpha() const
{
    return data && data->hasAlphaChannel();
}

/*!
    Returns \c true if the pixmap has a format that respects the alpha
    channel, otherwise returns \c false.

    \sa hasAlpha()
*/
bool QPixmap::hasAlphaChannel() const
{
    return data && data->hasAlphaChannel();
}

/*!
    \internal
*/
int QPixmap::metric(PaintDeviceMetric metric) const
{
    return data ? data->metric(metric) : 0;
}

/*!
    \internal
*/
QPaintEngine *QPixmap::paintEngine() const
{
    return data ? data->paintEngine() : nullptr;
}

/*!
    \fn QBitmap QPixmap::mask() const

    Extracts a bitmap mask from the pixmap's alpha channel.

    \warning This is potentially an expensive operation. The mask of
    the pixmap is extracted dynamically from the pixeldata.

    \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
*/
QBitmap QPixmap::mask() const
{
    return data ? data->mask() : QBitmap();
}

/*!
    Returns the default pixmap depth used by the application.

    On all platforms the depth of the primary screen will be returned.

    \note QGuiApplication must be created before calling this function.

    \sa depth(), QColormap::depth(), {QPixmap#Pixmap Information}{Pixmap Information}

*/
int QPixmap::defaultDepth()
{
    QScreen *primary = QGuiApplication::primaryScreen();
    if (Q_LIKELY(primary))
        return primary->depth();
    qWarning("QPixmap: QGuiApplication must be created before calling defaultDepth().");
    return 0;
}

/*!
    Detaches the pixmap from shared pixmap data.

    A pixmap is automatically detached by Qt whenever its contents are
    about to change. This is done in almost all QPixmap member
    functions that modify the pixmap (fill(), fromImage(),
    load(), etc.), and in QPainter::begin() on a pixmap.

    There are two exceptions in which detach() must be called
    explicitly, that is when calling the handle() or the
    x11PictureHandle() function (only available on X11). Otherwise,
    any modifications done using system calls, will be performed on
    the shared data.

    The detach() function returns immediately if there is just a
    single reference or if the pixmap has not been initialized yet.
*/
void QPixmap::detach()
{
    if (!data)
        return;

    // QPixmap.data member may be QRuntimePlatformPixmap so use handle() function to get
    // the actual underlaying runtime pixmap data.
    QPlatformPixmap *pd = handle();
    QPlatformPixmap::ClassId id = pd->classId();
    if (id == QPlatformPixmap::RasterClass) {
        QRasterPlatformPixmap *rasterData = static_cast<QRasterPlatformPixmap*>(pd);
        rasterData->image.detach();
    }

    if (data->is_cached && data->ref.loadRelaxed() == 1)
        QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(data.data());

    if (data->ref.loadRelaxed() != 1) {
        *this = copy();
    }
    ++data->detach_no;
}

/*!
    \fn QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)

    Converts the given \a image to a pixmap using the specified \a
    flags to control the conversion.  The \a flags argument is a
    bitwise-OR of the \l{Qt::ImageConversionFlags}. Passing 0 for \a
    flags sets all the default options.

    In case of monochrome and 8-bit images, the image is first
    converted to a 32-bit pixmap and then filled with the colors in
    the color table. If this is too expensive an operation, you can
    use QBitmap::fromImage() instead.

    \sa fromImageReader(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
*/
QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
{
    if (image.isNull())
        return QPixmap();

    if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
        qWarning("QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
        return QPixmap();
    }

    QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
    data->fromImage(image, flags);
    return QPixmap(data.take());
}

/*!
    \fn QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
    \since 5.3
    \overload

    Converts the given \a image to a pixmap without copying if possible.
*/


/*!
    \internal
*/
QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
{
    if (image.isNull())
        return QPixmap();

    if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
        qWarning("QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
        return QPixmap();
    }

    QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
    data->fromImageInPlace(image, flags);
    return QPixmap(data.take());
}

/*!
    \fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)

    Create a QPixmap from an image read directly from an \a imageReader.
    The \a flags argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
    Passing 0 for \a flags sets all the default options.

    On some systems, reading an image directly to QPixmap can use less memory than
    reading a QImage to convert it to QPixmap.

    \sa fromImage(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
*/
QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
{
    if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
        qWarning("QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
        return QPixmap();
    }

    QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
    data->fromImageReader(imageReader, flags);
    return QPixmap(data.take());
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int
    width, int height)

    Creates and returns a pixmap constructed by grabbing the contents
    of the given \a window restricted by QRect(\a x, \a y, \a width,
    \a height).

    The arguments (\a{x}, \a{y}) specify the offset in the window,
    whereas (\a{width}, \a{height}) specify the area to be copied.  If
    \a width is negative, the function copies everything to the right
    border of the window. If \a height is negative, the function
    copies everything to the bottom of the window.

    The window system identifier (\c WId) can be retrieved using the
    QWidget::winId() function. The rationale for using a window
    identifier and not a QWidget, is to enable grabbing of windows
    that are not part of the application, window system frames, and so
    on.

    The grabWindow() function grabs pixels from the screen, not from
    the window, i.e. if there is another window partially or entirely
    over the one you grab, you get pixels from the overlying window,
    too. The mouse cursor is generally not grabbed.

    Note on X11 that if the given \a window doesn't have the same depth
    as the root window, and another window partially or entirely
    obscures the one you grab, you will \e not get pixels from the
    overlying window.  The contents of the obscured areas in the
    pixmap will be undefined and uninitialized.

    On Windows Vista and above grabbing a layered window, which is
    created by setting the Qt::WA_TranslucentBackground attribute, will
    not work. Instead grabbing the desktop widget should work.

    \warning In general, grabbing an area outside the screen is not
    safe. This depends on the underlying window system.

    \warning The function is deprecated in Qt 5.0 since there might be
    platform plugins in which window system identifiers (\c WId)
    are local to a screen. Use QScreen::grabWindow() instead.

    \sa grabWidget(), {Screenshot Example}
    \sa QScreen
    \deprecated
*/

QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
{
    qWarning("this function is deprecated, use QScreen::grabWindow() instead."
             " Defaulting to primary screen.");
    return QGuiApplication::primaryScreen()->grabWindow(window, x, y, w, h);
}
#endif

/*!
  \internal
*/
QPlatformPixmap* QPixmap::handle() const
{
    return data.data();
}

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QPixmap &r)
{
    QDebugStateSaver saver(dbg);
    dbg.resetFormat();
    dbg.nospace();
    dbg << "QPixmap(";
    if (r.isNull()) {
        dbg << "null";
    } else {
        dbg << r.size() << ",depth=" << r.depth()
            << ",devicePixelRatio=" << r.devicePixelRatio()
            << ",cacheKey=" << Qt::showbase << Qt::hex << r.cacheKey() << Qt::dec << Qt::noshowbase;
    }
    dbg << ')';
    return dbg;
}
#endif

/*!
    \fn QPixmap QPixmap::alphaChannel() const

    Most use cases for this can be achieved using a QPainter and QPainter::CompositionMode instead.
*/

/*!
    \fn void QPixmap::setAlphaChannel(const QPixmap &p)

    Most use cases for this can be achieved using \a p with QPainter and QPainter::CompositionMode instead.
*/

QT_END_NAMESPACE
