tests/auto/qpainter/tst_qpainter.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 
       
    45 
       
    46 #include <qpainter.h>
       
    47 #include <qapplication.h>
       
    48 #include <qwidget.h>
       
    49 #include <qfontmetrics.h>
       
    50 #include <qbitmap.h>
       
    51 #include <qimage.h>
       
    52 #include <limits.h>
       
    53 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
       
    54 #include <qprinter.h>
       
    55 #include <math.h>
       
    56 #ifdef QT3_SUPPORT
       
    57 #include <q3painter.h>
       
    58 #endif
       
    59 #endif
       
    60 #include <qpaintengine.h>
       
    61 #include <qdesktopwidget.h>
       
    62 #include <qpixmap.h>
       
    63 
       
    64 #include <qpainter.h>
       
    65 
       
    66 #include <qlabel.h>
       
    67 
       
    68 #include <qqueue.h>
       
    69 
       
    70 #if defined(Q_OS_SYMBIAN)
       
    71 # define SRCDIR "."
       
    72 #endif
       
    73 
       
    74 Q_DECLARE_METATYPE(QLine)
       
    75 Q_DECLARE_METATYPE(QRect)
       
    76 Q_DECLARE_METATYPE(QSize)
       
    77 Q_DECLARE_METATYPE(QPoint)
       
    78 Q_DECLARE_METATYPE(QPainterPath)
       
    79 
       
    80 //TESTED_CLASS=
       
    81 //TESTED_FILES=
       
    82 
       
    83 class tst_QPainter : public QObject
       
    84 {
       
    85 Q_OBJECT
       
    86 
       
    87 public:
       
    88     tst_QPainter();
       
    89     virtual ~tst_QPainter();
       
    90 
       
    91 
       
    92 public slots:
       
    93     void init();
       
    94     void cleanup();
       
    95 private slots:
       
    96     void getSetCheck();
       
    97     void qt_format_text_clip();
       
    98     void qt_format_text_boundingRect();
       
    99     void drawPixmap_comp_data();
       
   100     void drawPixmap_comp();
       
   101     void saveAndRestore_data();
       
   102     void saveAndRestore();
       
   103 
       
   104     void drawLine_data();
       
   105     void drawLine();
       
   106     void drawLine_clipped();
       
   107     void drawLine_task121143();
       
   108     void drawLine_task216948();
       
   109 
       
   110     void drawLine_task190634();
       
   111     void drawLine_task229459();
       
   112     void drawLine_task234891();
       
   113 
       
   114     void drawRect_data() { fillData(); }
       
   115     void drawRect();
       
   116     void drawRect2();
       
   117 
       
   118     void fillRect();
       
   119     void fillRect2();
       
   120     void fillRect3();
       
   121     void fillRect4();
       
   122 
       
   123     void drawEllipse_data();
       
   124     void drawEllipse();
       
   125     void drawClippedEllipse_data();
       
   126     void drawClippedEllipse();
       
   127 
       
   128     void drawPath_data();
       
   129     void drawPath();
       
   130     void drawPath2();
       
   131     void drawPath3();
       
   132 
       
   133     void drawRoundRect_data() { fillData(); }
       
   134     void drawRoundRect();
       
   135 
       
   136     void qimageFormats_data();
       
   137     void qimageFormats();
       
   138     void textOnTransparentImage();
       
   139 
       
   140     void initFrom();
       
   141 
       
   142     void setWindow();
       
   143 
       
   144     void combinedMatrix();
       
   145     void renderHints();
       
   146 
       
   147     void disableEnableClipping();
       
   148     void setClipRect();
       
   149     void setEqualClipRegionAndPath_data();
       
   150     void setEqualClipRegionAndPath();
       
   151 
       
   152     void clipRectSaveRestore();
       
   153 
       
   154     void clippedFillPath_data();
       
   155     void clippedFillPath();
       
   156     void clippedLines_data();
       
   157     void clippedLines();
       
   158     void clippedPolygon_data();
       
   159     void clippedPolygon();
       
   160 
       
   161     void clippedText();
       
   162 
       
   163     void setOpacity_data();
       
   164     void setOpacity();
       
   165 
       
   166     void drawhelper_blend_untransformed_data();
       
   167     void drawhelper_blend_untransformed();
       
   168     void drawhelper_blend_tiled_untransformed_data();
       
   169     void drawhelper_blend_tiled_untransformed();
       
   170 
       
   171     void porterDuff_warning();
       
   172 
       
   173     void drawhelper_blend_color();
       
   174 
       
   175     void childWidgetViewport();
       
   176 
       
   177     void fillRect_objectBoundingModeGradient();
       
   178     void fillRect_stretchToDeviceMode();
       
   179     void monoImages();
       
   180 
       
   181     void linearGradientSymmetry();
       
   182     void gradientInterpolation();
       
   183 
       
   184     void fpe_pixmapTransform();
       
   185     void fpe_zeroLengthLines();
       
   186     void fpe_divByZero();
       
   187 
       
   188     void fpe_steepSlopes_data();
       
   189     void fpe_steepSlopes();
       
   190     void fpe_rasterizeLine_task232012();
       
   191 
       
   192     void fpe_radialGradients();
       
   193 
       
   194     void rasterizer_asserts();
       
   195     void rasterizer_negativeCoords();
       
   196 
       
   197     void blendOverFlow_data();
       
   198     void blendOverFlow();
       
   199 
       
   200     void largeImagePainting_data();
       
   201     void largeImagePainting();
       
   202 
       
   203     void imageScaling_task206785();
       
   204 
       
   205     void outlineFillConsistency();
       
   206 
       
   207     void drawImage_task217400_data();
       
   208     void drawImage_task217400();
       
   209     void drawImage_1x1();
       
   210     void drawImage_task258776();
       
   211     void drawRect_task215378();
       
   212     void drawRect_task247505();
       
   213 
       
   214     void drawImage_data();
       
   215     void drawImage();
       
   216 
       
   217     void clippedImage();
       
   218 
       
   219     void stateResetBetweenQPainters();
       
   220 
       
   221     void imageCoordinateLimit();
       
   222     void imageBlending_data();
       
   223     void imageBlending();
       
   224     void imageBlending_clipped();
       
   225 
       
   226     void paintOnNullPixmap();
       
   227     void checkCompositionMode();
       
   228 
       
   229     void drawPolygon();
       
   230 
       
   231     void inactivePainter();
       
   232 
       
   233     void extendedBlendModes();
       
   234 
       
   235     void zeroOpacity();
       
   236     void clippingBug();
       
   237     void emptyClip();
       
   238 
       
   239     void taskQT4444_dontOverflowDashOffset();
       
   240 
       
   241     void painterBegin();
       
   242 
       
   243 private:
       
   244     void fillData();
       
   245     QColor baseColor( int k, int intensity=255 );
       
   246     QImage getResImage( const QString &dir, const QString &addition, const QString &extension );
       
   247     QBitmap getBitmap( const QString &dir, const QString &filename, bool mask );
       
   248 };
       
   249 
       
   250 // Testing get/set functions
       
   251 void tst_QPainter::getSetCheck()
       
   252 {
       
   253     QImage img(QSize(10, 10), QImage::Format_ARGB32_Premultiplied);
       
   254     QPainter obj1;
       
   255     obj1.begin(&img);
       
   256     // CompositionMode QPainter::compositionMode()
       
   257     // void QPainter::setCompositionMode(CompositionMode)
       
   258     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_SourceOver));
       
   259     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_SourceOver), obj1.compositionMode());
       
   260     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_DestinationOver));
       
   261     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_DestinationOver), obj1.compositionMode());
       
   262     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_Clear));
       
   263     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_Clear), obj1.compositionMode());
       
   264     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_Source));
       
   265     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_Source), obj1.compositionMode());
       
   266     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_Destination));
       
   267     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_Destination), obj1.compositionMode());
       
   268     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_SourceIn));
       
   269     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_SourceIn), obj1.compositionMode());
       
   270     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_DestinationIn));
       
   271     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_DestinationIn), obj1.compositionMode());
       
   272     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_SourceOut));
       
   273     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_SourceOut), obj1.compositionMode());
       
   274     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_DestinationOut));
       
   275     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_DestinationOut), obj1.compositionMode());
       
   276     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_SourceAtop));
       
   277     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_SourceAtop), obj1.compositionMode());
       
   278     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_DestinationAtop));
       
   279     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_DestinationAtop), obj1.compositionMode());
       
   280     obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_Xor));
       
   281     QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_Xor), obj1.compositionMode());
       
   282 
       
   283     // const QPen & QPainter::pen()
       
   284     // void QPainter::setPen(const QPen &)
       
   285     QPen var3(Qt::red);
       
   286     obj1.setPen(var3);
       
   287     QCOMPARE(var3, obj1.pen());
       
   288     obj1.setPen(QPen());
       
   289     QCOMPARE(QPen(), obj1.pen());
       
   290 
       
   291     // const QBrush & QPainter::brush()
       
   292     // void QPainter::setBrush(const QBrush &)
       
   293     QBrush var4(Qt::red);
       
   294     obj1.setBrush(var4);
       
   295     QCOMPARE(var4, obj1.brush());
       
   296     obj1.setBrush(QBrush());
       
   297     QCOMPARE(QBrush(), obj1.brush());
       
   298 
       
   299     // const QBrush & QPainter::background()
       
   300     // void QPainter::setBackground(const QBrush &)
       
   301     QBrush var5(Qt::yellow);
       
   302     obj1.setBackground(var5);
       
   303     QCOMPARE(var5, obj1.background());
       
   304     obj1.setBackground(QBrush());
       
   305     QCOMPARE(QBrush(), obj1.background());
       
   306 
       
   307     // bool QPainter::matrixEnabled()
       
   308     // void QPainter::setMatrixEnabled(bool)
       
   309     obj1.setMatrixEnabled(false);
       
   310     QCOMPARE(false, obj1.matrixEnabled());
       
   311     obj1.setMatrixEnabled(true);
       
   312     QCOMPARE(true, obj1.matrixEnabled());
       
   313 
       
   314     // bool QPainter::viewTransformEnabled()
       
   315     // void QPainter::setViewTransformEnabled(bool)
       
   316     obj1.setViewTransformEnabled(false);
       
   317     QCOMPARE(false, obj1.viewTransformEnabled());
       
   318     obj1.setViewTransformEnabled(true);
       
   319     QCOMPARE(true, obj1.viewTransformEnabled());
       
   320 }
       
   321 
       
   322 Q_DECLARE_METATYPE(QPixmap)
       
   323 Q_DECLARE_METATYPE(QPolygon)
       
   324 Q_DECLARE_METATYPE(QBrush)
       
   325 Q_DECLARE_METATYPE(QPen)
       
   326 Q_DECLARE_METATYPE(QFont)
       
   327 Q_DECLARE_METATYPE(QColor)
       
   328 Q_DECLARE_METATYPE(QRegion)
       
   329 
       
   330 tst_QPainter::tst_QPainter()
       
   331 {
       
   332     // QtTestCase sets this to false, but this turns off alpha pixmaps on Unix.
       
   333     QApplication::setDesktopSettingsAware(TRUE);
       
   334 }
       
   335 
       
   336 tst_QPainter::~tst_QPainter()
       
   337 {
       
   338 }
       
   339 
       
   340 void tst_QPainter::init()
       
   341 {
       
   342 }
       
   343 
       
   344 void tst_QPainter::cleanup()
       
   345 {
       
   346 }
       
   347 
       
   348 /* tests the clipping operations in qt_format_text, making sure
       
   349    the clip rectangle after the call is the same as before
       
   350 */
       
   351 void tst_QPainter::qt_format_text_clip()
       
   352 {
       
   353     QVERIFY(1);
       
   354     QSKIP( "Needs fixing...", SkipAll);
       
   355 
       
   356     QWidget *w = new QWidget( 0 );
       
   357 
       
   358     int modes[] = { Qt::AlignVCenter|Qt::TextSingleLine,
       
   359 		   Qt::AlignVCenter|Qt::TextSingleLine|Qt::TextDontClip,
       
   360 		   Qt::AlignVCenter|Qt::TextWordWrap,
       
   361 		   Qt::AlignVCenter|Qt::TextWordWrap|Qt::TextDontClip,
       
   362 		   0
       
   363     };
       
   364 
       
   365     int *m = modes;
       
   366     while( *m ) {
       
   367 	{
       
   368 	    QPainter p( w );
       
   369 	    QRegion clipreg = p.clipRegion();
       
   370 	    bool hasClipping = p.hasClipping();
       
   371 	    qreal tx = p.matrix().dx();
       
   372 	    qreal ty = p.matrix().dy();
       
   373 
       
   374 	    p.drawText( 10, 10, 100, 100, *m,
       
   375 			"fooo" );
       
   376 
       
   377 	    QVERIFY( clipreg == p.clipRegion() );
       
   378 	    QVERIFY( hasClipping == p.hasClipping() );
       
   379 	    QCOMPARE( tx, p.matrix().dx() );
       
   380 	    QCOMPARE( ty, p.matrix().dy() );
       
   381 
       
   382 	    p.setClipRect( QRect( 5, 5, 50, 50 ) );
       
   383 	    clipreg = p.clipRegion();
       
   384 	    hasClipping = p.hasClipping();
       
   385 
       
   386 	    p.drawText( 10, 10, 100, 100, *m,
       
   387 			"fooo" );
       
   388 
       
   389 	    QVERIFY( clipreg == p.clipRegion() );
       
   390 	    QVERIFY( hasClipping == p.hasClipping() );
       
   391 	    QCOMPARE( tx, p.matrix().dx() );
       
   392 	    QCOMPARE( ty, p.matrix().dy() );
       
   393 	}
       
   394 	{
       
   395 	    QPainter p( w );
       
   396 	    p.setMatrix( QMatrix( 2, 1, 3, 4, 5, 6 ) );
       
   397 	    QRegion clipreg = p.clipRegion();
       
   398 	    bool hasClipping = p.hasClipping();
       
   399 	    qreal tx = p.matrix().dx();
       
   400 	    qreal ty = p.matrix().dy();
       
   401 
       
   402 	    p.drawText( 10, 10, 100, 100, *m,
       
   403 			"fooo" );
       
   404 
       
   405 	    QVERIFY( clipreg == p.clipRegion() );
       
   406 	    QVERIFY( hasClipping == p.hasClipping() );
       
   407 	    QCOMPARE( tx, p.matrix().dx() );
       
   408 	    QCOMPARE( ty, p.matrix().dy() );
       
   409 
       
   410 	    p.setClipRect( QRect( 5, 5, 50, 50 ) );
       
   411 	    clipreg = p.clipRegion();
       
   412 	    hasClipping = p.hasClipping();
       
   413 
       
   414 	    p.drawText( 10, 10, 100, 100, *m,
       
   415 			"fooo" );
       
   416 
       
   417 	    QVERIFY( clipreg == p.clipRegion() );
       
   418 	    QVERIFY( hasClipping == p.hasClipping() );
       
   419 	    QCOMPARE( tx, p.matrix().dx() );
       
   420 	    QCOMPARE( ty, p.matrix().dy() );
       
   421 	}
       
   422 	{
       
   423 	    QPainter p( w );
       
   424 	    QRegion clipreg = p.clipRegion();
       
   425 	    bool hasClipping = p.hasClipping();
       
   426 	    qreal tx = p.matrix().dx();
       
   427 	    qreal ty = p.matrix().dy();
       
   428 
       
   429 	    p.drawText( 10, 10, 100, 100, *m,
       
   430 			"fooo" );
       
   431 
       
   432 	    QVERIFY( clipreg == p.clipRegion() );
       
   433 	    QVERIFY( hasClipping == p.hasClipping() );
       
   434 	    QCOMPARE( tx, p.matrix().dx() );
       
   435 	    QCOMPARE( ty, p.matrix().dy() );
       
   436 
       
   437 	    p.setClipRect( QRect( 5, 5, 50, 50 ));
       
   438 	    clipreg = p.clipRegion();
       
   439 	    hasClipping = p.hasClipping();
       
   440 
       
   441 	    p.drawText( 10, 10, 100, 100, *m,
       
   442 			"fooo" );
       
   443 
       
   444 	    QVERIFY( clipreg == p.clipRegion() );
       
   445 	    QVERIFY( hasClipping == p.hasClipping() );
       
   446 	    QCOMPARE( tx, p.matrix().dx() );
       
   447 	    QCOMPARE( ty, p.matrix().dy() );
       
   448 	}
       
   449 	{
       
   450 	    QPainter p( w );
       
   451 	    p.setMatrix( QMatrix( 2, 1, 3, 4, 5, 6 ) );
       
   452 	    QRegion clipreg = p.clipRegion();
       
   453 	    bool hasClipping = p.hasClipping();
       
   454 	    qreal tx = p.matrix().dx();
       
   455 	    qreal ty = p.matrix().dy();
       
   456 
       
   457 	    p.drawText( 10, 10, 100, 100, *m,
       
   458 			"fooo" );
       
   459 
       
   460 	    QVERIFY( clipreg == p.clipRegion() );
       
   461 	    QVERIFY( hasClipping == p.hasClipping() );
       
   462 	    QCOMPARE( tx, p.matrix().dx() );
       
   463 	    QCOMPARE( ty, p.matrix().dy() );
       
   464 
       
   465 	    p.setClipRect(QRect( 5, 5, 50, 50 ));
       
   466 	    clipreg = p.clipRegion();
       
   467 	    hasClipping = p.hasClipping();
       
   468 
       
   469 	    p.drawText( 10, 10, 100, 100, *m,
       
   470 			"fooo" );
       
   471 
       
   472 	    QVERIFY( clipreg == p.clipRegion() );
       
   473 	    QVERIFY( hasClipping == p.hasClipping() );
       
   474 	    QCOMPARE( tx, p.matrix().dx() );
       
   475 	    QCOMPARE( ty, p.matrix().dy() );
       
   476 	}
       
   477 	++m;
       
   478     }
       
   479     delete w;
       
   480 }
       
   481 
       
   482 /* tests the bounding rect calculations in qt_format_text, making sure
       
   483    the bounding rect has a reasonable value.
       
   484 */
       
   485 void tst_QPainter::qt_format_text_boundingRect()
       
   486 {
       
   487     QVERIFY(1);
       
   488     QSKIP( "Needs fixing...", SkipAll);
       
   489 
       
   490     {
       
   491 	const char * strings[] = {
       
   492 	    "a\n\nb",
       
   493 	    "abc",
       
   494 	    "a\n \nb",
       
   495 	    "this is a longer string",
       
   496 	    "\327\222\327\223\327\233\327\223\327\222\327\233\327\222\327\223\327\233",
       
   497 	    "aa\327\222\327\233aa",
       
   498 	    "\327\222\327\223\327\233\327\223\327\222\327\233\327\222\327\223\327\233",
       
   499 	    "\327\222\327\233aa",
       
   500 	    "linebreakatend\n",
       
   501 	    "some text longer than 30 chars with a line break at the end\n",
       
   502 	    "some text\nwith line breaks\nin the middle\nand at the end\n",
       
   503 	    "foo\n\n\nfoo",
       
   504 	    0
       
   505 	};
       
   506 
       
   507 	int modes[] = { Qt::AlignVCenter|Qt::TextSingleLine,
       
   508 			Qt::AlignVCenter|Qt::TextSingleLine|Qt::TextDontClip,
       
   509 			Qt::AlignVCenter|Qt::TextWordWrap,
       
   510 			Qt::AlignVCenter|Qt::TextWordWrap|Qt::TextDontClip,
       
   511 			Qt::AlignLeft,
       
   512 			Qt::AlignCenter,
       
   513 			Qt::AlignRight,
       
   514 			0
       
   515 	};
       
   516 
       
   517 	QFont f;
       
   518 	for(int i = 5; i < 15; ++i) {
       
   519 	    f.setPointSize(i);
       
   520 	    QFontMetrics fm(f);
       
   521 	    const char **str = strings;
       
   522 	    while( *str ) {
       
   523 		int *m = modes;
       
   524 		while( *m ) {
       
   525 		    QRect br = fm.boundingRect( 0, 0, 2000, 100, *m, QString::fromUtf8( *str ) );
       
   526 		    QVERIFY( br.width() < 800 );
       
   527 
       
   528 		    QRect br2 = fm.boundingRect( br.x(), br.y(), br.width(), br.height(), *m, QString::fromUtf8( *str ) );
       
   529 		    QCOMPARE( br, br2 );
       
   530 #if 0
       
   531 		    {
       
   532 			QPrinter printer;
       
   533 			printer.setOutputToFile(TRUE);
       
   534 			printer.setOutputFileName("tmp.prn");
       
   535 			QPainter p(&printer);
       
   536 			QRect pbr = p.fontMetrics().boundingRect( 0, 0, 2000, 100, *m, QString::fromUtf8( *str ) );
       
   537 			QCOMPARE(pbr, br);
       
   538 		    }
       
   539 #endif
       
   540 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
       
   541 		    {
       
   542 			QPrinter printer(QPrinter::HighResolution);
       
   543 			if (printer.printerName().isEmpty()) {
       
   544 			    QSKIP( "No printers installed, skipping bounding rect test",
       
   545 				  SkipSingle );
       
   546 			    break;
       
   547 			}
       
   548 
       
   549 			printer.setOutputFileName("tmp.prn");
       
   550 			QPainter p(&printer);
       
   551 			QRect pbr = p.fontMetrics().boundingRect( 0, 0, 12000, 600, *m, QString::fromUtf8( *str ) );
       
   552 			QVERIFY(pbr.width() > 2*br.width());
       
   553 			QVERIFY(pbr.height() > 2*br.height());
       
   554 		    }
       
   555 #endif
       
   556 		    ++m;
       
   557 		}
       
   558 		++str;
       
   559 	    }
       
   560 	}
       
   561     }
       
   562 
       
   563     {
       
   564 	const char * strings[] = {
       
   565 	    "a",
       
   566 	    "a\nb",
       
   567 	    "a\n\nb",
       
   568 	    "abc",
       
   569 //	    "a\n \nb",
       
   570 	    "this is a longer string",
       
   571 //	    "\327\222\327\223\327\233\327\223\327\222\327\233\327\222\327\223\327\233",
       
   572 //	    "aa\327\222\327\233aa",
       
   573 //	    "\327\222\327\223\327\233\327\223\327\222\327\233\327\222\327\223\327\233",
       
   574 //	    "\327\222\327\233aa",
       
   575 //	    "linebreakatend\n",
       
   576 //	    "some text longer than 30 chars with a line break at the end\n",
       
   577 //	    "some text\nwith line breaks\nin the middle\nand at the end\n",
       
   578 	    "foo\n\n\nfoo",
       
   579 	    "a\n\n\n\n\nb",
       
   580 	    "a\n\n\n\n\n\nb",
       
   581 //	    "\347\231\273\351\214\262\346\203\205\345\240\261\343\201\214\350\246\213\343\201\244\343\201\213\343\202\211\343\201\252\343\201\204\343\201\213\347\204\241\345\212\271\343\201\252\343\201\237\343\202\201\343\200\201\nPhotoshop Album \343\202\222\350\265\267\345\213\225\343\201\247\343\201\215\343\201\276\343\201\233\343\202\223\343\200\202\345\206\215\343\202\244\343\203\263\343\202\271\343\203\210\343\203\274\343\203\253\343\201\227\343\201\246\343\201\217\343\201\240\343\201\225\343\201\204\343\200\202"
       
   582 //	    "\347\231\273\351\214\262\346\203\205\345\240\261\343\201\214\350\246\213\343\201\244\343\201\213\343\202\211\343\201\252\343\201\204\343\201\213\347\204\241\345\212\271\343\201\252\343\201\237\343\202\201\343\200\201\n\343\202\222\350\265\267\345\213\225\343\201\247\343\201\215\343\201\276\343\201\233\343\202\223\343\200\202\345\206\215\343\202\244\343\203\263\343\202\271\343\203\210\343\203\274\343\203\253\343\201\227\343\201\246\343\201\217\343\201\240\343\201\225\343\201\204\343\200\202",
       
   583 	    0
       
   584 	};
       
   585 
       
   586 	int modes[] = { Qt::AlignVCenter,
       
   587 			Qt::AlignLeft,
       
   588 			Qt::AlignCenter,
       
   589 			Qt::AlignRight,
       
   590 			0
       
   591 	};
       
   592 
       
   593 
       
   594 	QFont f;
       
   595 	for(int i = 5; i < 15; ++i) {
       
   596 	    f.setPointSize(i);
       
   597 	    QFontMetrics fm(f);
       
   598 	    const char **str = strings;
       
   599 	    while( *str ) {
       
   600 		int *m = modes;
       
   601 		while( *m ) {
       
   602 		    QString s = QString::fromUtf8(*str);
       
   603 		    QRect br = fm.boundingRect(0, 0, 1000, 1000, *m, s );
       
   604 		    int lines =
       
   605 		    s.count("\n");
       
   606 		    int expectedHeight = fm.height()+lines*fm.lineSpacing();
       
   607 		    QCOMPARE(br.height(), expectedHeight);
       
   608 		    ++m;
       
   609 		}
       
   610 		++str;
       
   611 	    }
       
   612 	    QRect br = fm.boundingRect(0, 0, 100, 0, Qt::TextWordWrap,
       
   613 		 "A paragraph with gggggggggggggggggggggggggggggggggggg in the middle.");
       
   614 	    QVERIFY(br.height() >= fm.height()+2*fm.lineSpacing());
       
   615 	}
       
   616     }
       
   617 }
       
   618 
       
   619 
       
   620 static const char* const maskSource_data[] = {
       
   621 "16 13 6 1",
       
   622 ". c None",
       
   623 "d c #000000",
       
   624 "# c #999999",
       
   625 "c c #cccccc",
       
   626 "b c #ffff00",
       
   627 "a c #ffffff",
       
   628 "...#####........",
       
   629 "..#aaaaa#.......",
       
   630 ".#abcbcba######.",
       
   631 ".#acbcbcaaaaaa#d",
       
   632 ".#abcbcbcbcbcb#d",
       
   633 "#############b#d",
       
   634 "#aaaaaaaaaa##c#d",
       
   635 "#abcbcbcbcbbd##d",
       
   636 ".#abcbcbcbcbcd#d",
       
   637 ".#acbcbcbcbcbd#d",
       
   638 "..#acbcbcbcbb#dd",
       
   639 "..#############d",
       
   640 "...ddddddddddddd"};
       
   641 
       
   642 static const char* const maskResult_data[] = {
       
   643 "16 13 6 1",
       
   644 ". c #ff0000",
       
   645 "d c #000000",
       
   646 "# c #999999",
       
   647 "c c #cccccc",
       
   648 "b c #ffff00",
       
   649 "a c #ffffff",
       
   650 "...#####........",
       
   651 "..#aaaaa#.......",
       
   652 ".#abcbcba######.",
       
   653 ".#acbcbcaaaaaa#d",
       
   654 ".#abcbcbcbcbcb#d",
       
   655 "#############b#d",
       
   656 "#aaaaaaaaaa##c#d",
       
   657 "#abcbcbcbcbbd##d",
       
   658 ".#abcbcbcbcbcd#d",
       
   659 ".#acbcbcbcbcbd#d",
       
   660 "..#acbcbcbcbb#dd",
       
   661 "..#############d",
       
   662 "...ddddddddddddd"};
       
   663 
       
   664 
       
   665 void tst_QPainter::drawPixmap_comp_data()
       
   666 {
       
   667     if (qApp->desktop()->depth() < 24) {
       
   668         QSKIP("Test only works on 32 bit displays", SkipAll);
       
   669         return;
       
   670     }
       
   671 
       
   672     QTest::addColumn<uint>("dest");
       
   673     QTest::addColumn<uint>("source");
       
   674 
       
   675     QTest::newRow("0% on 0%, 1")           << 0x00000000u<< 0x00000000u;
       
   676     QTest::newRow("0% on 0%, 2")           << 0x00007fffu << 0x00ff007fu;
       
   677 
       
   678     QTest::newRow("50% on a=0%")           << 0x00000000u << 0x7fff0000u;
       
   679     QTest::newRow("50% on a=50%")          << 0x7f000000u << 0x7fff0000u;
       
   680     QTest::newRow("50% on deadbeef")      << 0xdeafbeefu <<  0x7fff0000u;
       
   681     QTest::newRow("deadbeef on a=0%")      << 0x00000000u << 0xdeadbeefu;
       
   682     QTest::newRow("deadbeef on a=50%")     << 0x7f000000u << 0xdeadbeefu;
       
   683     QTest::newRow("50% blue on 50% red")   << 0x7fff0000u << 0x7f0000ffu;
       
   684     QTest::newRow("50% blue on 50% green") << 0x7f00ff00u << 0x7f0000ffu;
       
   685     QTest::newRow("50% red on 50% green")  << 0x7f00ff00u << 0x7fff0000u;
       
   686     QTest::newRow("0% on 50%")             << 0x7fff00ffu << 0x00ffffffu;
       
   687     QTest::newRow("100% on deadbeef")      << 0xdeafbeefu << 0xffabcdefu;
       
   688     QTest::newRow("100% on a=0%")           << 0x00000000u << 0xffabcdefu;
       
   689 }
       
   690 
       
   691 QRgb qt_compose_alpha(QRgb source, QRgb dest)
       
   692 {
       
   693     int r1 = qRed(dest), g1 = qGreen(dest), b1 = qBlue(dest), a1 = qAlpha(dest);
       
   694     int r2 = qRed(source), g2 = qGreen(source), b2 = qBlue(source), a2 = qAlpha(source);
       
   695 
       
   696     int alpha = qMin(a2 + ((255 - a2) * a1 + 127) / 255, 255);
       
   697     if (alpha == 0)
       
   698         return qRgba(0, 0, 0, 0);
       
   699 
       
   700     return qRgba(
       
   701         qMin((r2 * a2 + (255 - a2) * r1 * a1 / 255) / alpha, 255),
       
   702         qMin((g2 * a2 + (255 - a2) * g1 * a1 / 255) / alpha, 255),
       
   703         qMin((b2 * a2 + (255 - a2) * b1 * a1 / 255) / alpha, 255),
       
   704         alpha);
       
   705 }
       
   706 
       
   707 /* Tests that drawing masked pixmaps works
       
   708 */
       
   709 void tst_QPainter::drawPixmap_comp()
       
   710 {
       
   711 #ifdef Q_WS_MAC
       
   712     QSKIP("Mac has other ideas about alpha composition", SkipAll);
       
   713 #endif
       
   714 
       
   715     QFETCH(uint, dest);
       
   716     QFETCH(uint, source);
       
   717 
       
   718     QRgb expected = qt_compose_alpha(source, dest);
       
   719 
       
   720     QColor c1(qRed(dest), qGreen(dest), qBlue(dest), qAlpha(dest));
       
   721     QColor c2(qRed(source), qGreen(source), qBlue(source), qAlpha(source));
       
   722 
       
   723     QPixmap destPm(10, 10), srcPm(10, 10);
       
   724     destPm.fill(c1);
       
   725     srcPm.fill(c2);
       
   726 
       
   727 #if defined(Q_WS_X11)
       
   728     if (!destPm.x11PictureHandle())
       
   729         QSKIP("Requires XRender support", SkipAll);
       
   730 #endif
       
   731 
       
   732     QPainter p(&destPm);
       
   733     p.drawPixmap(0, 0, srcPm);
       
   734     p.end();
       
   735 
       
   736     QImage result = destPm.toImage().convertToFormat(QImage::Format_ARGB32);
       
   737     bool different = false;
       
   738     for (int y=0; y<result.height(); ++y)
       
   739         for (int x=0; x<result.width(); ++x) {
       
   740 	    bool diff;
       
   741             if (qAlpha(expected) == 0) {
       
   742                 diff = qAlpha(result.pixel(x, y)) != 0;
       
   743             } else {
       
   744                 // Compensate for possible roundoff / platform fudge
       
   745                 int off = 1;
       
   746                 QRgb pix = result.pixel(x, y);
       
   747                 diff = (qAbs(qRed(pix) - qRed(expected)) > off)
       
   748                              || (qAbs(qGreen(pix) - qGreen(expected)) > off)
       
   749                              || (qAbs(qBlue(pix) - qBlue(expected)) > off)
       
   750                              || (qAbs(qAlpha(pix) - qAlpha(expected)) > off);
       
   751             }
       
   752 	    if (diff && !different)
       
   753 		qDebug( "Different at %d,%d pixel [%d,%d,%d,%d] expected [%d,%d,%d,%d]", x, y,
       
   754                         qRed(result.pixel(x, y)), qGreen(result.pixel(x, y)),
       
   755                         qBlue(result.pixel(x, y)), qAlpha(result.pixel(x, y)),
       
   756                         qRed(expected), qGreen(expected), qBlue(expected), qAlpha(expected));
       
   757 	    different |= diff;
       
   758         }
       
   759 
       
   760     QVERIFY(!different);
       
   761 }
       
   762 
       
   763 void tst_QPainter::saveAndRestore_data()
       
   764 {
       
   765     QVERIFY(1);
       
   766 
       
   767     QTest::addColumn<QFont>("font");
       
   768     QTest::addColumn<QPen>("pen");
       
   769     QTest::addColumn<QBrush>("brush");
       
   770     QTest::addColumn<QColor>("backgroundColor");
       
   771     QTest::addColumn<int>("backgroundMode");
       
   772     QTest::addColumn<QPoint>("brushOrigin");
       
   773     QTest::addColumn<QRegion>("clipRegion");
       
   774     QTest::addColumn<QRect>("window");
       
   775     QTest::addColumn<QRect>("viewport");
       
   776 
       
   777     QPixmap pixmap(1, 1);
       
   778     QPainter p(&pixmap);
       
   779     QFont font = p.font();
       
   780     QPen pen = p.pen();
       
   781     QBrush brush = p.brush();
       
   782     QColor backgroundColor = p.background().color();
       
   783     Qt::BGMode backgroundMode = p.backgroundMode();
       
   784     QPoint brushOrigin = p.brushOrigin();
       
   785     QRegion clipRegion = p.clipRegion();
       
   786     QRect window = p.window();
       
   787     QRect viewport = p.viewport();
       
   788 
       
   789     QTest::newRow("Original") << font << pen << brush << backgroundColor << int(backgroundMode)
       
   790 	    << brushOrigin << clipRegion << window << viewport;
       
   791 
       
   792     QFont font2 = font;
       
   793     font2.setPointSize( 24 );
       
   794     QTest::newRow("Modified font.pointSize, brush, backgroundColor, backgroundMode")
       
   795             << font2 << pen << QBrush(Qt::red) << QColor(Qt::blue) << int(Qt::TransparentMode)
       
   796 	    << brushOrigin << clipRegion << window << viewport;
       
   797 
       
   798     font2 = font;
       
   799     font2.setPixelSize( 20 );
       
   800     QTest::newRow("Modified font.pixelSize, brushOrigin, pos")
       
   801             << font2 << pen << brush << backgroundColor << int(backgroundMode)
       
   802 	    << QPoint( 50, 32 ) << clipRegion << window << viewport;
       
   803 
       
   804     QTest::newRow("Modified clipRegion, window, viewport")
       
   805             << font << pen << brush << backgroundColor << int(backgroundMode)
       
   806 	    << brushOrigin << clipRegion.subtracted(QRect(10,10,50,30))
       
   807 	    << QRect(-500, -500, 500, 500 ) << QRect( 0, 0, 50, 50 );
       
   808 }
       
   809 
       
   810 void tst_QPainter::saveAndRestore()
       
   811 {
       
   812     QFETCH( QFont, font );
       
   813     QFETCH( QPen, pen );
       
   814     QFETCH( QBrush, brush );
       
   815     QFETCH( QColor, backgroundColor );
       
   816     QFETCH( int, backgroundMode );
       
   817     QFETCH( QPoint, brushOrigin );
       
   818     QFETCH( QRegion, clipRegion );
       
   819     QFETCH( QRect, window );
       
   820     QFETCH( QRect, viewport );
       
   821 
       
   822     QPixmap pixmap(1, 1);
       
   823     QPainter painter(&pixmap);
       
   824 
       
   825     QFont font_org = painter.font();
       
   826     QPen pen_org = painter.pen();
       
   827     QBrush brush_org = painter.brush();
       
   828     QColor backgroundColor_org = painter.background().color();
       
   829     Qt::BGMode backgroundMode_org = painter.backgroundMode();
       
   830     QPoint brushOrigin_org = painter.brushOrigin();
       
   831     QRegion clipRegion_org = painter.clipRegion();
       
   832     QRect window_org = painter.window();
       
   833     QRect viewport_org = painter.viewport();
       
   834 
       
   835     painter.save();
       
   836     painter.setFont( font );
       
   837     painter.setPen( QPen(pen) );
       
   838     painter.setBrush( brush );
       
   839     painter.setBackground( backgroundColor );
       
   840     painter.setBackgroundMode( (Qt::BGMode)backgroundMode );
       
   841     painter.setBrushOrigin( brushOrigin );
       
   842     painter.setClipRegion( clipRegion );
       
   843     painter.setWindow( window );
       
   844     painter.setViewport( viewport );
       
   845     painter.restore();
       
   846 
       
   847     QCOMPARE( painter.font(), font_org );
       
   848     QCOMPARE( painter.font().pointSize(), font_org.pointSize() );
       
   849     QCOMPARE( painter.font().pixelSize(), font_org.pixelSize() );
       
   850     QCOMPARE( painter.pen(), pen_org );
       
   851     QCOMPARE( painter.brush(), brush_org );
       
   852     QCOMPARE( painter.background().color(), backgroundColor_org );
       
   853     QCOMPARE( painter.backgroundMode(), backgroundMode_org );
       
   854     QCOMPARE( painter.brushOrigin(), brushOrigin_org );
       
   855     QCOMPARE( painter.clipRegion(), clipRegion_org );
       
   856     QCOMPARE( painter.window(), window_org );
       
   857     QCOMPARE( painter.viewport(), viewport_org );
       
   858 }
       
   859 
       
   860 /*
       
   861    Helper functions
       
   862 */
       
   863 
       
   864 QColor tst_QPainter::baseColor( int k, int intensity )
       
   865 {
       
   866     int r = ( k & 1 ) * intensity;
       
   867     int g = ( (k>>1) & 1 ) * intensity;
       
   868     int b = ( (k>>2) & 1 ) * intensity;
       
   869     return QColor( r, g, b );
       
   870 }
       
   871 
       
   872 QImage tst_QPainter::getResImage( const QString &dir, const QString &addition, const QString &extension )
       
   873 {
       
   874     QImage res;
       
   875     QString resFilename  = dir + QString( "/res_%1." ).arg( addition ) + extension;
       
   876     if ( !res.load( resFilename ) ) {
       
   877         QWARN(QString("Could not load result data %s %1").arg(resFilename).toLatin1());
       
   878         return QImage();
       
   879     }
       
   880     return res;
       
   881 }
       
   882 
       
   883 QBitmap tst_QPainter::getBitmap( const QString &dir, const QString &filename, bool mask )
       
   884 {
       
   885     QBitmap bm;
       
   886     QString bmFilename = dir + QString( "/%1.xbm" ).arg( filename );
       
   887     if ( !bm.load( bmFilename ) ) {
       
   888         QWARN(QString("Could not load bitmap '%1'").arg(bmFilename).toLatin1());
       
   889         return QBitmap();
       
   890     }
       
   891     if ( mask ) {
       
   892 	QBitmap mask;
       
   893 	QString maskFilename = dir + QString( "/%1-mask.xbm" ).arg( filename );
       
   894 	if ( !mask.load( maskFilename ) ) {
       
   895         QWARN(QString("Could not load mask '%1'").arg(maskFilename).toLatin1());
       
   896         return QBitmap();
       
   897 	}
       
   898 	bm.setMask( mask );
       
   899     }
       
   900     return bm;
       
   901 }
       
   902 
       
   903 static int getPaintedPixels(const QImage &image, const QColor &background)
       
   904 {
       
   905     uint color = background.rgba();
       
   906 
       
   907     int pixels = 0;
       
   908 
       
   909     for (int y = 0; y < image.height(); ++y)
       
   910         for (int x = 0; x < image.width(); ++x)
       
   911             if (image.pixel(x, y) != color)
       
   912                 ++pixels;
       
   913 
       
   914     return pixels;
       
   915 }
       
   916 
       
   917 static QRect getPaintedSize(const QImage &image, const QColor &background)
       
   918 {
       
   919     // not the fastest but at least it works..
       
   920     int xmin = image.width() + 1;
       
   921     int xmax = -1;
       
   922     int ymin = image.height() +1;
       
   923     int ymax = -1;
       
   924 
       
   925     uint color = background.rgba();
       
   926 
       
   927     for ( int y = 0; y < image.height(); ++y ) {
       
   928 	for ( int x = 0; x < image.width(); ++x ) {
       
   929             QRgb pixel = image.pixel( x, y );
       
   930 	    if ( pixel != color && x < xmin )
       
   931 		xmin = x;
       
   932 	    if ( pixel != color && x > xmax )
       
   933 		xmax = x;
       
   934 	    if ( pixel != color && y < ymin )
       
   935 		ymin = y;
       
   936 	    if ( pixel != color && y > ymax )
       
   937 		ymax = y;
       
   938 	}
       
   939     }
       
   940 
       
   941     return QRect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
       
   942 }
       
   943 
       
   944 static QRect getPaintedSize(const QPixmap &pm, const QColor &background)
       
   945 {
       
   946     return getPaintedSize(pm.toImage(), background);
       
   947 }
       
   948 
       
   949 void tst_QPainter::initFrom()
       
   950 {
       
   951     QWidget *widget = new QWidget();
       
   952     QPalette pal = widget->palette();
       
   953     pal.setColor(QPalette::Foreground, QColor(255, 0, 0));
       
   954     pal.setBrush(QPalette::Background, QColor(0, 255, 0));
       
   955     widget->setPalette(pal);
       
   956 
       
   957     QFont font = widget->font();
       
   958     font.setPointSize(26);
       
   959     font.setItalic(true);
       
   960     widget->setFont(font);
       
   961 
       
   962     QPixmap pm(100, 100);
       
   963     QPainter p(&pm);
       
   964     p.initFrom(widget);
       
   965 
       
   966     QCOMPARE(p.font(), font);
       
   967     QCOMPARE(p.pen().color(), pal.color(QPalette::Foreground));
       
   968     QCOMPARE(p.background(), pal.background());
       
   969 
       
   970     delete widget;
       
   971 }
       
   972 
       
   973 void tst_QPainter::drawLine_data()
       
   974 {
       
   975     QTest::addColumn<QLine>("line");
       
   976 
       
   977     QTest::newRow("0-45") << QLine(0, 20, 100, 0);
       
   978     QTest::newRow("45-90") << QLine(0, 100, 20, 0);
       
   979     QTest::newRow("90-135") << QLine(20, 100, 0, 0);
       
   980     QTest::newRow("135-180") << QLine(100, 20, 0, 0);
       
   981     QTest::newRow("180-225") << QLine(100, 0, 0, 20);
       
   982     QTest::newRow("225-270") << QLine(20, 0, 0, 100);
       
   983     QTest::newRow("270-315") << QLine(0, 0, 20, 100);
       
   984     QTest::newRow("315-360") << QLine(0, 0, 100, 20);
       
   985 }
       
   986 
       
   987 void tst_QPainter::drawLine()
       
   988 {
       
   989     const int offset = 5;
       
   990     const int epsilon = 1; // allow for one pixel difference
       
   991 
       
   992     QFETCH(QLine, line);
       
   993 
       
   994     QPixmap pixmapUnclipped(qMin(line.x1(), line.x2())
       
   995                             + 2*offset + qAbs(line.dx()),
       
   996                             qMin(line.y1(), line.y2())
       
   997                             + 2*offset + qAbs(line.dy()));
       
   998 
       
   999     { // unclipped
       
  1000         pixmapUnclipped.fill(Qt::white);
       
  1001         QPainter p(&pixmapUnclipped);
       
  1002         p.translate(offset, offset);
       
  1003         p.setPen(QPen(Qt::black));
       
  1004         p.drawLine(line);
       
  1005         p.end();
       
  1006 
       
  1007         const QRect painted = getPaintedSize(pixmapUnclipped, Qt::white);
       
  1008 
       
  1009         QLine l = line;
       
  1010         l.translate(offset, offset);
       
  1011         QVERIFY(qAbs(painted.width() - qAbs(l.dx())) <= epsilon);
       
  1012         QVERIFY(qAbs(painted.height() - qAbs(l.dy())) <= epsilon);
       
  1013         QVERIFY(qAbs(painted.top() - qMin(l.y1(), l.y2())) <= epsilon);
       
  1014         QVERIFY(qAbs(painted.left() - qMin(l.x1(), l.x2())) <= epsilon);
       
  1015         QVERIFY(qAbs(painted.bottom() - qMax(l.y1(), l.y2())) <= epsilon);
       
  1016         QVERIFY(qAbs(painted.right() - qMax(l.x1(), l.x2())) <= epsilon);
       
  1017     }
       
  1018 
       
  1019     QPixmap pixmapClipped(qMin(line.x1(), line.x2())
       
  1020                           + 2*offset + qAbs(line.dx()),
       
  1021                           qMin(line.y1(), line.y2())
       
  1022                           + 2*offset + qAbs(line.dy()));
       
  1023     { // clipped
       
  1024         const QRect clip = QRect(line.p1(), line.p2()).normalized();
       
  1025 
       
  1026         pixmapClipped.fill(Qt::white);
       
  1027         QPainter p(&pixmapClipped);
       
  1028         p.translate(offset, offset);
       
  1029         p.setClipRect(clip);
       
  1030         p.setPen(QPen(Qt::black));
       
  1031         p.drawLine(line);
       
  1032         p.end();
       
  1033     }
       
  1034 
       
  1035     const QImage unclipped = pixmapUnclipped.toImage();
       
  1036     const QImage clipped = pixmapClipped.toImage();
       
  1037     QCOMPARE(unclipped, clipped);
       
  1038 }
       
  1039 
       
  1040 void tst_QPainter::drawLine_clipped()
       
  1041 {
       
  1042     QImage image(16, 1, QImage::Format_ARGB32_Premultiplied);
       
  1043     image.fill(0x0);
       
  1044 
       
  1045     QPainter p(&image);
       
  1046     p.setPen(QPen(Qt::black, 10));
       
  1047 
       
  1048     // this should fill the whole image
       
  1049     p.drawLine(-1, -1, 17, 1);
       
  1050     p.end();
       
  1051 
       
  1052     for (int x = 0; x < 16; ++x)
       
  1053         QCOMPARE(image.pixel(x, 0), 0xff000000);
       
  1054 }
       
  1055 
       
  1056 void tst_QPainter::drawLine_task121143()
       
  1057 {
       
  1058     QPen pen(Qt::black);
       
  1059 
       
  1060     QImage image(5, 5, QImage::Format_ARGB32_Premultiplied);
       
  1061     image.fill(0xffffffff);
       
  1062     QPainter p(&image);
       
  1063     p.setPen(pen);
       
  1064     p.drawLine(QLine(0, 0+4, 0+4, 0));
       
  1065     p.end();
       
  1066 
       
  1067     QImage expected(5, 5, QImage::Format_ARGB32_Premultiplied);
       
  1068     expected.fill(0xffffffff);
       
  1069     for (int x = 0; x < 5; ++x)
       
  1070         expected.setPixel(x, 5-x-1, pen.color().rgb());
       
  1071 
       
  1072     QCOMPARE(image, expected);
       
  1073 }
       
  1074 
       
  1075 void tst_QPainter::drawLine_task190634()
       
  1076 {
       
  1077     QPen pen(Qt::black, 3);
       
  1078 
       
  1079     QImage image(32, 32, QImage::Format_ARGB32_Premultiplied);
       
  1080     QPainter p(&image);
       
  1081     p.fillRect(0, 0, image.width(), image.height(), Qt::white);
       
  1082 
       
  1083     p.setPen(pen);
       
  1084     p.drawLine(QLineF(2, -1.6, 10, -1.6));
       
  1085     p.end();
       
  1086 
       
  1087     const uint *data = reinterpret_cast<uint *>(image.bits());
       
  1088 
       
  1089     for (int i = 0; i < image.width() * image.height(); ++i)
       
  1090         QCOMPARE(data[i], 0xffffffff);
       
  1091 
       
  1092     p.begin(&image);
       
  1093     p.fillRect(0, 0, image.width(), image.height(), Qt::white);
       
  1094 
       
  1095     p.setPen(pen);
       
  1096     p.drawLine(QLineF(-1.6, 2, -1.6, 10));
       
  1097     p.end();
       
  1098 
       
  1099     data = reinterpret_cast<uint *>(image.bits());
       
  1100 
       
  1101     for (int i = 0; i < image.width() * image.height(); ++i)
       
  1102         QCOMPARE(data[i], 0xffffffff);
       
  1103 
       
  1104     p.begin(&image);
       
  1105     p.fillRect(0, 0, image.width(), image.height(), Qt::white);
       
  1106 
       
  1107     p.setPen(pen);
       
  1108     p.drawLine( QPoint(2,-2), QPoint(3,-5) );
       
  1109     p.end();
       
  1110 
       
  1111     data = reinterpret_cast<uint *>(image.bits());
       
  1112 
       
  1113     for (int i = 0; i < image.width() * image.height(); ++i)
       
  1114         QCOMPARE(data[i], 0xffffffff);
       
  1115 }
       
  1116 
       
  1117 void tst_QPainter::drawLine_task229459()
       
  1118 {
       
  1119     QImage image(32, 32, QImage::Format_ARGB32_Premultiplied);
       
  1120     image.fill(0x0);
       
  1121     QPen pen(Qt::black, 64);
       
  1122 
       
  1123     QPainter p(&image);
       
  1124     p.setPen(pen);
       
  1125     p.drawLine(-8, -8, 10000000, 10000000);
       
  1126     p.end();
       
  1127 
       
  1128     QImage expected = image;
       
  1129     expected.fill(0xff000000);
       
  1130 
       
  1131     QCOMPARE(image, expected);
       
  1132 }
       
  1133 
       
  1134 void tst_QPainter::drawLine_task234891()
       
  1135 {
       
  1136     QImage img(100, 1000, QImage::Format_ARGB32_Premultiplied);
       
  1137     img.fill(0x0);
       
  1138     QImage expected = img;
       
  1139 
       
  1140     QPainter p(&img);
       
  1141     p.setPen(QPen(QBrush(QColor(255,0,0)), 6));
       
  1142     p.drawLine(QPointF(25000,100),QPointF(30000,105));
       
  1143 
       
  1144     p.setPen(QPen(QBrush(QColor(0,255,0)), 6));
       
  1145     p.drawLine(QPointF(30000,150),QPointF(35000,155));
       
  1146 
       
  1147     p.setPen(QPen(QBrush(QColor(0,0,255)), 6));
       
  1148     p.drawLine(QPointF(65000,200),QPointF(66000,205));
       
  1149 
       
  1150     QCOMPARE(expected, img);
       
  1151 }
       
  1152 
       
  1153 void tst_QPainter::drawLine_task216948()
       
  1154 {
       
  1155     QImage img(1, 10, QImage::Format_ARGB32_Premultiplied);
       
  1156     img.fill(0x0);
       
  1157 
       
  1158     QPainter p(&img);
       
  1159     QLine line(10, 0, 10, 10);
       
  1160     p.translate(-10, 0);
       
  1161     p.drawLine(line);
       
  1162     p.end();
       
  1163 
       
  1164     for (int i = 0; i < img.height(); ++i)
       
  1165         QCOMPARE(img.pixel(0, i), QColor(Qt::black).rgba());
       
  1166 }
       
  1167 
       
  1168 void tst_QPainter::drawRect()
       
  1169 {
       
  1170     QFETCH(QRect, rect);
       
  1171     QFETCH(bool, usePen);
       
  1172 
       
  1173     QPixmap pixmap(rect.x() + rect.width() + 10,
       
  1174                    rect.y() + rect.height() + 10);
       
  1175     {
       
  1176         pixmap.fill(Qt::white);
       
  1177         QPainter p(&pixmap);
       
  1178         p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
       
  1179         p.setBrush(Qt::black);
       
  1180         p.drawRect(rect);
       
  1181         p.end();
       
  1182 
       
  1183         int increment = usePen ? 1 : 0;
       
  1184 
       
  1185         const QRect painted = getPaintedSize(pixmap, Qt::white);
       
  1186         QCOMPARE(painted.width(), rect.width() + increment);
       
  1187         QCOMPARE(painted.height(), rect.height() + increment);
       
  1188     }
       
  1189 
       
  1190 #ifdef QT3_SUPPORT
       
  1191     {
       
  1192         if (usePen && (rect.width() < 2 || rect.height() < 2))
       
  1193             return;
       
  1194         pixmap.fill(Qt::white);
       
  1195         Q3Painter p(&pixmap);
       
  1196         p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
       
  1197         p.setBrush(Qt::black);
       
  1198         p.drawRect(rect);
       
  1199         p.end();
       
  1200 
       
  1201         const QRect painted = getPaintedSize(pixmap, Qt::white);
       
  1202 
       
  1203         QCOMPARE(painted.width(), rect.width());
       
  1204         QCOMPARE(painted.height(), rect.height());
       
  1205     }
       
  1206 #endif
       
  1207 }
       
  1208 
       
  1209 void tst_QPainter::drawRect2()
       
  1210 {
       
  1211     QImage image(64, 64, QImage::Format_ARGB32_Premultiplied);
       
  1212     {
       
  1213         image.fill(0xffffffff);
       
  1214 
       
  1215         QTransform transform(0.368567, 0, 0, 0, 0.368567, 0, 0.0289, 0.0289, 1);
       
  1216 
       
  1217         QPainter p(&image);
       
  1218         p.setTransform(transform);
       
  1219         p.setBrush(Qt::red);
       
  1220         p.setPen(Qt::NoPen);
       
  1221         p.drawRect(QRect(14, 14, 39, 39));
       
  1222         p.end();
       
  1223 
       
  1224         QRect fill = getPaintedSize(image, Qt::white);
       
  1225         image.fill(0xffffffff);
       
  1226 
       
  1227         p.begin(&image);
       
  1228         p.setTransform(transform);
       
  1229         p.drawRect(QRect(14, 14, 39, 39));
       
  1230         p.end();
       
  1231 
       
  1232         QRect stroke = getPaintedSize(image, Qt::white);
       
  1233         QCOMPARE(stroke.adjusted(1, 1, 0, 0), fill.adjusted(0, 0, 1, 1));
       
  1234     }
       
  1235 }
       
  1236 
       
  1237 void tst_QPainter::fillRect()
       
  1238 {
       
  1239     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
       
  1240     image.fill(QColor(0, 0, 0, 0).rgba());
       
  1241 
       
  1242     QPainter p(&image);
       
  1243 
       
  1244     p.fillRect(0, 0, 100, 100, QColor(255, 0, 0, 127));
       
  1245 
       
  1246 //    pixmap.save("bla1.png", "PNG");
       
  1247     QCOMPARE(getPaintedSize(image, QColor(0, 0, 0, 0)),
       
  1248              QRect(0, 0, 100, 100));
       
  1249     QCOMPARE(getPaintedSize(image, QColor(127, 0, 0, 127)).isValid(),
       
  1250              QRect().isValid());
       
  1251 
       
  1252     p.setCompositionMode(QPainter::CompositionMode_SourceIn);
       
  1253     p.fillRect(50, 0, 50, 100, QColor(0, 0, 255, 255));
       
  1254 
       
  1255     QCOMPARE(getPaintedSize(image, QColor(127, 0, 0, 127)),
       
  1256              QRect(50, 0, 50, 100));
       
  1257     QCOMPARE(getPaintedSize(image, QColor(0, 0, 127, 127)),
       
  1258              QRect(0, 0, 50, 100));
       
  1259 }
       
  1260 
       
  1261 void tst_QPainter::fillRect2()
       
  1262 {
       
  1263     QRgb background = 0x0;
       
  1264 
       
  1265     QImage img(1, 20, QImage::Format_ARGB32_Premultiplied);
       
  1266     img.fill(background);
       
  1267 
       
  1268     QPainter p(&img);
       
  1269 
       
  1270     QRectF rect(0, 1, 1.2, 18);
       
  1271     p.fillRect(rect, Qt::black);
       
  1272 
       
  1273     p.end();
       
  1274 
       
  1275     QCOMPARE(img.pixel(0, 0), background);
       
  1276     QCOMPARE(img.pixel(0, img.height() - 1), background);
       
  1277 
       
  1278     QCOMPARE(img.pixel(0, 1), img.pixel(0, 2));
       
  1279     QCOMPARE(img.pixel(0, img.height() - 2), img.pixel(0, img.height() - 3));
       
  1280 }
       
  1281 
       
  1282 void tst_QPainter::fillRect3()
       
  1283 {
       
  1284     QImage img(1, 1, QImage::Format_ARGB32_Premultiplied);
       
  1285     img.fill(QColor(Qt::black).rgba());
       
  1286 
       
  1287     QPainter p(&img);
       
  1288     p.setCompositionMode(QPainter::CompositionMode_Source);
       
  1289     p.fillRect(img.rect(), Qt::transparent);
       
  1290     p.end();
       
  1291 
       
  1292     QCOMPARE(img.pixel(0, 0), 0U);
       
  1293 }
       
  1294 
       
  1295 void tst_QPainter::fillRect4()
       
  1296 {
       
  1297     QImage image(100, 1, QImage::Format_ARGB32_Premultiplied);
       
  1298     image.fill(0x0);
       
  1299 
       
  1300     QImage expected = image;
       
  1301     expected.fill(0xffffffff);
       
  1302 
       
  1303     QPainter p(&image);
       
  1304     p.scale(1.1, 1);
       
  1305     p.setPen(Qt::NoPen);
       
  1306 
       
  1307     for (int i = 0; i < 33; ++i)
       
  1308         p.fillRect(QRectF(3 * i, 0, 3, 1), Qt::white);
       
  1309 
       
  1310     p.end();
       
  1311 
       
  1312     QCOMPARE(image, expected);
       
  1313 }
       
  1314 
       
  1315 void tst_QPainter::drawPath_data()
       
  1316 {
       
  1317     QTest::addColumn<QPainterPath>("path");
       
  1318     QTest::addColumn<QRect>("expectedBounds");
       
  1319     QTest::addColumn<int>("expectedPixels");
       
  1320 
       
  1321     {
       
  1322         QPainterPath p;
       
  1323         p.addRect(2, 2, 10, 10);
       
  1324         QTest::newRow("int-aligned rect") << p << QRect(2, 2, 10, 10) << 10 * 10;
       
  1325     }
       
  1326 
       
  1327     {
       
  1328         QPainterPath p;
       
  1329         p.addRect(2.25, 2.25, 10, 10);
       
  1330         QTest::newRow("non-aligned rect") << p << QRect(3, 3, 10, 10) << 10 * 10;
       
  1331     }
       
  1332 
       
  1333     {
       
  1334         QPainterPath p;
       
  1335         p.addRect(2.25, 2.25, 10.5, 10.5);
       
  1336         QTest::newRow("non-aligned rect 2") << p << QRect(3, 3, 10, 10) << 10 * 10;
       
  1337     }
       
  1338 
       
  1339     {
       
  1340         QPainterPath p;
       
  1341         p.addRect(2.5, 2.5, 10, 10);
       
  1342         QTest::newRow("non-aligned rect 3") << p << QRect(3, 3, 10, 10) << 10 * 10;
       
  1343     }
       
  1344 
       
  1345     {
       
  1346         QPainterPath p;
       
  1347         p.addRect(2, 2, 10, 10);
       
  1348         p.addRect(4, 4, 6, 6);
       
  1349         QTest::newRow("rect-in-rect") << p << QRect(2, 2, 10, 10) << 10 * 10 - 6 * 6;
       
  1350     }
       
  1351 
       
  1352     {
       
  1353         QPainterPath p;
       
  1354         p.addRect(2, 2, 10, 10);
       
  1355         p.addRect(4, 4, 6, 6);
       
  1356         p.addRect(6, 6, 2, 2);
       
  1357         QTest::newRow("rect-in-rect-in-rect") << p << QRect(2, 2, 10, 10) << 10 * 10 - 6 * 6 + 2 * 2;
       
  1358     }
       
  1359 }
       
  1360 
       
  1361 void tst_QPainter::drawPath()
       
  1362 {
       
  1363     QFETCH(QPainterPath, path);
       
  1364     QFETCH(QRect, expectedBounds);
       
  1365     QFETCH(int, expectedPixels);
       
  1366 
       
  1367     const int offset = 2;
       
  1368 
       
  1369     QImage image(expectedBounds.width() + 2 * offset, expectedBounds.height() + 2 * offset,
       
  1370                  QImage::Format_ARGB32_Premultiplied);
       
  1371     image.fill(QColor(Qt::white).rgb());
       
  1372 
       
  1373     QPainter p(&image);
       
  1374     p.setPen(Qt::NoPen);
       
  1375     p.setBrush(Qt::black);
       
  1376     p.translate(offset - expectedBounds.left(), offset - expectedBounds.top());
       
  1377     p.drawPath(path);
       
  1378     p.end();
       
  1379 
       
  1380     const QRect paintedBounds = getPaintedSize(image, Qt::white);
       
  1381 
       
  1382     QCOMPARE(paintedBounds.x(), offset);
       
  1383     QCOMPARE(paintedBounds.y(), offset);
       
  1384     QCOMPARE(paintedBounds.width(), expectedBounds.width());
       
  1385     QCOMPARE(paintedBounds.height(), expectedBounds.height());
       
  1386 
       
  1387     if (expectedPixels != -1) {
       
  1388         int paintedPixels = getPaintedPixels(image, Qt::white);
       
  1389         QCOMPARE(paintedPixels, expectedPixels);
       
  1390     }
       
  1391 }
       
  1392 
       
  1393 void tst_QPainter::drawPath2()
       
  1394 {
       
  1395     const int w = 50;
       
  1396 
       
  1397     for (int h = 5; h < 200; ++h) {
       
  1398         QPainterPath p1, p2;
       
  1399         p1.lineTo(w, 0);
       
  1400         p1.lineTo(w, h);
       
  1401 
       
  1402         p2.lineTo(w, h);
       
  1403         p2.lineTo(0, h);
       
  1404 
       
  1405         const int offset = 2;
       
  1406 
       
  1407         QImage image(w + 2 * offset, h + 2 * offset,
       
  1408                      QImage::Format_ARGB32_Premultiplied);
       
  1409         image.fill(QColor(Qt::white).rgb());
       
  1410 
       
  1411         QPainter p(&image);
       
  1412         p.setPen(Qt::NoPen);
       
  1413         p.setBrush(Qt::black);
       
  1414         p.translate(offset, offset);
       
  1415         p.drawPath(p1);
       
  1416         p.end();
       
  1417 
       
  1418         const int p1Pixels = getPaintedPixels(image, Qt::white);
       
  1419 
       
  1420         image.fill(QColor(Qt::white).rgb());
       
  1421         p.begin(&image);
       
  1422         p.setPen(Qt::NoPen);
       
  1423         p.setBrush(Qt::black);
       
  1424         p.translate(offset, offset);
       
  1425         p.drawPath(p2);
       
  1426         p.end();
       
  1427 
       
  1428         const int p2Pixels = getPaintedPixels(image, Qt::white);
       
  1429 
       
  1430         QCOMPARE(p1Pixels + p2Pixels, w * h);
       
  1431     }
       
  1432 }
       
  1433 
       
  1434 void tst_QPainter::drawPath3()
       
  1435 {
       
  1436 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
       
  1437     QImage imgA(400, 400, QImage::Format_RGB32);
       
  1438 #else
       
  1439     QImage imgA(100, 100, QImage::Format_RGB32);
       
  1440 #endif
       
  1441     imgA.fill(0xffffff);
       
  1442     QImage imgB = imgA;
       
  1443 
       
  1444     QPainterPath path;
       
  1445     for (int y = 0; y < imgA.height(); ++y) {
       
  1446         for (int x = 0; x < imgA.width(); ++x) {
       
  1447             if ((x + y) & 1) {
       
  1448                 imgA.setPixel(x, y, 0);
       
  1449                 path.addRect(x, y, 1, 1);
       
  1450             }
       
  1451         }
       
  1452     }
       
  1453 
       
  1454     QPainter p(&imgB);
       
  1455     p.setPen(Qt::NoPen);
       
  1456     p.setBrush(Qt::black);
       
  1457 
       
  1458     p.drawPath(path);
       
  1459     p.end();
       
  1460 
       
  1461     QVERIFY(imgA == imgB);
       
  1462 
       
  1463     imgA.invertPixels();
       
  1464     imgB.fill(0xffffff);
       
  1465 
       
  1466     p.begin(&imgB);
       
  1467     p.setPen(Qt::NoPen);
       
  1468     p.setBrush(Qt::black);
       
  1469 
       
  1470     QRectF rect(0, 0, imgA.width(), imgA.height());
       
  1471     path.addRect(rect.adjusted(-10, -10, 10, 10));
       
  1472     p.drawPath(path);
       
  1473     p.end();
       
  1474 
       
  1475     QVERIFY(imgA == imgB);
       
  1476 
       
  1477     path.setFillRule(Qt::WindingFill);
       
  1478     imgB.fill(0xffffff);
       
  1479 
       
  1480     p.begin(&imgB);
       
  1481     p.setPen(Qt::NoPen);
       
  1482     p.setBrush(Qt::black);
       
  1483     QRect clip = rect.adjusted(10, 10, -10, -10).toRect();
       
  1484     p.setClipRect(clip);
       
  1485     p.drawPath(path);
       
  1486     p.end();
       
  1487 
       
  1488     QCOMPARE(getPaintedPixels(imgB, Qt::white), clip.width() * clip.height());
       
  1489 }
       
  1490 
       
  1491 void tst_QPainter::drawEllipse_data()
       
  1492 {
       
  1493     QTest::addColumn<QSize>("size");
       
  1494     QTest::addColumn<bool>("usePen");
       
  1495 
       
  1496     // The current drawEllipse algorithm (drawEllipse_midpoint_i in
       
  1497     // qpaintengine_raster.cpp) draws ellipses that are too wide if the
       
  1498     // ratio between width and hight is too large/small (task 114874). Those
       
  1499     // ratios are therefore currently avoided.
       
  1500     for (int w = 10; w < 128; w += 7) {
       
  1501         for (int h = w/2; h < qMin(2*w, 128); h += 13) {
       
  1502             QString s = QString("%1x%2").arg(w).arg(h);
       
  1503             QTest::newRow(QString("%1 with pen").arg(s).toLatin1()) << QSize(w, h) << true;
       
  1504             QTest::newRow(QString("%1 no pen").arg(s).toLatin1()) << QSize(w, h) << false;
       
  1505         }
       
  1506     }
       
  1507 }
       
  1508 
       
  1509 void tst_QPainter::drawEllipse()
       
  1510 {
       
  1511     QFETCH(QSize, size);
       
  1512     QFETCH(bool, usePen);
       
  1513 
       
  1514     const int offset = 10;
       
  1515     QRect rect(QPoint(offset, offset), size);
       
  1516 
       
  1517     QImage image(size.width() + 2 * offset, size.height() + 2 * offset,
       
  1518                  QImage::Format_ARGB32_Premultiplied);
       
  1519     image.fill(QColor(Qt::white).rgb());
       
  1520 
       
  1521     QPainter p(&image);
       
  1522     p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
       
  1523     p.setBrush(Qt::black);
       
  1524     p.drawEllipse(rect);
       
  1525     p.end();
       
  1526 
       
  1527     QPixmap pixmap = QPixmap::fromImage(image);
       
  1528 
       
  1529     const QRect painted = getPaintedSize(pixmap, Qt::white);
       
  1530 
       
  1531     QCOMPARE(painted.x(), rect.x());
       
  1532     QCOMPARE(painted.y(), rect.y() + (usePen ? 0 : 1));
       
  1533     QCOMPARE(painted.width(), size.width() + (usePen ? 1 : 0));
       
  1534     QCOMPARE(painted.height(), size.height() + (usePen ? 1 : -1));
       
  1535 }
       
  1536 
       
  1537 void tst_QPainter::drawClippedEllipse_data()
       
  1538 {
       
  1539     QTest::addColumn<QRect>("rect");
       
  1540 
       
  1541     for (int w = 20; w < 128; w += 7) {
       
  1542         for (int h = w/2; h < qMin(2*w, 128); h += 13) {
       
  1543             QString s = QString("%1x%2").arg(w).arg(h);
       
  1544             QTest::newRow(QString("%1 top").arg(s).toLatin1()) << QRect(0, -h/2, w, h);
       
  1545             QTest::newRow(QString("%1 topright").arg(s).toLatin1()) << QRect(w/2, -h/2, w, h);
       
  1546             QTest::newRow(QString("%1 right").arg(s).toLatin1()) << QRect(w/2, 0, w, h);
       
  1547             QTest::newRow(QString("%1 bottomright").arg(s).toLatin1()) << QRect(w/2, h/2, w, h);
       
  1548             QTest::newRow(QString("%1 bottom").arg(s).toLatin1()) << QRect(0, h/2, w, h);
       
  1549             QTest::newRow(QString("%1 bottomleft").arg(s).toLatin1()) << QRect(-w/2, h/2, w, h);
       
  1550             QTest::newRow(QString("%1 left").arg(s).toLatin1()) << QRect(-w/2, 0, w, h);
       
  1551             QTest::newRow(QString("%1 topleft").arg(s).toLatin1()) << QRect(-w/2, -h/2, w, h);
       
  1552         }
       
  1553     }
       
  1554 }
       
  1555 
       
  1556 void tst_QPainter::drawClippedEllipse()
       
  1557 {
       
  1558     QFETCH(QRect, rect);
       
  1559 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
  1560     if (sizeof(qreal) != sizeof(double))
       
  1561         QSKIP("Test only works for qreal==double", SkipAll);
       
  1562 #endif
       
  1563     QImage image(rect.width() + 1, rect.height() + 1,
       
  1564                  QImage::Format_ARGB32_Premultiplied);
       
  1565     QRect expected = QRect(rect.x(), rect.y(), rect.width()+1, rect.height()+1)
       
  1566                      & QRect(0, 0, image.width(), image.height());
       
  1567 
       
  1568 
       
  1569     image.fill(QColor(Qt::white).rgb());
       
  1570     QPainter p(&image);
       
  1571     p.drawEllipse(rect);
       
  1572     p.end();
       
  1573 
       
  1574     QPixmap pixmap = QPixmap::fromImage(image);
       
  1575     const QRect painted = getPaintedSize(pixmap, Qt::white);
       
  1576 
       
  1577     QCOMPARE(painted.x(), expected.x());
       
  1578     QCOMPARE(painted.y(), expected.y());
       
  1579     QCOMPARE(painted.width(), expected.width());
       
  1580     QCOMPARE(painted.height(), expected.height());
       
  1581 
       
  1582 }
       
  1583 
       
  1584 void tst_QPainter::drawRoundRect()
       
  1585 {
       
  1586     QFETCH(QRect, rect);
       
  1587     QFETCH(bool, usePen);
       
  1588 
       
  1589 #ifdef Q_WS_MAC
       
  1590     if (QTest::currentDataTag() == QByteArray("rect(6, 12, 3, 14) with pen") ||
       
  1591         QTest::currentDataTag() == QByteArray("rect(6, 17, 3, 25) with pen") ||
       
  1592         QTest::currentDataTag() == QByteArray("rect(10, 6, 10, 3) with pen") ||
       
  1593         QTest::currentDataTag() == QByteArray("rect(10, 12, 10, 14) with pen") ||
       
  1594         QTest::currentDataTag() == QByteArray("rect(13, 45, 17, 80) with pen") ||
       
  1595         QTest::currentDataTag() == QByteArray("rect(13, 50, 17, 91) with pen") ||
       
  1596         QTest::currentDataTag() == QByteArray("rect(17, 6, 24, 3) with pen") ||
       
  1597         QTest::currentDataTag() == QByteArray("rect(24, 12, 38, 14) with pen"))
       
  1598         QSKIP("The Mac paint engine is off-by-one on certain rect sizes", SkipSingle);
       
  1599 #endif
       
  1600     QPixmap pixmap(rect.x() + rect.width() + 10,
       
  1601                    rect.y() + rect.height() + 10);
       
  1602     {
       
  1603         pixmap.fill(Qt::white);
       
  1604         QPainter p(&pixmap);
       
  1605         p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
       
  1606         p.setBrush(Qt::black);
       
  1607         p.drawRoundRect(rect);
       
  1608         p.end();
       
  1609 
       
  1610         int increment = usePen ? 1 : 0;
       
  1611 
       
  1612         const QRect painted = getPaintedSize(pixmap, Qt::white);
       
  1613         QCOMPARE(painted.width(), rect.width() + increment);
       
  1614         QCOMPARE(painted.height(), rect.height() + increment);
       
  1615     }
       
  1616 
       
  1617 #ifdef QT3_SUPPORT
       
  1618     {
       
  1619         pixmap.fill(Qt::white);
       
  1620         Q3Painter p(&pixmap);
       
  1621         p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
       
  1622         p.setBrush(Qt::black);
       
  1623         p.drawRoundRect(rect);
       
  1624         p.end();
       
  1625 
       
  1626         const QRect painted = getPaintedSize(pixmap, Qt::white);
       
  1627 
       
  1628         QCOMPARE(painted.width(), rect.width());
       
  1629         QCOMPARE(painted.height(), rect.height());
       
  1630     }
       
  1631 #endif
       
  1632 }
       
  1633 
       
  1634 Q_DECLARE_METATYPE(QImage::Format)
       
  1635 
       
  1636 void tst_QPainter::qimageFormats_data()
       
  1637 {
       
  1638     QTest::addColumn<QImage::Format>("format");
       
  1639     QTest::newRow("QImage::Format_RGB32") << QImage::Format_RGB32;
       
  1640     QTest::newRow("QImage::Format_ARGB32") << QImage::Format_ARGB32;
       
  1641     QTest::newRow("QImage::Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied;
       
  1642     QTest::newRow("QImage::Format_RGB16") << QImage::Format_RGB16;
       
  1643     QTest::newRow("Qimage::Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied;
       
  1644     QTest::newRow("Qimage::Format_RGB666") << QImage::Format_RGB666;
       
  1645     QTest::newRow("Qimage::Format_RGB555") << QImage::Format_RGB555;
       
  1646     QTest::newRow("Qimage::Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied;
       
  1647     QTest::newRow("Qimage::Format_RGB888") << QImage::Format_RGB888;
       
  1648 }
       
  1649 
       
  1650 /*
       
  1651     Tests that QPainter can paint on various QImage formats.
       
  1652 */
       
  1653 void tst_QPainter::qimageFormats()
       
  1654 {
       
  1655     QFETCH(QImage::Format, format);
       
  1656 
       
  1657     const QSize size(100, 100);
       
  1658     QImage image(size, format);
       
  1659     image.fill(0);
       
  1660 
       
  1661     const QColor testColor(Qt::red);
       
  1662     QPainter p(&image);
       
  1663     QVERIFY(p.isActive());
       
  1664     p.setBrush(QBrush(testColor));
       
  1665     p.drawRect(QRect(QPoint(0,0), size));
       
  1666     QCOMPARE(image.pixel(50, 50), testColor.rgb());
       
  1667 }
       
  1668 
       
  1669 void tst_QPainter::fillData()
       
  1670 {
       
  1671     QTest::addColumn<QRect>("rect");
       
  1672     QTest::addColumn<bool>("usePen");
       
  1673 
       
  1674     for (int w = 3; w < 50; w += 7) {
       
  1675         for (int h = 3; h < 50; h += 11) {
       
  1676             int x = w/2 + 5;
       
  1677             int y = h/2 + 5;
       
  1678             QTest::newRow(QString("rect(%1, %2, %3, %4) with pen").arg(x).arg(y).arg(w).arg(h).toLatin1())
       
  1679                 << QRect(x, y, w, h) << true;
       
  1680             QTest::newRow(QString("rect(%1, %2, %3, %4) no pen").arg(x).arg(y).arg(w).arg(h).toLatin1())
       
  1681                 << QRect(x, y, w, h) << false;
       
  1682         }
       
  1683     }
       
  1684 }
       
  1685 
       
  1686 /*
       
  1687     Test that drawline works properly after setWindow has been called.
       
  1688 */
       
  1689 void tst_QPainter::setWindow()
       
  1690 {
       
  1691     QPixmap pixmap(600, 600);
       
  1692     pixmap.fill(QColor(Qt::white));
       
  1693 
       
  1694     QPainter painter(&pixmap);
       
  1695     painter.setWindow(0, 0, 3, 3);
       
  1696     painter.drawLine(1, 1, 2, 2);
       
  1697 
       
  1698     const QRect painted = getPaintedSize(pixmap, Qt::white);
       
  1699     QVERIFY(195 < painted.y() && painted.y() < 205); // correct value is around 200
       
  1700     QVERIFY(195 < painted.height() && painted.height() < 205); // correct value is around 200
       
  1701 }
       
  1702 
       
  1703 void tst_QPainter::combinedMatrix()
       
  1704 {
       
  1705     QPixmap pm(64, 64);
       
  1706 
       
  1707     QPainter p(&pm);
       
  1708     p.setWindow(0, 0, 1, 1);
       
  1709     p.setViewport(32, 0, 32, 32);
       
  1710 
       
  1711     p.translate(0.5, 0.5);
       
  1712 
       
  1713     QMatrix cm = p.combinedMatrix();
       
  1714 
       
  1715     QPointF pt = QPointF(0, 0) * cm;
       
  1716 
       
  1717     QCOMPARE(pt.x(), 48.0);
       
  1718     QCOMPARE(pt.y(), 16.0);
       
  1719 }
       
  1720 
       
  1721 void tst_QPainter::textOnTransparentImage()
       
  1722 {
       
  1723     bool foundPixel = false;
       
  1724     QImage image(10, 10, QImage::Format_ARGB32_Premultiplied);
       
  1725     image.fill(qRgba(0, 0, 0, 0)); // transparent
       
  1726     {
       
  1727         QPainter painter(&image);
       
  1728         painter.setPen(QColor(255, 255, 255));
       
  1729         painter.drawText(0, 10, "W");
       
  1730     }
       
  1731     for (int x = 0; x < image.width(); ++x)
       
  1732         for (int y = 0; y < image.height(); ++y)
       
  1733             if (image.pixel(x, y) != 0)
       
  1734                 foundPixel = true;
       
  1735     QVERIFY(foundPixel);
       
  1736 }
       
  1737 
       
  1738 void tst_QPainter::renderHints()
       
  1739 {
       
  1740     QImage img(1, 1, QImage::Format_RGB32);
       
  1741 
       
  1742     QPainter p(&img);
       
  1743 
       
  1744     // Turn off all...
       
  1745     p.setRenderHints(QPainter::RenderHints(0xffffffff), false);
       
  1746     QCOMPARE(p.renderHints(), QPainter::RenderHints(0));
       
  1747 
       
  1748     // Single set/get
       
  1749     p.setRenderHint(QPainter::Antialiasing);
       
  1750     QVERIFY(p.renderHints() & QPainter::Antialiasing);
       
  1751 
       
  1752     p.setRenderHint(QPainter::Antialiasing, false);
       
  1753     QVERIFY(!(p.renderHints() & QPainter::Antialiasing));
       
  1754 
       
  1755     // Multi set/get
       
  1756     p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
       
  1757     QVERIFY(p.renderHints() & (QPainter::Antialiasing | QPainter::SmoothPixmapTransform));
       
  1758 
       
  1759     p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
       
  1760     QVERIFY(!(p.renderHints() & (QPainter::Antialiasing | QPainter::SmoothPixmapTransform)));
       
  1761 }
       
  1762 
       
  1763 int countPixels(const QImage &img, const QRgb &color)
       
  1764 {
       
  1765     int count = 0;
       
  1766     for (int y = 0; y < img.height(); ++y) {
       
  1767         for (int x = 0; x < img.width(); ++x) {
       
  1768             count += ((img.pixel(x, y) & 0xffffff) == color);
       
  1769         }
       
  1770     }
       
  1771     return count;
       
  1772 }
       
  1773 
       
  1774 template <typename T>
       
  1775 void testClipping(QImage &img)
       
  1776 {
       
  1777     img.fill(0x0);
       
  1778     QPainterPath a, b;
       
  1779     a.addRect(QRect(2, 2, 4, 4));
       
  1780     b.addRect(QRect(4, 4, 4, 4));
       
  1781 
       
  1782     QPainter p(&img);
       
  1783     p.setClipPath(a);
       
  1784     p.setClipPath(b, Qt::UniteClip);
       
  1785 
       
  1786     p.setClipping(false);
       
  1787     p.setPen(Qt::NoPen);
       
  1788     p.setBrush(QColor(0xff0000));
       
  1789     p.drawRect(T(0, 0, 10, 10));
       
  1790 
       
  1791     p.setClipping(true);
       
  1792     p.setBrush(QColor(0x00ff00));
       
  1793     p.drawRect(T(0, 0, 10, 10));
       
  1794 
       
  1795     QCOMPARE(countPixels(img, 0xff0000), 72);
       
  1796     QCOMPARE(countPixels(img, 0x00ff00), 28);
       
  1797 
       
  1798     p.end();
       
  1799     img.fill(0x0);
       
  1800     p.begin(&img);
       
  1801     p.setClipPath(a);
       
  1802     p.setClipPath(b, Qt::IntersectClip);
       
  1803 
       
  1804     p.setClipping(false);
       
  1805     p.setPen(Qt::NoPen);
       
  1806     p.setBrush(QColor(0xff0000));
       
  1807     p.drawRect(T(0, 0, 10, 10));
       
  1808 
       
  1809     p.setClipping(true);
       
  1810     p.setBrush(QColor(0x00ff00));
       
  1811     p.drawRect(T(0, 0, 10, 10));
       
  1812 
       
  1813     QCOMPARE(countPixels(img, 0xff0000), 96);
       
  1814     QCOMPARE(countPixels(img, 0x00ff00), 4);
       
  1815 }
       
  1816 
       
  1817 void tst_QPainter::disableEnableClipping()
       
  1818 {
       
  1819     QImage img(10, 10, QImage::Format_RGB32);
       
  1820 
       
  1821     testClipping<QRectF>(img);
       
  1822     testClipping<QRect>(img);
       
  1823 }
       
  1824 
       
  1825 void tst_QPainter::setClipRect()
       
  1826 {
       
  1827     QImage img(10, 10, QImage::Format_RGB32);
       
  1828     // simple test to let valgrind check for buffer overflow
       
  1829     {
       
  1830         QPainter p(&img);
       
  1831         p.setClipRect(-10, -10, 100, 100);
       
  1832         p.fillRect(-10, -10, 100, 100, QBrush(QColor(Qt::red)));
       
  1833     }
       
  1834 
       
  1835     // rects with negative width/height
       
  1836     {
       
  1837         QPainter p(&img);
       
  1838         p.setClipRect(QRect(10, 10, -10, 10));
       
  1839         QVERIFY(p.clipRegion().isEmpty());
       
  1840         p.setClipRect(QRect(10, 10, 10, -10));
       
  1841         QVERIFY(p.clipRegion().isEmpty());
       
  1842         p.setClipRect(QRectF(10.5, 10.5, -10.5, 10.5));
       
  1843         QVERIFY(p.clipRegion().isEmpty());
       
  1844         p.setClipRect(QRectF(10.5, 10.5, 10.5, -10.5));
       
  1845         QVERIFY(p.clipRegion().isEmpty());
       
  1846     }
       
  1847 }
       
  1848 
       
  1849 /*
       
  1850     This tests the two different clipping approaches in QRasterPaintEngine,
       
  1851     one when using a QRegion and one when using a QPainterPath. They should
       
  1852     give equal results.
       
  1853 */
       
  1854 void tst_QPainter::setEqualClipRegionAndPath_data()
       
  1855 {
       
  1856     QTest::addColumn<QSize>("deviceSize");
       
  1857     QTest::addColumn<QRegion>("region");
       
  1858 
       
  1859     QTest::newRow("empty") << QSize(100, 100) << QRegion();
       
  1860     QTest::newRow("simple rect") << QSize(100, 100)
       
  1861                                  << QRegion(QRect(5, 5, 10, 10));
       
  1862 
       
  1863     QVector<QRect> rects;
       
  1864     QRegion region;
       
  1865 
       
  1866     rects << QRect(5, 5, 10, 10) << QRect(20, 20, 10, 10);
       
  1867     region.setRects(rects.constData(), rects.size());
       
  1868     QTest::newRow("two rects") << QSize(100, 100) << region;
       
  1869 
       
  1870     rects.clear();
       
  1871     rects << QRect(5, 5, 10, 10) << QRect(20, 5, 10, 10);
       
  1872     region.setRects(rects.constData(), rects.size());
       
  1873     QTest::newRow("two x-adjacent rects") << QSize(100, 100) << region;
       
  1874 
       
  1875     rects.clear();
       
  1876     rects << QRect(0, 0, 10, 100) << QRect(12, 0, 10, 100);
       
  1877     region.setRects(rects.constData(), rects.size());
       
  1878     QTest::newRow("two x-adjacent rects 2") << QSize(100, 100) << region;
       
  1879 
       
  1880     rects.clear();
       
  1881     rects << QRect(0, 0, 10, 100) << QRect(12, 0, 10, 100);
       
  1882     region.setRects(rects.constData(), rects.size());
       
  1883     QTest::newRow("two x-adjacent rects 3") << QSize(50, 50) << region;
       
  1884 
       
  1885     rects.clear();
       
  1886     rects << QRect(0, 0, 10, 100) << QRect(12, 0, 10, 100);
       
  1887     region.setRects(rects.constData(), rects.size());
       
  1888     QTest::newRow("two x-adjacent rects 4") << QSize(101, 101) << region;
       
  1889 
       
  1890     region = QRegion(QRect(0, 0, 200, 200), QRegion::Ellipse);
       
  1891 
       
  1892     QTest::newRow("ellipse") << QSize(190, 200) << region;
       
  1893 
       
  1894     region ^= QRect(50, 50, 50, 50);
       
  1895     QTest::newRow("ellipse 2") << QSize(200, 200) << region;
       
  1896 }
       
  1897 
       
  1898 void tst_QPainter::setEqualClipRegionAndPath()
       
  1899 {
       
  1900     QFETCH(QSize, deviceSize);
       
  1901     QFETCH(QRegion, region);
       
  1902 
       
  1903     QPainterPath path;
       
  1904     path.addRegion(region);
       
  1905 
       
  1906     QImage img1(deviceSize.width(), deviceSize.height(),
       
  1907                 QImage::Format_ARGB32);
       
  1908     QImage img2(deviceSize.width(), deviceSize.height(),
       
  1909                 QImage::Format_ARGB32);
       
  1910     img1.fill(0x12345678);
       
  1911     img2.fill(0x12345678);
       
  1912 
       
  1913     {
       
  1914         QPainter p(&img1);
       
  1915         p.setClipRegion(region);
       
  1916         p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
       
  1917     }
       
  1918     {
       
  1919         QPainter p(&img2);
       
  1920         p.setClipPath(path);
       
  1921         p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
       
  1922     }
       
  1923 
       
  1924 #if 0
       
  1925     if (img1 != img2) {
       
  1926         img1.save("setEqualClipRegionAndPath_1.xpm", "XPM");
       
  1927         img2.save("setEqualClipRegionAndPath_2.xpm", "XPM");
       
  1928     }
       
  1929 #endif
       
  1930     QCOMPARE(img1, img2);
       
  1931 
       
  1932 #if 0
       
  1933     // rotated
       
  1934     img1.fill(0x12345678);
       
  1935     img2.fill(0x12345678);
       
  1936 
       
  1937     {
       
  1938         QPainter p(&img1);
       
  1939         p.rotate(25);
       
  1940         p.setClipRegion(region);
       
  1941         p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
       
  1942     }
       
  1943     {
       
  1944         QPainter p(&img2);
       
  1945         p.rotate(25);
       
  1946         p.setClipPath(path);
       
  1947         p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
       
  1948     }
       
  1949 
       
  1950 #if 1
       
  1951     if (img1 != img2) {
       
  1952         img1.save("setEqualClipRegionAndPath_1.xpm", "XPM");
       
  1953         img2.save("setEqualClipRegionAndPath_2.xpm", "XPM");
       
  1954     }
       
  1955 #endif
       
  1956     QCOMPARE(img1, img2);
       
  1957 #endif
       
  1958 
       
  1959     // simple uniteclip
       
  1960     img1.fill(0x12345678);
       
  1961     img2.fill(0x12345678);
       
  1962     {
       
  1963         QPainter p(&img1);
       
  1964         p.setClipRegion(region);
       
  1965         p.setClipRegion(region, Qt::UniteClip);
       
  1966         p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
       
  1967     }
       
  1968     {
       
  1969         QPainter p(&img2);
       
  1970         p.setClipPath(path);
       
  1971         p.setClipPath(path, Qt::UniteClip);
       
  1972         p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
       
  1973     }
       
  1974     QCOMPARE(img1, img2);
       
  1975     img1.fill(0x12345678);
       
  1976     img2.fill(0x12345678);
       
  1977     {
       
  1978         QPainter p(&img1);
       
  1979         p.setClipPath(path);
       
  1980         p.setClipRegion(region, Qt::UniteClip);
       
  1981         p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
       
  1982     }
       
  1983     {
       
  1984         QPainter p(&img2);
       
  1985         p.setClipRegion(region);
       
  1986         p.setClipPath(path, Qt::UniteClip);
       
  1987         p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
       
  1988     }
       
  1989 #if 0
       
  1990     if (img1 != img2) {
       
  1991         img1.save("setEqualClipRegionAndPath_1.xpm", "XPM");
       
  1992         img2.save("setEqualClipRegionAndPath_2.xpm", "XPM");
       
  1993     }
       
  1994 #endif
       
  1995     QCOMPARE(img1, img2);
       
  1996 
       
  1997     // simple intersectclip
       
  1998     img1.fill(0x12345678);
       
  1999     img2.fill(0x12345678);
       
  2000     {
       
  2001         QPainter p(&img1);
       
  2002         p.setClipRegion(region);
       
  2003         p.setClipRegion(region, Qt::IntersectClip);
       
  2004         p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
       
  2005     }
       
  2006     {
       
  2007         QPainter p(&img2);
       
  2008         p.setClipPath(path);
       
  2009         p.setClipPath(path, Qt::IntersectClip);
       
  2010         p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
       
  2011     }
       
  2012 #if 0
       
  2013     if (img1 != img2) {
       
  2014         img1.save("setEqualClipRegionAndPath_1.png", "PNG");
       
  2015         img2.save("setEqualClipRegionAndPath_2.png", "PNG");
       
  2016     }
       
  2017 #endif
       
  2018     QCOMPARE(img1, img2);
       
  2019 
       
  2020     img1.fill(0x12345678);
       
  2021     img2.fill(0x12345678);
       
  2022     {
       
  2023         QPainter p(&img1);
       
  2024         p.setClipPath(path);
       
  2025         p.setClipRegion(region, Qt::IntersectClip);
       
  2026         p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
       
  2027     }
       
  2028     {
       
  2029         QPainter p(&img2);
       
  2030         p.setClipRegion(region);
       
  2031         p.setClipPath(path, Qt::IntersectClip);
       
  2032         p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
       
  2033     }
       
  2034 #if 0
       
  2035     if (img1 != img2) {
       
  2036         img1.save("setEqualClipRegionAndPath_1.xpm", "XPM");
       
  2037         img2.save("setEqualClipRegionAndPath_2.xpm", "XPM");
       
  2038     }
       
  2039 #endif
       
  2040     QCOMPARE(img1, img2);
       
  2041 
       
  2042 }
       
  2043 
       
  2044 void tst_QPainter::clippedFillPath_data()
       
  2045 {
       
  2046     QTest::addColumn<QSize>("imageSize");
       
  2047     QTest::addColumn<QPainterPath>("path");
       
  2048     QTest::addColumn<QRect>("clipRect");
       
  2049     QTest::addColumn<QBrush>("brush");
       
  2050     QTest::addColumn<QPen>("pen");
       
  2051 
       
  2052     QLinearGradient gradient(QPoint(0, 0), QPoint(100, 100));
       
  2053     gradient.setColorAt(0, Qt::red);
       
  2054     gradient.setColorAt(1, Qt::blue);
       
  2055 
       
  2056 
       
  2057     QPen pen2(QColor(223, 223, 0, 223));
       
  2058     pen2.setWidth(2);
       
  2059 
       
  2060     QPainterPath path;
       
  2061     path.addRect(QRect(15, 15, 50, 50));
       
  2062     QTest::newRow("simple rect 0") << QSize(100, 100) << path
       
  2063                                    << QRect(15, 15, 49, 49)
       
  2064                                    << QBrush(Qt::NoBrush)
       
  2065                                    << QPen(Qt::black);
       
  2066     QTest::newRow("simple rect 1") << QSize(100, 100) << path
       
  2067                                    << QRect(15, 15, 50, 50)
       
  2068                                    << QBrush(Qt::NoBrush)
       
  2069                                    << QPen(Qt::black);
       
  2070     QTest::newRow("simple rect 2") << QSize(100, 100) << path
       
  2071                                    << QRect(15, 15, 51, 51)
       
  2072                                    << QBrush(Qt::NoBrush)
       
  2073                                    << QPen(Qt::black);
       
  2074     QTest::newRow("simple rect 3") << QSize(100, 100) << path
       
  2075                                    << QRect(15, 15, 51, 51)
       
  2076                                    << QBrush(QColor(Qt::blue))
       
  2077                                    << QPen(Qt::NoPen);
       
  2078     QTest::newRow("simple rect 4") << QSize(100, 100) << path
       
  2079                                    << QRect(15, 15, 51, 51)
       
  2080                                    << QBrush(gradient)
       
  2081                                    << pen2;
       
  2082 
       
  2083     path = QPainterPath();
       
  2084     path.addEllipse(QRect(15, 15, 50, 50));
       
  2085     QTest::newRow("ellipse 0") << QSize(100, 100) << path
       
  2086                                << QRect(15, 15, 49, 49)
       
  2087                                << QBrush(Qt::NoBrush)
       
  2088                                << QPen(Qt::black);
       
  2089     QTest::newRow("ellipse 1") << QSize(100, 100) << path
       
  2090                                << QRect(15, 15, 50, 50)
       
  2091                                << QBrush(Qt::NoBrush)
       
  2092                                << QPen(Qt::black);
       
  2093     QTest::newRow("ellipse 2") << QSize(100, 100) << path
       
  2094                                << QRect(15, 15, 51, 51)
       
  2095                                << QBrush(Qt::NoBrush)
       
  2096                                << QPen(Qt::black);
       
  2097     QTest::newRow("ellipse 3") << QSize(100, 100) << path
       
  2098                                << QRect(15, 15, 51, 51)
       
  2099                                << QBrush(QColor(Qt::blue))
       
  2100                                << QPen(Qt::NoPen);
       
  2101     QTest::newRow("ellipse 4") << QSize(100, 100) << path
       
  2102                                << QRect(15, 15, 51, 51)
       
  2103                                << QBrush(gradient)
       
  2104                                << pen2;
       
  2105 
       
  2106     path = QPainterPath();
       
  2107     path.addRoundRect(QRect(15, 15, 50, 50), 20);
       
  2108     QTest::newRow("round rect 0") << QSize(100, 100) << path
       
  2109                                   << QRect(15, 15, 49, 49)
       
  2110                                   << QBrush(Qt::NoBrush)
       
  2111                                   << QPen(Qt::black);
       
  2112     QTest::newRow("round rect 1") << QSize(100, 100) << path
       
  2113                                   << QRect(15, 15, 50, 50)
       
  2114                                   << QBrush(Qt::NoBrush)
       
  2115                                   << QPen(Qt::black);
       
  2116     QTest::newRow("round rect 2") << QSize(100, 100) << path
       
  2117                                   << QRect(15, 15, 51, 51)
       
  2118                                   << QBrush(Qt::NoBrush)
       
  2119                                   << QPen(Qt::black);
       
  2120     QTest::newRow("round rect 3") << QSize(100, 100) << path
       
  2121                                   << QRect(15, 15, 51, 51)
       
  2122                                   << QBrush(QColor(Qt::blue))
       
  2123                                   << QPen(Qt::NoPen);
       
  2124     QTest::newRow("round rect 4") << QSize(100, 100) << path
       
  2125                                   << QRect(15, 15, 51, 51)
       
  2126                                   << QBrush(gradient)
       
  2127                                   << pen2;
       
  2128 
       
  2129     path = QPainterPath();
       
  2130     path.moveTo(15, 50);
       
  2131     path.cubicTo(40, 50, 40, 15, 65, 50);
       
  2132     path.lineTo(15, 50);
       
  2133     QTest::newRow("cubic 0") << QSize(100, 100) << path
       
  2134                              << QRect(15, 15, 49, 49)
       
  2135                              << QBrush(Qt::NoBrush)
       
  2136                              << QPen(Qt::black);
       
  2137     QTest::newRow("cubic 1") << QSize(100, 100) << path
       
  2138                              << QRect(15, 15, 50, 50)
       
  2139                              << QBrush(Qt::NoBrush)
       
  2140                              << QPen(Qt::black);
       
  2141     QTest::newRow("cubic 2") << QSize(100, 100) << path
       
  2142                              << QRect(15, 15, 51, 51)
       
  2143                              << QBrush(Qt::NoBrush)
       
  2144                              << QPen(Qt::black);
       
  2145     QTest::newRow("cubic 3") << QSize(100, 100) << path
       
  2146                              << QRect(15, 15, 51, 51)
       
  2147                              << QBrush(QColor(Qt::blue))
       
  2148                              << QPen(Qt::NoPen);
       
  2149     QTest::newRow("cubic 4") << QSize(100, 100) << path
       
  2150                              << QRect(15, 15, 51, 51)
       
  2151                              << QBrush(gradient)
       
  2152                              << pen2;
       
  2153 }
       
  2154 
       
  2155 void tst_QPainter::clippedFillPath()
       
  2156 {
       
  2157     QFETCH(QSize, imageSize);
       
  2158     QFETCH(QPainterPath, path);
       
  2159     QFETCH(QRect, clipRect);
       
  2160     QPainterPath clipPath;
       
  2161     clipPath.addRect(clipRect);
       
  2162     QFETCH(QBrush, brush);
       
  2163     QFETCH(QPen, pen);
       
  2164 
       
  2165     const int width = imageSize.width();
       
  2166     const int height = imageSize.height();
       
  2167 
       
  2168     QImage clippedRect(width, height, QImage::Format_ARGB32_Premultiplied);
       
  2169     clippedRect.fill(0x12345678);
       
  2170     {
       
  2171         QPainter painter(&clippedRect);
       
  2172         painter.setPen(pen);
       
  2173         painter.setBrush(brush);
       
  2174         painter.setClipRect(clipRect);
       
  2175         painter.drawPath(path);
       
  2176     }
       
  2177 
       
  2178     QImage clippedPath(width, height, QImage::Format_ARGB32_Premultiplied);
       
  2179     clippedPath.fill(0x12345678);
       
  2180     {
       
  2181         QPainter painter(&clippedPath);
       
  2182         painter.setPen(pen);
       
  2183         painter.setBrush(brush);
       
  2184         painter.setClipPath(clipPath);
       
  2185         painter.drawPath(path);
       
  2186     }
       
  2187 
       
  2188 #if 0
       
  2189     if (clippedRect != clippedPath) {
       
  2190         clippedRect.save(QString("clippedRect.png"), "PNG");
       
  2191         clippedPath.save(QString("clippedPath.png"), "PNG");
       
  2192     }
       
  2193 #endif
       
  2194     QCOMPARE(clippedRect, clippedPath);
       
  2195 
       
  2196     // repeat with antialiasing
       
  2197 
       
  2198     clippedRect.fill(0x12345678);
       
  2199     {
       
  2200         QPainter painter(&clippedRect);
       
  2201         painter.setRenderHint(QPainter::Antialiasing);
       
  2202         painter.setPen(pen);
       
  2203         painter.setBrush(brush);
       
  2204         painter.setClipRect(clipRect);
       
  2205         painter.drawPath(path);
       
  2206     }
       
  2207 
       
  2208     clippedPath.fill(0x12345678);
       
  2209     {
       
  2210         QPainter painter(&clippedPath);
       
  2211         painter.setRenderHint(QPainter::Antialiasing);
       
  2212         painter.setPen(pen);
       
  2213         painter.setBrush(brush);
       
  2214         painter.setClipPath(clipPath);
       
  2215         painter.drawPath(path);
       
  2216     }
       
  2217 
       
  2218 #if 1
       
  2219     if (clippedRect != clippedPath) {
       
  2220         clippedRect.save(QString("clippedRect.png"), "PNG");
       
  2221         clippedPath.save(QString("clippedPath.png"), "PNG");
       
  2222     }
       
  2223 #endif
       
  2224     QCOMPARE(clippedRect, clippedPath);
       
  2225 
       
  2226 }
       
  2227 
       
  2228 void tst_QPainter::clippedLines_data()
       
  2229 {
       
  2230     QTest::addColumn<QSize>("imageSize");
       
  2231     QTest::addColumn<QLineF>("line");
       
  2232     QTest::addColumn<QRect>("clipRect");
       
  2233     QTest::addColumn<QPen>("pen");
       
  2234 
       
  2235     QPen pen2(QColor(223, 223, 0, 223));
       
  2236     pen2.setWidth(2);
       
  2237 
       
  2238     QVector<QLineF> lines;
       
  2239     lines << QLineF(15, 15, 65, 65)
       
  2240           << QLineF(14, 14, 66, 66)
       
  2241           << QLineF(16, 16, 64, 64)
       
  2242           << QLineF(65, 65, 15, 15)
       
  2243           << QLineF(66, 66, 14, 14)
       
  2244           << QLineF(64, 64, 14, 14)
       
  2245           << QLineF(15, 50, 15, 64)
       
  2246           << QLineF(15, 50, 15, 65)
       
  2247           << QLineF(15, 50, 15, 66)
       
  2248           << QLineF(15, 50, 64, 50)
       
  2249           << QLineF(15, 50, 65, 50)
       
  2250           << QLineF(15, 50, 66, 50);
       
  2251 
       
  2252     foreach (QLineF line, lines) {
       
  2253         QString desc = QString("line (%1, %2, %3, %4) %5").arg(line.x1())
       
  2254                        .arg(line.y1()).arg(line.x2()).arg(line.y2());
       
  2255         QTest::newRow(qPrintable(desc.arg(0))) << QSize(100, 100) << line
       
  2256                                    << QRect(15, 15, 49, 49)
       
  2257                                    << QPen(Qt::black);
       
  2258         QTest::newRow(qPrintable(desc.arg(1))) << QSize(100, 100) << line
       
  2259                                    << QRect(15, 15, 50, 50)
       
  2260                                    << QPen(Qt::black);
       
  2261         QTest::newRow(qPrintable(desc.arg(2))) << QSize(100, 100) << line
       
  2262                                    << QRect(15, 15, 51, 51)
       
  2263                                    << QPen(Qt::black);
       
  2264         QTest::newRow(qPrintable(desc.arg(3))) << QSize(100, 100) << line
       
  2265                                    << QRect(15, 15, 51, 51)
       
  2266                                    << QPen(Qt::NoPen);
       
  2267         QTest::newRow(qPrintable(desc.arg(4))) << QSize(100, 100) << line
       
  2268                                    << QRect(15, 15, 51, 51)
       
  2269                                    << pen2;
       
  2270     }
       
  2271 }
       
  2272 
       
  2273 void tst_QPainter::clippedLines()
       
  2274 {
       
  2275     QFETCH(QSize, imageSize);
       
  2276     QFETCH(QLineF, line);
       
  2277     QFETCH(QRect, clipRect);
       
  2278     QPainterPath clipPath;
       
  2279     clipPath.addRect(clipRect);
       
  2280     QFETCH(QPen, pen);
       
  2281 
       
  2282     const int width = imageSize.width();
       
  2283     const int height = imageSize.height();
       
  2284 
       
  2285     QImage clippedRect(width, height, QImage::Format_ARGB32_Premultiplied);
       
  2286     clippedRect.fill(0x12345678);
       
  2287     {
       
  2288         QPainter painter(&clippedRect);
       
  2289         painter.setPen(pen);
       
  2290         painter.setClipRect(clipRect);
       
  2291         painter.drawLine(line);
       
  2292         painter.drawLine(line.toLine());
       
  2293     }
       
  2294 
       
  2295     QImage clippedPath(width, height, QImage::Format_ARGB32_Premultiplied);
       
  2296     clippedPath.fill(0x12345678);
       
  2297     {
       
  2298         QPainter painter(&clippedPath);
       
  2299         painter.setPen(pen);
       
  2300         painter.setClipPath(clipPath);
       
  2301         painter.drawLine(line);
       
  2302         painter.drawLine(line.toLine());
       
  2303     }
       
  2304 
       
  2305 #if 0
       
  2306     if (clippedRect != clippedPath) {
       
  2307         clippedRect.save(QString("clippedRect.png"), "PNG");
       
  2308         clippedPath.save(QString("clippedPath.png"), "PNG");
       
  2309     }
       
  2310 #endif
       
  2311     QCOMPARE(clippedRect, clippedPath);
       
  2312 
       
  2313     // repeat with antialiasing
       
  2314     clippedRect.fill(0x12345678);
       
  2315     {
       
  2316         QPainter painter(&clippedRect);
       
  2317         painter.setRenderHint(QPainter::Antialiasing);
       
  2318         painter.setPen(pen);
       
  2319         painter.setClipRect(clipRect);
       
  2320         painter.drawLine(line);
       
  2321         painter.drawLine(line.toLine());
       
  2322     }
       
  2323 
       
  2324     clippedPath.fill(0x12345678);
       
  2325     {
       
  2326         QPainter painter(&clippedPath);
       
  2327         painter.setRenderHint(QPainter::Antialiasing);
       
  2328         painter.setPen(pen);
       
  2329         painter.setClipPath(clipPath);
       
  2330         painter.drawLine(line);
       
  2331         painter.drawLine(line.toLine());
       
  2332     }
       
  2333 
       
  2334 #if 0
       
  2335     if (clippedRect != clippedPath) {
       
  2336         clippedRect.save(QString("clippedRect.png"), "PNG");
       
  2337         clippedPath.save(QString("clippedPath.png"), "PNG");
       
  2338     }
       
  2339 #endif
       
  2340     QCOMPARE(clippedRect, clippedPath);
       
  2341 }
       
  2342 
       
  2343 void tst_QPainter::clippedPolygon_data()
       
  2344 {
       
  2345     clippedFillPath_data();
       
  2346 };
       
  2347 
       
  2348 void tst_QPainter::clippedPolygon()
       
  2349 {
       
  2350     QFETCH(QSize, imageSize);
       
  2351     QFETCH(QPainterPath, path);
       
  2352     QPolygonF polygon = path.toFillPolygon();
       
  2353     QFETCH(QRect, clipRect);
       
  2354     QPainterPath clipPath;
       
  2355     clipPath.addRect(clipRect);
       
  2356     QFETCH(QPen, pen);
       
  2357     QFETCH(QBrush, brush);
       
  2358 
       
  2359     const int width = imageSize.width();
       
  2360     const int height = imageSize.height();
       
  2361 
       
  2362     QImage clippedRect(width, height, QImage::Format_ARGB32_Premultiplied);
       
  2363     clippedRect.fill(0x12345678);
       
  2364     {
       
  2365         QPainter painter(&clippedRect);
       
  2366         painter.setPen(pen);
       
  2367         painter.setBrush(brush);
       
  2368         painter.setClipRect(clipRect);
       
  2369         painter.drawPolygon(polygon);
       
  2370         painter.drawPolygon(polygon.toPolygon());
       
  2371     }
       
  2372 
       
  2373     QImage clippedPath(width, height, QImage::Format_ARGB32_Premultiplied);
       
  2374     clippedPath.fill(0x12345678);
       
  2375     {
       
  2376         QPainter painter(&clippedPath);
       
  2377         painter.setPen(pen);
       
  2378         painter.setBrush(brush);
       
  2379         painter.setClipRect(clipRect);
       
  2380         painter.drawPolygon(polygon);
       
  2381         painter.drawPolygon(polygon.toPolygon());
       
  2382     }
       
  2383 
       
  2384 #if 0
       
  2385     if (clippedRect != clippedPath) {
       
  2386         clippedRect.save(QString("clippedRect.png"), "PNG");
       
  2387         clippedPath.save(QString("clippedPath.png"), "PNG");
       
  2388     }
       
  2389 #endif
       
  2390     QCOMPARE(clippedRect, clippedPath);
       
  2391 
       
  2392     // repeat with antialiasing
       
  2393 
       
  2394     clippedRect.fill(0x12345678);
       
  2395     {
       
  2396         QPainter painter(&clippedRect);
       
  2397         painter.setRenderHint(QPainter::Antialiasing);
       
  2398         painter.setPen(pen);
       
  2399         painter.setBrush(brush);
       
  2400         painter.setClipRect(clipRect);
       
  2401         painter.drawPolygon(polygon);
       
  2402         painter.drawPolygon(polygon.toPolygon());
       
  2403     }
       
  2404 
       
  2405     clippedPath.fill(0x12345678);
       
  2406     {
       
  2407         QPainter painter(&clippedPath);
       
  2408         painter.setRenderHint(QPainter::Antialiasing);
       
  2409         painter.setPen(pen);
       
  2410         painter.setBrush(brush);
       
  2411         painter.setClipRect(clipRect);
       
  2412         painter.drawPolygon(polygon);
       
  2413         painter.drawPolygon(polygon.toPolygon());
       
  2414     }
       
  2415 
       
  2416 #if 0
       
  2417     if (clippedRect != clippedPath) {
       
  2418         clippedRect.save(QString("clippedRect.png"), "PNG");
       
  2419         clippedPath.save(QString("clippedPath.png"), "PNG");
       
  2420     }
       
  2421 #endif
       
  2422     QCOMPARE(clippedRect, clippedPath);
       
  2423 }
       
  2424 
       
  2425 // this just draws some text that should be clipped in the raster
       
  2426 // paint engine.
       
  2427 void tst_QPainter::clippedText()
       
  2428 {
       
  2429     for (char ch = 'A'; ch < 'Z'; ++ch) {
       
  2430         //qDebug() << ch;
       
  2431         QFont f;
       
  2432         f.setPixelSize(24);
       
  2433         QFontMetrics metrics(f);
       
  2434         QRect textRect = metrics.boundingRect(QChar(ch));
       
  2435 
       
  2436         if (textRect.width() <= 8)
       
  2437             continue;
       
  2438         if (textRect.height() <= 8)
       
  2439             continue;
       
  2440 
       
  2441         QRect imageRect = textRect.adjusted(4, 4, -4, -4);
       
  2442 
       
  2443         QImage image(imageRect.size(), QImage::Format_ARGB32_Premultiplied);
       
  2444 
       
  2445         image.fill(qRgba(255, 255, 255, 255));
       
  2446         {
       
  2447             QPainter painter(&image);
       
  2448             painter.setFont(f);
       
  2449             painter.setPen(Qt::black);
       
  2450 
       
  2451             painter.drawText(0, 0, QChar(ch));
       
  2452         }
       
  2453 
       
  2454         image.fill(qRgba(255, 255, 255, 255));
       
  2455         {
       
  2456             QPainter painter(&image);
       
  2457             painter.setFont(f);
       
  2458             painter.setPen(Qt::black);
       
  2459 
       
  2460             painter.drawText(-imageRect.topLeft(), QChar(ch));
       
  2461         }
       
  2462 
       
  2463         bool foundPixel = false;
       
  2464         for (int x = 0; x < image.width(); ++x)
       
  2465             for (int y = 0; y < image.height(); ++y)
       
  2466                 if (image.pixel(x, y) != 0)
       
  2467                     foundPixel = true;
       
  2468         // can't QVERIFY(foundPixel) as sometimes all pixels are clipped
       
  2469         // away. For example for 'O'
       
  2470         // just call /some/ function to prevent the compiler from optimizing
       
  2471         // foundPixel away
       
  2472         QString::number(foundPixel);
       
  2473 
       
  2474         //image.save(QString("debug") + ch + ".xpm");
       
  2475     }
       
  2476 
       
  2477     QVERIFY(true); // reached, don't trigger any valgrind errors
       
  2478 }
       
  2479 
       
  2480 void tst_QPainter::setOpacity_data()
       
  2481 {
       
  2482     QTest::addColumn<QImage::Format>("destFormat");
       
  2483     QTest::addColumn<QImage::Format>("srcFormat");
       
  2484 
       
  2485     QTest::newRow("ARGB32P on ARGB32P") << QImage::Format_ARGB32_Premultiplied
       
  2486                                         << QImage::Format_ARGB32_Premultiplied;
       
  2487 
       
  2488     QTest::newRow("ARGB32 on ARGB32") << QImage::Format_ARGB32
       
  2489                                       << QImage::Format_ARGB32;
       
  2490 
       
  2491     QTest::newRow("RGB32 on RGB32") << QImage::Format_RGB32
       
  2492                                     << QImage::Format_RGB32;
       
  2493 
       
  2494     QTest::newRow("RGB16 on RGB16") << QImage::Format_RGB16
       
  2495                                     << QImage::Format_RGB16;
       
  2496 
       
  2497     QTest::newRow("ARGB8565_Premultiplied on ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied
       
  2498                                                                       << QImage::Format_ARGB8565_Premultiplied;
       
  2499 
       
  2500     QTest::newRow("RGB555 on RGB555") << QImage::Format_RGB555
       
  2501                                       << QImage::Format_RGB555;
       
  2502 
       
  2503     QTest::newRow("RGB666 on RGB666") << QImage::Format_RGB666
       
  2504                                       << QImage::Format_RGB666;
       
  2505 
       
  2506     QTest::newRow("ARGB8555_Premultiplied on ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied
       
  2507                                                                       << QImage::Format_ARGB8555_Premultiplied;
       
  2508 
       
  2509     QTest::newRow("RGB888 on RGB888") << QImage::Format_RGB888
       
  2510                                       << QImage::Format_RGB888;
       
  2511 
       
  2512     QTest::newRow("RGB32 on RGB16") << QImage::Format_RGB16
       
  2513                                     << QImage::Format_RGB32;
       
  2514 
       
  2515     QTest::newRow("RGB32 on ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied
       
  2516                                                      << QImage::Format_RGB32;
       
  2517 
       
  2518     QTest::newRow("RGB32 on RGB666") << QImage::Format_RGB666
       
  2519                                      << QImage::Format_RGB32;
       
  2520 
       
  2521     QTest::newRow("RGB32 on RGB555") << QImage::Format_RGB555
       
  2522                                      << QImage::Format_RGB32;
       
  2523 
       
  2524     QTest::newRow("RGB32 on ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied
       
  2525                                                      << QImage::Format_RGB32;
       
  2526 
       
  2527     QTest::newRow("RGB32 on RGB888") << QImage::Format_RGB888
       
  2528                                      << QImage::Format_RGB32;
       
  2529 
       
  2530     QTest::newRow("RGB16 on RGB32") << QImage::Format_RGB32
       
  2531                                     << QImage::Format_RGB16;
       
  2532 
       
  2533     QTest::newRow("ARGB8565_Premultiplied on RGB32") << QImage::Format_RGB32
       
  2534                                                      << QImage::Format_ARGB8565_Premultiplied;
       
  2535 
       
  2536     QTest::newRow("RGB666 on RGB32") << QImage::Format_RGB32
       
  2537                                      << QImage::Format_RGB666;
       
  2538 
       
  2539     QTest::newRow("RGB555 on RGB32") << QImage::Format_RGB32
       
  2540                                      << QImage::Format_RGB555;
       
  2541 
       
  2542     QTest::newRow("ARGB8555_Premultiplied on RGB32") << QImage::Format_RGB32
       
  2543                                                      << QImage::Format_ARGB8555_Premultiplied;
       
  2544 
       
  2545     QTest::newRow("RGB888 on RGB32") << QImage::Format_RGB32
       
  2546                                      << QImage::Format_RGB888;
       
  2547 
       
  2548     QTest::newRow("RGB555 on RGB888") << QImage::Format_RGB888
       
  2549                                       << QImage::Format_RGB555;
       
  2550 
       
  2551     QTest::newRow("RGB666 on RGB888") << QImage::Format_RGB888
       
  2552                                       << QImage::Format_RGB666;
       
  2553 
       
  2554     QTest::newRow("RGB444 on RGB444") << QImage::Format_RGB444
       
  2555                                       << QImage::Format_RGB444;
       
  2556 }
       
  2557 
       
  2558 void tst_QPainter::setOpacity()
       
  2559 {
       
  2560     QFETCH(QImage::Format, destFormat);
       
  2561     QFETCH(QImage::Format, srcFormat);
       
  2562 
       
  2563     const QSize imageSize(12, 12);
       
  2564     const QRect imageRect(QPoint(0, 0), imageSize);
       
  2565     QColor destColor = Qt::black;
       
  2566     QColor srcColor = Qt::white;
       
  2567 
       
  2568     QImage dest(imageSize, destFormat);
       
  2569     QImage src(imageSize, srcFormat);
       
  2570 
       
  2571     QPainter p;
       
  2572     p.begin(&dest);
       
  2573     p.fillRect(imageRect, destColor);
       
  2574     p.end();
       
  2575 
       
  2576     p.begin(&src);
       
  2577     p.fillRect(imageRect, srcColor);
       
  2578     p.end();
       
  2579 
       
  2580     p.begin(&dest);
       
  2581     p.setOpacity(0.5);
       
  2582     p.drawImage(imageRect, src, imageRect);
       
  2583     p.end();
       
  2584 
       
  2585     QImage expected(imageSize, destFormat);
       
  2586     p.begin(&expected);
       
  2587     p.fillRect(imageRect, QColor(127, 127, 127));
       
  2588     p.end();
       
  2589 
       
  2590     QCOMPARE(dest, expected);
       
  2591 }
       
  2592 
       
  2593 void tst_QPainter::drawhelper_blend_untransformed_data()
       
  2594 {
       
  2595     setOpacity_data();
       
  2596 }
       
  2597 
       
  2598 void tst_QPainter::drawhelper_blend_untransformed()
       
  2599 {
       
  2600     QFETCH(QImage::Format, destFormat);
       
  2601     QFETCH(QImage::Format, srcFormat);
       
  2602 
       
  2603     const int size = 128;
       
  2604     const QSize imageSize(size, size);
       
  2605     const QRect paintRect(1, 0, size - 2, size); // needs alignment and tailing
       
  2606 
       
  2607     QColor destColor(127, 127, 127);
       
  2608     QColor srcColor(Qt::white);
       
  2609 
       
  2610     QImage dest(imageSize, destFormat);
       
  2611     QImage src(imageSize, srcFormat);
       
  2612 
       
  2613     QPainter p;
       
  2614     p.begin(&src);
       
  2615     p.fillRect(paintRect, srcColor);
       
  2616     p.end();
       
  2617 
       
  2618     QList<qreal> opacities = (QList<qreal>() << 0.0 << 0.1  << 0.01 << 0.4
       
  2619                               << 0.5 << 0.6 << 0.9 << 1.0);
       
  2620     foreach (qreal opacity, opacities) {
       
  2621         p.begin(&dest);
       
  2622         p.fillRect(paintRect, destColor);
       
  2623 
       
  2624         p.setOpacity(opacity);
       
  2625         p.drawImage(paintRect, src, paintRect);
       
  2626         p.end();
       
  2627 
       
  2628         // sanity check: make sure all pixels are equal
       
  2629         QImage expected(size - 2, size, destFormat);
       
  2630         p.begin(&expected);
       
  2631         p.fillRect(0, 0, expected.width(), expected.height(),
       
  2632                    QColor(dest.pixel(1, 0)));
       
  2633         p.end();
       
  2634 
       
  2635         const QImage subDest(dest.bits() + dest.depth() / 8,
       
  2636                              dest.width() - 2, dest.height(),
       
  2637                              dest.bytesPerLine(), dest.format());
       
  2638 
       
  2639         if (dest.format() == QImage::Format_ARGB8565_Premultiplied ||
       
  2640             dest.format() == QImage::Format_ARGB8555_Premultiplied) {
       
  2641             // Test skipped due to rounding errors...
       
  2642             continue;
       
  2643         }
       
  2644 #if 0
       
  2645         if (subDest != expected) {
       
  2646             qDebug() << "size" << size << "opacity" << opacity;
       
  2647             for (int j = 0; j < expected.height(); ++j) {
       
  2648                 for (int i = 0; i < expected.width(); ++i) {
       
  2649                     if (expected.pixel(i,j) != subDest.pixel(i,j))
       
  2650                         qDebug() << i << j << hex << expected.pixel(i, j)
       
  2651                                  << subDest.pixel(i, j);
       
  2652                 }
       
  2653             }
       
  2654         }
       
  2655 #endif
       
  2656         QCOMPARE(subDest, expected);
       
  2657     }
       
  2658 }
       
  2659 
       
  2660 void tst_QPainter::drawhelper_blend_tiled_untransformed_data()
       
  2661 {
       
  2662     setOpacity_data();
       
  2663 }
       
  2664 
       
  2665 void tst_QPainter::drawhelper_blend_tiled_untransformed()
       
  2666 {
       
  2667     QFETCH(QImage::Format, destFormat);
       
  2668     QFETCH(QImage::Format, srcFormat);
       
  2669 
       
  2670     const int size = 128;
       
  2671     const QSize imageSize(size, size);
       
  2672     const QRect paintRect(1, 0, size - 2, size); // needs alignment and tailing
       
  2673 
       
  2674     QColor destColor(127, 127, 127);
       
  2675     QColor srcColor(Qt::white);
       
  2676 
       
  2677     QImage dest(imageSize, destFormat);
       
  2678     QImage src(imageSize / 2, srcFormat);
       
  2679 
       
  2680     QPainter p;
       
  2681     p.begin(&src);
       
  2682     p.fillRect(QRect(QPoint(0, 0), imageSize/ 2), srcColor);
       
  2683     p.end();
       
  2684 
       
  2685     const QBrush brush(src);
       
  2686 
       
  2687     QList<qreal> opacities = (QList<qreal>() << 0.0 << 0.1  << 0.01 << 0.4
       
  2688                               << 0.5 << 0.6 << 0.9 << 1.0);
       
  2689     foreach (qreal opacity, opacities) {
       
  2690         p.begin(&dest);
       
  2691         p.fillRect(paintRect, destColor);
       
  2692 
       
  2693         p.setOpacity(opacity);
       
  2694         p.fillRect(paintRect, brush);
       
  2695         p.end();
       
  2696 
       
  2697         // sanity check: make sure all pixels are equal
       
  2698         QImage expected(size - 2, size, destFormat);
       
  2699         p.begin(&expected);
       
  2700         p.fillRect(0, 0, expected.width(), expected.height(),
       
  2701                    QColor(dest.pixel(1, 0)));
       
  2702         p.end();
       
  2703 
       
  2704         const QImage subDest(dest.bits() + dest.depth() / 8,
       
  2705                              dest.width() - 2, dest.height(),
       
  2706                              dest.bytesPerLine(), dest.format());
       
  2707 
       
  2708         if (dest.format() == QImage::Format_ARGB8565_Premultiplied ||
       
  2709             dest.format() == QImage::Format_ARGB8555_Premultiplied) {
       
  2710             // Skipping test due to rounding errors. Test needs rewrite
       
  2711             continue;
       
  2712         }
       
  2713 #if 0
       
  2714         if (subDest != expected) {
       
  2715             qDebug() << "size" << size << "opacity" << opacity;
       
  2716             for (int j = 0; j < expected.height(); ++j) {
       
  2717                 for (int i = 0; i < expected.width(); ++i) {
       
  2718                     if (expected.pixel(i,j) != subDest.pixel(i,j))
       
  2719                         qDebug() << i << j << hex << expected.pixel(i, j)
       
  2720                                  << subDest.pixel(i, j);
       
  2721                 }
       
  2722             }
       
  2723         }
       
  2724 #endif
       
  2725         QCOMPARE(subDest, expected);
       
  2726     }
       
  2727 }
       
  2728 
       
  2729 static QPaintEngine::PaintEngineFeatures no_porter_duff()
       
  2730 {
       
  2731     QPaintEngine::PaintEngineFeatures features = QPaintEngine::AllFeatures;
       
  2732     return features & ~QPaintEngine::PorterDuff;
       
  2733 }
       
  2734 
       
  2735 class DummyPaintEngine : public QPaintEngine, public QPaintDevice
       
  2736 {
       
  2737 public:
       
  2738     DummyPaintEngine() : QPaintEngine(no_porter_duff()) {}
       
  2739     virtual bool begin(QPaintDevice *) { return true; }
       
  2740     virtual bool end() { return true; }
       
  2741 
       
  2742     virtual void updateState(const QPaintEngineState &) {}
       
  2743     virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) {}
       
  2744 
       
  2745     virtual Type type() const { return User; }
       
  2746 
       
  2747     virtual QPaintEngine *paintEngine() const { return (QPaintEngine *)this; }
       
  2748 
       
  2749     virtual int metric(PaintDeviceMetric metric) const { Q_UNUSED(metric); return 0; };
       
  2750 };
       
  2751 
       
  2752 static bool success;
       
  2753 
       
  2754 void porterDuff_warningChecker(QtMsgType type, const char *msg)
       
  2755 {
       
  2756     if (type == QtWarningMsg && msg == QLatin1String("QPainter::setCompositionMode: PorterDuff modes not supported on device"))
       
  2757         success = false;
       
  2758 }
       
  2759 
       
  2760 void tst_QPainter::porterDuff_warning()
       
  2761 {
       
  2762     QtMsgHandler old = qInstallMsgHandler(porterDuff_warningChecker);
       
  2763     DummyPaintEngine dummy;
       
  2764     QPainter p(&dummy);
       
  2765 
       
  2766     success = true;
       
  2767     p.setCompositionMode(QPainter::CompositionMode_Source);
       
  2768     QVERIFY(success);
       
  2769 
       
  2770     success = true;
       
  2771     p.setCompositionMode(QPainter::CompositionMode_SourceOver);
       
  2772     QVERIFY(success);
       
  2773 
       
  2774     success = true;
       
  2775     p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
       
  2776     QVERIFY(!success);
       
  2777 
       
  2778     QVERIFY(qInstallMsgHandler(old) == porterDuff_warningChecker);
       
  2779 }
       
  2780 
       
  2781 class quint24
       
  2782 {
       
  2783 public:
       
  2784     inline quint24(quint32 v)
       
  2785     {
       
  2786         data[0] = qBlue(v);
       
  2787         data[1] = qGreen(v);
       
  2788         data[2] = qRed(v);
       
  2789     }
       
  2790 
       
  2791     inline operator quint32 ()
       
  2792     {
       
  2793         return qRgb(data[2], data[1], data[0]);
       
  2794     }
       
  2795 
       
  2796     inline bool operator==(const quint24 &v) const {
       
  2797         return (data[0] == v.data[0] && data[1] == v.data[1] && data[2] == v.data[2]);
       
  2798     }
       
  2799 
       
  2800     uchar data[3];
       
  2801 } Q_PACKED;
       
  2802 
       
  2803 void tst_QPainter::drawhelper_blend_color()
       
  2804 {
       
  2805     QImage dest(32, 32, QImage::Format_ARGB8555_Premultiplied);
       
  2806     dest.fill(0xff000000);
       
  2807 
       
  2808     {
       
  2809         QPainter p(&dest);
       
  2810         p.fillRect(0, 0, dest.width(), dest.height(), QColor(255, 0, 0, 127));
       
  2811     }
       
  2812 
       
  2813     QImage expected(32, 32, QImage::Format_ARGB8555_Premultiplied);
       
  2814     expected.fill(0xff3c007f);
       
  2815 
       
  2816     QCOMPARE(dest.pixel(1, 1), expected.pixel(1, 1));
       
  2817     QCOMPARE(dest, expected);
       
  2818 }
       
  2819 
       
  2820 class ViewportTestWidget : public QWidget
       
  2821 {
       
  2822 public:
       
  2823     ViewportTestWidget(QWidget *parent = 0) : QWidget(parent), hasPainted(false) {}
       
  2824     QSize sizeHint() const {
       
  2825         return QSize(100, 100);
       
  2826     }
       
  2827 
       
  2828     QRect viewport;
       
  2829     bool hasPainted;
       
  2830 
       
  2831 protected:
       
  2832     void paintEvent(QPaintEvent *) {
       
  2833         hasPainted = true;
       
  2834         QPainter p(this);
       
  2835         viewport = p.viewport();
       
  2836     }
       
  2837 };
       
  2838 
       
  2839 void tst_QPainter::childWidgetViewport()
       
  2840 {
       
  2841     QWidget parent;
       
  2842     parent.setAutoFillBackground(true);
       
  2843     parent.resize(200, 200);
       
  2844     ViewportTestWidget child(&parent);
       
  2845     child.setAutoFillBackground(true);
       
  2846     parent.show();
       
  2847     parent.update();
       
  2848     qApp->processEvents();
       
  2849 
       
  2850     if (child.hasPainted) {
       
  2851         QCOMPARE(child.viewport, QRect(QPoint(0, 0), child.sizeHint()));
       
  2852     } else {
       
  2853         qWarning("Failed to ensure that paintEvent has been run. Could not run test.");
       
  2854     }
       
  2855 }
       
  2856 
       
  2857 void tst_QPainter::fillRect_objectBoundingModeGradient()
       
  2858 {
       
  2859     QImage a(10, 10, QImage::Format_ARGB32_Premultiplied);
       
  2860     a.fill(0x0);
       
  2861     QImage b = a;
       
  2862 
       
  2863     QLinearGradient g(QPoint(0, 0), QPoint(0, 1));
       
  2864     g.setColorAt(0, Qt::red);
       
  2865     g.setColorAt(1, Qt::blue);
       
  2866     g.setCoordinateMode(QGradient::ObjectBoundingMode);
       
  2867 
       
  2868     QPainter p(&a);
       
  2869     p.fillRect(QRect(0, 0, a.width(), a.height()), g);
       
  2870     p.end();
       
  2871 
       
  2872     QPainterPath path;
       
  2873     path.addRect(0, 0, a.width(), a.height());
       
  2874 
       
  2875     p.begin(&b);
       
  2876     p.fillPath(path, g);
       
  2877     p.end();
       
  2878 
       
  2879     QCOMPARE(a, b);
       
  2880 }
       
  2881 
       
  2882 void tst_QPainter::fillRect_stretchToDeviceMode()
       
  2883 {
       
  2884     QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
       
  2885 
       
  2886     QLinearGradient g(QPoint(0, 0), QPoint(0, 1));
       
  2887     g.setCoordinateMode(QGradient::StretchToDeviceMode);
       
  2888 
       
  2889     QPainter p(&img);
       
  2890     p.fillRect(img.rect(), g);
       
  2891     p.end();
       
  2892 
       
  2893     for (int i = 1; i < img.height(); ++i)
       
  2894         QVERIFY(img.pixel(0, i) != img.pixel(0, i-1));
       
  2895 }
       
  2896 
       
  2897 void tst_QPainter::monoImages()
       
  2898 {
       
  2899     Qt::GlobalColor colorPairs[][2] = {
       
  2900         { Qt::white, Qt::black },
       
  2901         { Qt::color0, Qt::color1 },
       
  2902         { Qt::red, Qt::blue }
       
  2903     };
       
  2904 
       
  2905     const int numColorPairs = sizeof(colorPairs) / sizeof(QRgb[2]);
       
  2906 
       
  2907     QImage transparent(2, 2, QImage::Format_ARGB32_Premultiplied);
       
  2908     transparent.fill(0x0);
       
  2909 
       
  2910     for (int i = 1; i < QImage::NImageFormats; ++i) {
       
  2911         for (int j = 0; j < numColorPairs; ++j) {
       
  2912             const QImage::Format format = QImage::Format(i);
       
  2913             if (format == QImage::Format_Indexed8)
       
  2914                 continue;
       
  2915 
       
  2916             QImage img(2, 2, format);
       
  2917 
       
  2918             if (img.numColors() > 0) {
       
  2919                 img.setColor(0, QColor(colorPairs[j][0]).rgba());
       
  2920                 img.setColor(1, QColor(colorPairs[j][1]).rgba());
       
  2921             }
       
  2922 
       
  2923             img.fill(0x0);
       
  2924             QPainter p(&img);
       
  2925             p.fillRect(0, 0, 2, 2, colorPairs[j][0]);
       
  2926             p.fillRect(0, 0, 1, 1, colorPairs[j][1]);
       
  2927             p.fillRect(1, 1, 1, 1, colorPairs[j][1]);
       
  2928             p.end();
       
  2929 
       
  2930             QImage original = img;
       
  2931 
       
  2932             p.begin(&img);
       
  2933             p.drawImage(0, 0, transparent);
       
  2934             p.end();
       
  2935 
       
  2936             // drawing a transparent image on top of another image
       
  2937             // should not change the image
       
  2938             QCOMPARE(original, img);
       
  2939 
       
  2940             if (img.numColors() == 0)
       
  2941                 continue;
       
  2942 
       
  2943             for (int k = 0; k < 2; ++k) {
       
  2944                 QPainter p(&img);
       
  2945                 p.fillRect(0, 0, 2, 2, colorPairs[j][k]);
       
  2946                 p.end();
       
  2947 
       
  2948                 QImage argb32p(2, 2, QImage::Format_ARGB32_Premultiplied);
       
  2949                 p.begin(&argb32p);
       
  2950                 p.fillRect(0, 0, 2, 2, colorPairs[j][k]);
       
  2951                 p.end();
       
  2952 
       
  2953                 QCOMPARE(argb32p, img.convertToFormat(argb32p.format()));
       
  2954 
       
  2955                 // drawing argb32p image on mono image
       
  2956                 p.begin(&img);
       
  2957                 p.drawImage(0, 0, argb32p);
       
  2958                 p.end();
       
  2959 
       
  2960                 QCOMPARE(argb32p, img.convertToFormat(argb32p.format()));
       
  2961 
       
  2962                 // drawing mono image on argb32p image
       
  2963                 p.begin(&argb32p);
       
  2964                 p.drawImage(0, 0, img);
       
  2965                 p.end();
       
  2966 
       
  2967                 QCOMPARE(argb32p, img.convertToFormat(argb32p.format()));
       
  2968             }
       
  2969         }
       
  2970     }
       
  2971 }
       
  2972 
       
  2973 #if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_CC_MSVC) && !defined(Q_OS_SOLARIS) && !defined(Q_OS_SYMBIAN)
       
  2974 #include <fenv.h>
       
  2975 
       
  2976 static const QString fpeExceptionString(int exception)
       
  2977 {
       
  2978 #ifdef FE_INEXACT
       
  2979     if (exception & FE_INEXACT)
       
  2980         return QLatin1String("Inexact result");
       
  2981 #endif
       
  2982     if (exception & FE_UNDERFLOW)
       
  2983         return QLatin1String("Underflow");
       
  2984     if (exception & FE_OVERFLOW)
       
  2985         return QLatin1String("Overflow");
       
  2986     if (exception & FE_DIVBYZERO)
       
  2987         return QLatin1String("Divide by zero");
       
  2988     if (exception & FE_INVALID)
       
  2989         return QLatin1String("Invalid operation");
       
  2990     return QLatin1String("No exception");
       
  2991 }
       
  2992 
       
  2993 class FpExceptionChecker
       
  2994 {
       
  2995 public:
       
  2996     FpExceptionChecker(int exceptionMask)
       
  2997         : m_exceptionMask(exceptionMask)
       
  2998     {
       
  2999         feclearexcept(m_exceptionMask);
       
  3000     }
       
  3001 
       
  3002     ~FpExceptionChecker()
       
  3003     {
       
  3004         const int exceptions = fetestexcept(m_exceptionMask);
       
  3005         QVERIFY2(!exceptions, qPrintable(QLatin1String("Floating point exception: ") + fpeExceptionString(exceptions)));
       
  3006     }
       
  3007 
       
  3008 private:
       
  3009     int m_exceptionMask;
       
  3010 };
       
  3011 
       
  3012 void fpe_rasterizeLine_task232012()
       
  3013 {
       
  3014     FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
       
  3015     QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
       
  3016     img.fill(0x0);
       
  3017     QPainter p(&img);
       
  3018 
       
  3019     p.setBrush(Qt::black);
       
  3020     p.drawRect(QRectF(0, 0, 5, 0));
       
  3021     p.drawRect(QRectF(0, 0, 0, 5));
       
  3022 }
       
  3023 
       
  3024 void fpe_pixmapTransform()
       
  3025 {
       
  3026     FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
       
  3027 
       
  3028     QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
       
  3029 
       
  3030     QPainter p(&img);
       
  3031 
       
  3032     const qreal scaleFactor = 0.001;
       
  3033     const int translateDistance = 1000000;
       
  3034 
       
  3035     p.setPen(Qt::red);
       
  3036     p.setBrush(QBrush(Qt::red,Qt::Dense6Pattern));
       
  3037 
       
  3038     for (int i = 0; i < 2; ++i) {
       
  3039         p.setRenderHint(QPainter::SmoothPixmapTransform, i);
       
  3040 
       
  3041         p.resetTransform();
       
  3042         p.scale(1.1, 1.1);
       
  3043         p.translate(translateDistance, 0);
       
  3044         p.drawRect(-translateDistance, 0, 100, 100);
       
  3045 
       
  3046         p.resetTransform();
       
  3047         p.scale(scaleFactor, scaleFactor);
       
  3048         p.drawRect(QRectF(0, 0, 1 / scaleFactor, 1 / scaleFactor));
       
  3049     }
       
  3050 }
       
  3051 
       
  3052 void fpe_zeroLengthLines()
       
  3053 {
       
  3054     FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
       
  3055 
       
  3056     QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
       
  3057 
       
  3058     QPainter p(&img);
       
  3059 
       
  3060     p.setPen(QPen(Qt::black, 3));
       
  3061     p.drawLine(64, 64, 64, 64);
       
  3062 }
       
  3063 
       
  3064 void fpe_divByZero()
       
  3065 {
       
  3066     FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
       
  3067 
       
  3068     QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
       
  3069 
       
  3070     QPainter p(&img);
       
  3071 
       
  3072     p.setRenderHint(QPainter::Antialiasing);
       
  3073 
       
  3074     p.drawRect(QRectF(10, 10, 100, 0));
       
  3075     p.drawRect(QRectF(10, 10, 0, 100));
       
  3076 
       
  3077     p.drawRect(QRect(10, 10, 100, 0));
       
  3078     p.drawRect(QRect(10, 10, 0, 100));
       
  3079 
       
  3080     p.fillRect(QRectF(10, 10, 100, 0), Qt::black);
       
  3081     p.fillRect(QRectF(10, 10, 0, 100), Qt::black);
       
  3082 
       
  3083     p.fillRect(QRect(10, 10, 100, 0), Qt::black);
       
  3084     p.fillRect(QRect(10, 10, 0, 100), Qt::black);
       
  3085 }
       
  3086 
       
  3087 void fpe_steepSlopes()
       
  3088 {
       
  3089     FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
       
  3090 
       
  3091     QImage img(1024, 1024, QImage::Format_ARGB32_Premultiplied);
       
  3092 
       
  3093     QFETCH(QTransform, transform);
       
  3094     QFETCH(QLineF, line);
       
  3095     QFETCH(bool, antialiased);
       
  3096 
       
  3097     QPainter p(&img);
       
  3098 
       
  3099     p.setPen(QPen(Qt::black, 1));
       
  3100     p.setRenderHint(QPainter::Antialiasing, antialiased);
       
  3101     p.setTransform(transform);
       
  3102 
       
  3103     QEXPECT_FAIL("steep line 3 aa", "needs to be fixed", Continue);
       
  3104     p.drawLine(line);
       
  3105 }
       
  3106 
       
  3107 void fpe_radialGradients()
       
  3108 {
       
  3109     FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
       
  3110 
       
  3111     QImage img(21, 21, QImage::Format_ARGB32_Premultiplied);
       
  3112     img.fill(0);
       
  3113 
       
  3114     double m = img.width() * 0.5;
       
  3115 
       
  3116     QPainter p(&img);
       
  3117     p.setRenderHints(QPainter::Antialiasing);
       
  3118     p.setPen(Qt::NoPen);
       
  3119     p.setBrush(QRadialGradient(m, m, m));
       
  3120     p.drawEllipse(img.rect());
       
  3121 }
       
  3122 
       
  3123 #define FPE_TEST(x) \
       
  3124 void tst_QPainter::x() \
       
  3125 { \
       
  3126     ::x(); \
       
  3127 }
       
  3128 #else
       
  3129 #define FPE_TEST(x) \
       
  3130 void tst_QPainter::x() \
       
  3131 { \
       
  3132     QSKIP("Floating point exception checking (fenv.h) not available", SkipAll); \
       
  3133 }
       
  3134 #endif
       
  3135 
       
  3136 FPE_TEST(fpe_rasterizeLine_task232012)
       
  3137 FPE_TEST(fpe_pixmapTransform)
       
  3138 FPE_TEST(fpe_zeroLengthLines)
       
  3139 FPE_TEST(fpe_divByZero)
       
  3140 FPE_TEST(fpe_steepSlopes)
       
  3141 FPE_TEST(fpe_radialGradients)
       
  3142 
       
  3143 void tst_QPainter::fpe_steepSlopes_data()
       
  3144 {
       
  3145     QTest::addColumn<QTransform>("transform");
       
  3146     QTest::addColumn<QLineF>("line");
       
  3147     QTest::addColumn<bool>("antialiased");
       
  3148 
       
  3149     {
       
  3150         const qreal dsin = 0.000014946676875461832484392500630665523431162000633776187896728515625;
       
  3151         const qreal dcos = 0.9999999998882984630910186751862056553363800048828125;
       
  3152 
       
  3153         const QTransform transform = QTransform(QMatrix(dcos, dsin, -dsin, dcos, 64, 64));
       
  3154         const QLineF line(2, 2, 2, 6);
       
  3155 
       
  3156         QTest::newRow("task 207147 aa") << transform << line << true;
       
  3157         QTest::newRow("task 207147 no aa") << transform << line << false;
       
  3158     }
       
  3159 
       
  3160     {
       
  3161         QTransform transform;
       
  3162         transform.rotate(0.0000001);
       
  3163         const QLineF line(5, 5, 10, 5);
       
  3164 
       
  3165         QTest::newRow("task 166702 aa") << transform << line << true;
       
  3166         QTest::newRow("task 166702 no aa") << transform << line << false;
       
  3167     }
       
  3168 
       
  3169     {
       
  3170         const QTransform transform;
       
  3171         const QLineF line(2.5, 2.5, 2.5 + 1/256., 60000.5);
       
  3172 
       
  3173         QTest::newRow("steep line aa") << transform << line << true;
       
  3174         QTest::newRow("steep line no aa") << transform << line << false;
       
  3175     }
       
  3176 
       
  3177     {
       
  3178         const QTransform transform;
       
  3179         const QLineF line(2.5, 2.5, 2.5 + 1/256., 1024);
       
  3180 
       
  3181         QTest::newRow("steep line 2 aa") << transform << line << true;
       
  3182         QTest::newRow("steep line 2 no aa") << transform << line << false;
       
  3183     }
       
  3184 
       
  3185     {
       
  3186         const QTransform transform;
       
  3187         const QLineF line(2.5, 2.5, 2.5 + 1/64., 1024);
       
  3188 
       
  3189         QTest::newRow("steep line 3 aa") << transform << line << true;
       
  3190         QTest::newRow("steep line 3 no aa") << transform << line << false;
       
  3191     }
       
  3192 }
       
  3193 
       
  3194 qreal randf()
       
  3195 {
       
  3196     return rand() / (RAND_MAX + 1.0);
       
  3197 }
       
  3198 
       
  3199 QPointF randInRect(const QRectF &rect)
       
  3200 {
       
  3201     const qreal x = rect.left() + rect.width() * randf();
       
  3202     const qreal y = rect.top() + rect.height() * randf();
       
  3203 
       
  3204     return QPointF(x, y);
       
  3205 }
       
  3206 
       
  3207 void tst_QPainter::rasterizer_asserts()
       
  3208 {
       
  3209     QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
       
  3210 
       
  3211     QRectF middle(QPointF(0, 0), img.size());
       
  3212     QRectF left = middle.translated(-middle.width(), 0);
       
  3213     QRectF right = middle.translated(middle.width(), 0);
       
  3214 
       
  3215     QPainter p(&img);
       
  3216     img.fill(Qt::white);
       
  3217     p.setCompositionMode(QPainter::CompositionMode_Destination);
       
  3218     for (int i = 0; i < 100000; ++i) {
       
  3219         QPainterPath path;
       
  3220         path.moveTo(randInRect(middle));
       
  3221         path.lineTo(randInRect(left));
       
  3222         path.lineTo(randInRect(right));
       
  3223 
       
  3224         p.fillPath(path, Qt::black);
       
  3225     }
       
  3226 }
       
  3227 
       
  3228 void tst_QPainter::rasterizer_negativeCoords()
       
  3229 {
       
  3230     QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
       
  3231     img.fill(0x0);
       
  3232 
       
  3233     QImage original = img;
       
  3234 
       
  3235     QPainter p(&img);
       
  3236     p.rotate(90);
       
  3237     p.fillRect(0, 0, 70, 50, Qt::black);
       
  3238 
       
  3239     // image should not have changed
       
  3240     QCOMPARE(img.pixel(0, 0), 0x0U);
       
  3241     QCOMPARE(img, original);
       
  3242 }
       
  3243 
       
  3244 void tst_QPainter::blendOverFlow_data()
       
  3245 {
       
  3246     QTest::addColumn<QImage::Format>("format");
       
  3247     QTest::addColumn<int>("width");
       
  3248     QTest::addColumn<int>("height");
       
  3249 
       
  3250     QImage::Format format = QImage::Format_ARGB8555_Premultiplied;
       
  3251     QTest::newRow("555,1,1") << format << 1 << 1;
       
  3252     QTest::newRow("555,2,2") << format << 2 << 2;
       
  3253     QTest::newRow("555,10,10") << format << 10 << 10;
       
  3254 
       
  3255     format = QImage::Format_ARGB8565_Premultiplied;
       
  3256     QTest::newRow("565,1,1") << format << 1 << 1;
       
  3257     QTest::newRow("565,2,2") << format << 2 << 2;
       
  3258     QTest::newRow("565,10,10") << format << 10 << 10;
       
  3259 }
       
  3260 
       
  3261 void tst_QPainter::blendOverFlow()
       
  3262 {
       
  3263     QFETCH(QImage::Format, format);
       
  3264     QFETCH(int, width);
       
  3265     QFETCH(int, height);
       
  3266 
       
  3267     QImage dest(width, height, format);
       
  3268     QImage src(width, height, format);
       
  3269 
       
  3270     {
       
  3271         QPainter p(&dest);
       
  3272         p.fillRect(0, 0, width, height, Qt::green);
       
  3273     }
       
  3274     QImage expected = dest;
       
  3275 
       
  3276     {
       
  3277         QPainter p(&src);
       
  3278         p.setCompositionMode(QPainter::CompositionMode_Source);
       
  3279         p.fillRect(0, 0, width, height, QColor(0, 255, 0, 6));
       
  3280     }
       
  3281 
       
  3282     {
       
  3283         QPainter p(&dest);
       
  3284         p.drawImage(0, 0, src);
       
  3285     }
       
  3286 
       
  3287     QCOMPARE(dest.pixel(0, 0), expected.pixel(0, 0));
       
  3288     QCOMPARE(dest, expected);
       
  3289 }
       
  3290 
       
  3291 void tst_QPainter::largeImagePainting_data()
       
  3292 {
       
  3293     QTest::addColumn<int>("width");
       
  3294     QTest::addColumn<int>("height");
       
  3295     QTest::addColumn<bool>("antialiased");
       
  3296 
       
  3297     QTest::newRow("tall") << 1 << 32767 << false;
       
  3298     QTest::newRow("tall aa") << 1 << 32767 << true;
       
  3299     QTest::newRow("wide") << 32767 << 1 << false;
       
  3300     QTest::newRow("wide aa") << 32767 << 1 << true;
       
  3301 }
       
  3302 
       
  3303 void tst_QPainter::largeImagePainting()
       
  3304 {
       
  3305     QPainterPath path;
       
  3306     path.addRect(0, 0, 1, 1);
       
  3307     path.addRect(2, 0, 1, 1);
       
  3308     path.addRect(0, 2, 1, 1);
       
  3309 
       
  3310     QFETCH(int, width);
       
  3311     QFETCH(int, height);
       
  3312     QFETCH(bool, antialiased);
       
  3313 
       
  3314     QImage img(width, height, QImage::Format_ARGB32_Premultiplied);
       
  3315     img.fill(0x0);
       
  3316 
       
  3317     QPainter p(&img);
       
  3318     p.setPen(Qt::NoPen);
       
  3319     p.setBrush(Qt::white);
       
  3320 
       
  3321     p.setRenderHint(QPainter::Antialiasing, antialiased);
       
  3322 
       
  3323     for (int i = 0; i < img.width(); i += 4) {
       
  3324         p.drawPath(path);
       
  3325         p.translate(4, 0);
       
  3326     }
       
  3327 
       
  3328     p.resetMatrix();
       
  3329 
       
  3330     for (int i = 4; i < img.height(); i += 4) {
       
  3331         p.translate(0, 4);
       
  3332         p.drawPath(path);
       
  3333     }
       
  3334 
       
  3335     for (int i = 0; i < img.width(); ++i) {
       
  3336         if (i % 2)
       
  3337             QCOMPARE(img.pixel(i, 0), 0x0U);
       
  3338         else
       
  3339             QCOMPARE(img.pixel(i, 0), 0xffffffffU);
       
  3340     }
       
  3341 
       
  3342     for (int i = 1; i < img.height(); ++i) {
       
  3343         if (i % 2)
       
  3344             QCOMPARE(img.pixel(0, i), 0x0U);
       
  3345         else
       
  3346             QCOMPARE(img.pixel(0, i), 0xffffffffU);
       
  3347     }
       
  3348 }
       
  3349 
       
  3350 void tst_QPainter::imageScaling_task206785()
       
  3351 {
       
  3352     QImage src(32, 2, QImage::Format_ARGB32_Premultiplied);
       
  3353     src.fill(0xffffffff);
       
  3354 
       
  3355     QImage dst(128, 128, QImage::Format_ARGB32_Premultiplied);
       
  3356 
       
  3357     QImage expected(128, 128, QImage::Format_ARGB32_Premultiplied);
       
  3358     expected.fill(0xffffffff);
       
  3359 
       
  3360     for (int i = 1; i < 5; ++i) {
       
  3361         qreal scale = i / qreal(5);
       
  3362 
       
  3363         dst.fill(0xff000000);
       
  3364 
       
  3365         QPainter p(&dst);
       
  3366         p.scale(dst.width() / qreal(src.width()), scale);
       
  3367 
       
  3368         for (int y = 0; y * scale < dst.height(); ++y)
       
  3369             p.drawImage(0, y, src);
       
  3370 
       
  3371         p.end();
       
  3372 
       
  3373         QCOMPARE(dst, expected);
       
  3374     }
       
  3375 }
       
  3376 
       
  3377 #define FOR_EACH_NEIGHBOR_8 for (int dx = -1; dx <= 1; ++dx) for (int dy = -1; dy <= 1; ++dy) if (dx != 0 || dy != 0)
       
  3378 #define FOR_EACH_NEIGHBOR_4 for (int dx = -1; dx <= 1; ++dx) for (int dy = -1; dy <= 1; ++dy) if ((dx == 0) != (dy == 0))
       
  3379 
       
  3380 uint qHash(const QPoint &point)
       
  3381 {
       
  3382     return qHash(qMakePair(point.x(), point.y()));
       
  3383 }
       
  3384 
       
  3385 bool verifyOutlineFillConsistency(const QImage &img, QRgb outside, QRgb inside, QRgb outline)
       
  3386 {
       
  3387     if (img.pixel(img.width() / 2, img.height() / 2) != inside)
       
  3388         return false;
       
  3389 
       
  3390     int x = img.width() / 2;
       
  3391     int y = img.height() / 2;
       
  3392 
       
  3393     while (img.pixel(++x, y) == inside)
       
  3394         ;
       
  3395 
       
  3396     if (img.pixel(x, y) != outline)
       
  3397         return false;
       
  3398 
       
  3399     QQueue<QPoint> discovered;
       
  3400     discovered.enqueue(QPoint(x, y));
       
  3401 
       
  3402     QVector<bool> visited(img.width() * img.height());
       
  3403     visited.fill(false);
       
  3404 
       
  3405     while (!discovered.isEmpty()) {
       
  3406         QPoint p = discovered.dequeue();
       
  3407         QRgb pixel = img.pixel(p.x(), p.y());
       
  3408 
       
  3409         bool &v = visited[p.y() * img.width() + p.x()];
       
  3410         if (v)
       
  3411             continue;
       
  3412         v = true;
       
  3413 
       
  3414         if (pixel == outline) {
       
  3415             FOR_EACH_NEIGHBOR_8 {
       
  3416                 QPoint x(p.x() + dx, p.y() + dy);
       
  3417                 discovered.enqueue(x);
       
  3418             }
       
  3419         } else {
       
  3420             FOR_EACH_NEIGHBOR_4 {
       
  3421                 if ((dx == 0) == (dy == 0))
       
  3422                     continue;
       
  3423                 QRgb neighbor = img.pixel(p.x() + dx, p.y() + dy);
       
  3424                 if (pixel == inside && neighbor == outside ||
       
  3425                     pixel == outside && neighbor == inside)
       
  3426                     return false;
       
  3427             }
       
  3428         }
       
  3429     }
       
  3430 
       
  3431     return true;
       
  3432 }
       
  3433 
       
  3434 #undef FOR_EACH_NEIGHBOR_8
       
  3435 #undef FOR_EACH_NEIGHBOR_4
       
  3436 
       
  3437 void tst_QPainter::outlineFillConsistency()
       
  3438 {
       
  3439     QImage dst(256, 256, QImage::Format_ARGB32_Premultiplied);
       
  3440 
       
  3441     QPolygonF poly;
       
  3442     poly << QPointF(5, -100) << QPointF(-70, 20) << QPointF(95, 25);
       
  3443 
       
  3444     QPen pen(Qt::red);
       
  3445     QBrush brush(Qt::black);
       
  3446 
       
  3447     QRgb background = 0xffffffff;
       
  3448     for (int i = 0; i < 360; ++i) {
       
  3449         dst.fill(background);
       
  3450 
       
  3451         QPainter p(&dst);
       
  3452         p.translate(dst.width() / 2, dst.height() / 2);
       
  3453 
       
  3454         QPolygonF copy = poly;
       
  3455         for (int j = 0; j < copy.size(); ++j)
       
  3456             copy[j] = QTransform().rotate(i).map(copy[j]);
       
  3457 
       
  3458         p.setPen(pen);
       
  3459         p.setBrush(brush);
       
  3460         p.drawPolygon(copy);
       
  3461         p.end();
       
  3462 
       
  3463 #if 0
       
  3464         if (!verifyOutlineFillConsistency(dst, background, p.brush().color().rgba(), p.pen().color().rgba()))
       
  3465             dst.save(QString("outlineFillConsistency-%1.png").arg(i));
       
  3466 #endif
       
  3467 
       
  3468         QVERIFY(verifyOutlineFillConsistency(dst, background, brush.color().rgba(), pen.color().rgba()));
       
  3469     }
       
  3470 }
       
  3471 
       
  3472 void tst_QPainter::drawImage_task217400_data()
       
  3473 {
       
  3474     QTest::addColumn<QImage::Format>("format");
       
  3475 
       
  3476     QTest::newRow("444") << QImage::Format_ARGB4444_Premultiplied;
       
  3477     QTest::newRow("555") << QImage::Format_ARGB8555_Premultiplied;
       
  3478     QTest::newRow("565") << QImage::Format_ARGB8565_Premultiplied;
       
  3479 //    QTest::newRow("666") << QImage::Format_ARGB6666_Premultiplied;
       
  3480     QTest::newRow("888p") << QImage::Format_ARGB32_Premultiplied;
       
  3481     QTest::newRow("888") << QImage::Format_ARGB32;
       
  3482 }
       
  3483 
       
  3484 void tst_QPainter::drawImage_task217400()
       
  3485 {
       
  3486     QFETCH(QImage::Format, format);
       
  3487 
       
  3488     const QImage src = QImage(QString(SRCDIR) + "/task217400.png")
       
  3489                        .convertToFormat(format);
       
  3490     QVERIFY(!src.isNull());
       
  3491 
       
  3492     QImage expected(src.size(), format);
       
  3493     {
       
  3494         QPainter p(&expected);
       
  3495         p.fillRect(0, 0, expected.width(), expected.height(), Qt::white);
       
  3496         p.drawImage(0, 0, src);
       
  3497     }
       
  3498 
       
  3499     for (int i = 1; i <= 4; ++i) {
       
  3500         QImage dest(src.width() + i, src.height(), format);
       
  3501         {
       
  3502             QPainter p(&dest);
       
  3503             p.fillRect(0, 0, dest.width(), dest.height(), Qt::white);
       
  3504             p.drawImage(i, 0, src);
       
  3505         }
       
  3506 
       
  3507         const QImage result = dest.copy(i, 0, src.width(), src.height());
       
  3508 
       
  3509 #if 0
       
  3510         if (result != expected) {
       
  3511             qDebug("i=%i", i);
       
  3512             result.save("result.png");
       
  3513             expected.save("expected.png");
       
  3514         }
       
  3515 #endif
       
  3516         QCOMPARE(result, expected);
       
  3517     }
       
  3518 }
       
  3519 
       
  3520 void tst_QPainter::drawImage_task258776()
       
  3521 {
       
  3522     QImage src(16, 16, QImage::Format_RGB888);
       
  3523     QImage dest(33, 33, QImage::Format_RGB888);
       
  3524     src.fill(0x00ff00);
       
  3525     dest.fill(0x0000ff);
       
  3526 
       
  3527     QPainter painter(&dest);
       
  3528     painter.drawImage(QRectF(0.499, 0.499, 32, 32), src, QRectF(0, 0, 16, 16));
       
  3529     painter.end();
       
  3530 
       
  3531     QImage expected(33, 33, QImage::Format_RGB32);
       
  3532     expected.fill(0xff0000);
       
  3533 
       
  3534     painter.begin(&expected);
       
  3535     painter.drawImage(QRectF(0, 0, 32, 32), src);
       
  3536     painter.end();
       
  3537 
       
  3538     dest = dest.convertToFormat(QImage::Format_RGB32);
       
  3539 
       
  3540     dest.save("dest.png");
       
  3541     expected.save("expected.png");
       
  3542     QCOMPARE(dest, expected);
       
  3543 }
       
  3544 
       
  3545 void tst_QPainter::clipRectSaveRestore()
       
  3546 {
       
  3547     QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
       
  3548     img.fill(0x0);
       
  3549 
       
  3550     QPainter p(&img);
       
  3551     p.setClipRect(QRect(0, 0, 10, 10));
       
  3552     p.save();
       
  3553     p.setClipRect(QRect(5, 5, 5, 5), Qt::IntersectClip);
       
  3554     p.restore();
       
  3555     p.fillRect(0, 0, 64, 64, Qt::black);
       
  3556     p.end();
       
  3557 
       
  3558     QCOMPARE(img.pixel(0, 0), QColor(Qt::black).rgba());
       
  3559 }
       
  3560 
       
  3561 void tst_QPainter::clippedImage()
       
  3562 {
       
  3563     QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
       
  3564     img.fill(0x0);
       
  3565 
       
  3566     QImage src(16, 16, QImage::Format_RGB32);
       
  3567     src.fill(QColor(Qt::red).rgba());
       
  3568 
       
  3569     QPainter p(&img);
       
  3570     p.setClipRect(QRect(1, 1, 14, 14));
       
  3571     p.drawImage(0, 0, src);
       
  3572     p.end();
       
  3573 
       
  3574     QCOMPARE(img.pixel(0, 0), 0x0U);
       
  3575     QCOMPARE(img.pixel(1, 1), src.pixel(1, 1));
       
  3576 }
       
  3577 
       
  3578 void tst_QPainter::stateResetBetweenQPainters()
       
  3579 {
       
  3580     QImage img(16, 16, QImage::Format_ARGB32);
       
  3581 
       
  3582     {
       
  3583         QPainter p(&img);
       
  3584         p.setCompositionMode(QPainter::CompositionMode_Source);
       
  3585         p.fillRect(0, 0, 16, 16, Qt::red);
       
  3586     }
       
  3587 
       
  3588     {
       
  3589         QPainter p2(&img);
       
  3590         p2.fillRect(0, 0, 16, 16, QColor(0, 0, 255, 63));
       
  3591     }
       
  3592 
       
  3593     img.save("foo.png");
       
  3594 
       
  3595     QVERIFY(img.pixel(0, 0) != qRgba(0, 0, 255, 63));
       
  3596     QVERIFY(qRed(img.pixel(0, 0)) > 0); // We didn't erase the red channel...
       
  3597     QVERIFY(qBlue(img.pixel(0, 0)) < 255); // We blended the blue channel
       
  3598 }
       
  3599 
       
  3600 void tst_QPainter::drawRect_task215378()
       
  3601 {
       
  3602     QImage img(11, 11, QImage::Format_ARGB32_Premultiplied);
       
  3603     img.fill(QColor(Qt::white).rgba());
       
  3604 
       
  3605     QPainter p(&img);
       
  3606     p.setPen(QColor(127, 127, 127, 127));
       
  3607     p.drawRect(0, 0, 10, 10);
       
  3608     p.end();
       
  3609 
       
  3610     QCOMPARE(img.pixel(0, 0), img.pixel(1, 0));
       
  3611     QCOMPARE(img.pixel(0, 0), img.pixel(0, 1));
       
  3612     QVERIFY(img.pixel(0, 0) != img.pixel(1, 1));
       
  3613 }
       
  3614 
       
  3615 void tst_QPainter::drawRect_task247505()
       
  3616 {
       
  3617     QImage a(10, 10, QImage::Format_ARGB32_Premultiplied);
       
  3618     a.fill(0);
       
  3619     QImage b = a;
       
  3620 
       
  3621     QPainter p(&a);
       
  3622     p.setPen(Qt::NoPen);
       
  3623     p.setBrush(Qt::black);
       
  3624     p.drawRect(QRectF(10, 0, -10, 10));
       
  3625     p.end();
       
  3626     p.begin(&b);
       
  3627     p.setPen(Qt::NoPen);
       
  3628     p.setBrush(Qt::black);
       
  3629     p.drawRect(QRectF(0, 0, 10, 10));
       
  3630     p.end();
       
  3631 
       
  3632     QCOMPARE(a, b);
       
  3633 }
       
  3634 
       
  3635 void tst_QPainter::drawImage_data()
       
  3636 {
       
  3637     QTest::addColumn<int>("x");
       
  3638     QTest::addColumn<int>("y");
       
  3639     QTest::addColumn<int>("w");
       
  3640     QTest::addColumn<int>("h");
       
  3641     QTest::addColumn<QImage::Format>("srcFormat");
       
  3642     QTest::addColumn<QImage::Format>("dstFormat");
       
  3643 
       
  3644     for (int srcFormat = QImage::Format_Mono; srcFormat < QImage::NImageFormats; ++srcFormat) {
       
  3645         for (int dstFormat = QImage::Format_Mono; dstFormat < QImage::NImageFormats; ++dstFormat) {
       
  3646             if (dstFormat == QImage::Format_Indexed8)
       
  3647                 continue;
       
  3648             for (int odd_x = 0; odd_x <= 1; ++odd_x) {
       
  3649                 for (int odd_width = 0; odd_width <= 1; ++odd_width) {
       
  3650                     QString description =
       
  3651                         QString("srcFormat %1, dstFormat %2, odd x: %3, odd width: %4")
       
  3652                             .arg(srcFormat).arg(dstFormat).arg(odd_x).arg(odd_width);
       
  3653 
       
  3654                     QTest::newRow(qPrintable(description)) << (10 + odd_x) << 10 << (20 + odd_width) << 20
       
  3655                         << QImage::Format(srcFormat)
       
  3656                         << QImage::Format(dstFormat);
       
  3657                 }
       
  3658             }
       
  3659         }
       
  3660     }
       
  3661 }
       
  3662 
       
  3663 bool verifyImage(const QImage &img, int x, int y, int w, int h, uint background)
       
  3664 {
       
  3665     int imgWidth = img.width();
       
  3666     int imgHeight = img.height();
       
  3667     for (int i = 0; i < imgHeight; ++i) {
       
  3668         for (int j = 0; j < imgWidth; ++j) {
       
  3669             uint pixel = img.pixel(j, i);
       
  3670             bool outside = j < x || j >= (x + w) || i < y || i >= (y + h);
       
  3671             if (outside != (pixel == background)) {
       
  3672                 //printf("%d %d, expected %x, got %x, outside: %d\n", x, y, background, pixel, outside);
       
  3673                 return false;
       
  3674             }
       
  3675         }
       
  3676     }
       
  3677 
       
  3678     return true;
       
  3679 }
       
  3680 
       
  3681 void tst_QPainter::drawImage()
       
  3682 {
       
  3683     QFETCH(int, x);
       
  3684     QFETCH(int, y);
       
  3685     QFETCH(int, w);
       
  3686     QFETCH(int, h);
       
  3687     QFETCH(QImage::Format, srcFormat);
       
  3688     QFETCH(QImage::Format, dstFormat);
       
  3689 
       
  3690     QImage dst(40, 40, QImage::Format_RGB32);
       
  3691     dst.fill(0xffffffff);
       
  3692 
       
  3693     dst = dst.convertToFormat(dstFormat);
       
  3694     uint background = dst.pixel(0, 0);
       
  3695 
       
  3696     QImage src(w, h, QImage::Format_RGB32);
       
  3697     src.fill(0xff000000);
       
  3698     src = src.convertToFormat(srcFormat);
       
  3699 
       
  3700     QPainter p(&dst);
       
  3701     p.drawImage(x, y, src);
       
  3702     p.end();
       
  3703 
       
  3704     QVERIFY(verifyImage(dst, x, y, w, h, background));
       
  3705 }
       
  3706 
       
  3707 void tst_QPainter::imageCoordinateLimit()
       
  3708 {
       
  3709     QImage img(64, 40000, QImage::Format_MonoLSB);
       
  3710     QPainter p(&img);
       
  3711     p.drawText(10, 36000, QLatin1String("foo"));
       
  3712     p.setPen(QPen(Qt::black, 2));
       
  3713     p.drawLine(10, 0, 60, 40000);
       
  3714 
       
  3715     p.setRenderHint(QPainter::Antialiasing);
       
  3716     p.drawLine(10, 0, 60, 40000);
       
  3717 }
       
  3718 
       
  3719 
       
  3720 void tst_QPainter::imageBlending_data()
       
  3721 {
       
  3722     QTest::addColumn<QImage::Format>("sourceFormat");
       
  3723     QTest::addColumn<QImage::Format>("destFormat");
       
  3724     QTest::addColumn<int>("error");
       
  3725 
       
  3726     int error_rgb565 = ((1<<3) + (1<<2) + (1<<3));
       
  3727     QTest::newRow("rgb565_on_rgb565") << QImage::Format_RGB16
       
  3728                                       << QImage::Format_RGB16
       
  3729                                       << 0;
       
  3730     QTest::newRow("argb8565_on_rgb565") << QImage::Format_ARGB8565_Premultiplied
       
  3731                                         << QImage::Format_RGB16
       
  3732                                         << error_rgb565;
       
  3733 
       
  3734     QTest::newRow("rgb32_on_rgb565") << QImage::Format_RGB32
       
  3735                                      << QImage::Format_RGB16
       
  3736                                      << error_rgb565;
       
  3737 
       
  3738     QTest::newRow("argb32pm_on_rgb565") << QImage::Format_ARGB32_Premultiplied
       
  3739                                         << QImage::Format_RGB16
       
  3740                                         << error_rgb565;
       
  3741 }
       
  3742 
       
  3743 int diffColor(quint32 ap, quint32 bp)
       
  3744 {
       
  3745     int a = qAlpha(ap) - qAlpha(bp);
       
  3746     int r = qRed(ap) - qRed(bp);
       
  3747     int b = qBlue(ap) - qBlue(bp);
       
  3748     int g = qBlue(ap) - qBlue(bp);
       
  3749 
       
  3750     return qAbs(a) + qAbs(r) + qAbs(g) + qAbs(b);
       
  3751 }
       
  3752 
       
  3753 // this test assumes premultiplied pixels...
       
  3754 
       
  3755 void tst_QPainter::imageBlending()
       
  3756 {
       
  3757     QFETCH(QImage::Format, sourceFormat);
       
  3758     QFETCH(QImage::Format, destFormat);
       
  3759     QFETCH(int, error);
       
  3760 
       
  3761     QImage dest;
       
  3762     {
       
  3763         QImage orig_dest(6, 6, QImage::Format_ARGB32_Premultiplied);
       
  3764         orig_dest.fill(0);
       
  3765         QPainter p(&orig_dest);
       
  3766         p.fillRect(0, 0, 6, 3, QColor::fromRgbF(1, 0, 0));
       
  3767         p.fillRect(3, 0, 3, 6, QColor::fromRgbF(0, 0, 1, 0.5));
       
  3768         p.end();
       
  3769         dest = orig_dest.convertToFormat(destFormat);
       
  3770 
       
  3771         // An image like this: (r = red, m = magenta, b = light alpha blue, 0 = transparent)
       
  3772         // r r r m m m
       
  3773         // r r r m m m
       
  3774         // r r r m m m
       
  3775         // 0 0 0 b b b
       
  3776         // 0 0 0 b b b
       
  3777         // 0 0 0 b b b
       
  3778     }
       
  3779 
       
  3780     QImage source;
       
  3781     {
       
  3782         QImage orig_source(6, 6, QImage::Format_ARGB32_Premultiplied);
       
  3783         orig_source.fill(0);
       
  3784         QPainter p(&orig_source);
       
  3785         p.fillRect(1, 1, 4, 4, QColor::fromRgbF(0, 1, 0, 0.5));
       
  3786         p.fillRect(2, 2, 2, 2, QColor::fromRgbF(0, 1, 0));
       
  3787         p.end();
       
  3788         source = orig_source.convertToFormat(sourceFormat);
       
  3789 
       
  3790         // An image like this: (0 = transparent, . = green at 0.5 alpha, g = opaque green.
       
  3791         // 0 0 0 0 0 0
       
  3792         // 0 . . . . 0
       
  3793         // 0 . g g . 0
       
  3794         // 0 . g g . 0
       
  3795         // 0 . . . . 0
       
  3796         // 0 0 0 0 0 0
       
  3797     }
       
  3798 
       
  3799     QPainter p(&dest);
       
  3800     p.drawImage(0, 0, source);
       
  3801     p.end();
       
  3802 
       
  3803     // resulting image:
       
  3804     // r  r  r  m  m  m
       
  3805     // r  r. r. m. m. m
       
  3806     // r  r. g  g  m. m
       
  3807     // 0  .  g  g  b. b
       
  3808     // 0  .  .  b. b. b
       
  3809     // 0  0  0  b  b  b
       
  3810 
       
  3811     // the g pixels, always green..
       
  3812     QVERIFY(diffColor(dest.pixel(2, 2), 0xff00ff00) <= error); // g
       
  3813 
       
  3814     if (source.hasAlphaChannel()) {
       
  3815         QVERIFY(diffColor(dest.pixel(0, 0), 0xffff0000) <= error); // r
       
  3816         QVERIFY(diffColor(dest.pixel(5, 0), 0xff7f007f) <= error); // m
       
  3817         QVERIFY(diffColor(dest.pixel(1, 1), 0xff7f7f00) <= error); // r.
       
  3818         QVERIFY(diffColor(dest.pixel(4, 1), 0xff3f7f3f) <= error); // m.
       
  3819         if (dest.hasAlphaChannel()) {
       
  3820             QVERIFY(diffColor(dest.pixel(1, 3), 0x7f007f00) <= error); // .
       
  3821             QVERIFY(diffColor(dest.pixel(4, 3), 0x7f007f3f) <= error); // b.
       
  3822             QVERIFY(diffColor(dest.pixel(4, 3), 0x7f007f3f) <= error); // b.
       
  3823             QVERIFY(diffColor(dest.pixel(4, 4), 0x7f00007f) <= error); // b
       
  3824             QVERIFY(diffColor(dest.pixel(4, 0), 0) <= 0); // 0
       
  3825        }
       
  3826     } else {
       
  3827         QVERIFY(diffColor(dest.pixel(0, 0), 0xff000000) <= 0);
       
  3828         QVERIFY(diffColor(dest.pixel(1, 1), 0xff007f00) <= error);
       
  3829     }
       
  3830 }
       
  3831 
       
  3832 void tst_QPainter::imageBlending_clipped()
       
  3833 {
       
  3834     QImage src(20, 20, QImage::Format_RGB16);
       
  3835     QPainter p(&src);
       
  3836     p.fillRect(src.rect(), Qt::red);
       
  3837     p.end();
       
  3838 
       
  3839     QImage dst(40, 20, QImage::Format_RGB16);
       
  3840     p.begin(&dst);
       
  3841     p.fillRect(dst.rect(), Qt::white);
       
  3842     p.end();
       
  3843 
       
  3844     QImage expected = dst;
       
  3845 
       
  3846     p.begin(&dst);
       
  3847     p.setClipRect(QRect(23, 0, 20, 20));
       
  3848 
       
  3849     // should be completely clipped
       
  3850     p.drawImage(QRectF(3, 0, 20, 20), src);
       
  3851     p.end();
       
  3852 
       
  3853     // dst should be left unchanged
       
  3854     QCOMPARE(dst, expected);
       
  3855 }
       
  3856 
       
  3857 void tst_QPainter::paintOnNullPixmap()
       
  3858 {
       
  3859     QPixmap pix(16, 16);
       
  3860 
       
  3861     QPixmap textPixmap;
       
  3862     QPainter p(&textPixmap);
       
  3863     p.drawPixmap(10, 10, pix);
       
  3864     p.end();
       
  3865 
       
  3866     QPixmap textPixmap2(16,16);
       
  3867     p.begin(&textPixmap2);
       
  3868     p.end();
       
  3869 }
       
  3870 
       
  3871 void tst_QPainter::checkCompositionMode()
       
  3872 {
       
  3873     QImage refImage(50,50,QImage::Format_ARGB32);
       
  3874     QPainter painter(&refImage);
       
  3875     painter.fillRect(QRect(0,0,50,50),Qt::blue);
       
  3876 
       
  3877     QImage testImage(50,50,QImage::Format_ARGB32);
       
  3878     QPainter p(&testImage);
       
  3879     p.fillRect(QRect(0,0,50,50),Qt::red);
       
  3880     p.save();
       
  3881     p.setCompositionMode(QPainter::CompositionMode_SourceOut);
       
  3882     p.restore();
       
  3883     p.fillRect(QRect(0,0,50,50),Qt::blue);
       
  3884 
       
  3885     QCOMPARE(refImage.pixel(20,20),testImage.pixel(20,20));
       
  3886 }
       
  3887 
       
  3888 static QLinearGradient inverseGradient(QLinearGradient g)
       
  3889 {
       
  3890     QLinearGradient g2 = g;
       
  3891 
       
  3892     QGradientStops stops = g.stops();
       
  3893 
       
  3894     QGradientStops inverse;
       
  3895     foreach (QGradientStop stop, stops)
       
  3896         inverse << QGradientStop(1 - stop.first, stop.second);
       
  3897 
       
  3898     g2.setStops(inverse);
       
  3899     return g2;
       
  3900 }
       
  3901 
       
  3902 void tst_QPainter::linearGradientSymmetry()
       
  3903 {
       
  3904     QImage a(64, 8, QImage::Format_ARGB32_Premultiplied);
       
  3905     QImage b(64, 8, QImage::Format_ARGB32_Premultiplied);
       
  3906 
       
  3907     a.fill(0);
       
  3908     b.fill(0);
       
  3909 
       
  3910     QLinearGradient gradient(QRectF(b.rect()).topLeft(), QRectF(b.rect()).topRight());
       
  3911     gradient.setColorAt(0.0, Qt::blue);
       
  3912     gradient.setColorAt(0.2, QColor(220, 220, 220, 0));
       
  3913     gradient.setColorAt(0.6, Qt::red);
       
  3914     gradient.setColorAt(0.9, QColor(220, 220, 220, 255));
       
  3915     gradient.setColorAt(1.0, Qt::black);
       
  3916 
       
  3917     QPainter pa(&a);
       
  3918     pa.fillRect(a.rect(), gradient);
       
  3919     pa.end();
       
  3920 
       
  3921     QPainter pb(&b);
       
  3922     pb.fillRect(b.rect(), inverseGradient(gradient));
       
  3923     pb.end();
       
  3924 
       
  3925     b = b.mirrored(true);
       
  3926     QCOMPARE(a, b);
       
  3927 }
       
  3928 
       
  3929 void tst_QPainter::gradientInterpolation()
       
  3930 {
       
  3931     QImage image(256, 8, QImage::Format_ARGB32_Premultiplied);
       
  3932     QPainter painter;
       
  3933 
       
  3934     QLinearGradient gradient(QRectF(image.rect()).topLeft(), QRectF(image.rect()).topRight());
       
  3935     gradient.setColorAt(0.0, QColor(255, 0, 0, 0));
       
  3936     gradient.setColorAt(1.0, Qt::blue);
       
  3937 
       
  3938     image.fill(0);
       
  3939     painter.begin(&image);
       
  3940     painter.fillRect(image.rect(), gradient);
       
  3941     painter.end();
       
  3942 
       
  3943     const QRgb *line = reinterpret_cast<QRgb *>(image.scanLine(3));
       
  3944 
       
  3945     for (int i = 0; i < 256; ++i) {
       
  3946         QCOMPARE(qAlpha(line[i]), qBlue(line[i])); // bright blue
       
  3947         QVERIFY(qAbs(qAlpha(line[i]) - i) < 3); // linear alpha
       
  3948         QCOMPARE(qRed(line[i]), 0); // no red component
       
  3949         QCOMPARE(qGreen(line[i]), 0); // no green component
       
  3950     }
       
  3951 
       
  3952     gradient.setInterpolationMode(QGradient::ComponentInterpolation);
       
  3953 
       
  3954     image.fill(0);
       
  3955     painter.begin(&image);
       
  3956     painter.fillRect(image.rect(), gradient);
       
  3957     painter.end();
       
  3958 
       
  3959     for (int i = 1; i < 256; ++i) {
       
  3960         if (i < 128) {
       
  3961             QVERIFY(qRed(line[i]) >= qBlue(line[i])); // red is dominant
       
  3962         } else {
       
  3963             QVERIFY(qRed(line[i]) <= qBlue(line[i])); // blue is dominant
       
  3964         }
       
  3965         QVERIFY((qRed(line[i]) - 0.5) * (qAlpha(line[i - 1]) - 0.5) <= (qRed(line[i - 1]) + 0.5) * (qAlpha(line[i]) + 0.5)); // decreasing red
       
  3966         QVERIFY((qBlue(line[i]) + 0.5) * (qAlpha(line[i - 1]) + 0.5) >= (qBlue(line[i - 1]) - 0.5) * (qAlpha(line[i]) - 0.5)); // increasing blue
       
  3967         QVERIFY(qAbs(qAlpha(line[i]) - i) < 3); // linear alpha
       
  3968         QCOMPARE(qGreen(line[i]), 0); // no green component
       
  3969     }
       
  3970 }
       
  3971 
       
  3972 void tst_QPainter::drawPolygon()
       
  3973 {
       
  3974     QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
       
  3975 
       
  3976     QPainterPathStroker stroker;
       
  3977     stroker.setWidth(1.5);
       
  3978 
       
  3979     QPainterPath path;
       
  3980     path.moveTo(2, 34);
       
  3981     path.lineTo(34, 2);
       
  3982 
       
  3983     QPolygonF poly = stroker.createStroke(path).toFillPolygon();
       
  3984 
       
  3985     img.fill(0xffffffff);
       
  3986     QPainter p(&img);
       
  3987     p.setRenderHint(QPainter::Antialiasing);
       
  3988     p.setBrush(Qt::red);
       
  3989     p.setPen(Qt::NoPen);
       
  3990     p.drawPolygon(poly);
       
  3991     p.translate(64, 64);
       
  3992     p.drawPolygon(poly);
       
  3993     p.end();
       
  3994 
       
  3995     QImage a = img.copy();
       
  3996 
       
  3997     img.fill(0xffffffff);
       
  3998     p.begin(&img);
       
  3999     p.setRenderHint(QPainter::Antialiasing);
       
  4000     p.setBrush(Qt::red);
       
  4001     p.setPen(Qt::NoPen);
       
  4002     p.translate(64, 64);
       
  4003     p.drawPolygon(poly);
       
  4004     p.resetTransform();
       
  4005     p.drawPolygon(poly);
       
  4006     p.end();
       
  4007 
       
  4008     QCOMPARE(a, img);
       
  4009 }
       
  4010 
       
  4011 void tst_QPainter::inactivePainter()
       
  4012 {
       
  4013     // This test succeeds if it doesn't segfault.
       
  4014 
       
  4015     QPainter p;
       
  4016     QPainterPath path;
       
  4017     QRegion region(QRect(20, 20, 60, 40));
       
  4018     QPolygonF polygon(QVector<QPointF>() << QPointF(0, 0) << QPointF(12, 0) << QPointF(8, 6));
       
  4019     path.addPolygon(polygon);
       
  4020 
       
  4021     p.save();
       
  4022     p.restore();
       
  4023 
       
  4024     p.background();
       
  4025     p.setBackground(QBrush(Qt::blue));
       
  4026 
       
  4027     p.brush();
       
  4028     p.setBrush(Qt::red);
       
  4029     p.setBrush(Qt::NoBrush);
       
  4030     p.setBrush(QBrush(Qt::white, Qt::DiagCrossPattern));
       
  4031 
       
  4032     p.backgroundMode();
       
  4033     p.setBackgroundMode(Qt::OpaqueMode);
       
  4034 
       
  4035     p.boundingRect(QRectF(0, 0, 100, 20), Qt::AlignCenter, QLatin1String("Hello, World!"));
       
  4036     p.boundingRect(QRect(0, 0, 100, 20), Qt::AlignCenter, QLatin1String("Hello, World!"));
       
  4037 
       
  4038     p.brushOrigin();
       
  4039     p.setBrushOrigin(QPointF(12, 34));
       
  4040     p.setBrushOrigin(QPoint(12, 34));
       
  4041 
       
  4042     p.clipPath();
       
  4043     p.clipRegion();
       
  4044     p.hasClipping();
       
  4045     p.setClipPath(path);
       
  4046     p.setClipRect(QRectF(42, 42, 42, 42));
       
  4047     p.setClipRect(QRect(42, 42, 42, 42));
       
  4048     p.setClipRegion(region);
       
  4049     p.setClipping(true);
       
  4050 
       
  4051     p.combinedMatrix();
       
  4052     p.combinedTransform();
       
  4053 
       
  4054     p.compositionMode();
       
  4055     p.setCompositionMode(QPainter::CompositionMode_Plus);
       
  4056 
       
  4057     p.device();
       
  4058     p.deviceMatrix();
       
  4059     p.deviceTransform();
       
  4060 
       
  4061     p.font();
       
  4062     p.setFont(QFont(QLatin1String("Times"), 24));
       
  4063 
       
  4064     p.fontInfo();
       
  4065     p.fontMetrics();
       
  4066 
       
  4067     p.layoutDirection();
       
  4068     p.setLayoutDirection(Qt::RightToLeft);
       
  4069 
       
  4070     p.opacity();
       
  4071     p.setOpacity(0.75);
       
  4072 
       
  4073     p.pen();
       
  4074     p.setPen(QPen(Qt::red));
       
  4075     p.setPen(Qt::green);
       
  4076     p.setPen(Qt::NoPen);
       
  4077 
       
  4078     p.renderHints();
       
  4079     p.setRenderHint(QPainter::Antialiasing, true);
       
  4080     p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
       
  4081 
       
  4082     p.resetMatrix();
       
  4083     p.resetTransform();
       
  4084     p.rotate(1);
       
  4085     p.scale(2, 2);
       
  4086     p.shear(-1, 1);
       
  4087     p.translate(3, 14);
       
  4088 
       
  4089     p.viewTransformEnabled();
       
  4090     p.setViewTransformEnabled(true);
       
  4091 
       
  4092     p.viewport();
       
  4093     p.setViewport(QRect(10, 10, 620, 460));
       
  4094 
       
  4095     p.window();
       
  4096     p.setWindow(QRect(10, 10, 620, 460));
       
  4097 
       
  4098     p.worldMatrix();
       
  4099     p.setWorldMatrix(QMatrix().translate(43, 21), true);
       
  4100     p.setWorldMatrixEnabled(true);
       
  4101 
       
  4102     p.transform();
       
  4103     p.setTransform(QTransform().translate(12, 34), true);
       
  4104 
       
  4105     p.worldTransform();
       
  4106     p.setWorldTransform(QTransform().scale(0.5, 0.5), true);
       
  4107 }
       
  4108 
       
  4109 bool testCompositionMode(int src, int dst, int expected, QPainter::CompositionMode op)
       
  4110 {
       
  4111     QImage actual(1, 1, QImage::Format_ARGB32_Premultiplied);
       
  4112     actual.fill(QColor(dst, dst, dst).rgb());
       
  4113 
       
  4114     QPainter p(&actual);
       
  4115     p.setCompositionMode(op);
       
  4116     p.fillRect(0, 0, 1, 1, QColor(src, src, src));
       
  4117     p.end();
       
  4118 
       
  4119     if (qRed(actual.pixel(0, 0)) != expected) {
       
  4120         qDebug("Fail: mode %d, src[%d] dst [%d] actual [%d] expected [%d]", op,
       
  4121                src, dst, qRed(actual.pixel(0, 0)), expected);
       
  4122         return false;
       
  4123     } else {
       
  4124         return true;
       
  4125     }
       
  4126 }
       
  4127 
       
  4128 void tst_QPainter::extendedBlendModes()
       
  4129 {
       
  4130     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Plus));
       
  4131     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_Plus));
       
  4132     QVERIFY(testCompositionMode(127, 128, 255, QPainter::CompositionMode_Plus));
       
  4133     QVERIFY(testCompositionMode(127,   0, 127, QPainter::CompositionMode_Plus));
       
  4134     QVERIFY(testCompositionMode(  0, 127, 127, QPainter::CompositionMode_Plus));
       
  4135     QVERIFY(testCompositionMode(255,   0, 255, QPainter::CompositionMode_Plus));
       
  4136     QVERIFY(testCompositionMode(  0, 255, 255, QPainter::CompositionMode_Plus));
       
  4137     QVERIFY(testCompositionMode(128, 128, 255, QPainter::CompositionMode_Plus));
       
  4138 
       
  4139     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Multiply));
       
  4140     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_Multiply));
       
  4141     QVERIFY(testCompositionMode(127, 255, 127, QPainter::CompositionMode_Multiply));
       
  4142     QVERIFY(testCompositionMode(255, 127, 127, QPainter::CompositionMode_Multiply));
       
  4143     QVERIFY(testCompositionMode( 63, 255,  63, QPainter::CompositionMode_Multiply));
       
  4144     QVERIFY(testCompositionMode(255,  63,  63, QPainter::CompositionMode_Multiply));
       
  4145     QVERIFY(testCompositionMode(127, 127,  63, QPainter::CompositionMode_Multiply));
       
  4146 
       
  4147     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Screen));
       
  4148     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_Screen));
       
  4149     QVERIFY(testCompositionMode( 63, 255, 255, QPainter::CompositionMode_Screen));
       
  4150     QVERIFY(testCompositionMode(255,  63, 255, QPainter::CompositionMode_Screen));
       
  4151     QVERIFY(testCompositionMode( 63,   0,  63, QPainter::CompositionMode_Screen));
       
  4152     QVERIFY(testCompositionMode(  0,  63,  63, QPainter::CompositionMode_Screen));
       
  4153     QVERIFY(testCompositionMode(127, 127, 191, QPainter::CompositionMode_Screen));
       
  4154 
       
  4155     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Overlay));
       
  4156     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_Overlay));
       
  4157     QVERIFY(testCompositionMode( 63,  63,  31, QPainter::CompositionMode_Overlay));
       
  4158     QVERIFY(testCompositionMode( 63, 255, 255, QPainter::CompositionMode_Overlay));
       
  4159 
       
  4160     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Darken));
       
  4161     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_Darken));
       
  4162     QVERIFY(testCompositionMode( 63,  63,  63, QPainter::CompositionMode_Darken));
       
  4163     QVERIFY(testCompositionMode( 63, 255,  63, QPainter::CompositionMode_Darken));
       
  4164     QVERIFY(testCompositionMode(255,  63,  63, QPainter::CompositionMode_Darken));
       
  4165     QVERIFY(testCompositionMode( 63, 127,  63, QPainter::CompositionMode_Darken));
       
  4166     QVERIFY(testCompositionMode(127,  63,  63, QPainter::CompositionMode_Darken));
       
  4167 
       
  4168     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Lighten));
       
  4169     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_Lighten));
       
  4170     QVERIFY(testCompositionMode( 63,  63,  63, QPainter::CompositionMode_Lighten));
       
  4171     QVERIFY(testCompositionMode( 63, 255, 255, QPainter::CompositionMode_Lighten));
       
  4172     QVERIFY(testCompositionMode(255,  63, 255, QPainter::CompositionMode_Lighten));
       
  4173     QVERIFY(testCompositionMode( 63, 127, 127, QPainter::CompositionMode_Lighten));
       
  4174     QVERIFY(testCompositionMode(127,  63, 127, QPainter::CompositionMode_Lighten));
       
  4175 
       
  4176     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_ColorDodge));
       
  4177     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_ColorDodge));
       
  4178     QVERIFY(testCompositionMode( 63, 127, 169, QPainter::CompositionMode_ColorDodge));
       
  4179     QVERIFY(testCompositionMode(191, 127, 255, QPainter::CompositionMode_ColorDodge));
       
  4180     QVERIFY(testCompositionMode(127, 191, 255, QPainter::CompositionMode_ColorDodge));
       
  4181 
       
  4182     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_ColorBurn));
       
  4183     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_ColorBurn));
       
  4184     QVERIFY(testCompositionMode(127, 127,   0, QPainter::CompositionMode_ColorBurn));
       
  4185     QVERIFY(testCompositionMode(128, 128,   2, QPainter::CompositionMode_ColorBurn));
       
  4186     QVERIFY(testCompositionMode(191, 127,  84, QPainter::CompositionMode_ColorBurn));
       
  4187 
       
  4188     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_HardLight));
       
  4189     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_HardLight));
       
  4190     QVERIFY(testCompositionMode(127, 127, 127, QPainter::CompositionMode_HardLight));
       
  4191     QVERIFY(testCompositionMode( 63,  63,  31, QPainter::CompositionMode_HardLight));
       
  4192     QVERIFY(testCompositionMode(127,  63,  63, QPainter::CompositionMode_HardLight));
       
  4193 
       
  4194     QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_SoftLight));
       
  4195     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_SoftLight));
       
  4196     QVERIFY(testCompositionMode(127, 127, 127, QPainter::CompositionMode_SoftLight));
       
  4197     QVERIFY(testCompositionMode( 63,  63,  86, QPainter::CompositionMode_SoftLight));
       
  4198     QVERIFY(testCompositionMode(127,  63,  63, QPainter::CompositionMode_SoftLight));
       
  4199 
       
  4200     QVERIFY(testCompositionMode(255, 255,   0, QPainter::CompositionMode_Difference));
       
  4201     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_Difference));
       
  4202     QVERIFY(testCompositionMode(255,   0, 255, QPainter::CompositionMode_Difference));
       
  4203     QVERIFY(testCompositionMode(127, 127,   0, QPainter::CompositionMode_Difference));
       
  4204     QVERIFY(testCompositionMode(127, 128,   1, QPainter::CompositionMode_Difference));
       
  4205     QVERIFY(testCompositionMode(127,  63,  64, QPainter::CompositionMode_Difference));
       
  4206     QVERIFY(testCompositionMode(  0, 127, 127, QPainter::CompositionMode_Difference));
       
  4207 
       
  4208     QVERIFY(testCompositionMode(255, 255,   0, QPainter::CompositionMode_Exclusion));
       
  4209     QVERIFY(testCompositionMode(  0,   0,   0, QPainter::CompositionMode_Exclusion));
       
  4210     QVERIFY(testCompositionMode(255,   0, 255, QPainter::CompositionMode_Exclusion));
       
  4211     QVERIFY(testCompositionMode(127, 127, 127, QPainter::CompositionMode_Exclusion));
       
  4212     QVERIFY(testCompositionMode( 63, 127, 127, QPainter::CompositionMode_Exclusion));
       
  4213     QVERIFY(testCompositionMode( 63,  63,  95, QPainter::CompositionMode_Exclusion));
       
  4214     QVERIFY(testCompositionMode(191, 191,  96, QPainter::CompositionMode_Exclusion));
       
  4215 }
       
  4216 
       
  4217 void tst_QPainter::zeroOpacity()
       
  4218 {
       
  4219     QImage source(1, 1, QImage::Format_ARGB32_Premultiplied);
       
  4220     source.fill(0xffffffff);
       
  4221 
       
  4222     QImage target(1, 1, QImage::Format_RGB32);
       
  4223     target.fill(0xff000000);
       
  4224 
       
  4225     QPainter p(&target);
       
  4226     p.setOpacity(0.0);
       
  4227     p.drawImage(0, 0, source);
       
  4228     p.end();
       
  4229 
       
  4230     QCOMPARE(target.pixel(0, 0), 0xff000000);
       
  4231 }
       
  4232 
       
  4233 void tst_QPainter::clippingBug()
       
  4234 {
       
  4235     QImage img(32, 32, QImage::Format_ARGB32_Premultiplied);
       
  4236     img.fill(0);
       
  4237 
       
  4238     QImage expected = img;
       
  4239     QPainter p(&expected);
       
  4240     p.fillRect(1, 1, 30, 30, Qt::red);
       
  4241     p.end();
       
  4242 
       
  4243     QPainterPath path;
       
  4244     path.addRect(1, 1, 30, 30);
       
  4245     path.addRect(1, 1, 30, 30);
       
  4246     path.addRect(1, 1, 30, 30);
       
  4247 
       
  4248     p.begin(&img);
       
  4249     p.setClipPath(path);
       
  4250     p.fillRect(0, 0, 32, 32, Qt::red);
       
  4251     p.end();
       
  4252 
       
  4253     QCOMPARE(img, expected);
       
  4254 }
       
  4255 
       
  4256 void tst_QPainter::emptyClip()
       
  4257 {
       
  4258     QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
       
  4259     QPainter p(&img);
       
  4260     p.setRenderHints(QPainter::Antialiasing);
       
  4261     p.setClipRect(0, 32, 64, 0);
       
  4262     p.fillRect(0, 0, 64, 64, Qt::white);
       
  4263 
       
  4264     QPainterPath path;
       
  4265     path.lineTo(64, 0);
       
  4266     path.lineTo(64, 64);
       
  4267     path.lineTo(40, 64);
       
  4268     path.lineTo(40, 80);
       
  4269     path.lineTo(0, 80);
       
  4270 
       
  4271     p.fillPath(path, Qt::green);
       
  4272 }
       
  4273 
       
  4274 void tst_QPainter::drawImage_1x1()
       
  4275 {
       
  4276     QImage source(1, 1, QImage::Format_ARGB32_Premultiplied);
       
  4277     source.fill(0xffffffff);
       
  4278 
       
  4279     QImage img(32, 32, QImage::Format_ARGB32_Premultiplied);
       
  4280     img.fill(0xff000000);
       
  4281     QPainter p(&img);
       
  4282     p.drawImage(QRectF(0.9, 0.9, 32, 32), source);
       
  4283     p.end();
       
  4284 
       
  4285     QImage expected = img;
       
  4286     expected.fill(0xff000000);
       
  4287     p.begin(&expected);
       
  4288     p.fillRect(1, 1, 31, 31, Qt::white);
       
  4289     p.end();
       
  4290 
       
  4291     QCOMPARE(img, expected);
       
  4292 }
       
  4293 
       
  4294 void tst_QPainter::taskQT4444_dontOverflowDashOffset()
       
  4295 {
       
  4296     QPainter p;
       
  4297 
       
  4298     QPen pen;
       
  4299     pen.setWidth(2);
       
  4300     pen.setStyle(Qt::DashDotLine);
       
  4301 
       
  4302     QPointF point[4];
       
  4303     point[0] = QPointF(182.50868749707968,347.78457234212630);
       
  4304     point[1] = QPointF(182.50868749707968,107.22501998401277);
       
  4305     point[2] = QPointF(182.50868749707968,107.22501998401277);
       
  4306     point[3] = QPointF(520.46600762283651,107.22501998401277);
       
  4307 
       
  4308     QImage crashImage(QSize(1000, 120), QImage::Format_ARGB32_Premultiplied);
       
  4309     p.begin(&crashImage);
       
  4310     p.setPen(pen);
       
  4311     p.drawLines(point, 2);
       
  4312     p.end();
       
  4313 
       
  4314     QVERIFY(true); // Don't crash
       
  4315 }
       
  4316 
       
  4317 void tst_QPainter::painterBegin()
       
  4318 {
       
  4319     QImage nullImage;
       
  4320     QImage indexed8Image(16, 16, QImage::Format_Indexed8);
       
  4321     QImage rgb32Image(16, 16, QImage::Format_RGB32);
       
  4322     QImage argb32Image(16, 16, QImage::Format_ARGB32_Premultiplied);
       
  4323 
       
  4324     QPainter p;
       
  4325 
       
  4326     // Painting on null image should fail.
       
  4327     QVERIFY(!p.begin(&nullImage));
       
  4328 
       
  4329     // Check that the painter is not messed up by using it on another image.
       
  4330     QVERIFY(p.begin(&rgb32Image));
       
  4331     QVERIFY(p.end());
       
  4332 
       
  4333     // If painting on indexed8 image fails, the painter state should still be OK.
       
  4334     if (p.begin(&indexed8Image))
       
  4335         QVERIFY(p.end());
       
  4336     QVERIFY(p.begin(&rgb32Image));
       
  4337     QVERIFY(p.end());
       
  4338 
       
  4339     // Try opening a painter on the two different images.
       
  4340     QVERIFY(p.begin(&rgb32Image));
       
  4341     QVERIFY(!p.begin(&argb32Image));
       
  4342     QVERIFY(p.end());
       
  4343 
       
  4344     // Try opening two painters on the same image.
       
  4345     QVERIFY(p.begin(&rgb32Image));
       
  4346     QPainter q;
       
  4347     QVERIFY(!q.begin(&rgb32Image));
       
  4348     QVERIFY(!q.end());
       
  4349     QVERIFY(p.end());
       
  4350 
       
  4351     // Try ending an inactive painter.
       
  4352     QVERIFY(!p.end());
       
  4353 }
       
  4354 
       
  4355 QTEST_MAIN(tst_QPainter)
       
  4356 #include "tst_qpainter.moc"