tests/auto/qpixmap/tst_qpixmap.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 #include <qpixmap.h>
       
    45 #include <qbitmap.h>
       
    46 #include <qimage.h>
       
    47 #include <qmatrix.h>
       
    48 #include <qdesktopwidget.h>
       
    49 #include <qpaintengine.h>
       
    50 
       
    51 #include <private/qpixmapdata_p.h>
       
    52 
       
    53 #include <QSet>
       
    54 
       
    55 #ifdef Q_WS_WIN
       
    56 #include <windows.h>
       
    57 #endif
       
    58 
       
    59 #ifdef Q_WS_QWS
       
    60 #include <qscreen_qws.h>
       
    61 #endif
       
    62 
       
    63 #ifdef Q_OS_SYMBIAN
       
    64 #include <e32std.h>
       
    65 #include <fbs.h>
       
    66 #include <gdi.h>
       
    67 #include <bitdev.h>
       
    68 #endif
       
    69 
       
    70 #ifdef Q_WS_X11
       
    71 #include <QX11Info>
       
    72 #endif
       
    73 
       
    74 //TESTED_CLASS=
       
    75 //TESTED_FILES=
       
    76 #if defined(Q_OS_SYMBIAN)
       
    77 # define SRCDIR ""
       
    78 #endif
       
    79 Q_DECLARE_METATYPE(QImage::Format)
       
    80 
       
    81 class tst_QPixmap : public QObject
       
    82 {
       
    83     Q_OBJECT
       
    84 
       
    85 public:
       
    86     tst_QPixmap();
       
    87     virtual ~tst_QPixmap();
       
    88 
       
    89 
       
    90 public slots:
       
    91     void init();
       
    92     void cleanup();
       
    93 
       
    94 private slots:
       
    95     void setAlphaChannel_data();
       
    96     void setAlphaChannel();
       
    97 
       
    98     void fromImage_data();
       
    99     void fromImage();
       
   100 
       
   101     void fromUninitializedImage_data();
       
   102     void fromUninitializedImage();
       
   103 
       
   104     void convertFromImage_data();
       
   105     void convertFromImage();
       
   106 
       
   107     void testMetrics();
       
   108 
       
   109     void scroll_data();
       
   110     void scroll();
       
   111 
       
   112     void fill_data();
       
   113     void fill();
       
   114     void fill_transparent();
       
   115 
       
   116     void createMaskFromColor();
       
   117 
       
   118     void mask();
       
   119     void bitmapMask();
       
   120     void setGetMask_data();
       
   121     void setGetMask();
       
   122     void cacheKey();
       
   123     void drawBitmap();
       
   124     void grabWidget();
       
   125     void grabWindow();
       
   126     void isNull();
       
   127     void task_246446();
       
   128 
       
   129 #ifdef Q_WS_QWS
       
   130     void convertFromImageNoDetach();
       
   131 #endif
       
   132 
       
   133     void convertFromImageDetach();
       
   134 
       
   135 #if defined(Q_WS_WIN)
       
   136     void toWinHBITMAP_data();
       
   137     void toWinHBITMAP();
       
   138     void fromWinHBITMAP_data();
       
   139     void fromWinHBITMAP();
       
   140 
       
   141     void toWinHICON_data();
       
   142     void toWinHICON();
       
   143     void fromWinHICON_data();
       
   144     void fromWinHICON();
       
   145 #endif
       
   146 
       
   147 #if defined(Q_WS_S60)
       
   148     void fromSymbianCFbsBitmap_data();
       
   149     void fromSymbianCFbsBitmap();
       
   150 #endif
       
   151 
       
   152     void onlyNullPixmapsOutsideGuiThread();
       
   153     void refUnref();
       
   154 
       
   155     void copy();
       
   156     void depthOfNullObjects();
       
   157 
       
   158 #ifdef QT3_SUPPORT
       
   159     void resize();
       
   160     void resizePreserveMask();
       
   161 #endif
       
   162 
       
   163     void transformed();
       
   164     void transformed2();
       
   165 
       
   166     void fromImage_crash();
       
   167 
       
   168     void fromData();
       
   169 
       
   170     void preserveDepth();
       
   171 };
       
   172 
       
   173 static bool lenientCompare(const QPixmap &actual, const QPixmap &expected)
       
   174 {
       
   175     QImage expectedImage = expected.toImage().convertToFormat(QImage::Format_RGB32);
       
   176     QImage actualImage = actual.toImage().convertToFormat(QImage::Format_RGB32);
       
   177 
       
   178     if (expectedImage.size() != actualImage.size())
       
   179         return false;
       
   180 
       
   181     int size = actual.width() * actual.height();
       
   182 
       
   183     int threshold = 2;
       
   184 #ifdef Q_WS_X11
       
   185     if (QX11Info::appDepth() == 16)
       
   186         threshold = 10;
       
   187 #endif
       
   188 
       
   189     QRgb *a = (QRgb *)actualImage.bits();
       
   190     QRgb *e = (QRgb *)expectedImage.bits();
       
   191     for (int i = 0; i < size; ++i) {
       
   192         QColor ca(a[i]);
       
   193         QColor ce(e[i]);
       
   194 
       
   195         bool result = true;
       
   196 
       
   197         if (qAbs(ca.red() - ce.red()) > threshold)
       
   198             result = false;
       
   199         if (qAbs(ca.green() - ce.green()) > threshold)
       
   200             result = false;
       
   201         if (qAbs(ca.blue() - ce.blue()) > threshold)
       
   202             result = false;
       
   203 
       
   204         if (!result)
       
   205             return false;
       
   206     }
       
   207 
       
   208     return true;
       
   209 }
       
   210 
       
   211 Q_DECLARE_METATYPE(QImage)
       
   212 Q_DECLARE_METATYPE(QPixmap)
       
   213 Q_DECLARE_METATYPE(QMatrix)
       
   214 Q_DECLARE_METATYPE(QBitmap)
       
   215 
       
   216 tst_QPixmap::tst_QPixmap()
       
   217 {
       
   218 }
       
   219 
       
   220 tst_QPixmap::~tst_QPixmap()
       
   221 {
       
   222 }
       
   223 
       
   224 void tst_QPixmap::init()
       
   225 {
       
   226 }
       
   227 
       
   228 void tst_QPixmap::cleanup()
       
   229 {
       
   230 }
       
   231 
       
   232 void tst_QPixmap::setAlphaChannel_data()
       
   233 {
       
   234     QTest::addColumn<int>("red");
       
   235     QTest::addColumn<int>("green");
       
   236     QTest::addColumn<int>("blue");
       
   237     QTest::addColumn<int>("alpha");
       
   238 
       
   239     QTest::newRow("red 0") << 255 << 0 << 0 << 0;
       
   240     QTest::newRow("red 24") << 255 << 0 << 0 << 24;
       
   241     QTest::newRow("red 124") << 255 << 0 << 0 << 124;
       
   242     QTest::newRow("red 255") << 255 << 0 << 0 << 255;
       
   243 
       
   244     QTest::newRow("green 0") << 0 << 255 << 0 << 0;
       
   245     QTest::newRow("green 24") << 0 << 255 << 0 << 24;
       
   246     QTest::newRow("green 124") << 0 << 255 << 0 << 124;
       
   247     QTest::newRow("green 255") << 0 << 255 << 0 << 255;
       
   248 
       
   249     QTest::newRow("blue 0") << 0 << 0 << 255 << 0;
       
   250     QTest::newRow("blue 24") << 0 << 0 << 255 << 24;
       
   251     QTest::newRow("blue 124") << 0 << 0 << 255 << 124;
       
   252     QTest::newRow("blue 255") << 0 << 0 << 255 << 255;
       
   253 }
       
   254 
       
   255 void tst_QPixmap::setAlphaChannel()
       
   256 {
       
   257     QFETCH(int, red);
       
   258     QFETCH(int, green);
       
   259     QFETCH(int, blue);
       
   260     QFETCH(int, alpha);
       
   261 
       
   262     int width = 100;
       
   263     int height = 100;
       
   264 
       
   265     QPixmap pixmap(width, height);
       
   266     pixmap.fill(QColor(red, green, blue));
       
   267 
       
   268     QPixmap alphaChannel(width, height);
       
   269     alphaChannel.fill(QColor(alpha, alpha, alpha));
       
   270     pixmap.setAlphaChannel(alphaChannel);
       
   271 
       
   272 #ifdef Q_WS_X11
       
   273     if (pixmap.pixmapData()->classId() == QPixmapData::X11Class && !pixmap.x11PictureHandle())
       
   274         QSKIP("Requires XRender support", SkipAll);
       
   275 #endif
       
   276 
       
   277     QImage result;
       
   278     bool ok = true;
       
   279 
       
   280     QPixmap outAlpha = pixmap.alphaChannel();
       
   281     QCOMPARE(outAlpha.size(), pixmap.size());
       
   282 
       
   283     result = outAlpha.toImage().convertToFormat(QImage::Format_ARGB32);;
       
   284     for (int y = 0; y < height; ++y) {
       
   285         for (int x = 0; x < width; ++x) {
       
   286             ok &= qGray(result.pixel(x, y)) == alpha;
       
   287         }
       
   288     }
       
   289     QVERIFY(ok);
       
   290 
       
   291     result = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
       
   292     QRgb expected = alpha == 0 ? 0 : qRgba(red, green, blue, alpha);
       
   293     for (int y = 0; y < height; ++y) {
       
   294         for (int x = 0; x < width; ++x) {
       
   295             if (result.numColors() > 0) {
       
   296                 ok &= result.pixelIndex(x, y) == expected;
       
   297             } else {
       
   298                 ok &= result.pixel(x, y) == expected;
       
   299             }
       
   300         }
       
   301     }
       
   302     QVERIFY(ok);
       
   303 }
       
   304 
       
   305 void tst_QPixmap::fromImage_data()
       
   306 {
       
   307     bool is16bit = false;
       
   308 #ifdef Q_WS_X11
       
   309     if (QX11Info::appDepth() == 16)
       
   310         is16bit = true;
       
   311 #endif
       
   312 
       
   313     QTest::addColumn<QImage::Format>("format");
       
   314 
       
   315     QTest::newRow("Format_Mono") << QImage::Format_Mono;
       
   316     QTest::newRow("Format_MonoLSB") << QImage::Format_MonoLSB;
       
   317 //    QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8;
       
   318     if (!is16bit)
       
   319         QTest::newRow("Format_RGB32") << QImage::Format_RGB32;
       
   320     QTest::newRow("Format_ARGB32") << QImage::Format_ARGB32;
       
   321     QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied;
       
   322     if (!is16bit)
       
   323         QTest::newRow("Format_RGB16") << QImage::Format_RGB16;
       
   324 }
       
   325 
       
   326 void tst_QPixmap::fromImage()
       
   327 {
       
   328     QFETCH(QImage::Format, format);
       
   329 
       
   330     QImage image(37, 16, format);
       
   331 
       
   332     if (image.numColors() == 2) {
       
   333         image.setColor(0, QColor(Qt::color0).rgba());
       
   334         image.setColor(1, QColor(Qt::color1).rgba());
       
   335     }
       
   336     image.fill(0x7f7f7f7f);
       
   337 
       
   338     const QPixmap pixmap = QPixmap::fromImage(image);
       
   339 #ifdef Q_WS_X11
       
   340     if (pixmap.pixmapData()->classId() == QPixmapData::X11Class && !pixmap.x11PictureHandle())
       
   341         QSKIP("Requires XRender support", SkipAll);
       
   342 #endif
       
   343     const QImage result = pixmap.toImage();
       
   344     image = image.convertToFormat(result.format());
       
   345     QCOMPARE(result, image);
       
   346 }
       
   347 
       
   348 
       
   349 void tst_QPixmap::fromUninitializedImage_data()
       
   350 {
       
   351     QTest::addColumn<QImage::Format>("format");
       
   352 
       
   353     QTest::newRow("Format_Mono") << QImage::Format_Mono;
       
   354     QTest::newRow("Format_MonoLSB") << QImage::Format_MonoLSB;
       
   355     QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8;
       
   356     QTest::newRow("Format_RGB32") << QImage::Format_RGB32;
       
   357     QTest::newRow("Format_ARGB32") << QImage::Format_ARGB32;
       
   358     QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied;
       
   359     QTest::newRow("Format_RGB16") << QImage::Format_RGB16;
       
   360 }
       
   361 
       
   362 void tst_QPixmap::fromUninitializedImage()
       
   363 {
       
   364     QFETCH(QImage::Format, format);
       
   365 
       
   366     QImage image(100, 100, format);
       
   367     QPixmap pix = QPixmap::fromImage(image);
       
   368 
       
   369     // it simply shouldn't crash...
       
   370     QVERIFY(true);
       
   371 
       
   372 }
       
   373 
       
   374 void tst_QPixmap::convertFromImage_data()
       
   375 {
       
   376     QTest::addColumn<QImage>("img1");
       
   377     QTest::addColumn<QImage>("img2");
       
   378 #ifdef Q_OS_SYMBIAN
       
   379     const QString prefix = QLatin1String(SRCDIR) + "convertFromImage";
       
   380 #else
       
   381     const QString prefix = QLatin1String(SRCDIR) + "/convertFromImage";
       
   382 #endif
       
   383     {
       
   384         QImage img1;
       
   385         QImage img2;
       
   386         QVERIFY(img1.load(prefix + "/task31722_0/img1.png"));
       
   387         QVERIFY(img2.load(prefix + "/task31722_0/img2.png"));
       
   388         QVERIFY(img1.load(prefix + "/task31722_0/img1.png"));
       
   389         QVERIFY(img2.load(prefix + "/task31722_0/img2.png"));
       
   390         QTest::newRow("Task 31722 0") << img1 << img2;
       
   391     }
       
   392     {
       
   393         QImage img1;
       
   394         QImage img2;
       
   395         QVERIFY(img1.load(prefix + "/task31722_1/img1.png"));
       
   396         QVERIFY(img2.load(prefix + "/task31722_1/img2.png"));
       
   397         QTest::newRow("Task 31722 1") << img1 << img2;
       
   398     }
       
   399 }
       
   400 
       
   401 void tst_QPixmap::convertFromImage()
       
   402 {
       
   403     QFETCH(QImage, img1);
       
   404     QFETCH(QImage, img2);
       
   405 
       
   406     QPixmap pix = QPixmap::fromImage(img1);
       
   407     pix = QPixmap::fromImage(img2);
       
   408 
       
   409     QPixmap res = QPixmap::fromImage(img2);
       
   410     QVERIFY( pixmapsAreEqual(&pix, &res) );
       
   411 }
       
   412 
       
   413 void tst_QPixmap::scroll_data()
       
   414 {
       
   415     QTest::addColumn<QImage>("input");
       
   416     QTest::addColumn<int>("dx");
       
   417     QTest::addColumn<int>("dy");
       
   418     QTest::addColumn<QRect>("rect");
       
   419     QTest::addColumn<QRegion>("exposed");
       
   420     QTest::addColumn<bool>("newPix");
       
   421 
       
   422     QImage input(":/images/designer.png");
       
   423 
       
   424     // Noop tests
       
   425     QTest::newRow("null") << QImage() << 0 << 0 << QRect() << QRegion() << false;
       
   426     QTest::newRow("dx_0_dy_0_null") << input << 0 << 0 << QRect() << QRegion() << false;
       
   427     QTest::newRow("dx_1_dy_0_null") << input << 1 << 0 << QRect() << QRegion() << false;
       
   428     QTest::newRow("dx_0_dy_1_null") << input << 0 << 1 << QRect() << QRegion() << false;
       
   429     QTest::newRow("dx_0_dy_0_x_y_w_h") << input << 0 << 0 << input.rect() << QRegion() << false;
       
   430 
       
   431     QRegion r;
       
   432     // Scroll whole pixmap
       
   433     r = QRegion(); r += QRect(0, 0, 128, 10);
       
   434     QTest::newRow("dx_0_dy_10_x_y_w_h") << input << 0 << 10 << input.rect() << r << true;
       
   435     r = QRegion(); r += QRect(0, 0, 10, 128);
       
   436     QTest::newRow("dx_10_dy_0_x_y_w_h") << input << 10 << 0 << input.rect() << r << true;
       
   437     r = QRegion(); r += QRect(0, 0, 128, 10); r += QRect(0, 10, 10, 118);
       
   438     QTest::newRow("dx_10_dy_10_x_y_w_h") << input << 10 << 10 << input.rect() << r << true;
       
   439     r = QRegion(); r += QRect(118, 0, 10, 128);
       
   440     QTest::newRow("dx_-10_dy_0_x_y_w_h") << input << -10 << 0 << input.rect() << r << true;
       
   441     r = QRegion(); r += QRect(0, 118, 128, 10);
       
   442     QTest::newRow("dx_0_dy_-10_x_y_w_h") << input << 0 << -10 << input.rect() << r << true;
       
   443     r = QRegion(); r += QRect(118, 0, 10, 118); r += QRect(0, 118, 128, 10);
       
   444     QTest::newRow("dx_-10_dy_-10_x_y_w_h") << input << -10 << -10 << input.rect() << r << true;
       
   445 
       
   446     // Scroll part of pixmap
       
   447     QTest::newRow("dx_0_dy_0_50_50_100_100") << input << 0 << 0 << QRect(50, 50, 100, 100) << QRegion() << false;
       
   448     r = QRegion(); r += QRect(50, 50, 10, 78);
       
   449     QTest::newRow("dx_10_dy_0_50_50_100_100") << input << 10 << 0 << QRect(50, 50, 100, 100) << r << true;
       
   450     r = QRegion(); r += QRect(50, 50, 78, 10);
       
   451     QTest::newRow("dx_0_dy_10_50_50_100_100") << input << 0 << 10 << QRect(50, 50, 100, 100) << r << true;
       
   452     r = QRegion(); r += QRect(50, 50, 78, 10); r += QRect(50, 60, 10, 68);
       
   453     QTest::newRow("dx_10_dy_10_50_50_100_100") << input << 10 << 10 << QRect(50, 50, 100, 100) << r << true;
       
   454     r = QRegion(); r += QRect(118, 50, 10, 78);
       
   455     QTest::newRow("dx_-10_dy_0_50_50_100_100") << input << -10 << 0 << QRect(50, 50, 100, 100) << r << true;
       
   456     r = QRegion(); r += QRect(50, 118, 78, 10);
       
   457     QTest::newRow("dx_0_dy_-10_50_50_100_100") << input << 0 << -10 << QRect(50, 50, 100, 100) << r << true;
       
   458     r = QRegion(); r += QRect(118, 50, 10, 68); r += QRect(50, 118, 78, 10);
       
   459     QTest::newRow("dx_-10_dy_-10_50_50_100_100") << input << -10 << -10 << QRect(50, 50, 100, 100) << r << true;
       
   460 
       
   461     // Scroll away the whole pixmap
       
   462     r = input.rect();
       
   463     QTest::newRow("dx_128_dy_0_x_y_w_h") << input << 128 << 0 << input.rect() << r << false;
       
   464     QTest::newRow("dx_0_dy_128_x_y_w_h") << input << 0 << 128 << input.rect() << r << false;
       
   465     QTest::newRow("dx_128_dy_128_x_y_w_h") << input << 128 << 128 << input.rect() << r << false;
       
   466     QTest::newRow("dx_-128_dy_0_x_y_w_h") << input << -128 << 0 << input.rect() << r << false;
       
   467     QTest::newRow("dx_0_dy_-128_x_y_w_h") << input << 0 << -128 << input.rect() << r << false;
       
   468     QTest::newRow("dx_-128_dy_-128_x_y_w_h") << input << -128 << -128 << input.rect() << r << false;
       
   469 
       
   470     // Scroll away part of the pixmap
       
   471     r = QRegion(); r += QRect(64, 64, 64, 64);
       
   472     QTest::newRow("dx_128_dy_128_64_64_128_128") << input << 128 << 128 << QRect(64, 64, 128, 128) << r << false;
       
   473 }
       
   474 
       
   475 void tst_QPixmap::scroll()
       
   476 {
       
   477     QFETCH(QImage, input);
       
   478     QFETCH(int, dx);
       
   479     QFETCH(int, dy);
       
   480     QFETCH(QRect, rect);
       
   481     QFETCH(QRegion, exposed);
       
   482     QFETCH(bool, newPix);
       
   483 
       
   484     QPixmap pixmap = QPixmap::fromImage(input);
       
   485     QRegion exp;
       
   486     qint64 oldKey = pixmap.cacheKey();
       
   487     pixmap.scroll(dx, dy, rect, &exp);
       
   488     if (!newPix)
       
   489         QCOMPARE(pixmap.cacheKey(), oldKey);
       
   490     else
       
   491         QVERIFY(pixmap.cacheKey() != oldKey);
       
   492 
       
   493 #if 0
       
   494     // Remember to add to resources.
       
   495     QString fileName = QString("images/%1.png").arg(QTest::currentDataTag());
       
   496     pixmap.toImage().save(fileName);
       
   497 #else
       
   498     QString fileName = QString(":/images/%1.png").arg(QTest::currentDataTag());
       
   499 #endif
       
   500     QPixmap output(fileName);
       
   501     QVERIFY(input.isNull() == output.isNull());
       
   502     QVERIFY(lenientCompare(pixmap, output));
       
   503     QCOMPARE(exp, exposed);
       
   504 }
       
   505 
       
   506 void tst_QPixmap::fill_data()
       
   507 {
       
   508     QTest::addColumn<uint>("pixel");
       
   509     QTest::addColumn<bool>("syscolor");
       
   510     QTest::addColumn<bool>("bitmap");
       
   511     for (int color = Qt::black; color < Qt::darkYellow; ++color)
       
   512         QTest::newRow(QString("syscolor_%1").arg(color).toLatin1())
       
   513             << uint(color) << true << false;
       
   514 
       
   515 #ifdef Q_WS_QWS
       
   516     if (QScreen::instance()->depth() >= 24) {
       
   517 #elif defined (Q_WS_X11)
       
   518     QPixmap pm(1, 1);
       
   519     if (pm.x11PictureHandle()) {
       
   520 #elif defined (Q_OS_WINCE)
       
   521     QPixmap pixmap(1,1);
       
   522     if (QPixmap::grabWidget(QApplication::desktop()).depth() >= 24) {
       
   523 #else
       
   524     QPixmap pixmap(1, 1); {
       
   525 #endif
       
   526         QTest::newRow("alpha_7f_red")   << 0x7fff0000u << false << false;
       
   527         QTest::newRow("alpha_3f_blue")  << 0x3f0000ffu << false << false;
       
   528         QTest::newRow("alpha_b7_green") << 0xbf00ff00u << false << false;
       
   529         QTest::newRow("alpha_7f_white") << 0x7fffffffu << false << false;
       
   530         QTest::newRow("alpha_3f_white") << 0x3fffffffu << false << false;
       
   531         QTest::newRow("alpha_b7_white") << 0xb7ffffffu << false << false;
       
   532         QTest::newRow("alpha_7f_black") << 0x7f000000u << false << false;
       
   533         QTest::newRow("alpha_3f_black") << 0x3f000000u << false << false;
       
   534         QTest::newRow("alpha_b7_black") << 0xbf000000u << false << false;
       
   535     }
       
   536 
       
   537     QTest::newRow("bitmap_color0") << uint(Qt::color0) << true << true;
       
   538     QTest::newRow("bitmap_color1") << uint(Qt::color1) << true << true;
       
   539 }
       
   540 
       
   541 void tst_QPixmap::fill()
       
   542 {
       
   543     QFETCH(uint, pixel);
       
   544     QFETCH(bool, syscolor);
       
   545     QFETCH(bool, bitmap);
       
   546 
       
   547     QColor color;
       
   548 
       
   549     if (syscolor)
       
   550         color = QColor(Qt::GlobalColor(pixel));
       
   551     else
       
   552         color = QColor(qRed(pixel), qGreen(pixel), qBlue(pixel), qAlpha(pixel));
       
   553 
       
   554     QColor compareColor = color;
       
   555     if (bitmap && syscolor) {
       
   556         // special case color0 and color1 for bitmaps.
       
   557         if (pixel == Qt::color0)
       
   558             compareColor.setRgb(255, 255, 255);
       
   559         else
       
   560             compareColor.setRgb(0, 0, 0);
       
   561     }
       
   562 
       
   563     QPixmap pm;
       
   564 
       
   565     if (bitmap)
       
   566         pm = QBitmap(400, 400);
       
   567     else
       
   568         pm = QPixmap(400, 400);
       
   569 
       
   570 #if defined(Q_WS_X11)
       
   571     if (!bitmap && pm.pixmapData()->classId() == QPixmapData::X11Class && !pm.x11PictureHandle())
       
   572         QSKIP("Requires XRender support", SkipSingle);
       
   573 #endif
       
   574 
       
   575     pm.fill(color);
       
   576     if (syscolor && !bitmap && pm.depth() < 24) {
       
   577         QSKIP("Test does not work on displays without true color", SkipSingle);
       
   578     }
       
   579 
       
   580     QImage image = pm.toImage();
       
   581     if (bitmap && syscolor) {
       
   582         int pixelindex = (pixel == Qt::color0) ? 0 : 1;
       
   583         QCOMPARE(image.pixelIndex(0,0), pixelindex);
       
   584     }
       
   585     QImage::Format format = compareColor.alpha() != 255
       
   586                             ? QImage::Format_ARGB32
       
   587                             : QImage::Format_RGB32;
       
   588     image = image.convertToFormat(format);
       
   589 
       
   590 
       
   591     QImage shouldBe(400, 400, format);
       
   592     shouldBe.fill(compareColor.rgba());
       
   593 
       
   594     QCOMPARE(image, shouldBe);
       
   595 }
       
   596 
       
   597 void tst_QPixmap::fill_transparent()
       
   598 {
       
   599     QPixmap pixmap(10, 10);
       
   600 #ifdef Q_WS_X11
       
   601     if (pixmap.pixmapData()->classId() == QPixmapData::X11Class && !pixmap.x11PictureHandle())
       
   602         QSKIP("Requires XRender support", SkipAll);
       
   603 #endif
       
   604     pixmap.fill(Qt::transparent);
       
   605     QVERIFY(pixmap.hasAlphaChannel());
       
   606 }
       
   607 
       
   608 void tst_QPixmap::mask()
       
   609 {
       
   610     QPixmap pm(100, 100);
       
   611     QBitmap bm(100, 100);
       
   612 
       
   613     pm.fill();
       
   614     bm.fill();
       
   615 
       
   616     QVERIFY(!pm.isNull());
       
   617     QVERIFY(!bm.isNull());
       
   618     // hw: todo: this will fail if the default pixmap format is
       
   619     // argb32_premultiplied. The mask will be all 1's
       
   620     QVERIFY(pm.mask().isNull());
       
   621 
       
   622     QImage img = bm.toImage();
       
   623     QVERIFY(img.format() == QImage::Format_MonoLSB
       
   624             || img.format() == QImage::Format_Mono);
       
   625 
       
   626     pm.setMask(bm);
       
   627     QVERIFY(!pm.mask().isNull());
       
   628 
       
   629     bm = QBitmap();
       
   630     // Invalid format here, since isNull() == true
       
   631     QVERIFY(bm.toImage().isNull());
       
   632     QCOMPARE(bm.toImage().format(), QImage::Format_Invalid);
       
   633     pm.setMask(bm);
       
   634     QVERIFY(pm.mask().isNull());
       
   635 
       
   636     bm = QBitmap(100, 100);
       
   637     bm.fill();
       
   638     pm.setMask(bm);
       
   639     QVERIFY(!pm.mask().isNull());
       
   640 }
       
   641 
       
   642 void tst_QPixmap::bitmapMask()
       
   643 {
       
   644     QImage image(3, 3, QImage::Format_Mono);
       
   645     image.setColor(0, Qt::color0);
       
   646     image.setColor(1, Qt::color1);
       
   647     image.fill(Qt::color0);
       
   648     image.setPixel(1, 1, Qt::color1);
       
   649     image.setPixel(0, 0, Qt::color1);
       
   650 
       
   651     QImage image_mask(3, 3, QImage::Format_Mono);
       
   652     image_mask.setColor(0, Qt::color0);
       
   653     image_mask.setColor(1, Qt::color1);
       
   654     image_mask.fill(Qt::color0);
       
   655     image_mask.setPixel(1, 1, Qt::color1);
       
   656     image_mask.setPixel(2, 0, Qt::color1);
       
   657 
       
   658     QBitmap pm = QBitmap::fromImage(image);
       
   659     QBitmap pm_mask = QBitmap::fromImage(image_mask);
       
   660     pm.setMask(pm_mask);
       
   661 
       
   662     image = pm.toImage();
       
   663     image.setColor(0, Qt::color0);
       
   664     image.setColor(1, Qt::color1);
       
   665     image_mask = pm_mask.toImage();
       
   666     image_mask.setColor(0, Qt::color0);
       
   667     image_mask.setColor(1, Qt::color1);
       
   668 
       
   669     QVERIFY(!image.pixel(0, 0));
       
   670     QVERIFY(!image.pixel(2, 0));
       
   671     QVERIFY(image.pixel(1, 1));
       
   672 }
       
   673 
       
   674 void tst_QPixmap::setGetMask_data()
       
   675 {
       
   676     QTest::addColumn<QPixmap>("pixmap");
       
   677     QTest::addColumn<QBitmap>("mask");
       
   678     QTest::addColumn<QBitmap>("expected");
       
   679 
       
   680     QPixmap pixmap(10, 10);
       
   681     QBitmap mask(10, 10);
       
   682     QPainter p;
       
   683 
       
   684     p.begin(&pixmap);
       
   685     p.fillRect(0, 0, 10, 10, QColor(Qt::black));
       
   686     p.end();
       
   687 
       
   688     QTest::newRow("nullmask 0") << QPixmap() << QBitmap() << QBitmap();
       
   689     QTest::newRow("nullmask 1") << pixmap << QBitmap() << QBitmap();
       
   690     mask.clear();
       
   691     QTest::newRow("nullmask 2") << pixmap << mask << mask;
       
   692     QTest::newRow("nullmask 3") << QPixmap(QBitmap()) << QBitmap() << QBitmap();
       
   693 
       
   694     p.begin(&mask);
       
   695     p.fillRect(1, 1, 5, 5, QColor(Qt::color1));
       
   696     p.end();
       
   697     QTest::newRow("simple mask 0") << pixmap << mask << mask;
       
   698 }
       
   699 
       
   700 void tst_QPixmap::setGetMask()
       
   701 {
       
   702     QFETCH(QPixmap, pixmap);
       
   703     QFETCH(QBitmap, mask);
       
   704     QFETCH(QBitmap, expected);
       
   705 
       
   706     pixmap.setMask(mask);
       
   707     QBitmap result = pixmap.mask();
       
   708 
       
   709     QImage resultImage = result.toImage();
       
   710     QImage expectedImage = expected.toImage();
       
   711     QCOMPARE(resultImage.convertToFormat(expectedImage.format()),
       
   712              expectedImage);
       
   713 }
       
   714 
       
   715 void tst_QPixmap::testMetrics()
       
   716 {
       
   717     QPixmap pixmap(100, 100);
       
   718 
       
   719     QCOMPARE(pixmap.width(), 100);
       
   720     QCOMPARE(pixmap.height(), 100);
       
   721     QVERIFY(pixmap.depth() >= QPixmap::defaultDepth());
       
   722 
       
   723     QBitmap bitmap(100, 100);
       
   724 
       
   725     QCOMPARE(bitmap.width(), 100);
       
   726     QCOMPARE(bitmap.height(), 100);
       
   727     QCOMPARE(bitmap.depth(), 1);
       
   728 }
       
   729 
       
   730 void tst_QPixmap::createMaskFromColor()
       
   731 {
       
   732     QImage image(3, 3, QImage::Format_Indexed8);
       
   733     image.setNumColors(10);
       
   734     image.setColor(0, 0xffffffff);
       
   735     image.setColor(1, 0xff000000);
       
   736     image.setColor(2, 0xffff0000);
       
   737     image.setColor(3, 0xff0000ff);
       
   738     image.fill(0);
       
   739     image.setPixel(1, 0, 1);
       
   740     image.setPixel(0, 1, 2);
       
   741     image.setPixel(1, 1, 3);
       
   742 
       
   743     QImage im_mask = image.createMaskFromColor(0xffff0000);
       
   744     QCOMPARE((uint) im_mask.pixel(0, 1), QColor(Qt::color0).rgba());
       
   745     QCOMPARE((uint) im_mask.pixel(0, 1), QColor(Qt::color0).rgba());
       
   746 
       
   747     QPixmap pixmap = QPixmap::fromImage(image);
       
   748     QBitmap mask = pixmap.createMaskFromColor(Qt::red);
       
   749     QBitmap inv_mask = pixmap.createMaskFromColor(Qt::red, Qt::MaskOutColor);
       
   750     QCOMPARE((uint) mask.toImage().pixel(0, 1), QColor(Qt::color0).rgba());
       
   751     QCOMPARE((uint) inv_mask.toImage().pixel(0, 1), QColor(Qt::color1).rgba());
       
   752 }
       
   753 
       
   754 
       
   755 void tst_QPixmap::cacheKey()
       
   756 {
       
   757     QPixmap pixmap1(1, 1);
       
   758     QPixmap pixmap2(1, 1);
       
   759     qint64 pixmap1_key = pixmap1.cacheKey();
       
   760 
       
   761     QVERIFY(pixmap1.cacheKey() != pixmap2.cacheKey());
       
   762 
       
   763     pixmap2 = pixmap1;
       
   764     QVERIFY(pixmap2.cacheKey() == pixmap1.cacheKey());
       
   765 
       
   766     pixmap2.detach();
       
   767     QVERIFY(pixmap2.cacheKey() != pixmap1.cacheKey());
       
   768     QVERIFY(pixmap1.cacheKey() == pixmap1_key);
       
   769 }
       
   770 
       
   771 // Test drawing a bitmap on a pixmap.
       
   772 void tst_QPixmap::drawBitmap()
       
   773 {
       
   774     QBitmap bitmap(10,10);
       
   775     bitmap.fill(Qt::color1);
       
   776 
       
   777     QPixmap pixmap(10,10);
       
   778     QPainter painter2(&pixmap);
       
   779     painter2.fillRect(0,0,10,10, QBrush(Qt::green));
       
   780     painter2.setPen(Qt::red);
       
   781     painter2.drawPixmap(0,0,10,10, bitmap);
       
   782     painter2.end();
       
   783 
       
   784     QPixmap expected(10, 10);
       
   785     expected.fill(Qt::red);
       
   786 
       
   787     QVERIFY(lenientCompare(pixmap, expected));
       
   788 }
       
   789 
       
   790 void tst_QPixmap::grabWidget()
       
   791 {
       
   792     QWidget widget;
       
   793     widget.setPalette(Qt::green);
       
   794     widget.resize(128, 128);
       
   795 
       
   796     QPixmap expected(64, 64);
       
   797     expected.fill(Qt::green);
       
   798 
       
   799     QPixmap actual = QPixmap::grabWidget(&widget, QRect(64, 64, 64, 64));
       
   800     QVERIFY(lenientCompare(actual, expected));
       
   801 }
       
   802 
       
   803 void tst_QPixmap::grabWindow()
       
   804 {
       
   805 #ifdef Q_OS_WINCE
       
   806     // We get out of memory, if the desktop itself is too big.
       
   807     if (QApplication::desktop()->width() <= 480)
       
   808 #endif
       
   809     QVERIFY(QPixmap::grabWindow(QApplication::desktop()->winId()).isNull() == false);
       
   810     QWidget w;
       
   811     w.resize(640, 480);
       
   812     w.show();
       
   813     QTest::qWait(100);
       
   814 #ifdef Q_WS_X11
       
   815     qt_x11_wait_for_window_manager(&w);
       
   816 #endif
       
   817     QVERIFY(QPixmap::grabWindow(w.winId()).isNull() == false);
       
   818 
       
   819     QWidget child(&w);
       
   820     child.setGeometry(50, 50, 100, 100);
       
   821     child.setPalette(Qt::red);
       
   822     child.setAutoFillBackground(true);
       
   823     child.show();
       
   824     QTest::qWait(100);
       
   825 #ifdef Q_WS_X11
       
   826     qt_x11_wait_for_window_manager(&child);
       
   827 #endif
       
   828 
       
   829     QPixmap grabWindowPixmap = QPixmap::grabWindow(child.winId());
       
   830     QPixmap grabWidgetPixmap = QPixmap::grabWidget(&child);
       
   831     lenientCompare(grabWindowPixmap, grabWidgetPixmap);
       
   832 }
       
   833 
       
   834 void tst_QPixmap::isNull()
       
   835 {
       
   836     {
       
   837         QPixmap pixmap(1,1);
       
   838         QVERIFY(pixmap.isNull() == false);
       
   839     }
       
   840     {
       
   841         QPixmap pixmap(0,0);
       
   842         QVERIFY(pixmap.isNull());
       
   843     }
       
   844 
       
   845     {
       
   846         QPixmap pixmap(0,1);
       
   847         QVERIFY(pixmap.isNull());
       
   848     }
       
   849     {
       
   850         QPixmap pixmap(1,0);
       
   851         QVERIFY(pixmap.isNull());
       
   852     }
       
   853     {
       
   854         QPixmap pixmap(-1,-1);
       
   855         QVERIFY(pixmap.isNull());
       
   856     }
       
   857     {
       
   858         QPixmap pixmap(-1,5);
       
   859         QVERIFY(pixmap.isNull());
       
   860     }
       
   861 }
       
   862 
       
   863 #ifdef Q_WS_QWS
       
   864 void tst_QPixmap::convertFromImageNoDetach()
       
   865 {
       
   866     //first get the screen format
       
   867     QPixmap randomPixmap(10,10);
       
   868     QImage::Format screenFormat = randomPixmap.toImage().format();
       
   869     QVERIFY(screenFormat != QImage::Format_Invalid);
       
   870 
       
   871     QImage orig(100,100, screenFormat);
       
   872 
       
   873     QPixmap pix = QPixmap::fromImage(orig);
       
   874     QImage copy = pix.toImage();
       
   875 
       
   876     QVERIFY(copy.format() == screenFormat);
       
   877 
       
   878     const QImage constOrig = orig;
       
   879     const QImage constCopy = copy;
       
   880     QVERIFY(constOrig.bits() == constCopy.bits());
       
   881 }
       
   882 #endif //Q_WS_QWS
       
   883 
       
   884 void tst_QPixmap::convertFromImageDetach()
       
   885 {
       
   886     QImage img(10,10, QImage::Format_RGB32);
       
   887     img.fill(0);
       
   888     QVERIFY(!img.isNull());
       
   889     QPixmap p = QPixmap::fromImage(img);
       
   890     QVERIFY(p.isDetached());
       
   891     QPixmap copy = p;
       
   892     QVERIFY(!copy.isDetached());
       
   893     QVERIFY(!p.isDetached());
       
   894     img.fill(1);
       
   895     p = QPixmap::fromImage(img);
       
   896     QVERIFY(copy.isDetached());
       
   897 }
       
   898 
       
   899 #if defined(Q_WS_WIN)
       
   900 void tst_QPixmap::toWinHBITMAP_data()
       
   901 {
       
   902     QTest::addColumn<int>("red");
       
   903     QTest::addColumn<int>("green");
       
   904     QTest::addColumn<int>("blue");
       
   905 
       
   906     QTest::newRow("red")   << 255 << 0 << 0;
       
   907     QTest::newRow("green") << 0 << 255 << 0;
       
   908     QTest::newRow("blue")  << 0 << 0 << 255;
       
   909 }
       
   910 
       
   911 void tst_QPixmap::toWinHBITMAP()
       
   912 {
       
   913     QFETCH(int, red);
       
   914     QFETCH(int, green);
       
   915     QFETCH(int, blue);
       
   916 
       
   917     QPixmap pm(100, 100);
       
   918     pm.fill(QColor(red, green, blue));
       
   919 
       
   920     HBITMAP bitmap = pm.toWinHBITMAP();
       
   921 
       
   922     QVERIFY(bitmap != 0);
       
   923 
       
   924     // Verify size
       
   925     BITMAP bitmap_info;
       
   926     memset(&bitmap_info, 0, sizeof(BITMAP));
       
   927 
       
   928     int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info);
       
   929     QVERIFY(res);
       
   930 
       
   931     QCOMPARE(100, (int) bitmap_info.bmWidth);
       
   932     QCOMPARE(100, (int) bitmap_info.bmHeight);
       
   933 
       
   934     HDC display_dc = GetDC(0);
       
   935     HDC bitmap_dc = CreateCompatibleDC(display_dc);
       
   936 
       
   937     HBITMAP null_bitmap = (HBITMAP) SelectObject(bitmap_dc, bitmap);
       
   938 
       
   939     COLORREF pixel = GetPixel(bitmap_dc, 0, 0);
       
   940     QCOMPARE((int)GetRValue(pixel), red);
       
   941     QCOMPARE((int)GetGValue(pixel), green);
       
   942     QCOMPARE((int)GetBValue(pixel), blue);
       
   943 
       
   944     // Clean up
       
   945     SelectObject(bitmap_dc, null_bitmap);
       
   946     DeleteObject(bitmap);
       
   947     DeleteDC(bitmap_dc);
       
   948     ReleaseDC(0, display_dc);
       
   949 
       
   950 }
       
   951 
       
   952 void tst_QPixmap::fromWinHBITMAP_data()
       
   953 {
       
   954     toWinHBITMAP_data();
       
   955 }
       
   956 
       
   957 void tst_QPixmap::fromWinHBITMAP()
       
   958 {
       
   959     QFETCH(int, red);
       
   960     QFETCH(int, green);
       
   961     QFETCH(int, blue);
       
   962 
       
   963     HDC display_dc = GetDC(0);
       
   964     HDC bitmap_dc = CreateCompatibleDC(display_dc);
       
   965     HBITMAP bitmap = CreateCompatibleBitmap(display_dc, 100, 100);
       
   966     SelectObject(bitmap_dc, bitmap);
       
   967 
       
   968     SelectObject(bitmap_dc, GetStockObject(NULL_PEN));
       
   969     HGDIOBJ old_brush = SelectObject(bitmap_dc, CreateSolidBrush(RGB(red, green, blue)));
       
   970     Rectangle(bitmap_dc, 0, 0, 100, 100);
       
   971 
       
   972 #ifdef Q_OS_WINCE //the device context has to be deleted before QPixmap::fromWinHBITMAP()
       
   973     DeleteDC(bitmap_dc);
       
   974 #endif
       
   975     QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap);
       
   976     QCOMPARE(pixmap.width(), 100);
       
   977     QCOMPARE(pixmap.height(), 100);
       
   978 
       
   979     QImage image = pixmap.toImage();
       
   980     QRgb pixel = image.pixel(0, 0);
       
   981     QCOMPARE(qRed(pixel), red);
       
   982     QCOMPARE(qGreen(pixel), green);
       
   983     QCOMPARE(qBlue(pixel), blue);
       
   984 
       
   985     DeleteObject(SelectObject(bitmap_dc, old_brush));
       
   986     DeleteObject(SelectObject(bitmap_dc, bitmap));
       
   987 #ifndef Q_OS_WINCE
       
   988     DeleteDC(bitmap_dc);
       
   989 #endif
       
   990     ReleaseDC(0, display_dc);
       
   991 }
       
   992 
       
   993 static void compareImages(const QImage &image1, const QImage &image2)
       
   994 {
       
   995     QCOMPARE(image1.width(), image2.width());
       
   996     QCOMPARE(image1.height(), image2.height());
       
   997     QCOMPARE(image1.format(), image2.format());
       
   998 
       
   999     static const int fuzz = 1;
       
  1000 
       
  1001     for (int y = 0; y < image1.height(); y++)
       
  1002     {
       
  1003         for (int x = 0; x < image2.width(); x++)
       
  1004         {
       
  1005             QRgb p1 = image1.pixel(x, y);
       
  1006             QRgb p2 = image2.pixel(x, y);
       
  1007 
       
  1008             bool pixelMatches =
       
  1009                 qAbs(qRed(p1) - qRed(p2)) <= fuzz
       
  1010                 && qAbs(qGreen(p1) - qGreen(p2)) <= fuzz
       
  1011                 && qAbs(qBlue(p1) - qBlue(p2)) <= fuzz
       
  1012                 && qAbs(qAlpha(p1) - qAlpha(p2)) <= fuzz;
       
  1013 
       
  1014             QVERIFY(pixelMatches);
       
  1015         }
       
  1016     }
       
  1017 }
       
  1018 
       
  1019 void tst_QPixmap::toWinHICON_data()
       
  1020 {
       
  1021     QTest::addColumn<QString>("image");
       
  1022     QTest::addColumn<int>("width");
       
  1023     QTest::addColumn<int>("height");
       
  1024 
       
  1025     const QString prefix = QLatin1String(SRCDIR) + "/convertFromToHICON";
       
  1026 
       
  1027     QTest::newRow("32bpp_16x16") << prefix + QLatin1String("/icon_32bpp") << 16 << 16;
       
  1028     QTest::newRow("32bpp_32x32") << prefix + QLatin1String("/icon_32bpp") << 32 << 32;
       
  1029     QTest::newRow("32bpp_48x48") << prefix + QLatin1String("/icon_32bpp") << 48 << 48;
       
  1030     QTest::newRow("32bpp_256x256") << prefix + QLatin1String("/icon_32bpp") << 256 << 256;
       
  1031 
       
  1032     QTest::newRow("8bpp_16x16") << prefix + QLatin1String("/icon_8bpp") << 16 << 16;
       
  1033     QTest::newRow("8bpp_32x32") << prefix + QLatin1String("/icon_8bpp") << 32 << 32;
       
  1034     QTest::newRow("8bpp_48x48") << prefix + QLatin1String("/icon_8bpp") << 48 << 48;
       
  1035 }
       
  1036 
       
  1037 void tst_QPixmap::toWinHICON()
       
  1038 {
       
  1039 #ifdef Q_OS_WINCE
       
  1040     QSKIP("Test shall be enabled for Windows CE shortly.", SkipAll);
       
  1041 #endif
       
  1042 
       
  1043     QFETCH(int, width);
       
  1044     QFETCH(int, height);
       
  1045     QFETCH(QString, image);
       
  1046 
       
  1047     QPixmap empty(width, height);
       
  1048     empty.fill(Qt::transparent);
       
  1049 
       
  1050     HDC display_dc = GetDC(0);
       
  1051     HDC bitmap_dc = CreateCompatibleDC(display_dc);
       
  1052     HBITMAP bitmap = empty.toWinHBITMAP(QPixmap::Alpha);
       
  1053     SelectObject(bitmap_dc, bitmap);
       
  1054 
       
  1055     QImage imageFromFile(image + QString(QLatin1String("_%1x%2.png")).arg(width).arg(height));
       
  1056     imageFromFile = imageFromFile.convertToFormat(QImage::Format_ARGB32_Premultiplied);
       
  1057 
       
  1058     HICON icon = QPixmap::fromImage(imageFromFile).toWinHICON();
       
  1059 
       
  1060     DrawIconEx(bitmap_dc, 0, 0, icon, width, height, 0, 0, DI_NORMAL);
       
  1061 
       
  1062     DestroyIcon(icon);
       
  1063     DeleteDC(bitmap_dc);
       
  1064 
       
  1065     QImage imageFromHICON = QPixmap::fromWinHBITMAP(bitmap, QPixmap::Alpha).toImage();
       
  1066 
       
  1067     ReleaseDC(0, display_dc);
       
  1068 
       
  1069     // fuzzy comparison must be used, as the pixel values change slightly during conversion
       
  1070     // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere
       
  1071 
       
  1072     // QVERIFY(imageFromHICON == imageFromFile);
       
  1073     compareImages(imageFromHICON, imageFromFile);
       
  1074 }
       
  1075 
       
  1076 void tst_QPixmap::fromWinHICON_data()
       
  1077 {
       
  1078     toWinHICON_data();
       
  1079 }
       
  1080 
       
  1081 void tst_QPixmap::fromWinHICON()
       
  1082 {
       
  1083 #ifdef Q_OS_WINCE
       
  1084     QSKIP("Test shall be enabled for Windows CE shortly.", SkipAll);
       
  1085 
       
  1086 #else
       
  1087     QFETCH(int, width);
       
  1088     QFETCH(int, height);
       
  1089     QFETCH(QString, image);
       
  1090 
       
  1091     HICON icon = (HICON)LoadImage(0, (wchar_t*)(image + QLatin1String(".ico")).utf16(), IMAGE_ICON, width, height, LR_LOADFROMFILE);
       
  1092     QImage imageFromHICON = QPixmap::fromWinHICON(icon).toImage();
       
  1093     DestroyIcon(icon);
       
  1094 
       
  1095     QImage imageFromFile(image + QString(QLatin1String("_%1x%2.png")).arg(width).arg(height));
       
  1096     imageFromFile = imageFromFile.convertToFormat(QImage::Format_ARGB32_Premultiplied);
       
  1097 
       
  1098     // fuzzy comparison must be used, as the pixel values change slightly during conversion
       
  1099     // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere
       
  1100 
       
  1101     // QVERIFY(imageFromHICON == imageFromFile);
       
  1102     compareImages(imageFromHICON, imageFromFile);
       
  1103 #endif
       
  1104 }
       
  1105 
       
  1106 #endif // Q_WS_WIN
       
  1107 
       
  1108 #if defined(Q_WS_S60)
       
  1109 Q_DECLARE_METATYPE(TDisplayMode)
       
  1110 
       
  1111 void tst_QPixmap::fromSymbianCFbsBitmap_data()
       
  1112 {
       
  1113     QTest::addColumn<TDisplayMode>("format");
       
  1114     QTest::addColumn<int>("width");
       
  1115     QTest::addColumn<int>("height");
       
  1116     QTest::addColumn<QColor>("color");
       
  1117 
       
  1118     const int smallWidth = 20;
       
  1119     const int smallHeight = 20;
       
  1120     const int largeWidth = 240;
       
  1121     const int largeHeight = 320;
       
  1122 
       
  1123     // Indexed Color Formats - Disabled since images seem to be blank -> no palette?
       
  1124 //    QTest::newRow("EGray2 small") << EGray2 << smallWidth << smallHeight << QColor(Qt::black);
       
  1125 //    QTest::newRow("EGray2 big") << EGray2 << largeWidth << largeHeight << QColor(Qt::black);
       
  1126 //    QTest::newRow("EGray256 small") << EGray256 << smallWidth << smallHeight << QColor(Qt::blue);
       
  1127 //    QTest::newRow("EGray256 big") << EGray256 << largeWidth << largeHeight << QColor(Qt::blue);
       
  1128 //    QTest::newRow("EColor256 small") << EColor256 << smallWidth << smallHeight << QColor(Qt::red);
       
  1129 //    QTest::newRow("EColor256 big") << EColor256 << largeWidth << largeHeight << QColor(Qt::red);
       
  1130 
       
  1131     // Direct Color Formats
       
  1132     QTest::newRow("EColor4K small") << EColor4K << smallWidth << smallHeight << QColor(Qt::red);
       
  1133     QTest::newRow("EColor4K big") << EColor4K << largeWidth << largeHeight << QColor(Qt::red);
       
  1134     QTest::newRow("EColor64K small") << EColor64K << smallWidth << smallHeight << QColor(Qt::green);
       
  1135     QTest::newRow("EColor64K big") << EColor64K << largeWidth << largeHeight << QColor(Qt::green);
       
  1136     QTest::newRow("EColor16MU small") << EColor16MU << smallWidth << smallHeight << QColor(Qt::red);
       
  1137     QTest::newRow("EColor16MU big") << EColor16MU << largeWidth << largeHeight << QColor(Qt::red);
       
  1138     QTest::newRow("EColor16MA small opaque") << EColor16MA << smallWidth << smallHeight << QColor(255, 255, 0);
       
  1139     QTest::newRow("EColor16MA big opaque") << EColor16MA << largeWidth << largeHeight << QColor(255, 255, 0);
       
  1140 
       
  1141     // Semi-transparent Colors - Disabled for now, since the QCOMPARE fails, but visually confirmed to work
       
  1142 //    QTest::newRow("EColor16MA small semi") << EColor16MA << smallWidth << smallHeight << QColor(255, 255, 0, 127);
       
  1143 //    QTest::newRow("EColor16MA big semi") << EColor16MA << largeWidth << largeHeight << QColor(255, 255, 0, 127);
       
  1144 //    QTest::newRow("EColor16MA small trans") << EColor16MA << smallWidth << smallHeight << QColor(255, 255, 0, 0);
       
  1145 //    QTest::newRow("EColor16MA big trans") << EColor16MA << largeWidth << largeHeight << QColor(255, 255, 0, 0);
       
  1146 
       
  1147 #if !defined(__SERIES60_31__)
       
  1148     QTest::newRow("EColor16MAP small") << EColor16MAP << smallWidth << smallHeight << QColor(Qt::red);
       
  1149     QTest::newRow("EColor16MAP big") << EColor16MAP << largeWidth << largeHeight << QColor(Qt::red);
       
  1150 #endif
       
  1151 }
       
  1152 
       
  1153 void tst_QPixmap::fromSymbianCFbsBitmap()
       
  1154 {
       
  1155     QFETCH(TDisplayMode, format);
       
  1156     QFETCH(int, width);
       
  1157     QFETCH(int, height);
       
  1158     QFETCH(QColor, color);
       
  1159     int expectedDepth = TDisplayModeUtils::NumDisplayModeBitsPerPixel(format);
       
  1160 
       
  1161     CFbsBitmap *nativeBitmap = 0;
       
  1162     CFbsBitmapDevice *bitmapDevice = 0;
       
  1163     CBitmapContext *bitmapContext = 0;
       
  1164 
       
  1165     nativeBitmap = new (ELeave) CFbsBitmap();
       
  1166     TInt err = nativeBitmap->Create(TSize(width, height), format);
       
  1167     CleanupStack::PushL(nativeBitmap);
       
  1168     QVERIFY(err == KErrNone);
       
  1169     bitmapDevice = CFbsBitmapDevice::NewL(nativeBitmap);
       
  1170     CleanupStack::PushL(bitmapDevice);
       
  1171 
       
  1172     err = bitmapDevice->CreateBitmapContext(bitmapContext);
       
  1173     CleanupStack::PushL(bitmapContext);
       
  1174     QVERIFY(err == KErrNone);
       
  1175     TRgb symbianColor = TRgb(color.red(), color.green(), color.blue(), color.alpha());
       
  1176     bitmapContext->SetBrushColor(symbianColor);
       
  1177     bitmapContext->Clear();
       
  1178 
       
  1179     __UHEAP_MARK;
       
  1180     { // Test the null case
       
  1181         CFbsBitmap *bitmap = 0;
       
  1182         QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(bitmap);
       
  1183         QVERIFY(pixmap.isNull());
       
  1184     }
       
  1185     __UHEAP_MARKEND;
       
  1186 
       
  1187     __UHEAP_MARK;
       
  1188     { // Test the normal case
       
  1189         QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(nativeBitmap);
       
  1190 //        QCOMPARE(pixmap.depth(), expectedDepth); // Depth is not preserved now
       
  1191         QCOMPARE(pixmap.width(), width);
       
  1192         QCOMPARE(pixmap.height(), height);
       
  1193         QImage image = pixmap.toImage();
       
  1194 
       
  1195         QColor actualColor(image.pixel(1, 1));
       
  1196         QCOMPARE(actualColor, color);
       
  1197     }
       
  1198     __UHEAP_MARKEND;
       
  1199 
       
  1200     CleanupStack::PopAndDestroy(3);
       
  1201 }
       
  1202 #endif
       
  1203 
       
  1204 void tst_QPixmap::onlyNullPixmapsOutsideGuiThread()
       
  1205 {
       
  1206 #if !defined(Q_WS_WIN)
       
  1207     class Thread : public QThread
       
  1208     {
       
  1209     public:
       
  1210         void run()
       
  1211         {
       
  1212             QTest::ignoreMessage(QtWarningMsg,
       
  1213                                  "QPixmap: It is not safe to use pixmaps outside the GUI thread");
       
  1214             QPixmap pixmap;
       
  1215             QVERIFY(pixmap.isNull());
       
  1216 
       
  1217             QTest::ignoreMessage(QtWarningMsg,
       
  1218                                  "QPixmap: It is not safe to use pixmaps outside the GUI thread");
       
  1219             QPixmap pixmap1(100, 100);
       
  1220             QVERIFY(pixmap1.isNull());
       
  1221 
       
  1222             QTest::ignoreMessage(QtWarningMsg,
       
  1223                                  "QPixmap: It is not safe to use pixmaps outside the GUI thread");
       
  1224             QPixmap pixmap2(pixmap1);
       
  1225             QVERIFY(pixmap2.isNull());
       
  1226         }
       
  1227     };
       
  1228     Thread thread;
       
  1229 #if defined(Q_OS_SYMBIAN)
       
  1230     thread.setStackSize(0x10000);
       
  1231 #endif
       
  1232     thread.start();
       
  1233 #if defined(Q_OS_SYMBIAN)
       
  1234     QVERIFY(thread.wait(10000));
       
  1235 #else
       
  1236     thread.wait();
       
  1237 #endif
       
  1238 
       
  1239 #endif // !defined(Q_WS_WIN)
       
  1240 }
       
  1241 
       
  1242 void tst_QPixmap::refUnref()
       
  1243 {
       
  1244     // Simple ref/unref
       
  1245     {
       
  1246         QPixmap p;
       
  1247     }
       
  1248     {
       
  1249         QBitmap b;
       
  1250     }
       
  1251 
       
  1252     // Get a copy of a pixmap that goes out of scope
       
  1253     {
       
  1254         QPixmap b;
       
  1255         {
       
  1256             QPixmap a(10, 10);
       
  1257             a.fill(Qt::color0);
       
  1258             b = a;
       
  1259         }
       
  1260     }
       
  1261     {
       
  1262         QBitmap mask;
       
  1263         {
       
  1264             QBitmap bitmap(10, 10);
       
  1265             bitmap.fill(Qt::color1);
       
  1266             mask = bitmap.mask();
       
  1267         }
       
  1268         mask.fill(Qt::color0);
       
  1269     }
       
  1270 
       
  1271 }
       
  1272 
       
  1273 void tst_QPixmap::copy()
       
  1274 {
       
  1275     QPixmap src(32, 32);
       
  1276     {
       
  1277         QPainter p(&src);
       
  1278         p.fillRect(0, 0, 32, 32, Qt::red);
       
  1279         p.fillRect(10, 10, 10, 10, Qt::blue);
       
  1280     }
       
  1281 
       
  1282     QPixmap dest = src.copy(10, 10, 10, 10);
       
  1283 
       
  1284     QPixmap expected(10, 10);
       
  1285     expected.fill(Qt::blue);
       
  1286     QVERIFY(lenientCompare(dest, expected));
       
  1287 }
       
  1288 
       
  1289 #ifdef QT3_SUPPORT
       
  1290 void tst_QPixmap::resize()
       
  1291 {
       
  1292     QPixmap p1(10, 10);
       
  1293     p1.fill(Qt::red);
       
  1294 
       
  1295     QPixmap p2 = p1;
       
  1296     QPixmap p3(50, 50);
       
  1297     p3.fill(Qt::red);
       
  1298 
       
  1299     p1.resize(p3.size());
       
  1300     p1.resize(p2.size());
       
  1301     p3.resize(p2.size());
       
  1302     QCOMPARE(p1.toImage(), p2.toImage());
       
  1303     QCOMPARE(p1.toImage(), p3.toImage());
       
  1304 
       
  1305     QBitmap b1;
       
  1306     b1.resize(10, 10);
       
  1307     QVERIFY(b1.depth() == 1);
       
  1308     QPixmap p4;
       
  1309     p4.resize(10, 10);
       
  1310     QVERIFY(p4.depth() != 0);
       
  1311 }
       
  1312 
       
  1313 void tst_QPixmap::resizePreserveMask()
       
  1314 {
       
  1315     QPixmap pm(100, 100);
       
  1316     pm.fill(Qt::transparent);
       
  1317     QPainter p(&pm);
       
  1318     p.fillRect(10, 10, 80, 80, Qt::red);
       
  1319     p.drawRect(0, 0, 99, 99);
       
  1320     p.end();
       
  1321 
       
  1322     QBitmap mask = pm.mask();
       
  1323     pm.resize(50, 50);
       
  1324 
       
  1325     QCOMPARE(pm.mask().toImage(), mask.toImage().copy(0, 0, 50, 50));
       
  1326 
       
  1327     pm = QPixmap(100, 100);
       
  1328     pm.fill(Qt::red);
       
  1329     pm.setMask(mask);
       
  1330     pm.resize(50, 50);
       
  1331 
       
  1332     QCOMPARE(pm.mask().toImage(), mask.toImage().copy(0, 0, 50, 50));
       
  1333 }
       
  1334 #endif
       
  1335 
       
  1336 void tst_QPixmap::depthOfNullObjects()
       
  1337 {
       
  1338     QBitmap b1;
       
  1339     QVERIFY(b1.depth() == 0);
       
  1340     QPixmap p4;
       
  1341     QVERIFY(p4.depth() == 0);
       
  1342 }
       
  1343 
       
  1344 void tst_QPixmap::transformed()
       
  1345 {
       
  1346     QPixmap p1(20, 10);
       
  1347     p1.fill(Qt::red);
       
  1348     {
       
  1349         QPainter p(&p1);
       
  1350         p.drawRect(0, 0, p1.width() - 1, p1.height() - 1);
       
  1351     }
       
  1352 
       
  1353     QPixmap p2(10, 20);
       
  1354     {
       
  1355         QPainter p(&p2);
       
  1356         p.rotate(90);
       
  1357         p.drawPixmap(0, -p1.height(), p1);
       
  1358     }
       
  1359 
       
  1360     QPixmap p3(20, 10);
       
  1361     {
       
  1362         QPainter p(&p3);
       
  1363         p.rotate(180);
       
  1364         p.drawPixmap(-p1.width(), -p1.height(), p1);
       
  1365     }
       
  1366 
       
  1367     QPixmap p4(10, 20);
       
  1368     {
       
  1369         QPainter p(&p4);
       
  1370         p.rotate(270);
       
  1371         p.drawPixmap(-p1.width(), 0, p1);
       
  1372     }
       
  1373 
       
  1374     QPixmap p1_90 = p1.transformed(QTransform().rotate(90));
       
  1375     QPixmap p1_180 = p1.transformed(QTransform().rotate(180));
       
  1376     QPixmap p1_270 = p1.transformed(QTransform().rotate(270));
       
  1377 
       
  1378     QVERIFY(lenientCompare(p1_90, p2));
       
  1379     QVERIFY(lenientCompare(p1_180, p3));
       
  1380     QVERIFY(lenientCompare(p1_270, p4));
       
  1381 }
       
  1382 
       
  1383 void tst_QPixmap::transformed2()
       
  1384 {
       
  1385     QPixmap pm(3, 3);
       
  1386     pm.fill(Qt::red);
       
  1387     QPainter p(&pm);
       
  1388     p.fillRect(0, 0, 3, 3, QBrush(Qt::Dense4Pattern));
       
  1389     p.end();
       
  1390 
       
  1391     QTransform transform;
       
  1392     transform.rotate(-90);
       
  1393     transform.scale(3, 3);
       
  1394 
       
  1395     QPixmap actual = pm.transformed(transform);
       
  1396 
       
  1397     QPixmap expected(9, 9);
       
  1398     expected.fill(Qt::red);
       
  1399     p.begin(&expected);
       
  1400     p.setBrush(Qt::black);
       
  1401     p.setPen(Qt::NoPen);
       
  1402     p.drawRect(3, 0, 3, 3);
       
  1403     p.drawRect(0, 3, 3, 3);
       
  1404     p.drawRect(6, 3, 3, 3);
       
  1405     p.drawRect(3, 6, 3, 3);
       
  1406     p.end();
       
  1407 
       
  1408     QVERIFY(lenientCompare(actual, expected));
       
  1409 }
       
  1410 
       
  1411 void tst_QPixmap::fromImage_crash()
       
  1412 {
       
  1413     QImage *img = new QImage(64, 64, QImage::Format_ARGB32_Premultiplied);
       
  1414 
       
  1415     QPixmap pm = QPixmap::fromImage(*img);
       
  1416     QPainter painter(&pm);
       
  1417 
       
  1418     delete img;
       
  1419 }
       
  1420 
       
  1421 void tst_QPixmap::fromData()
       
  1422 {
       
  1423     unsigned char bits[] = { 0xaa, 0x55 };
       
  1424 
       
  1425     QBitmap bm = QBitmap::fromData(QSize(8, 2), bits);
       
  1426     QImage img = bm.toImage();
       
  1427 
       
  1428     QSet<QRgb> colors;
       
  1429     for (int y = 0; y < img.height(); ++y)
       
  1430         for (int x = 0; x < img.width(); ++x)
       
  1431             colors << img.pixel(x, y);
       
  1432 
       
  1433     QCOMPARE(colors.size(), 2);
       
  1434 
       
  1435     QCOMPARE(img.pixel(0, 0), QRgb(0xffffffff));
       
  1436     QCOMPARE(img.pixel(0, 1), QRgb(0xff000000));
       
  1437 }
       
  1438 
       
  1439 void tst_QPixmap::task_246446()
       
  1440 {
       
  1441     // This crashed without the bugfix in 246446
       
  1442     QPixmap pm(10, 10);
       
  1443     pm.fill(Qt::transparent); // force 32-bit depth
       
  1444     QBitmap bm;
       
  1445     pm.setMask(bm);
       
  1446     {
       
  1447         QPixmap pm2(pm);
       
  1448     }
       
  1449     QVERIFY(pm.width() == 10);
       
  1450     QVERIFY(pm.mask().isNull());
       
  1451 }
       
  1452 
       
  1453 void tst_QPixmap::preserveDepth()
       
  1454 {
       
  1455     QPixmap target(64, 64);
       
  1456     target.fill(Qt::transparent);
       
  1457 
       
  1458     QPixmap source(64, 64);
       
  1459     source.fill(Qt::white);
       
  1460 
       
  1461     int depth = source.depth();
       
  1462 
       
  1463     QPainter painter(&target);
       
  1464     painter.setBrush(source);
       
  1465     painter.drawRect(target.rect());
       
  1466     painter.end();
       
  1467 
       
  1468     QCOMPARE(depth, source.depth());
       
  1469 }
       
  1470 
       
  1471 QTEST_MAIN(tst_QPixmap)
       
  1472 #include "tst_qpixmap.moc"