Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/image/qpixmap_x11.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    315315
    316316QX11PixmapData::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),
    319319      share_mode(QPixmap::ImplicitlyShared), pengine(0)
    320320{
     
    11431143}
    11441144
    1145 void QX11PixmapData::bitmapFromImage(const QImage &image)
     1145Qt::HANDLE QX11PixmapData::createBitmapFromImage(const QImage &image)
    11461146{
    11471147    QImage img = image.convertToFormat(QImage::Format_MonoLSB);
     
    11561156    char  *bits;
    11571157    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();
    11621160    int bpl = (w + 7) / 8;
    11631161    int ibpl = img.bytesPerLine();
     
    11781176        tmp_bits = 0;
    11791177    }
    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(),
    11821180                                           bits, w, h);
    1183 
     1181    if (tmp_bits)                                // Avoid purify complaint
     1182        delete [] tmp_bits;
     1183    return hd;
     1184}
     1185
     1186void 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);
    11841193#ifndef QT_NO_XRENDER
    11851194    if (X11->use_xrender)
     
    11871196                                       XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
    11881197#endif // QT_NO_XRENDER
    1189 
    1190     if (tmp_bits)                                // Avoid purify complaint
    1191         delete [] tmp_bits;
    11921198}
    11931199
     
    12451251
    12461252    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.
    12511255        return;
    12521256    }
     
    13171321    return mask;
    13181322}
    1319 
    13201323
    13211324/*!
     
    14551458}
    14561459
     1460struct QXImageWrapper
     1461{
     1462    XImage *xi;
     1463};
     1464
     1465bool 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
     1488QImage 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
     1541QImage 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
    14571559/*!
    14581560    Converts the pixmap to a QImage. Returns a null image if the
     
    14721574QImage QX11PixmapData::toImage() const
    14731575{
     1576    return toImage(QRect(0, 0, w, h));
     1577}
     1578
     1579QImage QX11PixmapData::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const
     1580{
     1581    XImage *xi = xiWrapper.xi;
     1582
    14741583    int d = depth();
    14751584    Visual *visual = (Visual *)xinfo.visual();
     
    14891598    }
    14901599
    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 order
    1503         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 data
    1527         qSafeXDestroyImage(xi);
    1528 
    1529         return image;
    1530     }
    1531 
    15321600    if (d == 1 && xi->bitmap_bit_order == LSBFirst)
    15331601        format = QImage::Format_MonoLSB;
     
    15351603        format = QImage::Format_ARGB32;
    15361604
    1537     QImage image(w, h, format);
     1605    QImage image(xi->width, xi->height, format);
    15381606    if (image.isNull())                        // could not create image
    15391607        return image;
     
    15411609    QImage alpha;
    15421610    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);
    15441615    }
    15451616    bool ale = alpha.format() == QImage::Format_MonoLSB;
     
    15841655            bppc++;
    15851656
    1586         for (int y = 0; y < h; ++y) {
     1657        for (int y = 0; y < xi->height; ++y) {
    15871658            uchar* asrc = x11_mask ? alpha.scanLine(y) : 0;
    15881659            dst = (QRgb *)image.scanLine(y);
    15891660            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++) {
    15911662                switch (bppc) {
    15921663                case 8:
     
    16181689                    break;
    16191690                default:                        // should not really happen
    1620                     x = w;                        // leave loop
    1621                     y = h;
     1691                    x = xi->width;                        // leave loop
     1692                    y = xi->height;
    16221693                    pixel = 0;                // eliminate compiler warning
    16231694                    qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);
     
    16571728        char *xidata = xi->data;                // copy each scanline
    16581729        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++) {
    16601731            memcpy(image.scanLine(y), xidata, bpl);
    16611732            xidata += xi->bytes_per_line;
     
    16831754
    16841755        if (x11_mask) {                         // which pixels are used?
    1685             for (int i = 0; i < h; i++) {
     1756            for (int i = 0; i < xi->height; i++) {
    16861757                uchar* asrc = alpha.scanLine(i);
    16871758                p = image.scanLine(i);
    16881759                if (ale) {
    1689                     for (int x = 0; x < w; x++) {
     1760                    for (int x = 0; x < xi->width; x++) {
    16901761                        if (asrc[x >> 3] & (1 << (x & 7)))
    16911762                            use[*p] = 1;
     
    16931764                    }
    16941765                } else {
    1695                     for (int x = 0; x < w; x++) {
     1766                    for (int x = 0; x < xi->width; x++) {
    16961767                        if (asrc[x >> 3] & (0x80 >> (x & 7)))
    16971768                            use[*p] = 1;
     
    17011772            }
    17021773        } else {
    1703             for (int i = 0; i < h; i++) {
     1774            for (int i = 0; i < xi->height; i++) {
    17041775                p = image.scanLine(i);
    17051776                end = p + bpl;
     
    17131784                pix[i] = ncols++;
    17141785        }
    1715         for (int i = 0; i < h; i++) {                        // translate pixels
     1786        for (int i = 0; i < xi->height; i++) {                        // translate pixels
    17161787            p = image.scanLine(i);
    17171788            end = p + bpl;
     
    17331804                trans = image.scanLine(0)[0];
    17341805            }
    1735             for (int i = 0; i < h; i++) {
     1806            for (int i = 0; i < xi->height; i++) {
    17361807                uchar* asrc = alpha.scanLine(i);
    17371808                p = image.scanLine(i);
    17381809                if (ale) {
    1739                     for (int x = 0; x < w; x++) {
     1810                    for (int x = 0; x < xi->width; x++) {
    17401811                        if (!(asrc[x >> 3] & (1 << (x & 7))))
    17411812                            *p = trans;
     
    17431814                    }
    17441815                } else {
    1745                     for (int x = 0; x < w; x++) {
     1816                    for (int x = 0; x < xi->width; x++) {
    17461817                        if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
    17471818                            *p = trans;
     
    17601831        }
    17611832    }
    1762 
    1763     qSafeXDestroyImage(xi);
    17641833
    17651834    return image;
Note: See TracChangeset for help on using the changeset viewer.