src/gui/image/qpixmap.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   111     init(w, h, int(type));
   111     init(w, h, int(type));
   112 }
   112 }
   113 
   113 
   114 void QPixmap::init(int w, int h, int type)
   114 void QPixmap::init(int w, int h, int type)
   115 {
   115 {
   116     QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
   116     if ((w > 0 && h > 0) || type == QPixmapData::BitmapType)
   117     if (gs)
   117         data = QPixmapData::create(w, h, (QPixmapData::PixelType) type);
   118         data = gs->createPixmapData(static_cast<QPixmapData::PixelType>(type));
       
   119     else
   118     else
   120         data = QGraphicsSystem::createDefaultPixmapData(static_cast<QPixmapData::PixelType>(type));
   119         data = 0;
   121 
       
   122     data->resize(w, h);
       
   123 }
   120 }
   124 
   121 
   125 /*!
   122 /*!
   126     \enum QPixmap::ColorMode
   123     \enum QPixmap::ColorMode
   127 
   124 
   305     if (!xpm)
   302     if (!xpm)
   306         return;
   303         return;
   307 
   304 
   308     QImage image(xpm);
   305     QImage image(xpm);
   309     if (!image.isNull()) {
   306     if (!image.isNull()) {
   310         if (data->pixelType() == QPixmapData::BitmapType)
   307         if (data && data->pixelType() == QPixmapData::BitmapType)
   311             *this = QBitmap::fromImage(image);
   308             *this = QBitmap::fromImage(image);
   312         else
   309         else
   313             *this = fromImage(image);
   310             *this = fromImage(image);
   314     }
   311     }
   315 }
   312 }
   320     Destroys the pixmap.
   317     Destroys the pixmap.
   321 */
   318 */
   322 
   319 
   323 QPixmap::~QPixmap()
   320 QPixmap::~QPixmap()
   324 {
   321 {
   325     Q_ASSERT(data->ref >= 1); // Catch if ref-counting changes again
   322     Q_ASSERT(!data || data->ref >= 1); // Catch if ref-counting changes again
   326     if (data->is_cached && data->ref == 1) // ref will be decrememnted after destructor returns
   323     if (data && data->is_cached && data->ref == 1) // ref will be decrememnted after destructor returns
   327         QImagePixmapCleanupHooks::executePixmapDestructionHooks(this);
   324         QImagePixmapCleanupHooks::executePixmapDestructionHooks(this);
   328 }
   325 }
   329 
   326 
   330 /*!
   327 /*!
   331   \internal
   328   \internal
   542     A null pixmap has zero width, zero height and no contents. You
   539     A null pixmap has zero width, zero height and no contents. You
   543     cannot draw in a null pixmap.
   540     cannot draw in a null pixmap.
   544 */
   541 */
   545 bool QPixmap::isNull() const
   542 bool QPixmap::isNull() const
   546 {
   543 {
   547     return data->isNull();
   544     return !data || data->isNull();
   548 }
   545 }
   549 
   546 
   550 /*!
   547 /*!
   551     \fn int QPixmap::width() const
   548     \fn int QPixmap::width() const
   552 
   549 
   554 
   551 
   555     \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
   552     \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
   556 */
   553 */
   557 int QPixmap::width() const
   554 int QPixmap::width() const
   558 {
   555 {
   559     return data->width();
   556     return data ? data->width() : 0;
   560 }
   557 }
   561 
   558 
   562 /*!
   559 /*!
   563     \fn int QPixmap::height() const
   560     \fn int QPixmap::height() const
   564 
   561 
   566 
   563 
   567     \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
   564     \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
   568 */
   565 */
   569 int QPixmap::height() const
   566 int QPixmap::height() const
   570 {
   567 {
   571     return data->height();
   568     return data ? data->height() : 0;
   572 }
   569 }
   573 
   570 
   574 /*!
   571 /*!
   575     \fn QSize QPixmap::size() const
   572     \fn QSize QPixmap::size() const
   576 
   573 
   579     \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
   576     \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
   580     Information}
   577     Information}
   581 */
   578 */
   582 QSize QPixmap::size() const
   579 QSize QPixmap::size() const
   583 {
   580 {
   584     return QSize(data->width(), data->height());
   581     return data ? QSize(data->width(), data->height()) : QSize();
   585 }
   582 }
   586 
   583 
   587 /*!
   584 /*!
   588     \fn QRect QPixmap::rect() const
   585     \fn QRect QPixmap::rect() const
   589 
   586 
   591 
   588 
   592     \sa {QPixmap#Pixmap Information}{Pixmap Information}
   589     \sa {QPixmap#Pixmap Information}{Pixmap Information}
   593 */
   590 */
   594 QRect QPixmap::rect() const
   591 QRect QPixmap::rect() const
   595 {
   592 {
   596     return QRect(0, 0, data->width(), data->height());
   593     return data ? QRect(0, 0, data->width(), data->height()) : QRect();
   597 }
   594 }
   598 
   595 
   599 /*!
   596 /*!
   600     \fn int QPixmap::depth() const
   597     \fn int QPixmap::depth() const
   601 
   598 
   607     \sa defaultDepth(), {QPixmap#Pixmap Information}{Pixmap
   604     \sa defaultDepth(), {QPixmap#Pixmap Information}{Pixmap
   608     Information}
   605     Information}
   609 */
   606 */
   610 int QPixmap::depth() const
   607 int QPixmap::depth() const
   611 {
   608 {
   612     return data->depth();
   609     return data ? data->depth() : 0;
   613 }
   610 }
   614 
   611 
   615 /*!
   612 /*!
   616     \fn void QPixmap::resize(const QSize &size)
   613     \fn void QPixmap::resize(const QSize &size)
   617     \overload
   614     \overload
   637 
   634 
   638     if (size() == s)
   635     if (size() == s)
   639         return;
   636         return;
   640 
   637 
   641     // Create new pixmap
   638     // Create new pixmap
   642     QPixmap pm(QSize(w, h), data->type);
   639     QPixmap pm(QSize(w, h), data ? data->type : QPixmapData::PixmapType);
   643     bool uninit = false;
   640     bool uninit = false;
   644 #if defined(Q_WS_X11)
   641 #if defined(Q_WS_X11)
   645     QX11PixmapData *x11Data = data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data.data()) : 0;
   642     QX11PixmapData *x11Data = data && data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data.data()) : 0;
   646     if (x11Data) {
   643     if (x11Data) {
   647         pm.x11SetScreen(x11Data->xinfo.screen());
   644         pm.x11SetScreen(x11Data->xinfo.screen());
   648         uninit = x11Data->flags & QX11PixmapData::Uninitialized;
   645         uninit = x11Data->flags & QX11PixmapData::Uninitialized;
   649     }
   646     }
   650 #elif defined(Q_WS_MAC)
   647 #elif defined(Q_WS_MAC)
   651     QMacPixmapData *macData = data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
   648     QMacPixmapData *macData = data && data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
   652     if (macData)
   649     if (macData)
   653         uninit = macData->uninit;
   650         uninit = macData->uninit;
   654 #endif
   651 #endif
   655     if (!uninit && !isNull()) {
   652     if (!uninit && !isNull()) {
   656         // Copy old pixmap
   653         // Copy old pixmap
   726     if (!mask.isNull() && mask.size() != size()) {
   723     if (!mask.isNull() && mask.size() != size()) {
   727         qWarning("QPixmap::setMask() mask size differs from pixmap size");
   724         qWarning("QPixmap::setMask() mask size differs from pixmap size");
   728         return;
   725         return;
   729     }
   726     }
   730 
   727 
       
   728     if (isNull())
       
   729         return;
       
   730 
   731     if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
   731     if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
   732        return;
   732        return;
   733 
   733 
   734     detach();
   734     detach();
   735     data->setMask(mask);
   735     data->setMask(mask);
   824     if (fileName.isEmpty())
   824     if (fileName.isEmpty())
   825         return false;
   825         return false;
   826 
   826 
   827     QFileInfo info(fileName);
   827     QFileInfo info(fileName);
   828     QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') +
   828     QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') +
   829                   QString::number(info.size()) + QLatin1Char('_') + QString::number(data->pixelType());
   829         QString::number(info.size()) + QLatin1Char('_') + QString::number(data ? data->pixelType() : QPixmapData::PixmapType);
   830 
   830 
   831     if (QPixmapCache::find(key, *this))
   831     if (QPixmapCache::find(key, *this))
   832         return true;
   832         return true;
   833 
   833 
   834     if (data->fromFile(fileName, format, flags)) {
   834     QPixmapData *tmp = QPixmapData::create(0, 0, QPixmapData::PixmapType);
       
   835     if (tmp->fromFile(fileName, format, flags)) {
       
   836         data = tmp;
   835         QPixmapCache::insert(key, *this);
   837         QPixmapCache::insert(key, *this);
   836         return true;
   838         return true;
   837     }
   839     }
   838 
   840     delete tmp;
   839     return false;
   841     return false;
   840 }
   842 }
   841 
   843 
   842 /*!
   844 /*!
   843     \fn bool QPixmap::loadFromData(const uchar *data, uint len, const char *format, Qt::ImageConversionFlags flags)
   845     \fn bool QPixmap::loadFromData(const uchar *data, uint len, const char *format, Qt::ImageConversionFlags flags)
   858     Writing Image Files}
   860     Writing Image Files}
   859 */
   861 */
   860 
   862 
   861 bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
   863 bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
   862 {
   864 {
       
   865     if (len == 0 || buf == 0)
       
   866         return false;
       
   867 
       
   868     if (!data)
       
   869         data = QPixmapData::create(0, 0, QPixmapData::PixmapType);
       
   870 
   863     return data->fromData(buf, len, format, flags);
   871     return data->fromData(buf, len, format, flags);
   864 }
   872 }
   865 
   873 
   866 /*!
   874 /*!
   867     \fn bool QPixmap::loadFromData(const QByteArray &data, const char *format, Qt::ImageConversionFlags flags)
   875     \fn bool QPixmap::loadFromData(const QByteArray &data, const char *format, Qt::ImageConversionFlags flags)
  1003 
  1011 
  1004     The cacheKey() will change when the pixmap is altered.
  1012     The cacheKey() will change when the pixmap is altered.
  1005 */
  1013 */
  1006 qint64 QPixmap::cacheKey() const
  1014 qint64 QPixmap::cacheKey() const
  1007 {
  1015 {
       
  1016     if (isNull())
       
  1017         return 0;
       
  1018 
  1008     int classKey = data->classId();
  1019     int classKey = data->classId();
  1009     if (classKey >= 1024)
  1020     if (classKey >= 1024)
  1010         classKey = -(classKey >> 10);
  1021         classKey = -(classKey >> 10);
  1011     return ((((qint64) classKey) << 56)
  1022     return ((((qint64) classKey) << 56)
  1012             | (((qint64) data->serialNumber()) << 32)
  1023             | (((qint64) data->serialNumber()) << 32)
  1151 */
  1162 */
  1152 
  1163 
  1153 Qt::HANDLE QPixmap::handle() const
  1164 Qt::HANDLE QPixmap::handle() const
  1154 {
  1165 {
  1155 #if defined(Q_WS_X11)
  1166 #if defined(Q_WS_X11)
  1156     if (data->classId() == QPixmapData::X11Class)
  1167     if (data && data->classId() == QPixmapData::X11Class)
  1157         return static_cast<const QX11PixmapData*>(data.constData())->handle();
  1168         return static_cast<const QX11PixmapData*>(data.constData())->handle();
  1158 #endif
  1169 #endif
  1159     return 0;
  1170     return 0;
  1160 }
  1171 }
  1161 #endif
  1172 #endif
  1202 {
  1213 {
  1203     init(0, 0, QPixmapData::PixmapType);
  1214     init(0, 0, QPixmapData::PixmapType);
  1204     if (!qt_pixmap_thread_test())
  1215     if (!qt_pixmap_thread_test())
  1205         return;
  1216         return;
  1206 
  1217 
  1207     if (data->pixelType() == QPixmapData::BitmapType)
  1218     if (data && data->pixelType() == QPixmapData::BitmapType)
  1208         *this = QBitmap::fromImage(image);
  1219         *this = QBitmap::fromImage(image);
  1209     else
  1220     else
  1210         *this = fromImage(image);
  1221         *this = fromImage(image);
  1211 }
  1222 }
  1212 
  1223 
  1219     Use the static fromImage() function instead.
  1230     Use the static fromImage() function instead.
  1220 */
  1231 */
  1221 
  1232 
  1222 QPixmap &QPixmap::operator=(const QImage &image)
  1233 QPixmap &QPixmap::operator=(const QImage &image)
  1223 {
  1234 {
  1224     if (data->pixelType() == QPixmapData::BitmapType)
  1235     if (data && data->pixelType() == QPixmapData::BitmapType)
  1225         *this = QBitmap::fromImage(image);
  1236         *this = QBitmap::fromImage(image);
  1226     else
  1237     else
  1227         *this = fromImage(image);
  1238         *this = fromImage(image);
  1228     return *this;
  1239     return *this;
  1229 }
  1240 }
  1249 /*!
  1260 /*!
  1250     Use the static fromImage() function instead.
  1261     Use the static fromImage() function instead.
  1251 */
  1262 */
  1252 bool QPixmap::convertFromImage(const QImage &image, ColorMode mode)
  1263 bool QPixmap::convertFromImage(const QImage &image, ColorMode mode)
  1253 {
  1264 {
  1254     if (data->pixelType() == QPixmapData::BitmapType)
  1265     if (data && data->pixelType() == QPixmapData::BitmapType)
  1255         *this = QBitmap::fromImage(image, colorModeToFlags(mode));
  1266         *this = QBitmap::fromImage(image, colorModeToFlags(mode));
  1256     else
  1267     else
  1257         *this = fromImage(image, colorModeToFlags(mode));
  1268         *this = fromImage(image, colorModeToFlags(mode));
  1258     return !isNull();
  1269     return !isNull();
  1259 }
  1270 }
  1336     \internal
  1347     \internal
  1337 */
  1348 */
  1338 
  1349 
  1339 bool QPixmap::isDetached() const
  1350 bool QPixmap::isDetached() const
  1340 {
  1351 {
  1341     return data->ref == 1;
  1352     return data && data->ref == 1;
  1342 }
  1353 }
  1343 
  1354 
  1344 /*! \internal
  1355 /*! \internal
  1345   ### Qt5 - remove me.
  1356   ### Qt5 - remove me.
  1346 */
  1357 */
  1748 
  1759 
  1749     \sa hasAlphaChannel(), mask()
  1760     \sa hasAlphaChannel(), mask()
  1750 */
  1761 */
  1751 bool QPixmap::hasAlpha() const
  1762 bool QPixmap::hasAlpha() const
  1752 {
  1763 {
  1753     return (data->hasAlphaChannel() || !data->mask().isNull());
  1764     return data && (data->hasAlphaChannel() || !data->mask().isNull());
  1754 }
  1765 }
  1755 
  1766 
  1756 /*!
  1767 /*!
  1757     Returns true if the pixmap has a format that respects the alpha
  1768     Returns true if the pixmap has a format that respects the alpha
  1758     channel, otherwise returns false.
  1769     channel, otherwise returns false.
  1759 
  1770 
  1760     \sa hasAlpha()
  1771     \sa hasAlpha()
  1761 */
  1772 */
  1762 bool QPixmap::hasAlphaChannel() const
  1773 bool QPixmap::hasAlphaChannel() const
  1763 {
  1774 {
  1764     return data->hasAlphaChannel();
  1775     return data && data->hasAlphaChannel();
  1765 }
  1776 }
  1766 
  1777 
  1767 /*!
  1778 /*!
  1768     \internal
  1779     \internal
  1769 */
  1780 */
  1770 int QPixmap::metric(PaintDeviceMetric metric) const
  1781 int QPixmap::metric(PaintDeviceMetric metric) const
  1771 {
  1782 {
  1772     return data->metric(metric);
  1783     return data ? data->metric(metric) : 0;
  1773 }
  1784 }
  1774 
  1785 
  1775 /*!
  1786 /*!
  1776     \fn void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
  1787     \fn void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
  1777     \obsolete
  1788     \obsolete
  1839     \sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap
  1850     \sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap
  1840     Information}
  1851     Information}
  1841 */
  1852 */
  1842 QPixmap QPixmap::alphaChannel() const
  1853 QPixmap QPixmap::alphaChannel() const
  1843 {
  1854 {
  1844     return data->alphaChannel();
  1855     return data ? data->alphaChannel() : QPixmap();
  1845 }
  1856 }
  1846 
  1857 
  1847 /*!
  1858 /*!
  1848     \internal
  1859     \internal
  1849 */
  1860 */
  1850 QPaintEngine *QPixmap::paintEngine() const
  1861 QPaintEngine *QPixmap::paintEngine() const
  1851 {
  1862 {
  1852     return data->paintEngine();
  1863     return data ? data->paintEngine() : 0;
  1853 }
  1864 }
  1854 
  1865 
  1855 /*!
  1866 /*!
  1856     \fn QBitmap QPixmap::mask() const
  1867     \fn QBitmap QPixmap::mask() const
  1857 
  1868 
  1862 
  1873 
  1863     \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
  1874     \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
  1864 */
  1875 */
  1865 QBitmap QPixmap::mask() const
  1876 QBitmap QPixmap::mask() const
  1866 {
  1877 {
  1867     return data->mask();
  1878     return data ? data->mask() : QBitmap();
  1868 }
  1879 }
  1869 
  1880 
  1870 /*!
  1881 /*!
  1871     Returns the default pixmap depth used by the application.
  1882     Returns the default pixmap depth used by the application.
  1872 
  1883 
  1911     The detach() function returns immediately if there is just a
  1922     The detach() function returns immediately if there is just a
  1912     single reference or if the pixmap has not been initialized yet.
  1923     single reference or if the pixmap has not been initialized yet.
  1913 */
  1924 */
  1914 void QPixmap::detach()
  1925 void QPixmap::detach()
  1915 {
  1926 {
       
  1927     if (!data)
       
  1928         return;
       
  1929 
  1916     QPixmapData::ClassId id = data->classId();
  1930     QPixmapData::ClassId id = data->classId();
  1917     if (id == QPixmapData::RasterClass) {
  1931     if (id == QPixmapData::RasterClass) {
  1918         QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(data.data());
  1932         QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(data.data());
  1919         rasterData->image.detach();
  1933         rasterData->image.detach();
  1920     }
  1934     }
  2133 /*! \fn QRgb* QPixmap::clut() const
  2147 /*! \fn QRgb* QPixmap::clut() const
  2134     \internal
  2148     \internal
  2135 */
  2149 */
  2136 
  2150 
  2137 /*! \fn int QPixmap::numCols() const
  2151 /*! \fn int QPixmap::numCols() const
       
  2152     \obsolete
       
  2153     \internal
       
  2154     \sa colorCount()
       
  2155 */
       
  2156 
       
  2157 /*! \fn int QPixmap::colorCount() const
       
  2158     \since 4.6
  2138     \internal
  2159     \internal
  2139 */
  2160 */
  2140 
  2161 
  2141 /*! \fn const uchar* QPixmap::qwsBits() const
  2162 /*! \fn const uchar* QPixmap::qwsBits() const
  2142     \internal
  2163     \internal