summaryrefslogtreecommitdiffstats
path: root/src/gui/image/qpixmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image/qpixmap.cpp')
-rw-r--r--src/gui/image/qpixmap.cpp2010
1 files changed, 2010 insertions, 0 deletions
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
new file mode 100644
index 0000000..a16f8ee
--- /dev/null
+++ b/src/gui/image/qpixmap.cpp
@@ -0,0 +1,2010 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+
+#include "qpixmap.h"
+#include "qpixmapdata_p.h"
+
+#include "qbitmap.h"
+#include "qcolormap.h"
+#include "qimage.h"
+#include "qwidget.h"
+#include "qpainter.h"
+#include "qdatastream.h"
+#include "qbuffer.h"
+#include "qapplication.h"
+#include <private/qapplication_p.h>
+#include <private/qgraphicssystem_p.h>
+#include <private/qwidget_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 "qthread.h"
+
+#ifdef Q_WS_MAC
+# include "private/qt_mac_p.h"
+# include "private/qpixmap_mac_p.h"
+#endif
+
+#if defined(Q_WS_X11)
+# include "qx11info_x11.h"
+# include <private/qt_x11_p.h>
+# include <private/qpixmap_x11_p.h>
+#endif
+
+#if defined(Q_OS_SYMBIAN)
+# include <private/qt_s60_p.h>
+#endif
+
+#include "qpixmap_raster_p.h"
+
+QT_BEGIN_NAMESPACE
+
+// ### Qt 5: remove
+typedef void (*_qt_pixmap_cleanup_hook)(int);
+Q_GUI_EXPORT _qt_pixmap_cleanup_hook qt_pixmap_cleanup_hook = 0;
+
+// ### Qt 5: rename
+typedef void (*_qt_pixmap_cleanup_hook_64)(qint64);
+Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64 = 0;
+
+// ### Qt 5: remove
+Q_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap)
+{
+ return pixmap.cacheKey();
+}
+
+static bool qt_pixmap_thread_test()
+{
+ if (!qApp) {
+ qFatal("QPixmap: Must construct a QApplication before a QPaintDevice");
+ return false;
+ }
+#ifndef Q_WS_WIN
+ if (qApp->thread() != QThread::currentThread()) {
+ qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread");
+ return false;
+ }
+#endif
+ return true;
+}
+
+void QPixmap::init(int w, int h, Type type)
+{
+ init(w, h, int(type));
+}
+
+void QPixmap::init(int w, int h, int type)
+{
+ QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
+ if (gs)
+ data = gs->createPixmapData(static_cast<QPixmapData::PixelType>(type));
+ else
+ data = QGraphicsSystem::createDefaultPixmapData(static_cast<QPixmapData::PixelType>(type));
+
+ data->resize(w, h);
+ data->ref.ref();
+}
+
+/*!
+ \enum QPixmap::ColorMode
+
+ \compat
+
+ This enum type defines the color modes that exist for converting
+ QImage objects to QPixmap. It is provided here for compatibility
+ with earlier versions of Qt.
+
+ Use Qt::ImageConversionFlags instead.
+
+ \value Auto Select \c Color or \c Mono on a case-by-case basis.
+ \value Color Always create colored pixmaps.
+ \value Mono Always create bitmaps.
+*/
+
+/*!
+ Constructs a null pixmap.
+
+ \sa isNull()
+*/
+
+QPixmap::QPixmap()
+ : QPaintDevice()
+{
+ (void) qt_pixmap_thread_test();
+ init(0, 0, QPixmapData::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)
+ : QPaintDevice()
+{
+ if (!qt_pixmap_thread_test())
+ init(0, 0, QPixmapData::PixmapType);
+ else
+ init(w, h, QPixmapData::PixmapType);
+}
+
+/*!
+ \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)
+ : QPaintDevice()
+{
+ if (!qt_pixmap_thread_test())
+ init(0, 0, QPixmapData::PixmapType);
+ else
+ init(size.width(), size.height(), QPixmapData::PixmapType);
+}
+
+/*!
+ \internal
+*/
+QPixmap::QPixmap(const QSize &s, Type type)
+{
+ if (!qt_pixmap_thread_test())
+ init(0, 0, type);
+ else
+ init(s.width(), s.height(), type);
+}
+
+/*!
+ \internal
+*/
+QPixmap::QPixmap(const QSize &s, int type)
+{
+ if (!qt_pixmap_thread_test())
+ init(0, 0, static_cast<QPixmapData::PixelType>(type));
+ else
+ init(s.width(), s.height(), static_cast<QPixmapData::PixelType>(type));
+}
+
+/*!
+ \internal
+*/
+QPixmap::QPixmap(QPixmapData *d)
+ : QPaintDevice(), data(d)
+{
+ data->ref.ref();
+}
+
+/*!
+ 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()
+{
+ init(0, 0, QPixmapData::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()) {
+ init(0, 0, QPixmapData::PixmapType);
+ return;
+ }
+ if (pixmap.paintingActive()) { // make a deep copy
+ data = 0;
+ operator=(pixmap.copy());
+ } else {
+ data = pixmap.data;
+ data->ref.ref();
+ }
+}
+
+/*!
+ 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 doc/src/snippets/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()
+{
+ init(0, 0, QPixmapData::PixmapType);
+ if (!xpm)
+ return;
+
+ QImage image(xpm);
+ if (!image.isNull()) {
+ if (data->pixelType() == QPixmapData::BitmapType)
+ *this = QBitmap::fromImage(image);
+ else
+ *this = fromImage(image);
+ }
+}
+#endif
+
+
+/*!
+ Destroys the pixmap.
+*/
+
+QPixmap::~QPixmap()
+{
+ deref();
+}
+
+/*!
+ \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();
+
+ const QRect r = rect.isEmpty() ? QRect(0, 0, width(), height()) : rect;
+
+ QPixmapData *d;
+ QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
+ if (gs)
+ d = gs->createPixmapData(data->pixelType());
+ else
+ d = QGraphicsSystem::createDefaultPixmapData(data->pixelType());
+
+ d->copy(data, r);
+ return QPixmap(d);
+}
+
+/*!
+ 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
+ *this = pixmap.copy();
+ } else {
+ pixmap.data->ref.ref(); // avoid 'x = x'
+ deref();
+ data = pixmap.data;
+ }
+ return *this;
+}
+
+/*!
+ Returns the pixmap as a QVariant.
+*/
+QPixmap::operator QVariant() const
+{
+ return QVariant(QVariant::Pixmap, this);
+}
+
+/*!
+ \fn bool QPixmap::operator!() const
+
+ Returns true if this is a null pixmap; otherwise returns false.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QPixmap::operator QImage() const
+
+ Returns the pixmap as a QImage.
+
+ Use the toImage() function instead.
+*/
+
+/*!
+ 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. If the pixmap has 2- to 8-bit depth, the returned image
+ has 8-bit depth. If the pixmap has greater than 8-bit depth, the
+ returned image has 32-bit depth.
+
+ 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 QMatrix 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);
+}
+
+/*!
+ \overload
+
+ 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();
+}
+
+
+/*!
+ \fn bool QPixmap::isQBitmap() const
+
+ Returns true if this is a QBitmap; otherwise returns false.
+*/
+
+bool QPixmap::isQBitmap() const
+{
+ return data->type == QPixmapData::BitmapType;
+}
+
+/*!
+ \fn bool QPixmap::isNull() const
+
+ Returns true if this is a null pixmap; otherwise returns 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->width() == 0;
+}
+
+/*!
+ \fn int QPixmap::width() const
+
+ Returns the width of the pixmap.
+
+ \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
+*/
+int QPixmap::width() const
+{
+ return data->width();
+}
+
+/*!
+ \fn int QPixmap::height() const
+
+ Returns the height of the pixmap.
+
+ \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
+*/
+int QPixmap::height() const
+{
+ return data->height();
+}
+
+/*!
+ \fn QSize QPixmap::size() const
+
+ Returns the size of the pixmap.
+
+ \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
+ Information}
+*/
+QSize QPixmap::size() const
+{
+ return QSize(data->width(), data->height());
+}
+
+/*!
+ \fn QRect QPixmap::rect() const
+
+ Returns the pixmap's enclosing rectangle.
+
+ \sa {QPixmap#Pixmap Information}{Pixmap Information}
+*/
+QRect QPixmap::rect() const
+{
+ return QRect(0, 0, data->width(), data->height());
+}
+
+/*!
+ \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->depth();
+}
+
+/*!
+ \fn void QPixmap::resize(const QSize &size)
+ \overload
+ \compat
+
+ Use QPixmap::copy() instead to get the pixmap with the new size.
+
+ \oldcode
+ pixmap.resize(size);
+ \newcode
+ pixmap = pixmap.copy(QRect(QPoint(0, 0), size));
+ \endcode
+*/
+#ifdef QT3_SUPPORT
+void QPixmap::resize_helper(const QSize &s)
+{
+ int w = s.width();
+ int h = s.height();
+ if (w < 1 || h < 1) {
+ *this = QPixmap();
+ return;
+ }
+
+ if (size() == s)
+ return;
+
+ // Create new pixmap
+ QPixmap pm(QSize(w, h), data->type);
+ bool uninit = false;
+#if defined(Q_WS_X11)
+ QX11PixmapData *x11Data = data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data) : 0;
+ if (x11Data) {
+ pm.x11SetScreen(x11Data->xinfo.screen());
+ uninit = x11Data->uninit;
+ }
+#elif defined(Q_WS_MAC)
+ QMacPixmapData *macData = data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data) : 0;
+ if (macData)
+ uninit = macData->uninit;
+#endif
+ if (!uninit && !isNull()) {
+ // Copy old pixmap
+ if (hasAlphaChannel())
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h));
+ }
+
+#if defined(Q_WS_MAC)
+#ifndef QT_MAC_NO_QUICKDRAW
+ if(macData && macData->qd_alpha)
+ macData->macQDUpdateAlpha();
+#endif
+#elif defined(Q_WS_X11)
+ if (x11Data && x11Data->x11_mask) {
+ QX11PixmapData *pmData = static_cast<QX11PixmapData*>(pm.data);
+ pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display,
+ RootWindow(x11Data->xinfo.display(),
+ x11Data->xinfo.screen()),
+ w, h, 1);
+ GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0);
+ XCopyArea(X11->display, x11Data->x11_mask, pmData->x11_mask, gc, 0, 0, qMin(width(), w), qMin(height(), h), 0, 0);
+ XFreeGC(X11->display, gc);
+ }
+#endif
+ *this = pm;
+}
+#endif
+
+/*!
+ \fn void QPixmap::resize(int width, int height)
+ \compat
+
+ Use QPixmap::copy() instead to get the pixmap with the new size.
+
+ \oldcode
+ pixmap.resize(10, 20);
+ \newcode
+ pixmap = pixmap.copy(0, 0, 10, 20);
+ \endcode
+*/
+
+/*!
+ \fn bool QPixmap::selfMask() const
+ \compat
+
+ Returns whether the pixmap is its own mask or not.
+
+ This function is no longer relevant since the concept of self
+ masking doesn't exists anymore.
+*/
+
+/*!
+ 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.
+
+ 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 (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
+ return;
+
+ detach();
+ data->setMask(mask);
+}
+
+#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 doc/src/snippets/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 opaque. If \a mode is Qt::MaskOutColor, all pixels
+ matching the maskColor will be transparent.
+
+ 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(image.createMaskFromColor(maskColor.rgba(), mode));
+}
+
+/*! \overload
+
+ Creates and returns a mask for this pixmap based on the given \a
+ maskColor. Same as calling createMaskFromColor(maskColor,
+ Qt::MaskInColor)
+
+ \sa createHeuristicMask(), QImage::createMaskFromColor()
+*/
+QBitmap QPixmap::createMaskFromColor(const QColor &maskColor) const
+{
+ return createMaskFromColor(maskColor, Qt::MaskInColor);
+}
+
+/*!
+ Loads a pixmap from the file with the given \a fileName. Returns
+ true if the pixmap was successfully loaded; otherwise returns
+ 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; the key used is internal and can not
+ 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())
+ return false;
+
+ QFileInfo info(fileName);
+ QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') +
+ QString::number(info.size()) + QLatin1Char('_') + QString::number(data->pixelType());
+
+ if (QPixmapCache::find(key, *this))
+ return true;
+
+ QImage image = QImageReader(fileName, format).read();
+ if (image.isNull())
+ return false;
+ QPixmap pm;
+ if (data->pixelType() == QPixmapData::BitmapType)
+ pm = QBitmap::fromImage(image, flags);
+ else
+ pm = fromImage(image, flags);
+ if (!pm.isNull()) {
+ *this = pm;
+ QPixmapCache::insert(key, *this);
+ return true;
+ }
+ 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 true if the pixmap was loaded successfully;
+ otherwise returns 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)
+{
+ QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buf), len);
+ QBuffer b(&a);
+ b.open(QIODevice::ReadOnly);
+
+ QImage image = QImageReader(&b, format).read();
+ QPixmap pm;
+ if (data->pixelType() == QPixmapData::BitmapType)
+ pm = QBitmap::fromImage(image, flags);
+ else
+ pm = fromImage(image, flags);
+ if (!pm.isNull()) {
+ *this = pm;
+ return true;
+ }
+ 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 true
+ if successful; otherwise returns 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 0, 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 doc/src/snippets/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());
+}
+
+
+// The implementation (and documentation) of
+// QPixmap::fill(const QWidget *, const QPoint &)
+// is in qwidget.cpp
+
+/*!
+ \fn void QPixmap::fill(const QWidget *widget, int x, int y)
+ \overload
+
+ Fills the pixmap with the \a widget's background color or pixmap.
+ The given point, (\a x, \a y), defines an offset in widget
+ coordinates to which the pixmap's top-left pixel will be mapped
+ to.
+*/
+
+/*!
+ Fills the pixmap with the given \a color.
+
+ \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}
+*/
+
+void QPixmap::fill(const QColor &color)
+{
+ if (isNull())
+ return;
+
+ detach();
+ data->fill(color);
+}
+
+/*! \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.
+*/
+int QPixmap::serialNumber() const
+{
+ if (isNull())
+ return 0;
+ return data->serialNumber();
+}
+
+/*!
+ 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
+{
+ int classKey = data->classId();
+ if (classKey >= 1024)
+ classKey = -(classKey >> 10);
+ return ((((qint64) classKey) << 56)
+ | (((qint64) data->serialNumber()) << 32)
+ | ((qint64) (data->detach_no)));
+}
+
+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);
+ }
+}
+
+/*!
+ \fn QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rectangle)
+
+ Creates a pixmap and paints the given \a widget, restricted by the
+ given \a rectangle, in it. If the \a widget has any children, then
+ they are also painted in the appropriate positions.
+
+ If no rectangle is specified (the default) the entire widget is
+ painted.
+
+ If \a widget is 0, the specified rectangle doesn't overlap the
+ widget's rectangle, or an error occurs, the function will return a
+ null QPixmap. If the rectangle is a superset of the given \a
+ widget, the areas outside the \a widget are covered with the
+ widget's background.
+
+ This function actually asks \a widget to paint itself (and its
+ children to paint themselves) by calling paintEvent() with painter
+ redirection turned on. But QPixmap also provides the grabWindow()
+ function which is a bit faster by grabbing pixels directly off the
+ screen. In addition, if there are overlaying windows,
+ grabWindow(), unlike grabWidget(), will see them.
+
+ \warning Do not grab a widget from its QWidget::paintEvent().
+ However, it is safe to grab a widget from another widget's
+ \l {QWidget::}{paintEvent()}.
+
+ \sa grabWindow()
+*/
+
+QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect)
+{
+ if (!widget)
+ return QPixmap();
+
+ if (widget->testAttribute(Qt::WA_PendingResizeEvent) || !widget->testAttribute(Qt::WA_WState_Created))
+ sendResizeEvents(widget);
+
+ QRect r(rect);
+ if (r.width() < 0)
+ r.setWidth(widget->width() - rect.x());
+ if (r.height() < 0)
+ r.setHeight(widget->height() - rect.y());
+
+ if (!r.intersects(widget->rect()))
+ return QPixmap();
+
+ QPixmap res(r.size());
+ widget->render(&res, QPoint(), r,
+ QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask);
+ return res;
+}
+
+/*!
+ \fn QPixmap QPixmap::grabWidget(QWidget *widget, int x, int y, int
+ width, int height)
+
+ \overload
+
+ Creates a pixmap and paints the given \a widget, restricted by
+ QRect(\a x, \a y, \a width, \a height), in it.
+
+ \warning Do not grab a widget from its QWidget::paintEvent().
+ However, it is safe to grab a widget from another widget's
+ \l {QWidget::}{paintEvent()}.
+*/
+
+
+/*!
+ \since 4.5
+
+ \enum QPixmap::ShareMode
+
+ This enum type defines the share modes that are available when
+ creating a QPixmap object from a raw X11 Pixmap handle.
+
+ \value ImplicitlyShared This mode will cause the QPixmap object to
+ create a copy of the internal data before it is modified, thus
+ keeping the original X11 pixmap intact.
+
+ \value ExplicitlyShared In this mode, the pixmap data will \e not be
+ copied before it is modified, which in effect will change the
+ original X11 pixmap.
+
+ \warning This enum is only used for X11 specific functions; using
+ it is non-portable.
+
+ \sa QPixmap::fromX11Pixmap()
+*/
+
+/*!
+ \since 4.5
+
+ \fn QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
+
+ Creates a QPixmap from the native X11 Pixmap handle \a pixmap,
+ using \a mode as the share mode. The default share mode is
+ QPixmap::ImplicitlyShared, which means that a copy of the pixmap is
+ made if someone tries to modify it by e.g. drawing onto it.
+
+ QPixmap does \e not take ownership of the \a pixmap handle, and
+ have to be deleted by the user.
+
+ \warning This function is X11 specific; using it is non-portable.
+
+ \sa QPixmap::ShareMode
+*/
+
+
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+
+/*!
+ Returns the pixmap's handle to the device context.
+
+ Note that, since QPixmap make use of \l {Implicit Data
+ Sharing}{implicit data sharing}, the detach() function must be
+ called explicitly to ensure that only \e this pixmap's data is
+ modified if the pixmap data is shared.
+
+ \warning This function is X11 specific; using it is non-portable.
+
+ \sa detach()
+*/
+
+Qt::HANDLE QPixmap::handle() const
+{
+#if defined(Q_WS_X11)
+ if (data->classId() == QPixmapData::X11Class)
+ return static_cast<QX11PixmapData*>(data)->handle();
+#endif
+ return 0;
+}
+#endif
+
+
+#ifdef QT3_SUPPORT
+static Qt::ImageConversionFlags colorModeToFlags(QPixmap::ColorMode mode)
+{
+ Qt::ImageConversionFlags flags = Qt::AutoColor;
+ switch (mode) {
+ case QPixmap::Color:
+ flags |= Qt::ColorOnly;
+ break;
+ case QPixmap::Mono:
+ flags |= Qt::MonoOnly;
+ break;
+ default:
+ break;// Nothing.
+ }
+ return flags;
+}
+
+/*!
+ Use the constructor that takes a Qt::ImageConversionFlag instead.
+*/
+
+QPixmap::QPixmap(const QString& fileName, const char *format, ColorMode mode)
+ : QPaintDevice()
+{
+ init(0, 0, QPixmapData::PixmapType);
+ if (!qt_pixmap_thread_test())
+ return;
+
+ load(fileName, format, colorModeToFlags(mode));
+}
+
+/*!
+ Constructs a pixmap from the QImage \a image.
+
+ Use the static fromImage() function instead.
+*/
+QPixmap::QPixmap(const QImage& image)
+ : QPaintDevice()
+{
+ init(0, 0, QPixmapData::PixmapType);
+ if (!qt_pixmap_thread_test())
+ return;
+
+ if (data->pixelType() == QPixmapData::BitmapType)
+ *this = QBitmap::fromImage(image);
+ else
+ *this = fromImage(image);
+}
+
+/*!
+ \overload
+
+ Converts the given \a image to a pixmap that is assigned to this
+ pixmap.
+
+ Use the static fromImage() function instead.
+*/
+
+QPixmap &QPixmap::operator=(const QImage &image)
+{
+ if (data->pixelType() == QPixmapData::BitmapType)
+ *this = QBitmap::fromImage(image);
+ else
+ *this = fromImage(image);
+ return *this;
+}
+
+/*!
+ Use the load() function that takes a Qt::ImageConversionFlag instead.
+*/
+
+bool QPixmap::load(const QString &fileName, const char *format, ColorMode mode)
+{
+ return load(fileName, format, colorModeToFlags(mode));
+}
+
+/*!
+ Use the loadFromData() function that takes a Qt::ImageConversionFlag instead.
+*/
+
+bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, ColorMode mode)
+{
+ return loadFromData(buf, len, format, colorModeToFlags(mode));
+}
+
+/*!
+ Use the static fromImage() function instead.
+*/
+bool QPixmap::convertFromImage(const QImage &image, ColorMode mode)
+{
+ if (data->pixelType() == QPixmapData::BitmapType)
+ *this = QBitmap::fromImage(image, colorModeToFlags(mode));
+ else
+ *this = fromImage(image, colorModeToFlags(mode));
+ return !isNull();
+}
+
+#endif
+
+/*****************************************************************************
+ QPixmap stream functions
+ *****************************************************************************/
+#if !defined(QT_NO_DATASTREAM)
+/*!
+ \relates QPixmap
+
+ Writes the given \a pixmap to the 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(), {Format of the QDataStream Operators}
+*/
+
+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(), {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
+{
+ QImage image;
+ stream >> image;
+
+ if (image.isNull()) {
+ pixmap = QPixmap();
+ } else if (image.depth() == 1) {
+ pixmap = QBitmap::fromImage(image);
+ } else {
+ pixmap = QPixmap::fromImage(image);
+ }
+ return stream;
+}
+
+#endif //QT_NO_DATASTREAM
+
+#ifdef QT3_SUPPORT
+Q_GUI_EXPORT void copyBlt(QPixmap *dst, int dx, int dy,
+ const QPixmap *src, int sx, int sy, int sw, int sh)
+{
+ Q_ASSERT_X(dst, "::copyBlt", "Destination pixmap must be non-null");
+ Q_ASSERT_X(src, "::copyBlt", "Source pixmap must be non-null");
+
+ if (src->hasAlphaChannel()) {
+ if (dst->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) {
+ QPainter p(dst);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
+ } else {
+ QImage image = dst->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
+ p.end();
+ *dst = QPixmap::fromImage(image);
+ }
+ } else {
+ QPainter p(dst);
+ p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
+ }
+
+}
+#endif
+
+/*!
+ \internal
+*/
+
+bool QPixmap::isDetached() const
+{
+ return data->ref == 1;
+}
+
+void QPixmap::deref()
+{
+ if (data && !data->ref.deref()) { // Destroy image if last ref
+#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)
+ if (data->classId() == QPixmapData::RasterClass) {
+ QRasterPixmapData *rData = static_cast<QRasterPixmapData*>(data);
+ if (rData->texture)
+ rData->texture->Release();
+ rData->texture = 0;
+ }
+#endif
+ if (data->is_cached && qt_pixmap_cleanup_hook_64)
+ qt_pixmap_cleanup_hook_64(cacheKey());
+ delete data;
+ data = 0;
+ }
+}
+
+/*!
+ \fn QImage QPixmap::convertToImage() const
+
+ Use the toImage() function instead.
+*/
+
+/*!
+ \fn bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
+
+ Use the static fromImage() function instead.
+*/
+
+/*!
+ \fn QPixmap QPixmap::xForm(const QMatrix &matrix) const
+
+ Use transformed() instead.
+*/
+
+/*!
+ \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
+ \i If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
+ is scaled to \a size.
+ \i If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
+ scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
+ \i 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.
+
+ \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);
+ if (newSize == size())
+ return *this;
+
+ QPixmap pix;
+ QTransform wm;
+ wm.scale((qreal)newSize.width() / width(), (qreal)newSize.height() / height());
+ 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();
+
+ QTransform wm;
+ qreal factor = (qreal) w / width();
+ wm.scale(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();
+
+ QTransform wm;
+ qreal factor = (qreal) h / height();
+ wm.scale(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);
+}
+
+/*!
+ \overload
+
+ 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);
+}
+
+
+
+
+
+
+
+
+/*!
+ \class QPixmap
+
+ \brief The QPixmap class is an off-screen image representation
+ that can be used as a paint device.
+
+ \ingroup multimedia
+ \ingroup shared
+ \mainclass
+
+ 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 true if a QPixmap object is
+ really a bitmap, otherwise returns 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. And because QPixmap is a
+ QPaintDevice subclass, QPainter can be used to draw directly onto
+ pixmaps.
+
+ In addition to the ordinary constructors, a QPixmap can be
+ constructed using the static grabWidget() and grabWindow()
+ functions which creates a QPixmap and paints the given widget, or
+ window, in it.
+
+ Note that the pixel data in a pixmap is internal and is managed by
+ the underlying window system. Pixels can only be accessed through
+ QPainter functions or by converting the QPixmap to a QImage.
+ Depending on the system, QPixmap is stored using a RGB32 or a
+ premultiplied alpha format. If the image has an alpha channel, and
+ if the system allows, the preferred format is premultiplied alpha.
+ Note also that QPixmap, unlike QImage, may be hardware dependent.
+ On X11 and Mac, a QPixmap is stored on the server side while a
+ QImage is stored on the client side (on Windows, these two classes
+ have an equivalent internal representation, i.e. both QImage and
+ QPixmap are stored on the client side and don't use any GDI
+ resources).
+
+ 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. On Windows, the
+ QPixmap class also supports conversion between \c HBITMAP and
+ 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.
+
+ 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.
+
+ \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 \o Format \o Description \o Qt's support
+ \row \o BMP \o Windows Bitmap \o Read/write
+ \row \o GIF \o Graphic Interchange Format (optional) \o Read
+ \row \o JPG \o Joint Photographic Experts Group \o Read/write
+ \row \o JPEG \o Joint Photographic Experts Group \o Read/write
+ \row \o PNG \o Portable Network Graphics \o Read/write
+ \row \o PBM \o Portable Bitmap \o Read
+ \row \o PGM \o Portable Graymap \o Read
+ \row \o PPM \o Portable Pixmap \o Read/write
+ \row \o XBM \o X11 Bitmap \o Read/write
+ \row \o XPM \o X11 Pixmap \o 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
+ \o \o Available Functions
+ \row
+ \o Geometry
+ \o
+ The size(), width() and height() functions provide information
+ about the pixmap's size. The rect() function returns the image's
+ enclosing rectangle.
+
+ \row
+ \o Alpha component
+ \o
+
+ The hasAlphaChannel() returns true if the pixmap has a format that
+ respects the alpha channel, otherwise returns false, while the
+ hasAlpha() function returns true if the pixmap has an alpha
+ channel \e or a mask (otherwise false).
+
+ The alphaChannel() function returns the alpha channel as a new
+ QPixmap object, while the mask() function returns the mask as a
+ QBitmap object. The alpha channel and mask can be set using the
+ setAlphaChannel() and setMask() functions, respectively.
+
+ \row
+ \o Low-level information
+ \o
+
+ 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.
+
+ The x11Info() function returns information about the configuration
+ of the X display used to display the widget. The
+ x11PictureHandle() function returns the X11 Picture handle of the
+ pixmap for XRender support. Note that the two latter functions are
+ only available on x11.
+
+ \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.
+
+ In addition, on Windows, the QPixmap class supports conversion to
+ and from HBitmap: the toWinHBITMAP() function creates a HBITMAP
+ equivalent to the QPixmap, based on the given HBitmapFormat, and
+ returns the HBITMAP handle. The fromWinHBITMAP() function returns
+ a QPixmap that is equivalent to the given bitmap which has the
+ specified format.
+
+ \section1 Pixmap Transformations
+
+ QPixmap supports a number of functions for creating a new pixmap
+ that is a transformed version of the original: 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.
+
+
+ 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.
+
+ There are also functions for changing attributes of a pixmap.
+ in-place: The fill() function fills the entire image with the
+ given color, the setMask() function sets a mask bitmap, and the
+ setAlphaChannel() function sets the pixmap's alpha channel.
+
+ \sa QBitmap, QImage, QImageReader, QImageWriter
+*/
+
+
+/*!
+ \typedef QPixmap::DataPtr
+ \internal
+*/
+
+/*!
+ \fn DataPtr &QPixmap::data_ptr()
+ \internal
+*/
+
+/*!
+ Returns true if this pixmap has an alpha channel, \e or has a
+ mask, otherwise returns false.
+
+ \sa hasAlphaChannel(), alphaChannel(), mask()
+*/
+bool QPixmap::hasAlpha() const
+{
+ return (data->hasAlphaChannel() || !data->mask().isNull());
+}
+
+/*!
+ Returns true if the pixmap has a format that respects the alpha
+ channel, otherwise returns false.
+
+ \sa alphaChannel(), hasAlpha()
+*/
+bool QPixmap::hasAlphaChannel() const
+{
+ return data->hasAlphaChannel();
+}
+
+/*!
+ \reimp
+*/
+int QPixmap::metric(PaintDeviceMetric metric) const
+{
+ return data->metric(metric);
+}
+
+/*!
+ \fn void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
+
+ Sets the alpha channel of this pixmap to the given \a alphaChannel
+ by converting the \a alphaChannel into 32 bit and using the
+ intensity of the RGB pixel values.
+
+ The effect of this function is undefined when the pixmap is being
+ painted on.
+
+ \sa alphaChannel(), {QPixmap#Pixmap Transformations}{Pixmap
+ Transformations}
+ */
+void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
+{
+ if (alphaChannel.isNull())
+ return;
+
+ if (paintingActive()) {
+ qWarning("QPixmap::setAlphaChannel: "
+ "Cannot set alpha channel while pixmap is being painted on");
+ return;
+ }
+
+ if (width() != alphaChannel.width() && height() != alphaChannel.height()) {
+ qWarning("QPixmap::setAlphaChannel: "
+ "The pixmap and the alpha channel pixmap must have the same size");
+ return;
+ }
+
+ detach();
+ data->setAlphaChannel(alphaChannel);
+}
+
+/*!
+ Returns the alpha channel of the pixmap as a new grayscale QPixmap in which
+ each pixel's red, green, and blue values are given the alpha value of the
+ original pixmap. The color depth of the returned pixmap is the system depth
+ on X11 and 8-bit on Windows and Mac OS X.
+
+ You can use this function while debugging
+ to get a visible image of the alpha channel. If the pixmap doesn't have an
+ alpha channel, i.e., the alpha channel's value for all pixels equals
+ 0xff), a null pixmap is returned. You can check this with the \c isNull()
+ function.
+
+ We show an example:
+
+ \snippet doc/src/snippets/alphachannel.cpp 0
+
+ \image alphachannelimage.png The pixmap and channelImage QPixmaps
+
+ \sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap
+ Information}
+*/
+QPixmap QPixmap::alphaChannel() const
+{
+ return data->alphaChannel();
+}
+
+/*!
+ \reimp
+*/
+QPaintEngine *QPixmap::paintEngine() const
+{
+ return data->paintEngine();
+}
+
+/*!
+ \fn QBitmap QPixmap::mask() const
+
+ Extracts a bitmap mask from the pixmap's alphachannel.
+
+ This is potentially an expensive operation.
+
+ \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
+*/
+QBitmap QPixmap::mask() const
+{
+ return data->mask();
+}
+
+/*!
+ Returns the default pixmap depth used by the application.
+
+ On Windows and Mac, the default depth is always 32. On X11 and
+ embedded, the depth of the screen will be returned by this
+ function.
+
+ \sa depth(), QColormap::depth(), {QPixmap#Pixmap Information}{Pixmap Information}
+
+*/
+int QPixmap::defaultDepth()
+{
+#if defined(Q_WS_QWS)
+ return QScreen::instance()->depth();
+#elif defined(Q_WS_X11)
+ return QX11Info::appDepth();
+#elif defined(Q_OS_WINCE)
+ return QColormap::instance().depth();
+#elif defined(Q_WS_WIN)
+ return 32; // XXX
+#elif defined(Q_WS_MAC)
+ return 32;
+#elif defined(Q_OS_SYMBIAN)
+ return S60->screenDepth;
+#endif
+
+}
+
+typedef void (*_qt_pixmap_cleanup_hook_64)(qint64);
+extern _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64;
+
+/*!
+ 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()
+{
+ QPixmapData::ClassId id = data->classId();
+ if (id == QPixmapData::RasterClass) {
+ QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(data);
+ rasterData->image.detach();
+#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECT3D)
+ if (rasterData->texture) {
+ rasterData->texture->Release();
+ rasterData->texture = 0;
+ }
+#endif
+ }
+
+ if (data->is_cached && qt_pixmap_cleanup_hook_64 && data->ref == 1)
+ qt_pixmap_cleanup_hook_64(cacheKey());
+
+#if defined(Q_WS_MAC)
+ QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data) : 0;
+ if (macData) {
+ if (macData->cg_mask) {
+ CGImageRelease(macData->cg_mask);
+ macData->cg_mask = 0;
+ }
+ }
+#endif
+
+ if (data->ref != 1) {
+ *this = copy();
+#if defined(Q_WS_MAC) && !defined(QT_MAC_NO_QUICKDRAW)
+ if (id == QPixmapData::MacClass) {
+ macData->qd_alpha = 0;
+ }
+#endif
+ }
+ ++data->detach_no;
+
+#if defined(Q_WS_X11)
+ if (data->classId() == QPixmapData::X11Class) {
+ QX11PixmapData *d = static_cast<QX11PixmapData*>(data);
+ d->uninit = false;
+
+ // reset the cache data
+ if (d->hd2) {
+ XFreePixmap(X11->display, d->hd2);
+ d->hd2 = 0;
+ }
+ }
+#elif defined(Q_WS_MAC)
+ if (macData) {
+ macData->macReleaseCGImageRef();
+ macData->uninit = false;
+ }
+#endif
+}
+
+/*!
+ \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 toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
+*/
+QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
+{
+ if (image.isNull())
+ return QPixmap();
+
+ QPixmapData *data;
+ QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
+ if (gs)
+ data = gs->createPixmapData(QPixmapData::PixmapType);
+ else
+ data = QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType);
+
+ data->fromImage(image, flags);
+ return QPixmap(data);
+}
+
+/*!
+ \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 X11that 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.
+
+ \warning In general, grabbing an area outside the screen is not
+ safe. This depends on the underlying window system.
+
+ \sa grabWidget(), {Screenshot Example}
+*/
+
+/*!
+ \internal
+*/
+QPixmapData* QPixmap::pixmapData() const
+{
+ return data;
+}
+
+QT_END_NAMESPACE