src/gui/image/qpixmap.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    80 #if defined(Q_OS_SYMBIAN)
    80 #if defined(Q_OS_SYMBIAN)
    81 # include <private/qt_s60_p.h>
    81 # include <private/qt_s60_p.h>
    82 #endif
    82 #endif
    83 
    83 
    84 #include "qpixmap_raster_p.h"
    84 #include "qpixmap_raster_p.h"
       
    85 #include "private/qstylehelper_p.h"
    85 
    86 
    86 QT_BEGIN_NAMESPACE
    87 QT_BEGIN_NAMESPACE
    87 
    88 
    88 // ### Qt 5: remove
    89 // ### Qt 5: remove
    89 Q_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap)
    90 Q_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap)
   633     }
   634     }
   634 
   635 
   635     if (size() == s)
   636     if (size() == s)
   636         return;
   637         return;
   637 
   638 
       
   639     // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get
       
   640     // the actual underlaying runtime pixmap data.
       
   641     QPixmapData *pd = pixmapData();
       
   642 
   638     // Create new pixmap
   643     // Create new pixmap
   639     QPixmap pm(QSize(w, h), data ? data->type : QPixmapData::PixmapType);
   644     QPixmap pm(QSize(w, h), pd ? pd->type : QPixmapData::PixmapType);
   640     bool uninit = false;
   645     bool uninit = false;
   641 #if defined(Q_WS_X11)
   646 #if defined(Q_WS_X11)
   642     QX11PixmapData *x11Data = data && data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data.data()) : 0;
   647     QX11PixmapData *x11Data = pd && pd->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(pd) : 0;
   643     if (x11Data) {
   648     if (x11Data) {
   644         pm.x11SetScreen(x11Data->xinfo.screen());
   649         pm.x11SetScreen(x11Data->xinfo.screen());
   645         uninit = x11Data->flags & QX11PixmapData::Uninitialized;
   650         uninit = x11Data->flags & QX11PixmapData::Uninitialized;
   646     }
   651     }
   647 #elif defined(Q_WS_MAC)
   652 #elif defined(Q_WS_MAC)
   648     QMacPixmapData *macData = data && data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
   653     QMacPixmapData *macData = pd && pd->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0;
   649     if (macData)
   654     if (macData)
   650         uninit = macData->uninit;
   655         uninit = macData->uninit;
   651 #endif
   656 #endif
   652     if (!uninit && !isNull()) {
   657     if (!uninit && !isNull()) {
   653         // Copy old pixmap
   658         // Copy old pixmap
   657         p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h));
   662         p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h));
   658     }
   663     }
   659 
   664 
   660 #if defined(Q_WS_X11)
   665 #if defined(Q_WS_X11)
   661     if (x11Data && x11Data->x11_mask) {
   666     if (x11Data && x11Data->x11_mask) {
   662         QX11PixmapData *pmData = static_cast<QX11PixmapData*>(pm.data.data());
   667         QX11PixmapData *pmData = static_cast<QX11PixmapData*>(pd);
   663         pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display,
   668         pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display,
   664                                                      RootWindow(x11Data->xinfo.display(),
   669                                                      RootWindow(x11Data->xinfo.display(),
   665                                                                 x11Data->xinfo.screen()),
   670                                                                 x11Data->xinfo.screen()),
   666                                                       w, h, 1);
   671                                                       w, h, 1);
   667         GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0);
   672         GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0);
   823 {
   828 {
   824     if (fileName.isEmpty())
   829     if (fileName.isEmpty())
   825         return false;
   830         return false;
   826 
   831 
   827     QFileInfo info(fileName);
   832     QFileInfo info(fileName);
   828     QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') +
   833     if (!info.exists())
   829         QString::number(info.size()) + QLatin1Char('_') + QString::number(data ? data->pixelType() : QPixmapData::PixmapType);
   834         return false;
       
   835 
       
   836     QString key = QLatin1Literal("qt_pixmap")
       
   837                   % info.absoluteFilePath()
       
   838                   % HexString<uint>(info.lastModified().toTime_t())
       
   839                   % HexString<quint64>(info.size())
       
   840                   % HexString<uint>(data ? data->pixelType() : QPixmapData::PixmapType);
   830 
   841 
   831     if (QPixmapCache::find(key, *this))
   842     if (QPixmapCache::find(key, *this))
   832         return true;
   843         return true;
   833 
   844 
   834     QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, data ? data->type : QPixmapData::PixmapType));
   845     QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, data ? data->type : QPixmapData::PixmapType));
  1161 */
  1172 */
  1162 
  1173 
  1163 Qt::HANDLE QPixmap::handle() const
  1174 Qt::HANDLE QPixmap::handle() const
  1164 {
  1175 {
  1165 #if defined(Q_WS_X11)
  1176 #if defined(Q_WS_X11)
  1166     if (data && data->classId() == QPixmapData::X11Class)
  1177     const QPixmapData *pd = pixmapData();
  1167         return static_cast<const QX11PixmapData*>(data.constData())->handle();
  1178     if (pd && pd->classId() == QPixmapData::X11Class)
       
  1179         return static_cast<const QX11PixmapData*>(pd)->handle();
  1168 #endif
  1180 #endif
  1169     return 0;
  1181     return 0;
  1170 }
  1182 }
  1171 #endif
  1183 #endif
  1172 
  1184 
  1279 
  1291 
  1280     Writes the given \a pixmap to the given \a stream as a PNG
  1292     Writes the given \a pixmap to the given \a stream as a PNG
  1281     image. Note that writing the stream to a file will not produce a
  1293     image. Note that writing the stream to a file will not produce a
  1282     valid image file.
  1294     valid image file.
  1283 
  1295 
  1284     \sa QPixmap::save(), {Format of the QDataStream Operators}
  1296     \sa QPixmap::save(), {Serializing Qt Data Types}
  1285 */
  1297 */
  1286 
  1298 
  1287 QDataStream &operator<<(QDataStream &stream, const QPixmap &pixmap)
  1299 QDataStream &operator<<(QDataStream &stream, const QPixmap &pixmap)
  1288 {
  1300 {
  1289     return stream << pixmap.toImage();
  1301     return stream << pixmap.toImage();
  1292 /*!
  1304 /*!
  1293     \relates QPixmap
  1305     \relates QPixmap
  1294 
  1306 
  1295     Reads an image from the given \a stream into the given \a pixmap.
  1307     Reads an image from the given \a stream into the given \a pixmap.
  1296 
  1308 
  1297     \sa QPixmap::load(), {Format of the QDataStream Operators}
  1309     \sa QPixmap::load(), {Serializing Qt Data Types}
  1298 */
  1310 */
  1299 
  1311 
  1300 QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
  1312 QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
  1301 {
  1313 {
  1302     QImage image;
  1314     QImage image;
  1752     i.e. transformed() returns the smallest pixmap containing all
  1764     i.e. transformed() returns the smallest pixmap containing all
  1753     transformed points of the original pixmap. The static trueMatrix()
  1765     transformed points of the original pixmap. The static trueMatrix()
  1754     function returns the actual matrix used for transforming the
  1766     function returns the actual matrix used for transforming the
  1755     pixmap.
  1767     pixmap.
  1756 
  1768 
       
  1769     \note When using the native X11 graphics system, the pixmap
       
  1770     becomes invalid when the QApplication instance is destroyed.
       
  1771 
  1757     \sa QBitmap, QImage, QImageReader, QImageWriter
  1772     \sa QBitmap, QImage, QImageReader, QImageWriter
  1758 */
  1773 */
  1759 
  1774 
  1760 
  1775 
  1761 /*!
  1776 /*!
  1942 void QPixmap::detach()
  1957 void QPixmap::detach()
  1943 {
  1958 {
  1944     if (!data)
  1959     if (!data)
  1945         return;
  1960         return;
  1946 
  1961 
  1947     QPixmapData::ClassId id = data->classId();
  1962     // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get
       
  1963     // the actual underlaying runtime pixmap data.
       
  1964     QPixmapData *pd = pixmapData();
       
  1965     QPixmapData::ClassId id = pd->classId();
  1948     if (id == QPixmapData::RasterClass) {
  1966     if (id == QPixmapData::RasterClass) {
  1949         QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(data.data());
  1967         QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(pd);
  1950         rasterData->image.detach();
  1968         rasterData->image.detach();
  1951     }
  1969     }
  1952 
  1970 
  1953     if (data->is_cached && data->ref == 1)
  1971     if (data->is_cached && data->ref == 1)
  1954         QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data());
  1972         QImagePixmapCleanupHooks::executePixmapDataModificationHooks(pd);
  1955 
  1973 
  1956 #if defined(Q_WS_MAC)
  1974 #if defined(Q_WS_MAC)
  1957     QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
  1975     QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0;
  1958     if (macData) {
  1976     if (macData) {
  1959         if (macData->cg_mask) {
  1977         if (macData->cg_mask) {
  1960             CGImageRelease(macData->cg_mask);
  1978             CGImageRelease(macData->cg_mask);
  1961             macData->cg_mask = 0;
  1979             macData->cg_mask = 0;
  1962         }
  1980         }
  1967         *this = copy();
  1985         *this = copy();
  1968     }
  1986     }
  1969     ++data->detach_no;
  1987     ++data->detach_no;
  1970 
  1988 
  1971 #if defined(Q_WS_X11)
  1989 #if defined(Q_WS_X11)
  1972     if (data->classId() == QPixmapData::X11Class) {
  1990     if (pd->classId() == QPixmapData::X11Class) {
  1973         QX11PixmapData *d = static_cast<QX11PixmapData*>(data.data());
  1991         QX11PixmapData *d = static_cast<QX11PixmapData*>(pd);
  1974         d->flags &= ~QX11PixmapData::Uninitialized;
  1992         d->flags &= ~QX11PixmapData::Uninitialized;
  1975 
  1993 
  1976         // reset the cache data
  1994         // reset the cache data
  1977         if (d->hd2) {
  1995         if (d->hd2) {
  1978             XFreePixmap(X11->display, d->hd2);
  1996             XFreePixmap(X11->display, d->hd2);
  1998     In case of monochrome and 8-bit images, the image is first
  2016     In case of monochrome and 8-bit images, the image is first
  1999     converted to a 32-bit pixmap and then filled with the colors in
  2017     converted to a 32-bit pixmap and then filled with the colors in
  2000     the color table. If this is too expensive an operation, you can
  2018     the color table. If this is too expensive an operation, you can
  2001     use QBitmap::fromImage() instead.
  2019     use QBitmap::fromImage() instead.
  2002 
  2020 
  2003     \sa toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
  2021     \sa fromImageReader(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
  2004 */
  2022 */
  2005 QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
  2023 QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
  2006 {
  2024 {
  2007     if (image.isNull())
  2025     if (image.isNull())
  2008         return QPixmap();
  2026         return QPixmap();
  2013     data->fromImage(image, flags);
  2031     data->fromImage(image, flags);
  2014     return QPixmap(data.take());
  2032     return QPixmap(data.take());
  2015 }
  2033 }
  2016 
  2034 
  2017 /*!
  2035 /*!
       
  2036     \fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
       
  2037 
       
  2038     Create a QPixmap from an image read directly from an \a imageReader.
       
  2039     The \a flags argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
       
  2040     Passing 0 for \a flags sets all the default options.
       
  2041 
       
  2042     On some systems, reading an image directly to QPixmap can use less memory than
       
  2043     reading a QImage to convert it to QPixmap.
       
  2044 
       
  2045     \sa fromImage(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
       
  2046 */
       
  2047 QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
       
  2048 {
       
  2049     QGraphicsSystem *gs = QApplicationPrivate::graphicsSystem();
       
  2050     QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::PixmapType)
       
  2051             : QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType));
       
  2052     data->fromImageReader(imageReader, flags);
       
  2053     return QPixmap(data.take());
       
  2054 }
       
  2055 
       
  2056 /*!
  2018     \fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int
  2057     \fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int
  2019     width, int height)
  2058     width, int height)
  2020 
  2059 
  2021     Creates and returns a pixmap constructed by grabbing the contents
  2060     Creates and returns a pixmap constructed by grabbing the contents
  2022     of the given \a window restricted by QRect(\a x, \a y, \a width,
  2061     of the given \a window restricted by QRect(\a x, \a y, \a width,
  2058 /*!
  2097 /*!
  2059   \internal
  2098   \internal
  2060 */
  2099 */
  2061 QPixmapData* QPixmap::pixmapData() const
  2100 QPixmapData* QPixmap::pixmapData() const
  2062 {
  2101 {
  2063     return data.data();
  2102     if (data) {
  2064 }
  2103         QPixmapData* pm = data.data();
       
  2104         return pm->runtimeData() ? pm->runtimeData() : pm;
       
  2105     }
       
  2106 
       
  2107     return 0;
       
  2108 }
       
  2109 
  2065 
  2110 
  2066 /*!
  2111 /*!
  2067     \enum QPixmap::HBitmapFormat
  2112     \enum QPixmap::HBitmapFormat
  2068 
  2113 
  2069     \bold{Win32 only:} This enum defines how the conversion between \c
  2114     \bold{Win32 only:} This enum defines how the conversion between \c