Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

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

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6868#include "qx11info_x11.h"
    6969#include <private/qdrawhelper_p.h>
     70#include <private/qimage_p.h>
    7071
    7172#include <stdlib.h>
     
    313314
    314315QX11PixmapData::QX11PixmapData(PixelType type)
    315     : QPixmapData(type, X11Class), hd(0), w(0), h(0), d(0),
    316       uninit(true), read_only(false), x11_mask(0), picture(0), mask_picture(0), hd2(0),
     316    : QPixmapData(type, X11Class), hd(0),
     317      flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), gl_surface(0),
    317318      share_mode(QPixmap::ImplicitlyShared), pengine(0)
    318319{
     320}
     321
     322QPixmapData *QX11PixmapData::createCompatiblePixmapData() const
     323{
     324    return new QX11PixmapData(pixelType());
    319325}
    320326
     
    325331    w = width;
    326332    h = height;
     333    is_null = (w <= 0 || h <= 0);
    327334
    328335    if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
     
    348355        w = 0;
    349356        h = 0;
     357        is_null = true;
    350358        hd = 0;
    351359        picture = 0;
     
    368376}
    369377
     378struct QX11AlphaDetector
     379{
     380    bool hasAlpha() const {
     381        if (checked)
     382            return has;
     383        // Will implicitly also check format and return quickly for opaque types...
     384        checked = true;
     385        has = const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
     386        return has;
     387    }
     388
     389    bool hasXRenderAndAlpha() const {
     390        if (!X11->use_xrender)
     391            return false;
     392        return hasAlpha();
     393    }
     394
     395    QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
     396        : image(i), checked(false), has(false)
     397    {
     398        if (flags & Qt::NoOpaqueDetection) {
     399            checked = true;
     400            has = image->hasAlphaChannel();
     401        }
     402    }
     403
     404    const QImage *image;
     405    mutable bool checked;
     406    mutable bool has;
     407};
     408
    370409void QX11PixmapData::fromImage(const QImage &img,
    371410                               Qt::ImageConversionFlags flags)
     
    376415    h = img.height();
    377416    d = img.depth();
     417    is_null = (w <= 0 || h <= 0);
     418
     419    if (is_null) {
     420        w = h = 0;
     421        return;
     422    }
    378423
    379424    if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
     
    396441    if (uint(w) >= 32768 || uint(h) >= 32768) {
    397442        w = h = 0;
     443        is_null = true;
    398444        return;
    399445    }
    400446
    401     int dd = X11->use_xrender && img.hasAlphaChannel() ? 32 : xinfo.depth();
     447    QX11AlphaDetector alphaCheck(&img, flags);
     448    int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
     449
    402450    if (qt_x11_preferred_pixmap_depth)
    403451        dd = qt_x11_preferred_pixmap_depth;
     
    422470            conv8 = (d == 1);                        // native depth wanted
    423471        } else if (d == 1) {
    424             if (image.numColors() == 2) {
     472            if (image.colorCount() == 2) {
    425473                QRgb c0 = image.color(0);        // Auto: convert to best
    426474                QRgb c1 = image.color(1);
     
    447495    XImage *xi = 0;
    448496    bool    trucol = (visual->c_class >= TrueColor);
    449     int     nbytes = image.numBytes();
     497    int     nbytes = image.byteCount();
    450498    uchar  *newbits= 0;
    451499
    452500#ifndef QT_NO_XRENDER
    453     if (X11->use_xrender && image.hasAlphaChannel()) {
     501    if (alphaCheck.hasXRenderAndAlpha()) {
    454502        const QImage &cimage = image;
    455503
     
    589637        if (d8) {                                // setup pixel translation
    590638            QVector<QRgb> ctable = cimage.colorTable();
    591             for (int i=0; i < cimage.numColors(); i++) {
     639            for (int i=0; i < cimage.colorCount(); i++) {
    592640                int r = qRed  (ctable[i]);
    593641                int g = qGreen(ctable[i]);
     
    915963        int  pop[256];                                // pixel popularity
    916964
    917         if (image.numColors() == 0)
    918             image.setNumColors(1);
     965        if (image.colorCount() == 0)
     966            image.setColorCount(1);
    919967
    920968        const QImage &cimage = image;
     
    946994        };
    947995        int ncols = 0;
    948         for (int i=0; i< cimage.numColors(); i++) { // compute number of colors
     996        for (int i=0; i< cimage.colorCount(); i++) { // compute number of colors
    949997            if (pop[i] > 0)
    950998                ncols++;
    951999        }
    952         for (int i = cimage.numColors(); i < 256; i++) // ignore out-of-range pixels
     1000        for (int i = cimage.colorCount(); i < 256; i++) // ignore out-of-range pixels
    9531001            pop[i] = 0;
    9541002
     
    10881136#endif
    10891137
    1090     if (image.hasAlphaChannel()) {
     1138    if (alphaCheck.hasAlpha()) {
    10911139        QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
    10921140        setMask(m);
     
    11101158    h = img.height();
    11111159    d = 1;
     1160    is_null = (w <= 0 || h <= 0);
    11121161    int bpl = (w + 7) / 8;
    11131162    int ibpl = img.bytesPerLine();
     
    12131262            hd2 = 0;
    12141263        }
    1215         if (!read_only)
     1264        if (!(flags & Readonly))
    12161265            XFreePixmap(xinfo.display(), hd);
    12171266        hd = 0;
     
    12211270QPixmap QX11PixmapData::alphaChannel() const
    12221271{
    1223     if (!hasAlphaChannel())
    1224         return QPixmap();
     1272    if (!hasAlphaChannel()) {
     1273        QPixmap pm(w, h);
     1274        pm.fill(Qt::white);
     1275        return pm;
     1276    }
    12251277    QImage im(toImage());
    12261278    return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither);
     
    14381490        // we may have to swap the byte order
    14391491        if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
    1440             || (QSysInfo::ByteOrder == QSysInfo::BigEndian))
     1492            || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
    14411493        {
    14421494            for (int i=0; i < image.height(); i++) {
     
    16051657
    16061658    if (d == 1) {                                // bitmap
    1607         image.setNumColors(2);
     1659        image.setColorCount(2);
    16081660        image.setColor(0, qRgb(255,255,255));
    16091661        image.setColor(1, qRgb(0,0,0));
     
    16611713            if (ncols < 256) {
    16621714                trans = ncols++;
    1663                 image.setNumColors(ncols);        // create color table
     1715                image.setColorCount(ncols);        // create color table
    16641716                image.setColor(trans, 0x00000000);
    16651717            } else {
    1666                 image.setNumColors(ncols);        // create color table
     1718                image.setColorCount(ncols);        // create color table
    16671719                // oh dear... no spare "transparent" pixel.
    16681720                // use first pixel in image (as good as any).
     
    16871739            }
    16881740        } else {
    1689             image.setNumColors(ncols);        // create color table
     1741            image.setColorCount(ncols);        // create color table
    16901742        }
    16911743        QVector<QColor> colors = QColormap::instance(xinfo.screen()).colormap();
     
    18701922        return bm;
    18711923    } else {                                        // color pixmap
    1872         QPixmap pm;
    1873         QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pm.data);
    1874         x11Data->uninit = false;
     1924        QX11PixmapData *x11Data = new QX11PixmapData(QPixmapData::PixmapType);
     1925        QPixmap pm(x11Data);
     1926        x11Data->flags &= ~QX11PixmapData::Uninitialized;
    18751927        x11Data->xinfo = xinfo;
    18761928        x11Data->d = d;
    18771929        x11Data->w = w;
    18781930        x11Data->h = h;
     1931        x11Data->is_null = (w <= 0 || h <= 0);
    18791932        x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
    18801933                                                RootWindow(X11->display, xinfo.screen()),
    18811934                                                w, h, d);
     1935        x11Data->setSerialNumber(++qt_pixmap_serial);
     1936
    18821937#ifndef QT_NO_XRENDER
    18831938        if (X11->use_xrender) {
     
    19151970}
    19161971
    1917 /*!
    1918   \internal
    1919 */
    19201972int QPixmap::x11SetDefaultScreen(int screen)
    19211973{
     
    19251977}
    19261978
    1927 /*!
    1928   \internal
    1929 */
    19301979void QPixmap::x11SetScreen(int screen)
    19311980{
     
    19351984    }
    19361985
     1986    if (isNull())
     1987        return;
     1988
    19371989    if (data->classId() != QPixmapData::X11Class)
    19381990        return;
     
    19411993        screen = QX11Info::appScreen();
    19421994
    1943     QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(data);
     1995    QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(data.data());
    19441996    if (screen == x11Data->xinfo.screen())
    19451997        return; // nothing to do
     
    20192071    QPixmap pm(data);
    20202072
    2021     data->uninit = false;
     2073    data->flags &= ~QX11PixmapData::Uninitialized;
    20222074    pm.x11SetScreen(scr);
    20232075
     
    20352087}
    20362088
    2037 /*!
    2038     Returns information about the configuration of the X display used to display
    2039     the widget.
    2040 
    2041     \warning This function is only available on X11.
    2042 
    2043     \sa {QPixmap#Pixmap Information}{Pixmap Information}
    2044 */
    20452089const QX11Info &QPixmap::x11Info() const
    20462090{
    2047     if (data->classId() == QPixmapData::X11Class)
    2048         return static_cast<QX11PixmapData*>(data)->xinfo;
     2091    if (data && data->classId() == QPixmapData::X11Class)
     2092        return static_cast<QX11PixmapData*>(data.data())->xinfo;
    20492093    else {
    20502094        static QX11Info nullX11Info;
     
    20692113    QX11PixmapData *that = const_cast<QX11PixmapData*>(this);
    20702114
    2071     if (read_only && share_mode == QPixmap::ImplicitlyShared) {
     2115    if ((flags & Readonly) && share_mode == QPixmap::ImplicitlyShared) {
    20722116        // if someone wants to draw onto us, copy the shared contents
    20732117        // and turn it into a fully fledged QPixmap
     
    20912135        }
    20922136        that->hd = hd_copy;
    2093         that->read_only = false;
     2137        that->flags &= ~QX11PixmapData::Readonly;
    20942138    }
    20952139
     
    20992143}
    21002144
    2101 /*!
    2102     Returns the X11 Picture handle of the pixmap for XRender
    2103     support.
    2104 
    2105     This function will return 0 if XRender support is not compiled
    2106     into Qt, if the XRender extension is not supported on the X11
    2107     display, or if the handle could not be created. Use of this
    2108     function is not portable.
    2109 
    2110     \warning This function is only available on X11.
    2111 
    2112     \sa {QPixmap#Pixmap Information}{Pixmap Information}
    2113 */
    2114 
    21152145Qt::HANDLE QPixmap::x11PictureHandle() const
    21162146{
    21172147#ifndef QT_NO_XRENDER
    2118     if (data->classId() == QPixmapData::X11Class)
    2119         return static_cast<QX11PixmapData*>(data)->picture;
     2148    if (data && data->classId() == QPixmapData::X11Class)
     2149        return static_cast<const QX11PixmapData*>(data.data())->picture;
    21202150    else
    21212151        return 0;
     
    21562186    setSerialNumber(++qt_pixmap_serial);
    21572187
    2158     uninit = false;
     2188    flags &= ~Uninitialized;
    21592189    xinfo = x11Data->xinfo;
    21602190    d = x11Data->d;
    21612191    w = rect.width();
    21622192    h = rect.height();
     2193    is_null = (w <= 0 || h <= 0);
    21632194    hd = (Qt::HANDLE)XCreatePixmap(X11->display,
    21642195                                   RootWindow(X11->display, x11Data->xinfo.screen()),
     
    22062237}
    22072238
     2239bool QX11PixmapData::scroll(int dx, int dy, const QRect &rect)
     2240{
     2241    GC gc = XCreateGC(X11->display, hd, 0, 0);
     2242    XCopyArea(X11->display, hd, hd, gc,
     2243              rect.left(), rect.top(), rect.width(), rect.height(),
     2244              rect.left() + dx, rect.top() + dy);
     2245    XFreeGC(X11->display, gc);
     2246    return true;
     2247}
     2248
    22082249#if !defined(QT_NO_XRENDER)
    22092250void QX11PixmapData::convertToARGB32(bool preserveContents)
     
    22132254
    22142255    // Q_ASSERT(count == 1);
    2215     if (read_only && share_mode == QPixmap::ExplicitlyShared)
     2256    if ((flags & Readonly) && share_mode == QPixmap::ExplicitlyShared)
    22162257        return;
    22172258
     
    22232264        if (preserveContents)
    22242265            XRenderComposite(X11->display, PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h);
    2225         if (!read_only)
     2266        if (!(flags & Readonly))
    22262267            XRenderFreePicture(X11->display, picture);
    22272268    }
    2228     if (hd && !read_only)
     2269    if (hd && !(flags & Readonly))
    22292270        XFreePixmap(X11->display, hd);
    22302271    if (x11_mask) {
     
    22642305    QX11PixmapData *data = new QX11PixmapData(depth == 1 ? QPixmapData::BitmapType : QPixmapData::PixmapType);
    22652306    data->setSerialNumber(++qt_pixmap_serial);
    2266     data->read_only = true;
     2307    data->flags = QX11PixmapData::Readonly;
    22672308    data->share_mode = mode;
    2268     data->uninit = false;
    22692309    data->w = width;
    22702310    data->h = height;
     2311    data->is_null = (width <= 0 || height <= 0);
    22712312    data->d = depth;
    22722313    data->hd = pixmap;
Note: See TracChangeset for help on using the changeset viewer.