Changeset 846 for trunk/src/gui/image/qpixmap_x11.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/image/qpixmap_x11.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 315 315 316 316 QX11PixmapData::QX11PixmapData(PixelType type) 317 : QPixmapData(type, X11Class), hd(0),318 flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), gl_surface(0),317 : QPixmapData(type, X11Class), gl_surface(0), hd(0), 318 flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), 319 319 share_mode(QPixmap::ImplicitlyShared), pengine(0) 320 320 { … … 1143 1143 } 1144 1144 1145 void QX11PixmapData::bitmapFromImage(const QImage &image)1145 Qt::HANDLE QX11PixmapData::createBitmapFromImage(const QImage &image) 1146 1146 { 1147 1147 QImage img = image.convertToFormat(QImage::Format_MonoLSB); … … 1156 1156 char *bits; 1157 1157 uchar *tmp_bits; 1158 w = img.width(); 1159 h = img.height(); 1160 d = 1; 1161 is_null = (w <= 0 || h <= 0); 1158 int w = img.width(); 1159 int h = img.height(); 1162 1160 int bpl = (w + 7) / 8; 1163 1161 int ibpl = img.bytesPerLine(); … … 1178 1176 tmp_bits = 0; 1179 1177 } 1180 hd = (Qt::HANDLE)XCreateBitmapFromData(xinfo.display(),1181 RootWindow(xinfo.display(), xinfo.screen()),1178 Qt::HANDLE hd = (Qt::HANDLE)XCreateBitmapFromData(X11->display, 1179 QX11Info::appRootWindow(), 1182 1180 bits, w, h); 1183 1181 if (tmp_bits) // Avoid purify complaint 1182 delete [] tmp_bits; 1183 return hd; 1184 } 1185 1186 void QX11PixmapData::bitmapFromImage(const QImage &image) 1187 { 1188 w = image.width(); 1189 h = image.height(); 1190 d = 1; 1191 is_null = (w <= 0 || h <= 0); 1192 hd = createBitmapFromImage(image); 1184 1193 #ifndef QT_NO_XRENDER 1185 1194 if (X11->use_xrender) … … 1187 1196 XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0); 1188 1197 #endif // QT_NO_XRENDER 1189 1190 if (tmp_bits) // Avoid purify complaint1191 delete [] tmp_bits;1192 1198 } 1193 1199 … … 1245 1251 1246 1252 if (!X11) { 1247 #ifndef QT_NO_DEBUG 1248 qWarning("~QX11PixmapData(): QPixmap objects must be destroyed before the QApplication" 1249 " object, otherwise the native pixmap object will be leaked."); 1250 #endif 1253 // At this point, the X server will already have freed our resources, 1254 // so there is nothing to do. 1251 1255 return; 1252 1256 } … … 1317 1321 return mask; 1318 1322 } 1319 1320 1323 1321 1324 /*! … … 1455 1458 } 1456 1459 1460 struct QXImageWrapper 1461 { 1462 XImage *xi; 1463 }; 1464 1465 bool QX11PixmapData::canTakeQImageFromXImage(const QXImageWrapper &xiWrapper) const 1466 { 1467 XImage *xi = xiWrapper.xi; 1468 1469 // ARGB32_Premultiplied 1470 if (picture && depth() == 32) 1471 return true; 1472 1473 Visual *visual = (Visual *)xinfo.visual(); 1474 1475 // RGB32 1476 if (depth() == 24 && xi->bits_per_pixel == 32 && visual->red_mask == 0xff0000 1477 && visual->green_mask == 0xff00 && visual->blue_mask == 0xff) 1478 return true; 1479 1480 // RGB16 1481 if (depth() == 16 && xi->bits_per_pixel == 16 && visual->red_mask == 0xf800 1482 && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f) 1483 return true; 1484 1485 return false; 1486 } 1487 1488 QImage QX11PixmapData::takeQImageFromXImage(const QXImageWrapper &xiWrapper) const 1489 { 1490 XImage *xi = xiWrapper.xi; 1491 1492 QImage::Format format = QImage::Format_ARGB32_Premultiplied; 1493 if (depth() == 24) 1494 format = QImage::Format_RGB32; 1495 else if (depth() == 16) 1496 format = QImage::Format_RGB16; 1497 1498 QImage image((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format); 1499 // take ownership 1500 image.data_ptr()->own_data = true; 1501 xi->data = 0; 1502 1503 // we may have to swap the byte order 1504 if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst) 1505 || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst)) 1506 { 1507 for (int i=0; i < image.height(); i++) { 1508 if (depth() == 16) { 1509 ushort *p = (ushort*)image.scanLine(i); 1510 ushort *end = p + image.width(); 1511 while (p < end) { 1512 *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff); 1513 p++; 1514 } 1515 } else { 1516 uint *p = (uint*)image.scanLine(i); 1517 uint *end = p + image.width(); 1518 while (p < end) { 1519 *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000) 1520 | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff); 1521 p++; 1522 } 1523 } 1524 } 1525 } 1526 1527 // fix-up alpha channel 1528 if (format == QImage::Format_RGB32) { 1529 QRgb *p = (QRgb *)image.bits(); 1530 for (int y = 0; y < xi->height; ++y) { 1531 for (int x = 0; x < xi->width; ++x) 1532 p[x] |= 0xff000000; 1533 p += xi->bytes_per_line / 4; 1534 } 1535 } 1536 1537 XDestroyImage(xi); 1538 return image; 1539 } 1540 1541 QImage QX11PixmapData::toImage(const QRect &rect) const 1542 { 1543 QXImageWrapper xiWrapper; 1544 xiWrapper.xi = XGetImage(X11->display, hd, rect.x(), rect.y(), rect.width(), rect.height(), 1545 AllPlanes, (depth() == 1) ? XYPixmap : ZPixmap); 1546 1547 Q_CHECK_PTR(xiWrapper.xi); 1548 if (!xiWrapper.xi) 1549 return QImage(); 1550 1551 if (!x11_mask && canTakeQImageFromXImage(xiWrapper)) 1552 return takeQImageFromXImage(xiWrapper); 1553 1554 QImage image = toImage(xiWrapper, rect); 1555 qSafeXDestroyImage(xiWrapper.xi); 1556 return image; 1557 } 1558 1457 1559 /*! 1458 1560 Converts the pixmap to a QImage. Returns a null image if the … … 1472 1574 QImage QX11PixmapData::toImage() const 1473 1575 { 1576 return toImage(QRect(0, 0, w, h)); 1577 } 1578 1579 QImage QX11PixmapData::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const 1580 { 1581 XImage *xi = xiWrapper.xi; 1582 1474 1583 int d = depth(); 1475 1584 Visual *visual = (Visual *)xinfo.visual(); … … 1489 1598 } 1490 1599 1491 XImage *xi = XGetImage(X11->display, hd, 0, 0, w, h, AllPlanes,1492 (d == 1) ? XYPixmap : ZPixmap);1493 1494 Q_CHECK_PTR(xi);1495 if (!xi)1496 return QImage();1497 1498 if (picture && depth() == 32) {1499 QImage image(w, h, QImage::Format_ARGB32_Premultiplied);1500 memcpy(image.bits(), xi->data, xi->bytes_per_line * xi->height);1501 1502 // we may have to swap the byte order1503 if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)1504 || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))1505 {1506 for (int i=0; i < image.height(); i++) {1507 uint *p = (uint*)image.scanLine(i);1508 uint *end = p + image.width();1509 if ((xi->byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)1510 || (xi->byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {1511 while (p < end) {1512 *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)1513 | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);1514 p++;1515 }1516 } else if (xi->byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian) {1517 while (p < end) {1518 *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff)1519 | ((*p ) & 0xff00ff00);1520 p++;1521 }1522 }1523 }1524 }1525 1526 // throw away image data1527 qSafeXDestroyImage(xi);1528 1529 return image;1530 }1531 1532 1600 if (d == 1 && xi->bitmap_bit_order == LSBFirst) 1533 1601 format = QImage::Format_MonoLSB; … … 1535 1603 format = QImage::Format_ARGB32; 1536 1604 1537 QImage image( w, h, format);1605 QImage image(xi->width, xi->height, format); 1538 1606 if (image.isNull()) // could not create image 1539 1607 return image; … … 1541 1609 QImage alpha; 1542 1610 if (x11_mask) { 1543 alpha = mask().toImage(); 1611 if (rect.contains(QRect(0, 0, w, h))) 1612 alpha = mask().toImage(); 1613 else 1614 alpha = mask().toImage().copy(rect); 1544 1615 } 1545 1616 bool ale = alpha.format() == QImage::Format_MonoLSB; … … 1584 1655 bppc++; 1585 1656 1586 for (int y = 0; y < h; ++y) {1657 for (int y = 0; y < xi->height; ++y) { 1587 1658 uchar* asrc = x11_mask ? alpha.scanLine(y) : 0; 1588 1659 dst = (QRgb *)image.scanLine(y); 1589 1660 src = (uchar *)xi->data + xi->bytes_per_line*y; 1590 for (int x = 0; x < w; x++) {1661 for (int x = 0; x < xi->width; x++) { 1591 1662 switch (bppc) { 1592 1663 case 8: … … 1618 1689 break; 1619 1690 default: // should not really happen 1620 x = w; // leave loop1621 y = h;1691 x = xi->width; // leave loop 1692 y = xi->height; 1622 1693 pixel = 0; // eliminate compiler warning 1623 1694 qWarning("QPixmap::convertToImage: Invalid depth %d", bppc); … … 1657 1728 char *xidata = xi->data; // copy each scanline 1658 1729 int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line); 1659 for (int y=0; y< h; y++) {1730 for (int y=0; y<xi->height; y++) { 1660 1731 memcpy(image.scanLine(y), xidata, bpl); 1661 1732 xidata += xi->bytes_per_line; … … 1683 1754 1684 1755 if (x11_mask) { // which pixels are used? 1685 for (int i = 0; i < h; i++) {1756 for (int i = 0; i < xi->height; i++) { 1686 1757 uchar* asrc = alpha.scanLine(i); 1687 1758 p = image.scanLine(i); 1688 1759 if (ale) { 1689 for (int x = 0; x < w; x++) {1760 for (int x = 0; x < xi->width; x++) { 1690 1761 if (asrc[x >> 3] & (1 << (x & 7))) 1691 1762 use[*p] = 1; … … 1693 1764 } 1694 1765 } else { 1695 for (int x = 0; x < w; x++) {1766 for (int x = 0; x < xi->width; x++) { 1696 1767 if (asrc[x >> 3] & (0x80 >> (x & 7))) 1697 1768 use[*p] = 1; … … 1701 1772 } 1702 1773 } else { 1703 for (int i = 0; i < h; i++) {1774 for (int i = 0; i < xi->height; i++) { 1704 1775 p = image.scanLine(i); 1705 1776 end = p + bpl; … … 1713 1784 pix[i] = ncols++; 1714 1785 } 1715 for (int i = 0; i < h; i++) { // translate pixels1786 for (int i = 0; i < xi->height; i++) { // translate pixels 1716 1787 p = image.scanLine(i); 1717 1788 end = p + bpl; … … 1733 1804 trans = image.scanLine(0)[0]; 1734 1805 } 1735 for (int i = 0; i < h; i++) {1806 for (int i = 0; i < xi->height; i++) { 1736 1807 uchar* asrc = alpha.scanLine(i); 1737 1808 p = image.scanLine(i); 1738 1809 if (ale) { 1739 for (int x = 0; x < w; x++) {1810 for (int x = 0; x < xi->width; x++) { 1740 1811 if (!(asrc[x >> 3] & (1 << (x & 7)))) 1741 1812 *p = trans; … … 1743 1814 } 1744 1815 } else { 1745 for (int x = 0; x < w; x++) {1816 for (int x = 0; x < xi->width; x++) { 1746 1817 if (!(asrc[x >> 3] & (1 << (7 -(x & 7))))) 1747 1818 *p = trans; … … 1760 1831 } 1761 1832 } 1762 1763 qSafeXDestroyImage(xi);1764 1833 1765 1834 return image;
Note:
See TracChangeset
for help on using the changeset viewer.