summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/painting
diff options
context:
space:
mode:
authorJo Asplin <jo.asplin@nokia.com>2011-08-31 17:11:06 +0200
committerJo Asplin <jo.asplin@nokia.com>2011-09-01 10:59:49 +0200
commita90f50942e5304e6bf1c8a3e32f1f65c7a38f60b (patch)
tree6ed9a3d0a0a3dd09a78593d89c000f29d3494b89 /tests/auto/gui/painting
parenta863eb1c7bbd5d40a741151f811bd7c62cf51e2d (diff)
Moved gui autotests into new directory structure
Task-number: QTBUG-21133 Change-Id: I83b8f652935cf92151265ca2530a3cf81c31fdef Reviewed-on: http://codereview.qt.nokia.com/3996 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Jo Asplin <jo.asplin@nokia.com>
Diffstat (limited to 'tests/auto/gui/painting')
-rw-r--r--tests/auto/gui/painting/painting.pro21
-rw-r--r--tests/auto/gui/painting/qbrush/.gitignore1
-rw-r--r--tests/auto/gui/painting/qbrush/qbrush.pro3
-rw-r--r--tests/auto/gui/painting/qbrush/tst_qbrush.cpp423
-rw-r--r--tests/auto/gui/painting/qcolor/.gitignore1
-rw-r--r--tests/auto/gui/painting/qcolor/qcolor.pro5
-rw-r--r--tests/auto/gui/painting/qcolor/tst_qcolor.cpp1538
-rw-r--r--tests/auto/gui/painting/qpaintengine/.gitignore1
-rw-r--r--tests/auto/gui/painting/qpaintengine/qpaintengine.pro9
-rw-r--r--tests/auto/gui/painting/qpaintengine/tst_qpaintengine.cpp99
-rw-r--r--tests/auto/gui/painting/qpainter/.gitignore2
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt0x0.pngbin0 -> 243 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt100x100.pngbin0 -> 245 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt200x200.pngbin0 -> 195 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt0x0.pngbin0 -> 461 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt100x100.pngbin0 -> 470 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt200x200.pngbin0 -> 195 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt0x0.pngbin0 -> 1294 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt100x100.pngbin0 -> 619 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt200x200.pngbin0 -> 195 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/dst.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_AndNotROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_AndROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_ClearROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_CopyROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NandROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NopROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NorROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotAndROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotCopyROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotOrROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotXorROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_OrNotROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_OrROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_SetROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_XorROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/dst1.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/dst2.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/dst3.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP0.pngbin0 -> 214 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP1.pngbin0 -> 247 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP2.pngbin0 -> 258 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP3.pngbin0 -> 253 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP4.pngbin0 -> 237 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP5.pngbin0 -> 260 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP6.pngbin0 -> 258 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP7.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP0.pngbin0 -> 173 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP1.pngbin0 -> 203 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP2.pngbin0 -> 217 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP3.pngbin0 -> 207 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP4.pngbin0 -> 196 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP5.pngbin0 -> 213 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP6.pngbin0 -> 218 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP7.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP0.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP1.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP2.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP3.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP4.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP5.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP6.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP7.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP0.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP1.pngbin0 -> 176 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP2.pngbin0 -> 175 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP3.pngbin0 -> 177 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP4.pngbin0 -> 176 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP5.pngbin0 -> 176 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP6.pngbin0 -> 176 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP7.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP0.pngbin0 -> 217 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP1.pngbin0 -> 242 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP2.pngbin0 -> 249 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP3.pngbin0 -> 244 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP4.pngbin0 -> 234 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP5.pngbin0 -> 254 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP6.pngbin0 -> 251 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP7.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP0.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP1.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP2.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP3.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP4.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP5.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP6.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP7.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP0.pngbin0 -> 211 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP1.pngbin0 -> 208 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP2.pngbin0 -> 215 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP3.pngbin0 -> 187 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP4.pngbin0 -> 213 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP5.pngbin0 -> 204 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP6.pngbin0 -> 198 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP7.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP0.pngbin0 -> 177 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP1.pngbin0 -> 198 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP2.pngbin0 -> 195 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP3.pngbin0 -> 185 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP4.pngbin0 -> 188 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP5.pngbin0 -> 198 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP6.pngbin0 -> 185 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP7.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP0.pngbin0 -> 168 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP1.pngbin0 -> 167 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP2.pngbin0 -> 167 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP3.pngbin0 -> 167 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP4.pngbin0 -> 167 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP5.pngbin0 -> 167 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP6.pngbin0 -> 167 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP7.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP0.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP1.pngbin0 -> 224 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP2.pngbin0 -> 229 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP3.pngbin0 -> 224 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP4.pngbin0 -> 198 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP5.pngbin0 -> 229 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP6.pngbin0 -> 227 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP7.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP0.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP1.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP2.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP3.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP4.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP5.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP6.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP7.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP0.pngbin0 -> 239 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP1.pngbin0 -> 237 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP2.pngbin0 -> 243 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP3.pngbin0 -> 226 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP4.pngbin0 -> 235 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP5.pngbin0 -> 230 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP6.pngbin0 -> 232 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP7.pngbin0 -> 184 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP0.pngbin0 -> 217 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP1.pngbin0 -> 213 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP2.pngbin0 -> 222 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP3.pngbin0 -> 194 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP4.pngbin0 -> 219 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP5.pngbin0 -> 215 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP6.pngbin0 -> 212 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP7.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP0.pngbin0 -> 186 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP1.pngbin0 -> 212 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP2.pngbin0 -> 216 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP3.pngbin0 -> 194 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP4.pngbin0 -> 207 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP5.pngbin0 -> 214 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP6.pngbin0 -> 208 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP7.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP0.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP1.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP2.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP3.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP4.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP5.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP6.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP7.pngbin0 -> 169 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP0.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP1.pngbin0 -> 255 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP2.pngbin0 -> 260 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP3.pngbin0 -> 251 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP4.pngbin0 -> 251 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP5.pngbin0 -> 261 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP6.pngbin0 -> 264 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP7.pngbin0 -> 228 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/src1.xbm12
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/src2-mask.xbm16
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/src2.xbm16
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop/src3.xbm12
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/dst.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_AndNotROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_AndROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_ClearROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_CopyROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NandROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NopROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NorROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotAndROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotCopyROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotOrROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotXorROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_OrNotROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_OrROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_SetROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_XorROP.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src1-mask.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src1.xbm6
-rw-r--r--tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src2.xbm5
-rw-r--r--tests/auto/gui/painting/qpainter/qpainter.pro20
-rw-r--r--tests/auto/gui/painting/qpainter/task217400.pngbin0 -> 526 bytes
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp4697
-rw-r--r--tests/auto/gui/painting/qpainter/utils/createImages/createImages.pro11
-rw-r--r--tests/auto/gui/painting/qpainter/utils/createImages/main.cpp194
-rw-r--r--tests/auto/gui/painting/qpainterpath/.gitignore2
-rw-r--r--tests/auto/gui/painting/qpainterpath/qpainterpath.pro5
-rw-r--r--tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp1332
-rw-r--r--tests/auto/gui/painting/qpainterpathstroker/.gitignore1
-rw-r--r--tests/auto/gui/painting/qpainterpathstroker/qpainterpathstroker.pro5
-rw-r--r--tests/auto/gui/painting/qpainterpathstroker/tst_qpainterpathstroker.cpp75
-rw-r--r--tests/auto/gui/painting/qpathclipper/.gitignore1
-rw-r--r--tests/auto/gui/painting/qpathclipper/pathcompare.h126
-rw-r--r--tests/auto/gui/painting/qpathclipper/paths.cpp734
-rw-r--r--tests/auto/gui/painting/qpathclipper/paths.h95
-rw-r--r--tests/auto/gui/painting/qpathclipper/qpathclipper.pro11
-rw-r--r--tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp1334
-rw-r--r--tests/auto/gui/painting/qpen/.gitignore1
-rw-r--r--tests/auto/gui/painting/qpen/qpen.pro5
-rw-r--r--tests/auto/gui/painting/qpen/tst_qpen.cpp226
-rw-r--r--tests/auto/gui/painting/qpolygon/.gitignore1
-rw-r--r--tests/auto/gui/painting/qpolygon/qpolygon.pro7
-rw-r--r--tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp105
-rw-r--r--tests/auto/gui/painting/qprinter/.gitignore4
-rw-r--r--tests/auto/gui/painting/qprinter/qprinter.pro5
-rw-r--r--tests/auto/gui/painting/qprinter/tst_qprinter.cpp1044
-rw-r--r--tests/auto/gui/painting/qprinterinfo/.gitignore1
-rw-r--r--tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro7
-rw-r--r--tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp401
-rw-r--r--tests/auto/gui/painting/qregion/.gitignore1
-rw-r--r--tests/auto/gui/painting/qregion/qregion.pro8
-rw-r--r--tests/auto/gui/painting/qregion/tst_qregion.cpp1012
-rw-r--r--tests/auto/gui/painting/qtransform/.gitignore1
-rw-r--r--tests/auto/gui/painting/qtransform/qtransform.pro7
-rw-r--r--tests/auto/gui/painting/qtransform/tst_qtransform.cpp807
-rw-r--r--tests/auto/gui/painting/qwmatrix/.gitignore1
-rw-r--r--tests/auto/gui/painting/qwmatrix/qwmatrix.pro6
-rw-r--r--tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp436
230 files changed, 15109 insertions, 0 deletions
diff --git a/tests/auto/gui/painting/painting.pro b/tests/auto/gui/painting/painting.pro
new file mode 100644
index 0000000000..62230eeac7
--- /dev/null
+++ b/tests/auto/gui/painting/painting.pro
@@ -0,0 +1,21 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qpainterpath \
+ qpainterpathstroker \
+ qcolor \
+ qbrush \
+ qregion \
+ qpainter \
+ qpathclipper \
+ qprinterinfo \
+ qpen \
+ qpaintengine \
+ qtransform \
+ qwmatrix \
+ qprinter \
+ qpolygon \
+
+!contains(QT_CONFIG, private_tests): SUBDIRS -= \
+ qpathclipper \
+
+
diff --git a/tests/auto/gui/painting/qbrush/.gitignore b/tests/auto/gui/painting/qbrush/.gitignore
new file mode 100644
index 0000000000..e9321a18bd
--- /dev/null
+++ b/tests/auto/gui/painting/qbrush/.gitignore
@@ -0,0 +1 @@
+tst_qbrush
diff --git a/tests/auto/gui/painting/qbrush/qbrush.pro b/tests/auto/gui/painting/qbrush/qbrush.pro
new file mode 100644
index 0000000000..1c3efd46be
--- /dev/null
+++ b/tests/auto/gui/painting/qbrush/qbrush.pro
@@ -0,0 +1,3 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qbrush.cpp
diff --git a/tests/auto/gui/painting/qbrush/tst_qbrush.cpp b/tests/auto/gui/painting/qbrush/tst_qbrush.cpp
new file mode 100644
index 0000000000..9ee679e0f7
--- /dev/null
+++ b/tests/auto/gui/painting/qbrush/tst_qbrush.cpp
@@ -0,0 +1,423 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include "qbrush.h"
+#include <QPainter>
+#include <QBitmap>
+
+#include <qdebug.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QBrush : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QBrush();
+
+private slots:
+ void operator_eq_eq();
+ void operator_eq_eq_data();
+
+ void stream();
+ void stream_data();
+
+ void badStyles();
+
+ void testQLinearGradientSetters();
+ void testQRadialGradientSetters();
+ void testQConicalGradientSetters();
+ void testQGradientCopyConstructor();
+
+ void gradientStops();
+
+ void textures();
+
+ void swap();
+ void nullBrush();
+ void isOpaque();
+ void debug();
+};
+
+Q_DECLARE_METATYPE(QBrush)
+
+tst_QBrush::tst_QBrush()
+{
+}
+
+void tst_QBrush::operator_eq_eq_data()
+{
+ QTest::addColumn<QBrush>("brush1");
+ QTest::addColumn<QBrush>("brush2");
+ QTest::addColumn<bool>("isEqual");
+
+ QLinearGradient lg(10, 10, 100, 100);
+ lg.setColorAt(0, Qt::red);
+ lg.setColorAt(0.5, Qt::blue);
+ lg.setColorAt(1, Qt::green);
+
+ QTest::newRow("black vs black") << QBrush(Qt::black) << QBrush(Qt::black) << true;
+ QTest::newRow("black vs blue") << QBrush(Qt::black) << QBrush(Qt::blue) << false;
+
+ QTest::newRow("red vs no") << QBrush(Qt::red) << QBrush(Qt::NoBrush) << false;
+ QTest::newRow("no vs no") << QBrush(Qt::NoBrush) << QBrush(Qt::NoBrush) << true;
+
+ QTest::newRow("lg vs same lg") << QBrush(lg) << QBrush(lg) << true;
+ QTest::newRow("lg vs diff lg") << QBrush(lg) << QBrush(QLinearGradient(QPoint(0, 0), QPoint(1, 1)))
+ << false;
+
+ QTest::newRow("rad vs con") << QBrush(QRadialGradient(0, 0, 0, 0, 0)) << QBrush(QConicalGradient(0, 0, 0)) << false;
+
+ QBrush b1(lg);
+ QBrush b2(lg);
+ b1.setTransform(QTransform().scale(2, 2));
+ QTest::newRow("lg with transform vs same lg") << b1 << b2 << false;
+
+ b2.setTransform(QTransform().scale(2, 2));
+ QTest::newRow("lg w/transform vs same lg w/same transform") << b1 << b2 << true;
+
+}
+
+void tst_QBrush::operator_eq_eq()
+{
+ QFETCH(QBrush, brush1);
+ QFETCH(QBrush, brush2);
+ QFETCH(bool, isEqual);
+ QCOMPARE(brush1 == brush2, isEqual);
+}
+
+void tst_QBrush::stream_data()
+{
+ QTest::addColumn<QBrush>("brush");
+
+ QLinearGradient lg(10, 10, 100, 100);
+ lg.setColorAt(0, Qt::red);
+ lg.setColorAt(0.5, Qt::blue);
+ lg.setColorAt(1, Qt::green);
+
+ QTest::newRow("black") << QBrush(Qt::black);
+ QTest::newRow("red") << QBrush(Qt::red);
+ QTest::newRow("no") << QBrush(Qt::NoBrush);
+ QTest::newRow("lg") << QBrush(lg);
+ QTest::newRow("rad") << QBrush(QRadialGradient(0, 0, 0, 0, 0));
+ QTest::newRow("con") << QBrush(QConicalGradient(0, 0, 0));
+}
+
+void tst_QBrush::stream()
+{
+ QFETCH(QBrush, brush);
+
+ QByteArray data;
+
+ {
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << brush;
+ }
+
+ QBrush cmp;
+ {
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ stream >> cmp;
+ }
+
+ QCOMPARE(brush.style(), cmp.style());
+ QCOMPARE(brush.color(), cmp.color());
+ QCOMPARE(brush, cmp);
+}
+
+void tst_QBrush::testQLinearGradientSetters()
+{
+ QLinearGradient lg;
+
+ QCOMPARE(lg.start(), QPointF(0, 0));
+ QCOMPARE(lg.finalStop(), QPointF(1, 1));
+
+ lg.setStart(101, 102);
+ QCOMPARE(lg.start(), QPointF(101, 102));
+
+ lg.setStart(QPointF(201, 202));
+ QCOMPARE(lg.start(), QPointF(201, 202));
+
+ lg.setFinalStop(103, 104);
+ QCOMPARE(lg.finalStop(), QPointF(103, 104));
+
+ lg.setFinalStop(QPointF(203, 204));
+ QCOMPARE(lg.finalStop(), QPointF(203, 204));
+}
+
+void tst_QBrush::testQRadialGradientSetters()
+{
+ QRadialGradient rg;
+
+ QCOMPARE(rg.radius(), qreal(1.0));
+ QCOMPARE(rg.center(), QPointF(0, 0));
+ QCOMPARE(rg.focalPoint(), QPointF(0, 0));
+
+ rg.setRadius(100);
+ QCOMPARE(rg.radius(), qreal(100.0));
+
+ rg.setCenter(101, 102);
+ QCOMPARE(rg.center(), QPointF(101, 102));
+
+ rg.setCenter(QPointF(201, 202));
+ QCOMPARE(rg.center(), QPointF(201, 202));
+
+ rg.setFocalPoint(103, 104);
+ QCOMPARE(rg.focalPoint(), QPointF(103, 104));
+
+ rg.setFocalPoint(QPointF(203, 204));
+ QCOMPARE(rg.focalPoint(), QPointF(203, 204));
+}
+
+void tst_QBrush::testQConicalGradientSetters()
+{
+ QConicalGradient cg;
+
+ QCOMPARE(cg.angle(), qreal(0.0));
+ QCOMPARE(cg.center(), QPointF(0, 0));
+
+ cg.setAngle(100);
+ QCOMPARE(cg.angle(), qreal(100.0));
+
+ cg.setCenter(102, 103);
+ QCOMPARE(cg.center(), QPointF(102, 103));
+
+ cg.setCenter(QPointF(202, 203));
+ QCOMPARE(cg.center(), QPointF(202, 203));
+}
+
+void tst_QBrush::testQGradientCopyConstructor()
+{
+ {
+ QLinearGradient lg1(101, 102, 103, 104);
+
+ QLinearGradient lg2 = lg1;
+ QCOMPARE(lg1.start(), lg2.start());
+ QCOMPARE(lg1.finalStop(), lg2.finalStop());
+
+ QGradient g = lg1;
+ QCOMPARE(((QLinearGradient *) &g)->start(), lg1.start());
+ QCOMPARE(((QLinearGradient *) &g)->finalStop(), lg1.finalStop());
+ }
+
+ {
+ QRadialGradient rg1(101, 102, 103, 104, 105);
+
+ QRadialGradient rg2 = rg1;
+ QCOMPARE(rg1.center(), rg2.center());
+ QCOMPARE(rg1.focalPoint(), rg2.focalPoint());
+ QCOMPARE(rg1.radius(), rg2.radius());
+
+ QGradient g = rg1;
+ QCOMPARE(((QRadialGradient *) &g)->center(), rg1.center());
+ QCOMPARE(((QRadialGradient *) &g)->focalPoint(), rg1.focalPoint());
+ QCOMPARE(((QRadialGradient *) &g)->radius(), rg1.radius());
+ }
+
+ {
+ QConicalGradient cg1(101, 102, 103);
+
+ QConicalGradient cg2 = cg1;
+ QCOMPARE(cg1.center(), cg2.center());
+ QCOMPARE(cg1.angle(), cg2.angle());
+
+ QGradient g = cg1;
+ QCOMPARE(((QConicalGradient *) &g)->center(), cg1.center());
+ QCOMPARE(((QConicalGradient *) &g)->angle(), cg1.angle());
+ }
+
+}
+
+void tst_QBrush::badStyles()
+{
+ // QBrush(Qt::BrushStyle) constructor
+ QCOMPARE(QBrush(Qt::LinearGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(Qt::RadialGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(Qt::ConicalGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(Qt::TexturePattern).style(), Qt::NoBrush);
+
+ // QBrush(QColor, Qt::BrushStyle) constructor
+ QCOMPARE(QBrush(QColor(0, 0, 0), Qt::LinearGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(QColor(0, 0, 0), Qt::RadialGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(QColor(0, 0, 0), Qt::ConicalGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(QColor(0, 0, 0), Qt::TexturePattern).style(), Qt::NoBrush);
+
+ // QBrush(Qt::GlobalColor, Qt::BrushStyle) constructor
+ QCOMPARE(QBrush(Qt::black, Qt::LinearGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(Qt::black, Qt::RadialGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(Qt::black, Qt::ConicalGradientPattern).style(), Qt::NoBrush);
+ QCOMPARE(QBrush(Qt::black, Qt::TexturePattern).style(), Qt::NoBrush);
+
+ // Set style...
+ QBrush brush(Qt::red);
+
+ brush.setStyle(Qt::LinearGradientPattern);
+ QCOMPARE(brush.style(), Qt::SolidPattern);
+
+ brush.setStyle(Qt::RadialGradientPattern);
+ QCOMPARE(brush.style(), Qt::SolidPattern);
+
+ brush.setStyle(Qt::ConicalGradientPattern);
+ QCOMPARE(brush.style(), Qt::SolidPattern);
+
+ brush.setStyle(Qt::TexturePattern);
+ QCOMPARE(brush.style(), Qt::SolidPattern);
+
+}
+
+void tst_QBrush::gradientStops()
+{
+ QLinearGradient gradient;
+ gradient.setColorAt(0, Qt::red);
+ gradient.setColorAt(1, Qt::blue);
+
+ QCOMPARE(gradient.stops().size(), 2);
+
+ QCOMPARE(gradient.stops().at(0), QGradientStop(0, QColor(Qt::red)));
+ QCOMPARE(gradient.stops().at(1), QGradientStop(1, QColor(Qt::blue)));
+
+ gradient.setColorAt(0, Qt::blue);
+ gradient.setColorAt(1, Qt::red);
+
+ QCOMPARE(gradient.stops().size(), 2);
+
+ QCOMPARE(gradient.stops().at(0), QGradientStop(0, QColor(Qt::blue)));
+ QCOMPARE(gradient.stops().at(1), QGradientStop(1, QColor(Qt::red)));
+
+ gradient.setColorAt(0.5, Qt::green);
+
+ QCOMPARE(gradient.stops().size(), 3);
+ QCOMPARE(gradient.stops().at(1), QGradientStop(0.5, QColor(Qt::green)));
+
+ // A hack in parseStopNode() in qsvghandler.cpp depends on inserting stops at NaN.
+ gradient.setStops(QGradientStops() << QGradientStop(qQNaN(), QColor()));
+ QCOMPARE(gradient.stops().size(), 1);
+ QVERIFY(qIsNaN(gradient.stops().at(0).first));
+ QCOMPARE(gradient.stops().at(0).second, QColor());
+}
+
+void fill(QPaintDevice *pd) {
+ QPainter p(pd);
+
+ int w = pd->width();
+ int h = pd->height();
+
+ p.fillRect(0, 0, w, h, Qt::white);
+ p.fillRect(0, 0, w/3, h/3, Qt::black);
+}
+
+void tst_QBrush::textures()
+{
+ QPixmap pixmap_source(10, 10);
+ QImage image_source(10, 10, QImage::Format_RGB32);
+
+ fill(&pixmap_source);
+ fill(&image_source);
+
+ // Create a pixmap brush and compare its texture and textureImage
+ // to the expected image
+ QBrush pixmap_brush;
+ pixmap_brush.setTexture(pixmap_source);
+ QImage image = pixmap_brush.texture().toImage().convertToFormat(QImage::Format_RGB32);
+ QCOMPARE(image, image_source);
+ image = pixmap_brush.textureImage().convertToFormat(QImage::Format_RGB32);
+ QCOMPARE(image, image_source);
+
+ pixmap_brush = QBrush(pixmap_source);
+ image = pixmap_brush.texture().toImage().convertToFormat(QImage::Format_RGB32);
+ QCOMPARE(image, image_source);
+ image = pixmap_brush.textureImage().convertToFormat(QImage::Format_RGB32);
+ QCOMPARE(image, image_source);
+
+ // Create a image brush and compare its texture and textureImage
+ // to the expected image
+ QBrush image_brush;
+ image_brush.setTextureImage(image_source);
+ image = image_brush.texture().toImage().convertToFormat(QImage::Format_RGB32);
+ QCOMPARE(image, image_source);
+ QCOMPARE(image_brush.textureImage(), image_source);
+
+ image_brush = QBrush(image_source);
+ image = image_brush.texture().toImage().convertToFormat(QImage::Format_RGB32);
+ QCOMPARE(image, image_source);
+ QCOMPARE(image_brush.textureImage(), image_source);
+}
+
+void tst_QBrush::swap()
+{
+ QBrush b1(Qt::black), b2(Qt::white);
+ b1.swap(b2);
+ QCOMPARE(b1.color(), QColor(Qt::white));
+ QCOMPARE(b2.color(), QColor(Qt::black));
+}
+
+void tst_QBrush::nullBrush()
+{
+ QBrush brush(QColor(100,0,0), Qt::NoBrush);
+ QCOMPARE(brush.color(), QColor(100,0,0));
+}
+
+void tst_QBrush::isOpaque()
+{
+ QBitmap bm(8, 8);
+ bm.fill(Qt::black);
+
+ QBrush brush(bm);
+ QVERIFY(!brush.isOpaque());
+}
+
+void tst_QBrush::debug()
+{
+ QPixmap pixmap_source(10, 10);
+ fill(&pixmap_source);
+ QBrush pixmap_brush;
+ pixmap_brush.setTexture(pixmap_source);
+ QCOMPARE(pixmap_brush.style(), Qt::TexturePattern);
+ qDebug() << pixmap_brush; // don't crash
+}
+
+QTEST_MAIN(tst_QBrush)
+#include "tst_qbrush.moc"
diff --git a/tests/auto/gui/painting/qcolor/.gitignore b/tests/auto/gui/painting/qcolor/.gitignore
new file mode 100644
index 0000000000..92f91eb54e
--- /dev/null
+++ b/tests/auto/gui/painting/qcolor/.gitignore
@@ -0,0 +1 @@
+tst_qcolor
diff --git a/tests/auto/gui/painting/qcolor/qcolor.pro b/tests/auto/gui/painting/qcolor/qcolor.pro
new file mode 100644
index 0000000000..b9d437ef7c
--- /dev/null
+++ b/tests/auto/gui/painting/qcolor/qcolor.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+SOURCES += tst_qcolor.cpp
+
+
+
diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
new file mode 100644
index 0000000000..2b6896ae5d
--- /dev/null
+++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
@@ -0,0 +1,1538 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <limits.h>
+
+#include <qcolor.h>
+#include <qdebug.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QColor : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QColor();
+
+private slots:
+ void getSetCheck();
+ void isValid_data();
+ void isValid();
+
+ void name_data();
+ void name();
+ void setNamedColor();
+
+ void constructNamedColorWithSpace();
+
+ void colorNames();
+
+ void spec();
+
+ void globalColors_data();
+ void globalColors();
+
+ void alpha();
+ void setAlpha();
+
+ void red();
+ void green();
+ void blue();
+
+ void setRed();
+ void setGreen();
+ void setBlue();
+
+ void getRgb();
+ void setRgb();
+
+ void rgba();
+ void setRgba();
+
+ void rgb();
+
+ void hue();
+ void saturation();
+ void value();
+
+ void getHsv();
+ void setHsv();
+
+ void cyan();
+ void magenta();
+ void yellow();
+ void black();
+
+ void getCmyk();
+ void setCmyk();
+
+ void hueHsl();
+ void saturationHsl();
+ void lightness();
+
+ void getHsl();
+ void setHsl();
+
+ void toRgb_data();
+ void toRgb();
+ void toRgbNonDestructive();
+
+ void toHsv_data();
+ void toHsv();
+ void toHsvNonDestructive();
+
+ void toCmyk_data();
+ void toCmyk();
+ void toCmykNonDestructive();
+
+ void toHsl_data();
+ void toHsl();;
+ void toHslNonDestructive();
+
+ void convertTo();
+
+ void fromRgb();
+ void fromHsv();
+ void fromCmyk();
+ void fromHsl();
+
+ void light();
+ void dark();
+
+ void assignmentOoperator();
+ void equalityOperator();
+
+ void specConstructor_data();
+ void specConstructor();
+
+ void achromaticHslHue();
+
+#ifdef Q_WS_X11
+ void allowX11ColorNames();
+ void setallowX11ColorNames();
+#endif
+};
+
+// Testing get/set functions
+void tst_QColor::getSetCheck()
+{
+ QColor obj1;
+ // int QColor::alpha()
+ // void QColor::setAlpha(int)
+ obj1.setAlpha(0);
+ QCOMPARE(obj1.alpha(), 0);
+ obj1.setAlpha(-1);
+ QCOMPARE(obj1.alpha(), 0); // range<0, 255>
+ obj1.setAlpha(INT_MIN);
+ QCOMPARE(obj1.alpha(), 0); // range<0, 255>
+ obj1.setAlpha(255);
+ QCOMPARE(obj1.alpha(), 255); // range<0, 255>
+ obj1.setAlpha(INT_MAX);
+ QCOMPARE(obj1.alpha(), 255); // range<0, 255>
+
+ // qreal QColor::alphaF()
+ // void QColor::setAlphaF(qreal)
+ obj1.setAlphaF(0.0);
+ QCOMPARE(obj1.alphaF(), qreal(0.0)); // range<0.0, 1.0>
+ obj1.setAlphaF(-0.2);
+ QCOMPARE(obj1.alphaF(), qreal(0.0)); // range<0.0, 1.0>
+ obj1.setAlphaF(1.0);
+ QCOMPARE(obj1.alphaF(), qreal(1.0)); // range<0.0, 1.0>
+ obj1.setAlphaF(1.1);
+ QCOMPARE(obj1.alphaF(), qreal(1.0)); // range<0.0, 1.0>
+
+ // int QColor::red()
+ // void QColor::setRed(int)
+ obj1.setRed(0);
+ QCOMPARE(obj1.red(), 0);
+ obj1.setRed(-1);
+ QCOMPARE(obj1.red(), 0); // range<0, 255>
+ obj1.setRed(INT_MIN);
+ QCOMPARE(obj1.red(), 0); // range<0, 255>
+ obj1.setRed(255);
+ QCOMPARE(obj1.red(), 255); // range<0, 255>
+ obj1.setRed(INT_MAX);
+ QCOMPARE(obj1.red(), 255); // range<0, 255>
+
+ // int QColor::green()
+ // void QColor::setGreen(int)
+ obj1.setGreen(0);
+ QCOMPARE(obj1.green(), 0);
+ obj1.setGreen(-1);
+ QCOMPARE(obj1.green(), 0); // range<0, 255>
+ obj1.setGreen(INT_MIN);
+ QCOMPARE(obj1.green(), 0); // range<0, 255>
+ obj1.setGreen(255);
+ QCOMPARE(obj1.green(), 255); // range<0, 255>
+ obj1.setGreen(INT_MAX);
+ QCOMPARE(obj1.green(), 255); // range<0, 255>
+
+ // int QColor::blue()
+ // void QColor::setBlue(int)
+ obj1.setBlue(0);
+ QCOMPARE(obj1.blue(), 0);
+ obj1.setBlue(-1);
+ QCOMPARE(obj1.blue(), 0); // range<0, 255>
+ obj1.setBlue(INT_MIN);
+ QCOMPARE(obj1.blue(), 0); // range<0, 255>
+ obj1.setBlue(255);
+ QCOMPARE(obj1.blue(), 255); // range<0, 255>
+ obj1.setBlue(INT_MAX);
+ QCOMPARE(obj1.blue(), 255); // range<0, 255>
+
+ // qreal QColor::redF()
+ // void QColor::setRedF(qreal)
+ obj1.setRedF(0.0);
+ QCOMPARE(obj1.redF(), qreal(0.0));
+ obj1.setRedF(-0.2);
+ QCOMPARE(obj1.redF(), qreal(0.0)); // range<0.0, 1.0
+ obj1.setRedF(1.1);
+ QCOMPARE(obj1.redF(), qreal(1.0)); // range<0.0, 1.0
+
+ // qreal QColor::greenF()
+ // void QColor::setGreenF(qreal)
+ obj1.setGreenF(0.0);
+ QCOMPARE(obj1.greenF(), qreal(0.0));
+ obj1.setGreenF(-0.2);
+ QCOMPARE(obj1.greenF(), qreal(0.0)); // range<0.0, 1.0
+ obj1.setGreenF(1.1);
+ QCOMPARE(obj1.greenF(), qreal(1.0)); // range<0.0, 1.0
+
+ // qreal QColor::blueF()
+ // void QColor::setBlueF(qreal)
+ obj1.setBlueF(0.0);
+ QCOMPARE(obj1.blueF(), qreal(0.0));
+ obj1.setBlueF(-0.2);
+ QCOMPARE(obj1.blueF(), qreal(0.0)); // range<0.0, 1.0
+ obj1.setBlueF(1.1);
+ QCOMPARE(obj1.blueF(), qreal(1.0)); // range<0.0, 1.0
+
+ // QRgb QColor::rgba()
+ // void QColor::setRgba(QRgb)
+ QRgb var9(qRgba(10, 20, 30, 40));
+ obj1.setRgba(var9);
+ QCOMPARE(obj1.rgba(), var9);
+ obj1.setRgba(QRgb(0));
+ QCOMPARE(obj1.rgba(), QRgb(0));
+
+ // QRgb QColor::rgb()
+ // void QColor::setRgb(QRgb)
+ QRgb var10(qRgb(10, 20, 30));
+ obj1.setRgb(var10);
+ QCOMPARE(obj1.rgb(), var10);
+ obj1.setRgb(QRgb(0));
+ QCOMPARE(obj1.rgb(), qRgb(0, 0, 0));
+}
+
+Q_DECLARE_METATYPE(QColor)
+
+
+tst_QColor::tst_QColor()
+
+{ }
+
+void tst_QColor::isValid_data()
+{
+ QTest::addColumn<QColor>("color");
+ QTest::addColumn<bool>("isValid");
+
+ QTest::newRow("defaultConstructor") << QColor() << false;
+ QTest::newRow("rgbConstructor-valid") << QColor(2,5,7) << true;
+ QTest::newRow("rgbConstructor-invalid") << QColor(2,5,999) << false;
+ QTest::newRow("nameQStringConstructor-valid") << QColor(QString("#ffffff")) << true;
+ QTest::newRow("nameQStringConstructor-invalid") << QColor(QString("#ffffgg")) << false;
+ QTest::newRow("nameQStringConstructor-empty") << QColor(QString("")) << false;
+ QTest::newRow("nameQStringConstructor-named") << QColor(QString("red")) << true;
+ QTest::newRow("nameCharConstructor-valid") << QColor("#ffffff") << true;
+ QTest::newRow("nameCharConstructor-invalid") << QColor("#ffffgg") << false;
+ QTest::newRow("nameCharConstructor-invalid-2") << QColor("#fffffg") << false;
+}
+
+void tst_QColor::isValid()
+{
+ QFETCH(QColor, color);
+ QFETCH(bool, isValid);
+ QVERIFY(color.isValid() == isValid);
+}
+
+void tst_QColor::name_data()
+{
+ QTest::addColumn<QColor>("color");
+ QTest::addColumn<QString>("name");
+
+ QTest::newRow("invalid") << QColor() << "#000000";
+ QTest::newRow("global color black") << QColor(Qt::black) << "#000000";
+ QTest::newRow("global color white") << QColor(Qt::white) << "#ffffff";
+ QTest::newRow("global color darkGray") << QColor(Qt::darkGray) << "#808080";
+ QTest::newRow("global color gray") << QColor(Qt::gray) << "#a0a0a4";
+ QTest::newRow("global color lightGray") << QColor(Qt::lightGray) << "#c0c0c0";
+ QTest::newRow("global color red") << QColor(Qt::red) << "#ff0000";
+ QTest::newRow("global color green") << QColor(Qt::green) << "#00ff00";
+ QTest::newRow("global color blue") << QColor(Qt::blue) << "#0000ff";
+ QTest::newRow("global color cyan") << QColor(Qt::cyan) << "#00ffff";
+ QTest::newRow("global color magenta") << QColor(Qt::magenta) << "#ff00ff";
+ QTest::newRow("global color yellow") << QColor(Qt::yellow) << "#ffff00";
+ QTest::newRow("global color darkRed") << QColor(Qt::darkRed) << "#800000";
+ QTest::newRow("global color darkGreen") << QColor(Qt::darkGreen) << "#008000";
+ QTest::newRow("global color darkBlue") << QColor(Qt::darkBlue) << "#000080";
+ QTest::newRow("global color darkCyan") << QColor(Qt::darkCyan) << "#008080";
+ QTest::newRow("global color darkMagenta") << QColor(Qt::darkMagenta) << "#800080";
+ QTest::newRow("global color darkYellow") << QColor(Qt::darkYellow) << "#808000";
+}
+
+void tst_QColor::name()
+{
+ QFETCH(QColor, color);
+ QFETCH(QString, name);
+ QCOMPARE(color.name(), name);
+}
+
+void tst_QColor::globalColors_data()
+{
+ QTest::addColumn<QColor>("color");
+ QTest::addColumn<uint>("argb");
+
+ QTest::newRow("invalid") << QColor() << 0xff000000;
+ QTest::newRow("global color black") << QColor(Qt::black) << 0xff000000;
+ QTest::newRow("global color white") << QColor(Qt::white) << 0xffffffff;
+ QTest::newRow("global color darkGray") << QColor(Qt::darkGray) << 0xff808080;
+ QTest::newRow("global color gray") << QColor(Qt::gray) << 0xffa0a0a4;
+ QTest::newRow("global color lightGray") << QColor(Qt::lightGray) << 0xffc0c0c0;
+ QTest::newRow("global color red") << QColor(Qt::red) << 0xffff0000;
+ QTest::newRow("global color green") << QColor(Qt::green) << 0xff00ff00;
+ QTest::newRow("global color blue") << QColor(Qt::blue) << 0xff0000ff;
+ QTest::newRow("global color cyan") << QColor(Qt::cyan) << 0xff00ffff;
+ QTest::newRow("global color magenta") << QColor(Qt::magenta) << 0xffff00ff;
+ QTest::newRow("global color yellow") << QColor(Qt::yellow) << 0xffffff00;
+ QTest::newRow("global color darkRed") << QColor(Qt::darkRed) << 0xff800000;
+ QTest::newRow("global color darkGreen") << QColor(Qt::darkGreen) << 0xff008000;
+ QTest::newRow("global color darkBlue") << QColor(Qt::darkBlue) << 0xff000080;
+ QTest::newRow("global color darkCyan") << QColor(Qt::darkCyan) << 0xff008080;
+ QTest::newRow("global color darkMagenta") << QColor(Qt::darkMagenta) << 0xff800080;
+ QTest::newRow("global color darkYellow") << QColor(Qt::darkYellow) << 0xff808000;
+ QTest::newRow("global color transparent") << QColor(Qt::transparent) << 0x00000000u;
+}
+
+
+void tst_QColor::globalColors()
+{
+ QFETCH(QColor, color);
+ QFETCH(uint, argb);
+ QCOMPARE(color.rgba(), argb);
+}
+
+/*
+ CSS color names = SVG 1.0 color names + transparent (rgba(0,0,0,0))
+*/
+
+#ifdef rgb
+# undef rgb
+#endif
+#define rgb(r,g,b) (0xff000000 | r << 16 | g << 8 | b)
+
+static const struct RGBData {
+ const char *name;
+ uint value;
+} rgbTbl[] = {
+ { "aliceblue", rgb(240, 248, 255) },
+ { "antiquewhite", rgb(250, 235, 215) },
+ { "aqua", rgb( 0, 255, 255) },
+ { "aquamarine", rgb(127, 255, 212) },
+ { "azure", rgb(240, 255, 255) },
+ { "beige", rgb(245, 245, 220) },
+ { "bisque", rgb(255, 228, 196) },
+ { "black", rgb( 0, 0, 0) },
+ { "blanchedalmond", rgb(255, 235, 205) },
+ { "blue", rgb( 0, 0, 255) },
+ { "blueviolet", rgb(138, 43, 226) },
+ { "brown", rgb(165, 42, 42) },
+ { "burlywood", rgb(222, 184, 135) },
+ { "cadetblue", rgb( 95, 158, 160) },
+ { "chartreuse", rgb(127, 255, 0) },
+ { "chocolate", rgb(210, 105, 30) },
+ { "coral", rgb(255, 127, 80) },
+ { "cornflowerblue", rgb(100, 149, 237) },
+ { "cornsilk", rgb(255, 248, 220) },
+ { "crimson", rgb(220, 20, 60) },
+ { "cyan", rgb( 0, 255, 255) },
+ { "darkblue", rgb( 0, 0, 139) },
+ { "darkcyan", rgb( 0, 139, 139) },
+ { "darkgoldenrod", rgb(184, 134, 11) },
+ { "darkgray", rgb(169, 169, 169) },
+ { "darkgreen", rgb( 0, 100, 0) },
+ { "darkgrey", rgb(169, 169, 169) },
+ { "darkkhaki", rgb(189, 183, 107) },
+ { "darkmagenta", rgb(139, 0, 139) },
+ { "darkolivegreen", rgb( 85, 107, 47) },
+ { "darkorange", rgb(255, 140, 0) },
+ { "darkorchid", rgb(153, 50, 204) },
+ { "darkred", rgb(139, 0, 0) },
+ { "darksalmon", rgb(233, 150, 122) },
+ { "darkseagreen", rgb(143, 188, 143) },
+ { "darkslateblue", rgb( 72, 61, 139) },
+ { "darkslategray", rgb( 47, 79, 79) },
+ { "darkslategrey", rgb( 47, 79, 79) },
+ { "darkturquoise", rgb( 0, 206, 209) },
+ { "darkviolet", rgb(148, 0, 211) },
+ { "deeppink", rgb(255, 20, 147) },
+ { "deepskyblue", rgb( 0, 191, 255) },
+ { "dimgray", rgb(105, 105, 105) },
+ { "dimgrey", rgb(105, 105, 105) },
+ { "dodgerblue", rgb( 30, 144, 255) },
+ { "firebrick", rgb(178, 34, 34) },
+ { "floralwhite", rgb(255, 250, 240) },
+ { "forestgreen", rgb( 34, 139, 34) },
+ { "fuchsia", rgb(255, 0, 255) },
+ { "gainsboro", rgb(220, 220, 220) },
+ { "ghostwhite", rgb(248, 248, 255) },
+ { "gold", rgb(255, 215, 0) },
+ { "goldenrod", rgb(218, 165, 32) },
+ { "gray", rgb(128, 128, 128) },
+ { "green", rgb( 0, 128, 0) },
+ { "greenyellow", rgb(173, 255, 47) },
+ { "grey", rgb(128, 128, 128) },
+ { "honeydew", rgb(240, 255, 240) },
+ { "hotpink", rgb(255, 105, 180) },
+ { "indianred", rgb(205, 92, 92) },
+ { "indigo", rgb( 75, 0, 130) },
+ { "ivory", rgb(255, 255, 240) },
+ { "khaki", rgb(240, 230, 140) },
+ { "lavender", rgb(230, 230, 250) },
+ { "lavenderblush", rgb(255, 240, 245) },
+ { "lawngreen", rgb(124, 252, 0) },
+ { "lemonchiffon", rgb(255, 250, 205) },
+ { "lightblue", rgb(173, 216, 230) },
+ { "lightcoral", rgb(240, 128, 128) },
+ { "lightcyan", rgb(224, 255, 255) },
+ { "lightgoldenrodyellow", rgb(250, 250, 210) },
+ { "lightgray", rgb(211, 211, 211) },
+ { "lightgreen", rgb(144, 238, 144) },
+ { "lightgrey", rgb(211, 211, 211) },
+ { "lightpink", rgb(255, 182, 193) },
+ { "lightsalmon", rgb(255, 160, 122) },
+ { "lightseagreen", rgb( 32, 178, 170) },
+ { "lightskyblue", rgb(135, 206, 250) },
+ { "lightslategray", rgb(119, 136, 153) },
+ { "lightslategrey", rgb(119, 136, 153) },
+ { "lightsteelblue", rgb(176, 196, 222) },
+ { "lightyellow", rgb(255, 255, 224) },
+ { "lime", rgb( 0, 255, 0) },
+ { "limegreen", rgb( 50, 205, 50) },
+ { "linen", rgb(250, 240, 230) },
+ { "magenta", rgb(255, 0, 255) },
+ { "maroon", rgb(128, 0, 0) },
+ { "mediumaquamarine", rgb(102, 205, 170) },
+ { "mediumblue", rgb( 0, 0, 205) },
+ { "mediumorchid", rgb(186, 85, 211) },
+ { "mediumpurple", rgb(147, 112, 219) },
+ { "mediumseagreen", rgb( 60, 179, 113) },
+ { "mediumslateblue", rgb(123, 104, 238) },
+ { "mediumspringgreen", rgb( 0, 250, 154) },
+ { "mediumturquoise", rgb( 72, 209, 204) },
+ { "mediumvioletred", rgb(199, 21, 133) },
+ { "midnightblue", rgb( 25, 25, 112) },
+ { "mintcream", rgb(245, 255, 250) },
+ { "mistyrose", rgb(255, 228, 225) },
+ { "moccasin", rgb(255, 228, 181) },
+ { "navajowhite", rgb(255, 222, 173) },
+ { "navy", rgb( 0, 0, 128) },
+ { "oldlace", rgb(253, 245, 230) },
+ { "olive", rgb(128, 128, 0) },
+ { "olivedrab", rgb(107, 142, 35) },
+ { "orange", rgb(255, 165, 0) },
+ { "orangered", rgb(255, 69, 0) },
+ { "orchid", rgb(218, 112, 214) },
+ { "palegoldenrod", rgb(238, 232, 170) },
+ { "palegreen", rgb(152, 251, 152) },
+ { "paleturquoise", rgb(175, 238, 238) },
+ { "palevioletred", rgb(219, 112, 147) },
+ { "papayawhip", rgb(255, 239, 213) },
+ { "peachpuff", rgb(255, 218, 185) },
+ { "peru", rgb(205, 133, 63) },
+ { "pink", rgb(255, 192, 203) },
+ { "plum", rgb(221, 160, 221) },
+ { "powderblue", rgb(176, 224, 230) },
+ { "purple", rgb(128, 0, 128) },
+ { "red", rgb(255, 0, 0) },
+ { "rosybrown", rgb(188, 143, 143) },
+ { "royalblue", rgb( 65, 105, 225) },
+ { "saddlebrown", rgb(139, 69, 19) },
+ { "salmon", rgb(250, 128, 114) },
+ { "sandybrown", rgb(244, 164, 96) },
+ { "seagreen", rgb( 46, 139, 87) },
+ { "seashell", rgb(255, 245, 238) },
+ { "sienna", rgb(160, 82, 45) },
+ { "silver", rgb(192, 192, 192) },
+ { "skyblue", rgb(135, 206, 235) },
+ { "slateblue", rgb(106, 90, 205) },
+ { "slategray", rgb(112, 128, 144) },
+ { "slategrey", rgb(112, 128, 144) },
+ { "snow", rgb(255, 250, 250) },
+ { "springgreen", rgb( 0, 255, 127) },
+ { "steelblue", rgb( 70, 130, 180) },
+ { "tan", rgb(210, 180, 140) },
+ { "teal", rgb( 0, 128, 128) },
+ { "thistle", rgb(216, 191, 216) },
+ { "tomato", rgb(255, 99, 71) },
+ { "transparent", 0 },
+ { "turquoise", rgb( 64, 224, 208) },
+ { "violet", rgb(238, 130, 238) },
+ { "wheat", rgb(245, 222, 179) },
+ { "white", rgb(255, 255, 255) },
+ { "whitesmoke", rgb(245, 245, 245) },
+ { "yellow", rgb(255, 255, 0) },
+ { "yellowgreen", rgb(154, 205, 50) }
+};
+static const int rgbTblSize = sizeof(rgbTbl) / sizeof(RGBData);
+
+#undef rgb
+
+void tst_QColor::setNamedColor()
+{
+ for (int i = 0; i < rgbTblSize; ++i) {
+ QColor color;
+ color.setNamedColor(QLatin1String(rgbTbl[i].name));
+ QColor expected;
+ expected.setRgba(rgbTbl[i].value);
+ QCOMPARE(color, expected);
+ }
+}
+
+void tst_QColor::constructNamedColorWithSpace()
+{
+ QColor whiteSmoke("white smoke");
+ QCOMPARE(whiteSmoke, QColor(245, 245, 245));
+}
+
+void tst_QColor::colorNames()
+{
+ DEPENDS_ON("setNamedColor()");
+
+ QStringList all = QColor::colorNames();
+ QCOMPARE(all.size(), rgbTblSize);
+ for (int i = 0; i < all.size(); ++i)
+ QCOMPARE(all.at(i), QString::fromLatin1(rgbTbl[i].name));
+}
+
+void tst_QColor::spec()
+{
+ QColor invalid;
+ QCOMPARE(invalid.spec(), QColor::Invalid);
+
+ QColor rgb = QColor::fromRgb(0, 0, 0);
+ QCOMPARE(rgb.spec(), QColor::Rgb);
+
+ QColor hsv = QColor::fromHsv(0, 0, 0);
+ QCOMPARE(hsv.spec(), QColor::Hsv);
+
+ QColor cmyk = QColor::fromCmyk(0, 0, 0, 0);
+ QCOMPARE(cmyk.spec(), QColor::Cmyk);
+
+ QColor hsl = QColor::fromHsl(0, 0, 0, 0);
+ QCOMPARE(hsl.spec(), QColor::Hsl);
+
+}
+
+void tst_QColor::alpha()
+{ DEPENDS_ON(setRgb()); }
+
+void tst_QColor::red()
+{ DEPENDS_ON(setRgb()); }
+
+void tst_QColor::green()
+{ DEPENDS_ON(setRgb()); }
+
+void tst_QColor::blue()
+{ DEPENDS_ON(setRgb()); }
+
+void tst_QColor::getRgb()
+{ DEPENDS_ON(setRgb()); }
+
+void tst_QColor::setAlpha()
+{ DEPENDS_ON(setRgb()); }
+
+bool veryFuzzyCompare(double a, double b)
+{
+ return qAbs(a - b) < 0.01;
+}
+
+void tst_QColor::setRed()
+{
+ DEPENDS_ON(setRgb());
+
+ QColor c = QColor(Qt::blue).toHsv();
+ c.setRed(127);
+ QCOMPARE(c.red(), 127);
+ QCOMPARE(c.green(), 0);
+ QCOMPARE(c.blue(), 255);
+
+ c = QColor(Qt::blue).toHsv();
+ c.setRedF(0.5);
+ QVERIFY(veryFuzzyCompare(c.redF(), 0.5));
+ QCOMPARE(c.greenF(), qreal(0.0));
+ QCOMPARE(c.blueF(), qreal(1.0));
+}
+
+void tst_QColor::setGreen()
+{
+ DEPENDS_ON(setRgb());
+
+ QColor c = QColor(Qt::blue).toHsv();
+ c.setGreen(127);
+ QCOMPARE(c.red(), 0);
+ QCOMPARE(c.green(), 127);
+ QCOMPARE(c.blue(), 255);
+
+ c = QColor(Qt::blue).toHsv();
+ c.setGreenF(0.5);
+ QCOMPARE(c.redF(), qreal(0.0));
+ QVERIFY(veryFuzzyCompare(c.greenF(), 0.5));
+ QCOMPARE(c.blueF(), qreal(1.0));
+}
+
+void tst_QColor::setBlue()
+{
+ DEPENDS_ON(setRgb());
+
+ QColor c = QColor(Qt::red).toHsv();
+ c.setBlue(127);
+ QCOMPARE(c.red(), 255);
+ QCOMPARE(c.green(), 0);
+ QCOMPARE(c.blue(), 127);
+
+ c = QColor(Qt::red).toHsv();
+ c.setBlueF(0.5);
+ QCOMPARE(c.redF(), qreal(1.0));
+ QCOMPARE(c.greenF(), qreal(0.0));
+ QVERIFY(veryFuzzyCompare(c.blueF(), 0.5));
+}
+
+
+void tst_QColor::setRgb()
+{
+ QColor color;
+
+ for (int A = 0; A <= USHRT_MAX; ++A) {
+ {
+ // 0-255
+ int a = A >> 8;
+ QRgb rgb = qRgba(0, 0, 0, a);
+
+ color.setRgb(0, 0, 0, a);
+ QCOMPARE(color.alpha(), a);
+ QCOMPARE(color.rgb(), qRgb(0, 0, 0));
+
+ color.setRgb(rgb);
+ QCOMPARE(color.alpha(), 255);
+ QCOMPARE(color.rgb(), qRgb(0, 0, 0));
+
+ int r, g, b, a2;
+ color.setRgb(0, 0, 0, a);
+ color.getRgb(&r, &g, &b, &a2);
+ QCOMPARE(a2, a);
+
+ QColor c(0, 0, 0);
+ c.setAlpha(a);
+ QCOMPARE(c.alpha(), a);
+ }
+
+ {
+ // 0.0-1.0
+ qreal a = A / qreal(USHRT_MAX);
+ color.setRgbF(0.0, 0.0, 0.0, a);
+ QCOMPARE(color.alphaF(), a);
+
+ qreal r, g, b, a2;
+ color.getRgbF(&r, &g, &b, &a2);
+ QCOMPARE(a2, a);
+
+ QColor c(0, 0, 0);
+ c.setAlphaF(a);
+
+ QCOMPARE(c.alphaF(), a);
+ }
+ }
+
+ for (int R = 0; R <= USHRT_MAX; ++R) {
+ {
+ // 0-255
+ int r = R >> 8;
+ QRgb rgb = qRgb(r, 0, 0);
+
+ color.setRgb(r, 0, 0);
+ QCOMPARE(color.red(), r);
+ QCOMPARE(color.rgb(), rgb);
+
+ color.setRgb(rgb);
+ QCOMPARE(color.red(), r);
+ QCOMPARE(color.rgb(), rgb);
+
+ int r2, g, b, a;
+ color.getRgb(&r2, &g, &b, &a);
+ QCOMPARE(r2, r);
+ }
+
+ {
+ // 0.0-1.0
+ qreal r = R / qreal(USHRT_MAX);
+ color.setRgbF(r, 0.0, 0.0);
+ QCOMPARE(color.redF(), r);
+
+ qreal r2, g, b, a;
+ color.getRgbF(&r2, &g, &b, &a);
+ QCOMPARE(r2, r);
+ }
+ }
+
+ for (int G = 0; G <= USHRT_MAX; ++G) {
+ {
+ // 0-255
+ int g = G >> 8;
+ QRgb rgb = qRgb(0, g, 0);
+
+ color.setRgb(0, g, 0);
+ QCOMPARE(color.green(), g);
+ QCOMPARE(color.rgb(), rgb);
+
+ color.setRgb(rgb);
+ QCOMPARE(color.green(), g);
+ QCOMPARE(color.rgb(), rgb);
+
+ int r, g2, b, a;
+ color.getRgb(&r, &g2, &b, &a);
+ QCOMPARE(g2, g);
+ }
+
+ {
+ // 0.0-1.0
+ qreal g = G / qreal(USHRT_MAX);
+ color.setRgbF(0.0, g, 0.0);
+ QCOMPARE(color.greenF(), g);
+
+ qreal r, g2, b, a;
+ color.getRgbF(&r, &g2, &b, &a);
+ QCOMPARE(g2, g);
+ }
+ }
+
+ for (int B = 0; B <= USHRT_MAX; ++B) {
+ {
+ // 0-255
+ int b = B >> 8;
+ QRgb rgb = qRgb(0, 0, b);
+
+ color.setRgb(0, 0, b);
+ QCOMPARE(color.blue(), b);
+ QCOMPARE(color.rgb(), rgb);
+
+ color.setRgb(rgb);
+ QCOMPARE(color.blue(), b);
+ QCOMPARE(color.rgb(), rgb);
+
+ int r, g, b2, a;
+ color.getRgb(&r, &g, &b2, &a);
+ QCOMPARE(b2, b);
+ }
+
+ {
+ // 0.0-1.0
+ qreal b = B / qreal(USHRT_MAX);
+ color.setRgbF(0.0, 0.0, b);
+ QCOMPARE(color.blueF(), b);
+
+ qreal r, g, b2, a;
+ color.getRgbF(&r, &g, &b2, &a);
+ QCOMPARE(b2, b);
+ }
+ }
+}
+
+void tst_QColor::rgba()
+{ DEPENDS_ON("setRgba()"); }
+
+void tst_QColor::setRgba()
+{
+ for (int a = 0; a < 255; ++a) {
+ const QRgb rgba1 = qRgba(a, a, a, a);
+ QColor color;
+ color.setRgba(rgba1);
+ QCOMPARE(color.alpha(), a);
+ const QRgb rgba2 = color.rgba();
+ QCOMPARE(rgba2, rgba1);
+ QCOMPARE(qAlpha(rgba2), a);
+ }
+}
+
+void tst_QColor::rgb()
+{ DEPENDS_ON(setRgb()); }
+
+void tst_QColor::hue()
+{ DEPENDS_ON(setHsv()); }
+
+void tst_QColor::saturation()
+{ DEPENDS_ON(setHsv()); }
+
+void tst_QColor::value()
+{ DEPENDS_ON(setHsv()); }
+
+void tst_QColor::getHsv()
+{ DEPENDS_ON(setHsv()); }
+
+void tst_QColor::setHsv()
+{
+ QColor color;
+
+ for (int A = 0; A <= USHRT_MAX; ++A) {
+ {
+ // 0-255
+ int a = A >> 8;
+ color.setHsv(0, 0, 0, a);
+ QCOMPARE(color.alpha(), a);
+
+ int h, s, v, a2;
+ color.getHsv(&h, &s, &v, &a2);
+ QCOMPARE(a2, a);
+ }
+
+ {
+ // 0.0-1.0
+ qreal a = A / qreal(USHRT_MAX);
+ color.setHsvF(0.0, 0.0, 0.0, a); QCOMPARE(color.alphaF(), a);
+
+ qreal h, s, v, a2;
+ color.getHsvF(&h, &s, &v, &a2);
+ QCOMPARE(a2, a);
+ }
+ }
+
+ for (int H = 0; H < 36000; ++H) {
+ {
+ // 0-255
+ int h = H / 100;
+
+ color.setHsv(h, 0, 0, 0);
+ QCOMPARE(color.hue(), h);
+
+ int h2, s, v, a;
+ color.getHsv(&h2, &s, &v, &a);
+ QCOMPARE(h2, h);
+ }
+
+ {
+ // 0.0-1.0
+ qreal h = H / 36000.0;
+ color.setHsvF(h, 0.0, 0.0, 0.0);
+ QCOMPARE(color.hueF(), h);
+
+ qreal h2, s, v, a;
+ color.getHsvF(&h2, &s, &v, &a);
+ QCOMPARE(h2, h);
+ }
+ }
+
+ for (int S = 0; S <= USHRT_MAX; ++S) {
+ {
+ // 0-255
+ int s = S >> 8;
+ color.setHsv(0, s, 0, 0);
+ QCOMPARE(color.saturation(), s);
+
+ int h, s2, v, a;
+ color.getHsv(&h, &s2, &v, &a);
+ QCOMPARE(s2, s);
+ }
+
+ {
+ // 0.0-1.0
+ qreal s = S / qreal(USHRT_MAX);
+ color.setHsvF(0.0, s, 0.0, 0.0);
+ QCOMPARE(color.saturationF(), s);
+
+ qreal h, s2, v, a;
+ color.getHsvF(&h, &s2, &v, &a);
+ QCOMPARE(s2, s);
+ }
+ }
+
+ for (int V = 0; V <= USHRT_MAX; ++V) {
+ {
+ // 0-255
+ int v = V >> 8;
+ color.setHsv(0, 0, v, 0);
+ QCOMPARE(color.value(), v);
+
+ int h, s, v2, a;
+ color.getHsv(&h, &s, &v2, &a);
+ QCOMPARE(v2, v);
+ }
+
+ {
+ // 0.0-1.0
+ qreal v = V / qreal(USHRT_MAX);
+ color.setHsvF(0.0, 0.0, v, 0.0);
+ QCOMPARE(color.valueF(), v);
+
+ qreal h, s, v2, a;
+ color.getHsvF(&h, &s, &v2, &a);
+ QCOMPARE(v2, v);
+ }
+ }
+}
+
+void tst_QColor::cyan()
+{ DEPENDS_ON(setCmyk()); }
+
+void tst_QColor::magenta()
+{ DEPENDS_ON(setCmyk()); }
+
+void tst_QColor::yellow()
+{ DEPENDS_ON(setCmyk()); }
+
+void tst_QColor::black()
+{ DEPENDS_ON(setCmyk()); }
+
+void tst_QColor::getCmyk()
+{ DEPENDS_ON(setCmyk()); }
+
+void tst_QColor::setCmyk()
+{
+ QColor color;
+
+ for (int A = 0; A <= USHRT_MAX; ++A) {
+ {
+ // 0-255
+ int a = A >> 8;
+ color.setCmyk(0, 0, 0, 0, a);
+ QCOMPARE(color.alpha(), a);
+
+ int c, m, y, k, a2;
+ color.getCmyk(&c, &m, &y, &k, &a2);
+ QCOMPARE(a2, a);
+ }
+
+ {
+ // 0.0-1.0
+ qreal a = A / qreal(USHRT_MAX);
+ color.setCmykF(0.0, 0.0, 0.0, 0.0, a);
+ QCOMPARE(color.alphaF(), a);
+
+ qreal c, m, y, k, a2;
+ color.getCmykF(&c, &m, &y, &k, &a2);
+ QCOMPARE(a2, a);
+ }
+ }
+
+ for (int C = 0; C <= USHRT_MAX; ++C) {
+ {
+ // 0-255
+ int c = C >> 8;
+ color.setCmyk(c, 0, 0, 0, 0);
+ QCOMPARE(color.cyan(), c);
+
+ int c2, m, y, k, a;
+ color.getCmyk(&c2, &m, &y, &k, &a);
+ QCOMPARE(c2, c);
+ }
+
+ {
+ // 0.0-1.0
+ qreal c = C / qreal(USHRT_MAX);
+ color.setCmykF(c, 0.0, 0.0, 0.0, 0.0);
+ QCOMPARE(color.cyanF(), c);
+
+ qreal c2, m, y, k, a;
+ color.getCmykF(&c2, &m, &y, &k, &a);
+ QCOMPARE(c2, c);
+ }
+ }
+
+ for (int M = 0; M <= USHRT_MAX; ++M) {
+ {
+ // 0-255
+ int m = M >> 8;
+ color.setCmyk(0, m, 0, 0, 0);
+ QCOMPARE(color.magenta(), m);
+
+ int c, m2, y, k, a;
+ color.getCmyk(&c, &m2, &y, &k, &a);
+ QCOMPARE(m2, m);
+ }
+
+ {
+ // 0.0-1.0
+ qreal m = M / qreal(USHRT_MAX);
+ color.setCmykF(0.0, m, 0.0, 0.0, 0.0);
+ QCOMPARE(color.magentaF(), m);
+
+ qreal c, m2, y, k, a;
+ color.getCmykF(&c, &m2, &y, &k, &a);
+ QCOMPARE(m2, m);
+ }
+ }
+
+ for (int Y = 0; Y <= USHRT_MAX; ++Y) {
+ {
+ // 0-255
+ int y = Y >> 8;
+ color.setCmyk(0, 0, y, 0, 0);
+ QCOMPARE(color.yellow(), y);
+
+ int c, m, y2, k, a;
+ color.getCmyk(&c, &m, &y2, &k, &a);
+ QCOMPARE(y2, y);
+ }
+
+ {
+ // 0.0-1.0
+ qreal y = Y / qreal(USHRT_MAX);
+ color.setCmykF(0.0, 0.0, y, 0.0, 0.0);
+ QCOMPARE(color.yellowF(), y);
+
+ qreal c, m, y2, k, a;
+ color.getCmykF(&c, &m, &y2, &k, &a);
+ QCOMPARE(y2, y);
+ }
+ }
+
+ for (int K = 0; K <= USHRT_MAX; ++K) {
+ {
+ // 0-255
+ int k = K >> 8;
+ color.setCmyk(0, 0, 0, k, 0);
+ QCOMPARE(color.black(), k);
+
+ int c, m, y, k2, a;
+ color.getCmyk(&c, &m, &y, &k2, &a);
+ QCOMPARE(k2, k);
+ }
+
+ {
+ // 0.0-1.0
+ qreal k = K / qreal(USHRT_MAX);
+ color.setCmykF(0.0, 0.0, 0.0, k, 0.0);
+ QCOMPARE(color.blackF(), k);
+
+ qreal c, m, y, k2, a;
+ color.getCmykF(&c, &m, &y, &k2, &a);
+ QCOMPARE(k2, k);
+ }
+ }
+}
+
+void tst_QColor::hueHsl()
+{ DEPENDS_ON(setHsl()); }
+
+void tst_QColor::saturationHsl()
+{ DEPENDS_ON(setHsl()); }
+
+void tst_QColor::lightness()
+{ DEPENDS_ON(setHsl()); }
+
+void tst_QColor::getHsl()
+{ DEPENDS_ON(setHsl()); }
+
+void tst_QColor::setHsl()
+{
+ QColor color;
+
+ for (int A = 0; A <= USHRT_MAX; ++A) {
+ {
+ // 0-255
+ int a = A >> 8;
+ color.setHsl(0, 0, 0, a);
+ QCOMPARE(color.alpha(), a);
+
+ int h, s, l, a2;
+ color.getHsv(&h, &s, &l, &a2);
+ QCOMPARE(a2, a);
+ }
+
+ {
+ // 0.0-1.0
+ qreal a = A / qreal(USHRT_MAX);
+ color.setHslF(0.0, 0.0, 0.0, a); QCOMPARE(color.alphaF(), a);
+
+ qreal h, s, l, a2;
+ color.getHslF(&h, &s, &l, &a2);
+ QCOMPARE(a2, a);
+ }
+ }
+
+ for (int H = 0; H < 36000; ++H) {
+ {
+ // 0-255
+ int h = H / 100;
+
+ color.setHsl(h, 0, 0, 0);
+ QCOMPARE(color.hslHue(), h);
+
+ int h2, s, l, a;
+ color.getHsl(&h2, &s, &l, &a);
+ QCOMPARE(h2, h);
+ }
+
+ {
+ // 0.0-1.0
+ qreal h = H / 36000.0;
+ color.setHslF(h, 0.0, 0.0, 0.0);
+ QCOMPARE(color.hslHueF(), h);
+
+ qreal h2, s, l, a;
+ color.getHslF(&h2, &s, &l, &a);
+ QCOMPARE(h2, h);
+ }
+ }
+
+ for (int S = 0; S <= USHRT_MAX; ++S) {
+ {
+ // 0-255
+ int s = S >> 8;
+ color.setHsl(0, s, 0, 0);
+ QCOMPARE(color.hslSaturation(), s);
+
+ int h, s2, l, a;
+ color.getHsl(&h, &s2, &l, &a);
+ QCOMPARE(s2, s);
+ }
+
+ {
+ // 0.0-1.0
+ qreal s = S / qreal(USHRT_MAX);
+ color.setHslF(0.0, s, 0.0, 0.0);
+ QCOMPARE(color.hslSaturationF(), s);
+
+ qreal h, s2, l, a;
+ color.getHslF(&h, &s2, &l, &a);
+ QCOMPARE(s2, s);
+ }
+ }
+
+ for (int L = 0; L <= USHRT_MAX; ++L) {
+ {
+ // 0-255
+ int l = L >> 8;
+ color.setHsl(0, 0, l, 0);
+ QCOMPARE(color.lightness(), l);
+
+ int h, s, l2, a;
+ color.getHsl(&h, &s, &l2, &a);
+ QCOMPARE(l2, l);
+ }
+
+ {
+ // 0.0-1.0
+ qreal l = L / qreal(USHRT_MAX);
+ color.setHslF(0.0, 0.0, l, 0.0);
+ QCOMPARE(color.lightnessF(), l);
+
+ qreal h, s, l2, a;
+ color.getHslF(&h, &s, &l2, &a);
+ QCOMPARE(l2, l);
+ }
+ }
+}
+
+void tst_QColor::toRgb_data()
+{
+ QTest::addColumn<QColor>("expectedColor");
+ QTest::addColumn<QColor>("hsvColor");
+ QTest::addColumn<QColor>("cmykColor");
+ QTest::addColumn<QColor>("hslColor");
+
+ QTest::newRow("black")
+ << QColor::fromRgbF(0.0, 0.0, 0.0)
+ << QColor::fromHsvF(-1.0, 0.0, 0.0)
+ << QColor::fromCmykF(0.0, 0.0, 0.0, 1.0)
+ << QColor::fromHslF(-1.0, 0.0, 0.0);
+
+ QTest::newRow("white")
+ << QColor::fromRgbF(1.0, 1.0, 1.0)
+ << QColor::fromHsvF(-1.0, 0.0, 1.0)
+ << QColor::fromCmykF(0.0, 0.0, 0.0, 0.0)
+ << QColor::fromHslF(-1.0, 0.0, 1.0);
+
+ QTest::newRow("red")
+ << QColor::fromRgbF(1.0, 0.0, 0.0)
+ << QColor::fromHsvF(0.0, 1.0, 1.0)
+ << QColor::fromCmykF(0.0, 1.0, 1.0, 0.0)
+ << QColor::fromHslF(0.0, 1.0, 0.5, 1.0);
+
+ QTest::newRow("green")
+ << QColor::fromRgbF(0.0, 1.0, 0.0)
+ << QColor::fromHsvF(0.33333, 1.0, 1.0)
+ << QColor::fromCmykF(1.0, 0.0, 1.0, 0.0)
+ << QColor::fromHslF(0.33333, 1.0, 0.5);
+
+ QTest::newRow("blue")
+ << QColor::fromRgbF(0.0, 0.0, 1.0)
+ << QColor::fromHsvF(0.66667, 1.0, 1.0)
+ << QColor::fromCmykF(1.0, 1.0, 0.0, 0.0)
+ << QColor::fromHslF(0.66667, 1.0, 0.5);
+
+ QTest::newRow("cyan")
+ << QColor::fromRgbF(0.0, 1.0, 1.0)
+ << QColor::fromHsvF(0.5, 1.0, 1.0)
+ << QColor::fromCmykF(1.0, 0.0, 0.0, 0.0)
+ << QColor::fromHslF(0.5, 1.0, 0.5);
+
+ QTest::newRow("magenta")
+ << QColor::fromRgbF(1.0, 0.0, 1.0)
+ << QColor::fromHsvF(0.83333, 1.0, 1.0)
+ << QColor::fromCmykF(0.0, 1.0, 0.0, 0.0)
+ << QColor::fromHslF(0.83333, 1.0, 0.5);
+
+ QTest::newRow("yellow")
+ << QColor::fromRgbF(1.0, 1.0, 0.0)
+ << QColor::fromHsvF(0.16667, 1.0, 1.0)
+ << QColor::fromCmykF(0.0, 0.0, 1.0, 0.0)
+ << QColor::fromHslF(0.16667, 1.0, 0.5);
+
+ QTest::newRow("gray")
+ << QColor::fromRgbF(0.6431375, 0.6431375, 0.6431375)
+ << QColor::fromHsvF(-1.0, 0.0, 0.6431375)
+ << QColor::fromCmykF(0.0, 0.0, 0.0, 0.356863)
+ << QColor::fromHslF(-1.0, 0.0, 0.6431375);
+
+ // ### add colors using the 0-255 functions
+}
+
+void tst_QColor::toRgb()
+{
+ // invalid should remain invalid
+ QVERIFY(!QColor().toRgb().isValid());
+
+ QFETCH(QColor, expectedColor);
+ QFETCH(QColor, hsvColor);
+ QFETCH(QColor, cmykColor);
+ QFETCH(QColor, hslColor);
+ QCOMPARE(hsvColor.toRgb(), expectedColor);
+ QCOMPARE(cmykColor.toRgb(), expectedColor);
+ QCOMPARE(hslColor.toRgb(), expectedColor);
+
+}
+
+void tst_QColor::toHsv_data()
+{
+ QTest::addColumn<QColor>("expectedColor");
+ QTest::addColumn<QColor>("rgbColor");
+ QTest::addColumn<QColor>("cmykColor");
+ QTest::addColumn<QColor>("hslColor");
+
+ QTest::newRow("data0")
+ << QColor::fromHsv(300, 255, 255)
+ << QColor(255, 0, 255)
+ << QColor::fromCmyk(0, 255, 0, 0)
+ << QColor::fromHslF(300./360., 1., 0.5, 1.0);
+
+ QTest::newRow("data1")
+ << QColor::fromHsvF(1., 1., 1., 1.)
+ << QColor(255, 0, 0, 255)
+ << QColor::fromCmykF(0., 1., 1., 0.)
+ << QColor::fromHsvF(1., 1., 1., 1.);
+}
+
+void tst_QColor::toRgbNonDestructive()
+{
+ QColor aColor = QColor::fromRgbF(0.11, 0.22, 0.33, 0.44);
+ QCOMPARE(aColor, aColor.toRgb());
+}
+
+void tst_QColor::toHsv()
+{
+ // invalid should remain invalid
+ QVERIFY(!QColor().toHsv().isValid());
+
+ QFETCH(QColor, expectedColor);
+ QFETCH(QColor, rgbColor);
+ QFETCH(QColor, cmykColor);
+ QFETCH(QColor, hslColor);
+ QCOMPARE(rgbColor.toHsv(), expectedColor);
+ QCOMPARE(cmykColor.toHsv(), expectedColor);
+ QCOMPARE(hslColor.toHsv(), expectedColor);
+}
+
+void tst_QColor::toHsvNonDestructive()
+{
+ QColor aColor = QColor::fromHsvF(0.11, 0.22, 0.33, 0.44);
+ QCOMPARE(aColor, aColor.toHsv());
+}
+
+void tst_QColor::toCmyk_data()
+{
+ QTest::addColumn<QColor>("expectedColor");
+ QTest::addColumn<QColor>("rgbColor");
+ QTest::addColumn<QColor>("hsvColor");
+ QTest::addColumn<QColor>("hslColor");
+
+ QTest::newRow("data0")
+ << QColor::fromCmykF(1.0, 0.0, 0.0, 0.0)
+ << QColor(0, 255, 255)
+ << QColor::fromHsv(180, 255, 255)
+ << QColor::fromHslF(180./360., 1., 0.5, 1.0);
+
+ QTest::newRow("data1")
+ << QColor::fromCmyk(255, 255, 255, 255)
+ << QColor::fromRgb(0, 0, 0)
+ << QColor::fromRgb(0, 0, 0).toHsv()
+ << QColor::fromRgb(0, 0, 0).toHsl();
+}
+
+void tst_QColor::toCmyk()
+{
+ // invalid should remain invalid
+ QVERIFY(!QColor().toCmyk().isValid());
+
+ QFETCH(QColor, expectedColor);
+ QFETCH(QColor, rgbColor);
+ QFETCH(QColor, hsvColor);
+ QFETCH(QColor, hslColor);
+ QCOMPARE(rgbColor.toHsv().toCmyk(), expectedColor);
+ QCOMPARE(hsvColor.toCmyk(), expectedColor);
+ QCOMPARE(hslColor.toCmyk(), expectedColor);
+}
+
+void tst_QColor::toCmykNonDestructive()
+{
+ QColor aColor = QColor::fromCmykF(0.11, 0.22, 0.33, 0.44);
+ QCOMPARE(aColor, aColor.toCmyk());
+}
+
+void tst_QColor::toHsl_data()
+{
+ QTest::addColumn<QColor>("expectedColor");
+ QTest::addColumn<QColor>("hsvColor");
+ QTest::addColumn<QColor>("rgbColor");
+ QTest::addColumn<QColor>("cmykColor");
+
+
+ QTest::newRow("data0")
+ << QColor::fromHslF(300./360., 1., 0.5, 1.0)
+ << QColor::fromHsv(300, 255, 255)
+ << QColor(255, 0, 255)
+ << QColor::fromCmyk(0, 255, 0, 0);
+
+ QTest::newRow("data1")
+ << QColor::fromHslF(1., 1., 0.5, 1.0)
+ << QColor::fromHsvF(1., 1., 1., 1.)
+ << QColor(255, 0, 0, 255)
+ << QColor::fromCmykF(0., 1., 1., 0.);
+}
+
+void tst_QColor::toHsl()
+{
+ // invalid should remain invalid
+ QVERIFY(!QColor().toHsl().isValid());
+
+ QFETCH(QColor, expectedColor);
+ QFETCH(QColor, rgbColor);
+ QFETCH(QColor, cmykColor);
+ QFETCH(QColor, hsvColor);
+
+ QCOMPARE(rgbColor.toHsl(), expectedColor);
+ QCOMPARE(cmykColor.toHsl(), expectedColor);
+ QCOMPARE(hsvColor.toHsl(), expectedColor);
+
+}
+
+
+void tst_QColor::toHslNonDestructive()
+{
+ QColor aColor = QColor::fromHslF(0.11, 0.22, 0.33, 0.44);
+ QCOMPARE(aColor, aColor.toHsl());
+}
+
+
+void tst_QColor::convertTo()
+{
+ QColor color(Qt::black);
+
+ QColor rgb = color.convertTo(QColor::Rgb);
+ QVERIFY(rgb.spec() == QColor::Rgb);
+
+ QColor hsv = color.convertTo(QColor::Hsv);
+ QVERIFY(hsv.spec() == QColor::Hsv);
+
+ QColor cmyk = color.convertTo(QColor::Cmyk);
+ QVERIFY(cmyk.spec() == QColor::Cmyk);
+
+ QColor hsl = color.convertTo(QColor::Hsl);
+ QVERIFY(hsl.spec() == QColor::Hsl);
+
+ QColor invalid = color.convertTo(QColor::Invalid);
+ QVERIFY(invalid.spec() == QColor::Invalid);
+
+ DEPENDS_ON(toRgb());
+ DEPENDS_ON(toHsv());
+ DEPENDS_ON(toCmyk());
+ DEPENDS_ON(toHsl());
+}
+
+void tst_QColor::fromRgb()
+{ DEPENDS_ON(convertTo()); }
+
+void tst_QColor::fromHsv()
+{ DEPENDS_ON(convertTo()); }
+
+void tst_QColor::fromCmyk()
+{ DEPENDS_ON(convertTo()); }
+
+void tst_QColor::fromHsl()
+{ DEPENDS_ON(convertTo()); }
+
+void tst_QColor::light()
+{
+ QColor gray(Qt::gray);
+ QColor lighter = gray.light();
+ QVERIFY(lighter.value() > gray.value());
+}
+
+void tst_QColor::dark()
+{
+ QColor gray(Qt::gray);
+ QColor darker = gray.dark();
+ QVERIFY(darker.value() < gray.value());
+}
+
+void tst_QColor::assignmentOoperator()
+{ DEPENDS_ON(convertTo()); }
+
+void tst_QColor::equalityOperator()
+{ DEPENDS_ON(convertTo()); }
+
+Q_DECLARE_METATYPE(QColor::Spec);
+
+void tst_QColor::specConstructor_data()
+{
+ QTest::addColumn<QColor::Spec>("spec");
+
+ QTest::newRow("Invalid") << QColor::Invalid;
+ QTest::newRow("Rgb") << QColor::Rgb;
+ QTest::newRow("Hsv") << QColor::Hsv;
+ QTest::newRow("Cmyk") << QColor::Cmyk;
+}
+
+void tst_QColor::specConstructor()
+{
+ QFETCH(QColor::Spec, spec);
+ QColor color = spec;
+ QCOMPARE(color.spec(), spec);
+}
+
+void tst_QColor::achromaticHslHue()
+{
+ QColor color = Qt::black;
+
+ QColor hsl = color.toHsl();
+ QCOMPARE(hsl.hslHue(), -1);
+}
+
+#ifdef Q_WS_X11
+void tst_QColor::allowX11ColorNames()
+{
+ DEPENDS_ON(setallowX11ColorNames());
+}
+
+void tst_QColor::setallowX11ColorNames()
+{
+#if defined(Q_OS_IRIX)
+ QSKIP("This fails due to the gamma settings in the SGI X server", SkipAll);
+#else
+ RGBData x11RgbTbl[] = {
+ // a few standard X11 color names
+ { "DodgerBlue1", qRgb(30, 144, 255) },
+ { "DodgerBlue2", qRgb(28, 134, 238) },
+ { "DodgerBlue3", qRgb(24, 116, 205) },
+ { "DodgerBlue4", qRgb(16, 78, 139) },
+ { "SteelBlue1", qRgb(99, 184, 255) },
+ { "SteelBlue2", qRgb(92, 172, 238) },
+ { "SteelBlue3", qRgb(79, 148, 205) },
+ { "SteelBlue4", qRgb(54, 100, 139) },
+ { "DeepSkyBlue1", qRgb(0, 191, 255) },
+ { "DeepSkyBlue2", qRgb(0, 178, 238) },
+ { "DeepSkyBlue3", qRgb(0, 154, 205) },
+ { "DeepSkyBlue4", qRgb(0, 104, 139) },
+ { "SkyBlue1", qRgb(135, 206, 255) },
+ { "SkyBlue2", qRgb(126, 192, 238) },
+ { "SkyBlue3", qRgb(108, 166, 205) },
+ { "SkyBlue4", qRgb(74, 112, 139) }
+ };
+ static const int x11RgbTblSize = sizeof(x11RgbTbl) / sizeof(RGBData);
+
+ // X11 color names should not work by default
+ QVERIFY(!QColor::allowX11ColorNames());
+ for (int i = 0; i < x11RgbTblSize; ++i) {
+ QString colorName = QLatin1String(x11RgbTbl[i].name);
+ QColor color;
+ color.setNamedColor(colorName);
+ QVERIFY(!color.isValid());
+ }
+
+ // enable X11 color names
+ QColor::setAllowX11ColorNames(true);
+ QVERIFY(QColor::allowX11ColorNames());
+ for (int i = 0; i < x11RgbTblSize; ++i) {
+ QString colorName = QLatin1String(x11RgbTbl[i].name);
+ QColor color;
+ color.setNamedColor(colorName);
+ QColor expected(x11RgbTbl[i].value);
+ QCOMPARE(color, expected);
+ }
+
+ // should be able to turn off X11 color names
+ QColor::setAllowX11ColorNames(false);
+ QVERIFY(!QColor::allowX11ColorNames());
+ for (int i = 0; i < x11RgbTblSize; ++i) {
+ QString colorName = QLatin1String(x11RgbTbl[i].name);
+ QColor color;
+ color.setNamedColor(colorName);
+ QVERIFY(!color.isValid());
+ }
+#endif // Q_OS_IRIX
+}
+#endif // Q_WS_X11
+
+QTEST_MAIN(tst_QColor)
+#include "tst_qcolor.moc"
diff --git a/tests/auto/gui/painting/qpaintengine/.gitignore b/tests/auto/gui/painting/qpaintengine/.gitignore
new file mode 100644
index 0000000000..e55942ea9f
--- /dev/null
+++ b/tests/auto/gui/painting/qpaintengine/.gitignore
@@ -0,0 +1 @@
+tst_qpaintengine
diff --git a/tests/auto/gui/painting/qpaintengine/qpaintengine.pro b/tests/auto/gui/painting/qpaintengine/qpaintengine.pro
new file mode 100644
index 0000000000..e37c1668ac
--- /dev/null
+++ b/tests/auto/gui/painting/qpaintengine/qpaintengine.pro
@@ -0,0 +1,9 @@
+############################################################
+# Project file for autotest for file qpaintengine.h
+############################################################
+
+load(qttest_p4)
+
+SOURCES += tst_qpaintengine.cpp
+
+
diff --git a/tests/auto/gui/painting/qpaintengine/tst_qpaintengine.cpp b/tests/auto/gui/painting/qpaintengine/tst_qpaintengine.cpp
new file mode 100644
index 0000000000..ba9cc62a3d
--- /dev/null
+++ b/tests/auto/gui/painting/qpaintengine/tst_qpaintengine.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qpaintengine.h>
+#include <qpixmap.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QPaintEngine : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QPaintEngine();
+ virtual ~tst_QPaintEngine();
+
+private slots:
+ void getSetCheck();
+};
+
+tst_QPaintEngine::tst_QPaintEngine()
+{
+}
+
+tst_QPaintEngine::~tst_QPaintEngine()
+{
+}
+
+class MyPaintEngine : public QPaintEngine
+{
+public:
+ MyPaintEngine() : QPaintEngine() {}
+ bool begin(QPaintDevice *) { return true; }
+ bool end() { return true; }
+ void updateState(const QPaintEngineState &) {}
+ void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) {}
+ Type type() const { return Raster; }
+};
+
+// Testing get/set functions
+void tst_QPaintEngine::getSetCheck()
+{
+ MyPaintEngine obj1;
+ // QPaintDevice * QPaintEngine::paintDevice()
+ // void QPaintEngine::setPaintDevice(QPaintDevice *)
+ QPixmap *var1 = new QPixmap;
+ obj1.setPaintDevice(var1);
+ QCOMPARE((QPaintDevice *)var1, obj1.paintDevice());
+ obj1.setPaintDevice((QPaintDevice *)0);
+ QCOMPARE((QPaintDevice *)0, obj1.paintDevice());
+ delete var1;
+}
+
+QTEST_MAIN(tst_QPaintEngine)
+#include "tst_qpaintengine.moc"
diff --git a/tests/auto/gui/painting/qpainter/.gitignore b/tests/auto/gui/painting/qpainter/.gitignore
new file mode 100644
index 0000000000..33e0dbe945
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/.gitignore
@@ -0,0 +1,2 @@
+tst_qpainter
+foo.png
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt0x0.png b/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt0x0.png
new file mode 100644
index 0000000000..f2ab9a776d
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt0x0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt100x100.png b/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt100x100.png
new file mode 100644
index 0000000000..b1c755b5b0
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt100x100.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt200x200.png b/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt200x200.png
new file mode 100644
index 0000000000..0e30498da5
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/10x10SizeAt200x200.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt0x0.png b/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt0x0.png
new file mode 100644
index 0000000000..f00796a3ad
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt0x0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt100x100.png b/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt100x100.png
new file mode 100644
index 0000000000..a9a1a8a536
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt100x100.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt200x200.png b/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt200x200.png
new file mode 100644
index 0000000000..0e30498da5
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/13x100SizeAt200x200.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt0x0.png b/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt0x0.png
new file mode 100644
index 0000000000..67db116b90
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt0x0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt100x100.png b/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt100x100.png
new file mode 100644
index 0000000000..7d32afa4a8
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt100x100.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt200x200.png b/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt200x200.png
new file mode 100644
index 0000000000..0e30498da5
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawEllipse/200x200SizeAt200x200.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/dst.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/dst.xbm
new file mode 100644
index 0000000000..e645a0b86b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/dst.xbm
@@ -0,0 +1,6 @@
+#define dst_width 8
+#define dst_height 8
+static char dst_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0x30,0x00,0x30,0x00,
+ 0x11,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x10,0x00,0x00,
+ 0x00,0x11 };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_AndNotROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_AndNotROP.xbm
new file mode 100644
index 0000000000..303c799264
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_AndNotROP.xbm
@@ -0,0 +1,6 @@
+#define res_AndNotROP_width 8
+#define res_AndNotROP_height 8
+static char res_AndNotROP_bits[] = {
+ 0xf0,0xf0,0xcc,0xcc,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_AndROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_AndROP.xbm
new file mode 100644
index 0000000000..31333de879
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_AndROP.xbm
@@ -0,0 +1,6 @@
+#define res_AndROP_width 8
+#define res_AndROP_height 8
+static char res_AndROP_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_ClearROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_ClearROP.xbm
new file mode 100644
index 0000000000..9cc25ea147
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_ClearROP.xbm
@@ -0,0 +1,6 @@
+#define res_ClearROP_width 8
+#define res_ClearROP_height 8
+static char res_ClearROP_bits[] = {
+ 0xf0,0xf0,0xc0,0xc0,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_CopyROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_CopyROP.xbm
new file mode 100644
index 0000000000..869844dcee
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_CopyROP.xbm
@@ -0,0 +1,6 @@
+#define res_CopyROP_width 8
+#define res_CopyROP_height 8
+static char res_CopyROP_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0x35,0x00,0x5a,0x00,
+ 0x41,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xc0,0x5b,0x2f,
+ 0x2b,0x50 };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NandROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NandROP.xbm
new file mode 100644
index 0000000000..d058484fa8
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NandROP.xbm
@@ -0,0 +1,6 @@
+#define res_NandROP_width 8
+#define res_NandROP_height 8
+static char res_NandROP_bits[] = {
+ 0xf0,0xf0,0xcc,0xcc,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NopROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NopROP.xbm
new file mode 100644
index 0000000000..3a2bc23468
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NopROP.xbm
@@ -0,0 +1,6 @@
+#define res_NopROP_width 8
+#define res_NopROP_height 8
+static char res_NopROP_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NorROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NorROP.xbm
new file mode 100644
index 0000000000..c74be41bbd
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NorROP.xbm
@@ -0,0 +1,6 @@
+#define res_NorROP_width 8
+#define res_NorROP_height 8
+static char res_NorROP_bits[] = {
+ 0xf0,0xf0,0xc0,0xc0,0xcc,0xcc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotAndROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotAndROP.xbm
new file mode 100644
index 0000000000..0cf8c3a82c
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotAndROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotAndROP_width 8
+#define res_NotAndROP_height 8
+static char res_NotAndROP_bits[] = {
+ 0xf0,0xf0,0xc0,0xc0,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotCopyROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotCopyROP.xbm
new file mode 100644
index 0000000000..65474e16c5
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotCopyROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotCopyROP_width 8
+#define res_NotCopyROP_height 8
+static char res_NotCopyROP_bits[] = {
+ 0xf0,0xf0,0xc0,0xc0,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotOrROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotOrROP.xbm
new file mode 100644
index 0000000000..144d8995b6
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotOrROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotOrROP_width 8
+#define res_NotOrROP_height 8
+static char res_NotOrROP_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotROP.xbm
new file mode 100644
index 0000000000..ccb3d36fb4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotROP_width 8
+#define res_NotROP_height 8
+static char res_NotROP_bits[] = {
+ 0xf0,0xf0,0xcc,0xcc,0xcc,0xcc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotXorROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotXorROP.xbm
new file mode 100644
index 0000000000..4be8f51a80
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_NotXorROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotXorROP_width 8
+#define res_NotXorROP_height 8
+static char res_NotXorROP_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xcc,0xcc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_OrNotROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_OrNotROP.xbm
new file mode 100644
index 0000000000..d53fbe00e1
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_OrNotROP.xbm
@@ -0,0 +1,6 @@
+#define res_OrNotROP_width 8
+#define res_OrNotROP_height 8
+static char res_OrNotROP_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xcc,0xcc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_OrROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_OrROP.xbm
new file mode 100644
index 0000000000..06b51fcc68
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_OrROP.xbm
@@ -0,0 +1,6 @@
+#define res_OrROP_width 8
+#define res_OrROP_height 8
+static char res_OrROP_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_SetROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_SetROP.xbm
new file mode 100644
index 0000000000..ab42472bb0
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_SetROP.xbm
@@ -0,0 +1,6 @@
+#define res_SetROP_width 8
+#define res_SetROP_height 8
+static char res_SetROP_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_XorROP.xbm b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_XorROP.xbm
new file mode 100644
index 0000000000..5ac892dd0b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawLine_rop_bitmap/res/res_XorROP.xbm
@@ -0,0 +1,6 @@
+#define res_XorROP_width 8
+#define res_XorROP_height 8
+static char res_XorROP_bits[] = {
+ 0xf0,0xf0,0xcc,0xcc,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst1.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst2.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst3.png
new file mode 100644
index 0000000000..8a3d28f3ed
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/dst3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP0.png
new file mode 100644
index 0000000000..fe017ac1ab
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP1.png
new file mode 100644
index 0000000000..82d938c023
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP2.png
new file mode 100644
index 0000000000..2b67b928e4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP3.png
new file mode 100644
index 0000000000..c95b5a10ba
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP4.png
new file mode 100644
index 0000000000..bbe2a24530
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP5.png
new file mode 100644
index 0000000000..0158278b84
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP6.png
new file mode 100644
index 0000000000..aa1f403075
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP7.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndNotROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP0.png
new file mode 100644
index 0000000000..ebf8244eee
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP1.png
new file mode 100644
index 0000000000..88568bc330
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP2.png
new file mode 100644
index 0000000000..0ed6de2865
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP3.png
new file mode 100644
index 0000000000..c2ff341e6b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP4.png
new file mode 100644
index 0000000000..e08c9acbe2
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP5.png
new file mode 100644
index 0000000000..e9d7a57333
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP6.png
new file mode 100644
index 0000000000..01438a195c
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP7.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_AndROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP0.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP1.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP2.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP3.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP4.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP5.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP6.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP7.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_ClearROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP0.png
new file mode 100644
index 0000000000..587623d3e8
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP1.png
new file mode 100644
index 0000000000..10e7ae59d5
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP2.png
new file mode 100644
index 0000000000..5c14136eb4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP3.png
new file mode 100644
index 0000000000..207f52564b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP4.png
new file mode 100644
index 0000000000..6981cee080
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP5.png
new file mode 100644
index 0000000000..8b8de9892a
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP6.png
new file mode 100644
index 0000000000..9825c0539f
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP7.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_CopyROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP0.png
new file mode 100644
index 0000000000..8d26638c03
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP1.png
new file mode 100644
index 0000000000..f5b33589ba
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP2.png
new file mode 100644
index 0000000000..adc4ee3701
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP3.png
new file mode 100644
index 0000000000..dccc94c43b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP4.png
new file mode 100644
index 0000000000..4d207e7968
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP5.png
new file mode 100644
index 0000000000..aa93d4d4a4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP6.png
new file mode 100644
index 0000000000..ad320f950b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP7.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NandROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP0.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP1.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP2.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP3.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP4.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP5.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP6.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP7.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NopROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP0.png
new file mode 100644
index 0000000000..3e33bb1078
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP1.png
new file mode 100644
index 0000000000..ce2b6f4e15
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP2.png
new file mode 100644
index 0000000000..9eddc9840b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP3.png
new file mode 100644
index 0000000000..4ea9669dd3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP4.png
new file mode 100644
index 0000000000..c64e0a5630
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP5.png
new file mode 100644
index 0000000000..1fe3def383
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP6.png
new file mode 100644
index 0000000000..9c294b04d9
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP7.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NorROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP0.png
new file mode 100644
index 0000000000..01c694cdcc
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP1.png
new file mode 100644
index 0000000000..4b11aa9c41
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP2.png
new file mode 100644
index 0000000000..accbe42112
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP3.png
new file mode 100644
index 0000000000..3c58d4fac7
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP4.png
new file mode 100644
index 0000000000..3b0a41c396
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP5.png
new file mode 100644
index 0000000000..045ef33012
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP6.png
new file mode 100644
index 0000000000..3a83725938
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP7.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotAndROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP0.png
new file mode 100644
index 0000000000..7c51fc16fa
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP1.png
new file mode 100644
index 0000000000..8f519e8c52
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP2.png
new file mode 100644
index 0000000000..a0f9f60653
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP3.png
new file mode 100644
index 0000000000..95931a4317
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP4.png
new file mode 100644
index 0000000000..f825d523b0
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP5.png
new file mode 100644
index 0000000000..245a27ea2f
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP6.png
new file mode 100644
index 0000000000..b32020675b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP7.png
new file mode 100644
index 0000000000..cff8926587
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotCopyROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP0.png
new file mode 100644
index 0000000000..3622f3a2b1
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP1.png
new file mode 100644
index 0000000000..e31793e4a3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP2.png
new file mode 100644
index 0000000000..8e8237548b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP3.png
new file mode 100644
index 0000000000..f4b98914b4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP4.png
new file mode 100644
index 0000000000..b14fdba341
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP5.png
new file mode 100644
index 0000000000..129d7f3dc6
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP6.png
new file mode 100644
index 0000000000..d894c5cb68
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP7.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotOrROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP0.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP1.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP2.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP3.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP4.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP5.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP6.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP7.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP0.png
new file mode 100644
index 0000000000..b1e61504cd
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP1.png
new file mode 100644
index 0000000000..8cf29cde81
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP2.png
new file mode 100644
index 0000000000..99fedf8c04
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP3.png
new file mode 100644
index 0000000000..bc220f546e
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP4.png
new file mode 100644
index 0000000000..f48e8b9f4d
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP5.png
new file mode 100644
index 0000000000..c5e3c0fc63
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP6.png
new file mode 100644
index 0000000000..13bb69f91b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP7.png
new file mode 100644
index 0000000000..4a7ca7f9b3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_NotXorROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP0.png
new file mode 100644
index 0000000000..85b964301d
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP1.png
new file mode 100644
index 0000000000..d92bf16044
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP2.png
new file mode 100644
index 0000000000..bb81c5abe8
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP3.png
new file mode 100644
index 0000000000..9378f166cd
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP4.png
new file mode 100644
index 0000000000..2ea026eb6c
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP5.png
new file mode 100644
index 0000000000..8366d37eda
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP6.png
new file mode 100644
index 0000000000..39c36d1b52
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP7.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrNotROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP0.png
new file mode 100644
index 0000000000..beb2bc35b8
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP1.png
new file mode 100644
index 0000000000..6ed17a72ed
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP2.png
new file mode 100644
index 0000000000..9e0b63c220
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP3.png
new file mode 100644
index 0000000000..6471b4aaa4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP4.png
new file mode 100644
index 0000000000..c158ea0d01
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP5.png
new file mode 100644
index 0000000000..eb3deacc86
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP6.png
new file mode 100644
index 0000000000..51948b0ac9
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP7.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_OrROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP0.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP1.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP2.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP3.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP4.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP5.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP6.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP7.png
new file mode 100644
index 0000000000..00968ffd06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_SetROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP0.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP0.png
new file mode 100644
index 0000000000..c2b009cac3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP0.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP1.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP1.png
new file mode 100644
index 0000000000..42b0b3c308
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP1.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP2.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP2.png
new file mode 100644
index 0000000000..bc43614ab3
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP2.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP3.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP3.png
new file mode 100644
index 0000000000..7486d4b3f4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP3.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP4.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP4.png
new file mode 100644
index 0000000000..8098634be4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP4.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP5.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP5.png
new file mode 100644
index 0000000000..8c5b9feb7c
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP5.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP6.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP6.png
new file mode 100644
index 0000000000..c7e51a1410
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP6.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP7.png b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP7.png
new file mode 100644
index 0000000000..8605b64d93
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/res/res_XorROP7.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/src1.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop/src1.xbm
new file mode 100644
index 0000000000..f088d28c8c
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/src1.xbm
@@ -0,0 +1,12 @@
+#define src1_width 32
+#define src1_height 32
+static char src1_bits[] = {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/src2-mask.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop/src2-mask.xbm
new file mode 100644
index 0000000000..bd73f9433c
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/src2-mask.xbm
@@ -0,0 +1,16 @@
+#define src2_width 32
+#define src2_height 48
+static char src2_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/src2.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop/src2.xbm
new file mode 100644
index 0000000000..40126a9d17
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/src2.xbm
@@ -0,0 +1,16 @@
+#define src2_width 32
+#define src2_height 48
+static char src2_bits[] = {
+ 0xa7,0x01,0xc0,0x03,0x40,0x9b,0x80,0x08,0x18,0x00,0x00,0x00,0x48,0x00,0x00,
+ 0x00,0xbb,0xbb,0xbb,0xbb,0xee,0xee,0xee,0xee,0x00,0x00,0x00,0x00,0xfe,0xff,
+ 0xff,0xff,0x0d,0x00,0x0d,0x00,0x20,0x00,0x20,0x00,0x80,0xed,0xb7,0x08,0xe8,
+ 0x61,0x54,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x68,0xa2,0x02,
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop/src3.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop/src3.xbm
new file mode 100644
index 0000000000..2f2d5472a4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop/src3.xbm
@@ -0,0 +1,12 @@
+#define src3_width 32
+#define src3_height 32
+static char src3_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/dst.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/dst.xbm
new file mode 100644
index 0000000000..45543c8ebf
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/dst.xbm
@@ -0,0 +1,6 @@
+#define dst_width 8
+#define dst_height 8
+static char dst_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xb1,0x00,0x00,0x00,0x70,0xe6,0x6e,0x2b,0x70,0xe6,0x6e,0x2b,0x24,0x00,0x00,
+ 0x00,0x81 };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_AndNotROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_AndNotROP.xbm
new file mode 100644
index 0000000000..303c799264
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_AndNotROP.xbm
@@ -0,0 +1,6 @@
+#define res_AndNotROP_width 8
+#define res_AndNotROP_height 8
+static char res_AndNotROP_bits[] = {
+ 0xf0,0xf0,0xcc,0xcc,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_AndROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_AndROP.xbm
new file mode 100644
index 0000000000..31333de879
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_AndROP.xbm
@@ -0,0 +1,6 @@
+#define res_AndROP_width 8
+#define res_AndROP_height 8
+static char res_AndROP_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_ClearROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_ClearROP.xbm
new file mode 100644
index 0000000000..9cc25ea147
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_ClearROP.xbm
@@ -0,0 +1,6 @@
+#define res_ClearROP_width 8
+#define res_ClearROP_height 8
+static char res_ClearROP_bits[] = {
+ 0xf0,0xf0,0xc0,0xc0,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_CopyROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_CopyROP.xbm
new file mode 100644
index 0000000000..869844dcee
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_CopyROP.xbm
@@ -0,0 +1,6 @@
+#define res_CopyROP_width 8
+#define res_CopyROP_height 8
+static char res_CopyROP_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0x35,0x00,0x5a,0x00,
+ 0x41,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xc0,0x5b,0x2f,
+ 0x2b,0x50 };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NandROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NandROP.xbm
new file mode 100644
index 0000000000..d058484fa8
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NandROP.xbm
@@ -0,0 +1,6 @@
+#define res_NandROP_width 8
+#define res_NandROP_height 8
+static char res_NandROP_bits[] = {
+ 0xf0,0xf0,0xcc,0xcc,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NopROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NopROP.xbm
new file mode 100644
index 0000000000..3a2bc23468
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NopROP.xbm
@@ -0,0 +1,6 @@
+#define res_NopROP_width 8
+#define res_NopROP_height 8
+static char res_NopROP_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NorROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NorROP.xbm
new file mode 100644
index 0000000000..c74be41bbd
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NorROP.xbm
@@ -0,0 +1,6 @@
+#define res_NorROP_width 8
+#define res_NorROP_height 8
+static char res_NorROP_bits[] = {
+ 0xf0,0xf0,0xc0,0xc0,0xcc,0xcc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotAndROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotAndROP.xbm
new file mode 100644
index 0000000000..0cf8c3a82c
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotAndROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotAndROP_width 8
+#define res_NotAndROP_height 8
+static char res_NotAndROP_bits[] = {
+ 0xf0,0xf0,0xc0,0xc0,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotCopyROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotCopyROP.xbm
new file mode 100644
index 0000000000..65474e16c5
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotCopyROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotCopyROP_width 8
+#define res_NotCopyROP_height 8
+static char res_NotCopyROP_bits[] = {
+ 0xf0,0xf0,0xc0,0xc0,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotOrROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotOrROP.xbm
new file mode 100644
index 0000000000..144d8995b6
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotOrROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotOrROP_width 8
+#define res_NotOrROP_height 8
+static char res_NotOrROP_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotROP.xbm
new file mode 100644
index 0000000000..ccb3d36fb4
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotROP_width 8
+#define res_NotROP_height 8
+static char res_NotROP_bits[] = {
+ 0xf0,0xf0,0xcc,0xcc,0xcc,0xcc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotXorROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotXorROP.xbm
new file mode 100644
index 0000000000..4be8f51a80
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_NotXorROP.xbm
@@ -0,0 +1,6 @@
+#define res_NotXorROP_width 8
+#define res_NotXorROP_height 8
+static char res_NotXorROP_bits[] = {
+ 0xf0,0xf0,0xf0,0xf0,0xcc,0xcc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_OrNotROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_OrNotROP.xbm
new file mode 100644
index 0000000000..d53fbe00e1
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_OrNotROP.xbm
@@ -0,0 +1,6 @@
+#define res_OrNotROP_width 8
+#define res_OrNotROP_height 8
+static char res_OrNotROP_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xcc,0xcc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_OrROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_OrROP.xbm
new file mode 100644
index 0000000000..06b51fcc68
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_OrROP.xbm
@@ -0,0 +1,6 @@
+#define res_OrROP_width 8
+#define res_OrROP_height 8
+static char res_OrROP_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0xff,0xff,0xff,0x7f,
+ 0xff,0xff,0xff,0x7f,0x50,0x00,0x00,0x00,0x09,0x02,0x00,0x00,0xff,0xff,0xff,
+ 0x7f,0xff };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_SetROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_SetROP.xbm
new file mode 100644
index 0000000000..ab42472bb0
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_SetROP.xbm
@@ -0,0 +1,6 @@
+#define res_SetROP_width 8
+#define res_SetROP_height 8
+static char res_SetROP_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xfc,0xfc,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_XorROP.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_XorROP.xbm
new file mode 100644
index 0000000000..5ac892dd0b
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/res/res_XorROP.xbm
@@ -0,0 +1,6 @@
+#define res_XorROP_width 8
+#define res_XorROP_height 8
+static char res_XorROP_bits[] = {
+ 0xf0,0xf0,0xcc,0xcc,0xf0,0xf0,0xf0,0xf0,0x00,0x00,0x00,0x62,0x00,0x6d,0x00,
+ 0x00,0xb5,0x7a,0x2b,0x50,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x42,0x55,0x53,
+ 0x59,0x3a };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src1-mask.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src1-mask.xbm
new file mode 100644
index 0000000000..ac9031f1f1
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src1-mask.xbm
@@ -0,0 +1,6 @@
+#define src1_width 8
+#define src1_height 8
+static char src1_bits[] = {
+ 0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,
+ 0x59,0x00,0x00,0x00,0x18,0xe6,0x6e,0x2b,0x18,0xe6,0x6e,0x2b,0x00,0x00,0x00,
+ 0x00,0x49 };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src1.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src1.xbm
new file mode 100644
index 0000000000..d883569db2
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src1.xbm
@@ -0,0 +1,6 @@
+#define src1_width 8
+#define src1_height 8
+static char src1_bits[] = {
+ 0xf0,0xf0,0xfc,0xfc,0xc0,0xc0,0xf0,0xf0,0x00,0x00,0x00,0xe0,0xe5,0x6e,0x2b,
+ 0x29,0x00,0x00,0x00,0xe8,0xe5,0x6e,0x2b,0xe8,0xe5,0x6e,0x2b,0x3c,0x00,0x00,
+ 0x05,0x3c };
diff --git a/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src2.xbm b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src2.xbm
new file mode 100644
index 0000000000..fb203df28a
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/drawPixmap_rop_bitmap/src2.xbm
@@ -0,0 +1,5 @@
+#define src2_width 4
+#define src2_height 4
+static char src2_bits[] = {
+ 0x0f,0x5f,0x40,0x00,0x00,0x00,0x00,0x2d,0x00,0x39,0x00,0x5f,0x00,0x5d,0x00,
+ 0x30 };
diff --git a/tests/auto/gui/painting/qpainter/qpainter.pro b/tests/auto/gui/painting/qpainter/qpainter.pro
new file mode 100644
index 0000000000..00307d3e58
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/qpainter.pro
@@ -0,0 +1,20 @@
+load(qttest_p4)
+
+QT += widgets widgets-private printsupport
+
+SOURCES += tst_qpainter.cpp
+wince*|symbian: {
+ addFiles.files = drawEllipse drawLine_rop_bitmap drawPixmap_rop drawPixmap_rop_bitmap task217400.png
+ addFiles.path = .
+ DEPLOYMENT += addFiles
+}
+
+wince* {
+ DEFINES += SRCDIR=\\\".\\\"
+} else:!symbian {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
+
+
+mac*:CONFIG+=insignificant_test
+contains(QT_CONFIG,xcb):qpa:CONFIG+=insignificant_test # QTBUG-20756 crashes on qpa, xcb
diff --git a/tests/auto/gui/painting/qpainter/task217400.png b/tests/auto/gui/painting/qpainter/task217400.png
new file mode 100644
index 0000000000..c12a602ba6
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/task217400.png
Binary files differ
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
new file mode 100644
index 0000000000..c2c9002023
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -0,0 +1,4697 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include "../../../../shared/util.h"
+
+#include <qpainter.h>
+#include <qapplication.h>
+#include <qwidget.h>
+#include <qfontmetrics.h>
+#include <qbitmap.h>
+#include <qimage.h>
+#include <qthread.h>
+#include <limits.h>
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+#include <qprinter.h>
+#include <math.h>
+#endif
+#include <qpaintengine.h>
+#include <qdesktopwidget.h>
+#include <qpixmap.h>
+
+#include <qpainter.h>
+
+#include <qlabel.h>
+
+#include <qqueue.h>
+
+#include <qgraphicsview.h>
+#include <qgraphicsscene.h>
+#include <qgraphicsproxywidget.h>
+#include <qlayout.h>
+#include <qfontdatabase.h>
+
+#if defined(Q_OS_SYMBIAN)
+# define SRCDIR "."
+#endif
+
+Q_DECLARE_METATYPE(QGradientStops)
+Q_DECLARE_METATYPE(QLine)
+Q_DECLARE_METATYPE(QRect)
+Q_DECLARE_METATYPE(QSize)
+Q_DECLARE_METATYPE(QPoint)
+Q_DECLARE_METATYPE(QPainterPath)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QPainter : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QPainter();
+ virtual ~tst_QPainter();
+
+
+public slots:
+ void init();
+ void cleanup();
+private slots:
+ void getSetCheck();
+ void qt_format_text_clip();
+ void qt_format_text_boundingRect();
+ void drawPixmap_comp_data();
+ void drawPixmap_comp();
+ void saveAndRestore_data();
+ void saveAndRestore();
+
+ void drawBorderPixmap();
+ void drawPixmapFragments();
+
+ void drawLine_data();
+ void drawLine();
+ void drawLine_clipped();
+ void drawLine_task121143();
+ void drawLine_task216948();
+
+ void drawLine_task190634();
+ void drawLine_task229459();
+ void drawLine_task234891();
+
+ void drawRect_data() { fillData(); }
+ void drawRect();
+ void drawRect2();
+
+ void fillRect();
+ void fillRect2();
+ void fillRect3();
+ void fillRect4();
+
+ void drawEllipse_data();
+ void drawEllipse();
+ void drawClippedEllipse_data();
+ void drawClippedEllipse();
+
+ void drawPath_data();
+ void drawPath();
+ void drawPath2();
+ void drawPath3();
+
+ void drawRoundRect_data() { fillData(); }
+ void drawRoundRect();
+
+ void qimageFormats_data();
+ void qimageFormats();
+ void textOnTransparentImage();
+
+ void initFrom();
+
+ void setWindow();
+
+ void combinedMatrix();
+ void renderHints();
+
+ void disableEnableClipping();
+ void setClipRect();
+ void setEqualClipRegionAndPath_data();
+ void setEqualClipRegionAndPath();
+
+ void clipRectSaveRestore();
+
+ void clippedFillPath_data();
+ void clippedFillPath();
+ void clippedLines_data();
+ void clippedLines();
+ void clippedPolygon_data();
+ void clippedPolygon();
+
+ void clippedText();
+
+ void clipBoundingRect();
+
+ void setOpacity_data();
+ void setOpacity();
+
+ void drawhelper_blend_untransformed_data();
+ void drawhelper_blend_untransformed();
+ void drawhelper_blend_tiled_untransformed_data();
+ void drawhelper_blend_tiled_untransformed();
+
+ void porterDuff_warning();
+
+ void drawhelper_blend_color();
+
+ void childWidgetViewport();
+
+ void fillRect_objectBoundingModeGradient();
+ void fillRect_stretchToDeviceMode();
+ void monoImages();
+
+ void linearGradientSymmetry_data();
+ void linearGradientSymmetry();
+ void gradientInterpolation();
+
+ void fpe_pixmapTransform();
+ void fpe_zeroLengthLines();
+ void fpe_divByZero();
+
+ void fpe_steepSlopes_data();
+ void fpe_steepSlopes();
+ void fpe_rasterizeLine_task232012();
+
+ void fpe_radialGradients();
+
+ void rasterizer_asserts();
+ void rasterizer_negativeCoords();
+
+ void blendOverFlow_data();
+ void blendOverFlow();
+
+ void largeImagePainting_data();
+ void largeImagePainting();
+
+ void imageScaling_task206785();
+
+ void outlineFillConsistency();
+
+ void drawImage_task217400_data();
+ void drawImage_task217400();
+ void drawImage_1x1();
+ void drawImage_task258776();
+ void drawRect_task215378();
+ void drawRect_task247505();
+
+ void drawText_subPixelPositionsInRaster_qtbug5053();
+
+ void drawImage_data();
+ void drawImage();
+
+ void clippedImage();
+
+ void stateResetBetweenQPainters();
+
+ void imageCoordinateLimit();
+ void imageBlending_data();
+ void imageBlending();
+ void imageBlending_clipped();
+
+ void paintOnNullPixmap();
+ void checkCompositionMode();
+
+ void drawPolygon();
+
+ void inactivePainter();
+
+ void extendedBlendModes();
+
+ void zeroOpacity();
+ void clippingBug();
+ void emptyClip();
+
+ void taskQT4444_dontOverflowDashOffset();
+
+ void painterBegin();
+ void setPenColorOnImage();
+ void setPenColorOnPixmap();
+
+ void QTBUG5939_attachPainterPrivate();
+
+ void drawPointScaled();
+
+ void QTBUG14614_gradientCacheRaceCondition();
+ void drawTextOpacity();
+
+ void QTBUG17053_zeroDashPattern();
+
+ void drawTextOutsideGuiThread();
+
+private:
+ void fillData();
+ void setPenColor(QPainter& p);
+ QColor baseColor( int k, int intensity=255 );
+ QImage getResImage( const QString &dir, const QString &addition, const QString &extension );
+ QBitmap getBitmap( const QString &dir, const QString &filename, bool mask );
+};
+
+// Testing get/set functions
+void tst_QPainter::getSetCheck()
+{
+ QImage img(QSize(10, 10), QImage::Format_ARGB32_Premultiplied);
+ QPainter obj1;
+ obj1.begin(&img);
+ // CompositionMode QPainter::compositionMode()
+ // void QPainter::setCompositionMode(CompositionMode)
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_SourceOver));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_SourceOver), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_DestinationOver));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_DestinationOver), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_Clear));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_Clear), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_Source));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_Source), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_Destination));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_Destination), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_SourceIn));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_SourceIn), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_DestinationIn));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_DestinationIn), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_SourceOut));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_SourceOut), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_DestinationOut));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_DestinationOut), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_SourceAtop));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_SourceAtop), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_DestinationAtop));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_DestinationAtop), obj1.compositionMode());
+ obj1.setCompositionMode(QPainter::CompositionMode(QPainter::CompositionMode_Xor));
+ QCOMPARE(QPainter::CompositionMode(QPainter::CompositionMode_Xor), obj1.compositionMode());
+
+ // const QPen & QPainter::pen()
+ // void QPainter::setPen(const QPen &)
+ QPen var3(Qt::red);
+ obj1.setPen(var3);
+ QCOMPARE(var3, obj1.pen());
+ obj1.setPen(QPen());
+ QCOMPARE(QPen(), obj1.pen());
+
+ // const QBrush & QPainter::brush()
+ // void QPainter::setBrush(const QBrush &)
+ QBrush var4(Qt::red);
+ obj1.setBrush(var4);
+ QCOMPARE(var4, obj1.brush());
+ obj1.setBrush(QBrush());
+ QCOMPARE(QBrush(), obj1.brush());
+
+ // const QBrush & QPainter::background()
+ // void QPainter::setBackground(const QBrush &)
+ QBrush var5(Qt::yellow);
+ obj1.setBackground(var5);
+ QCOMPARE(var5, obj1.background());
+ obj1.setBackground(QBrush());
+ QCOMPARE(QBrush(), obj1.background());
+
+ // bool QPainter::matrixEnabled()
+ // void QPainter::setMatrixEnabled(bool)
+ obj1.setMatrixEnabled(false);
+ QCOMPARE(false, obj1.matrixEnabled());
+ obj1.setMatrixEnabled(true);
+ QCOMPARE(true, obj1.matrixEnabled());
+
+ // bool QPainter::viewTransformEnabled()
+ // void QPainter::setViewTransformEnabled(bool)
+ obj1.setViewTransformEnabled(false);
+ QCOMPARE(false, obj1.viewTransformEnabled());
+ obj1.setViewTransformEnabled(true);
+ QCOMPARE(true, obj1.viewTransformEnabled());
+}
+
+Q_DECLARE_METATYPE(QPixmap)
+Q_DECLARE_METATYPE(QPolygon)
+Q_DECLARE_METATYPE(QBrush)
+Q_DECLARE_METATYPE(QPen)
+Q_DECLARE_METATYPE(QFont)
+Q_DECLARE_METATYPE(QColor)
+Q_DECLARE_METATYPE(QRegion)
+
+tst_QPainter::tst_QPainter()
+{
+ // QtTestCase sets this to false, but this turns off alpha pixmaps on Unix.
+ QApplication::setDesktopSettingsAware(TRUE);
+}
+
+tst_QPainter::~tst_QPainter()
+{
+}
+
+void tst_QPainter::init()
+{
+}
+
+void tst_QPainter::cleanup()
+{
+}
+
+/* tests the clipping operations in qt_format_text, making sure
+ the clip rectangle after the call is the same as before
+*/
+void tst_QPainter::qt_format_text_clip()
+{
+ QVERIFY(1);
+ QSKIP( "Needs fixing...", SkipAll);
+
+ QWidget *w = new QWidget( 0 );
+
+ int modes[] = { Qt::AlignVCenter|Qt::TextSingleLine,
+ Qt::AlignVCenter|Qt::TextSingleLine|Qt::TextDontClip,
+ Qt::AlignVCenter|Qt::TextWordWrap,
+ Qt::AlignVCenter|Qt::TextWordWrap|Qt::TextDontClip,
+ 0
+ };
+
+ int *m = modes;
+ while( *m ) {
+ {
+ QPainter p( w );
+ QRegion clipreg = p.clipRegion();
+ bool hasClipping = p.hasClipping();
+ qreal tx = p.matrix().dx();
+ qreal ty = p.matrix().dy();
+
+ p.drawText( 10, 10, 100, 100, *m,
+ "fooo" );
+
+ QVERIFY( clipreg == p.clipRegion() );
+ QVERIFY( hasClipping == p.hasClipping() );
+ QCOMPARE( tx, p.matrix().dx() );
+ QCOMPARE( ty, p.matrix().dy() );
+
+ p.setClipRect( QRect( 5, 5, 50, 50 ) );
+ clipreg = p.clipRegion();
+ hasClipping = p.hasClipping();
+
+ p.drawText( 10, 10, 100, 100, *m,
+ "fooo" );
+
+ QVERIFY( clipreg == p.clipRegion() );
+ QVERIFY( hasClipping == p.hasClipping() );
+ QCOMPARE( tx, p.matrix().dx() );
+ QCOMPARE( ty, p.matrix().dy() );
+ }
+ {
+ QPainter p( w );
+ p.setMatrix( QMatrix( 2, 1, 3, 4, 5, 6 ) );
+ QRegion clipreg = p.clipRegion();
+ bool hasClipping = p.hasClipping();
+ qreal tx = p.matrix().dx();
+ qreal ty = p.matrix().dy();
+
+ p.drawText( 10, 10, 100, 100, *m,
+ "fooo" );
+
+ QVERIFY( clipreg == p.clipRegion() );
+ QVERIFY( hasClipping == p.hasClipping() );
+ QCOMPARE( tx, p.matrix().dx() );
+ QCOMPARE( ty, p.matrix().dy() );
+
+ p.setClipRect( QRect( 5, 5, 50, 50 ) );
+ clipreg = p.clipRegion();
+ hasClipping = p.hasClipping();
+
+ p.drawText( 10, 10, 100, 100, *m,
+ "fooo" );
+
+ QVERIFY( clipreg == p.clipRegion() );
+ QVERIFY( hasClipping == p.hasClipping() );
+ QCOMPARE( tx, p.matrix().dx() );
+ QCOMPARE( ty, p.matrix().dy() );
+ }
+ {
+ QPainter p( w );
+ QRegion clipreg = p.clipRegion();
+ bool hasClipping = p.hasClipping();
+ qreal tx = p.matrix().dx();
+ qreal ty = p.matrix().dy();
+
+ p.drawText( 10, 10, 100, 100, *m,
+ "fooo" );
+
+ QVERIFY( clipreg == p.clipRegion() );
+ QVERIFY( hasClipping == p.hasClipping() );
+ QCOMPARE( tx, p.matrix().dx() );
+ QCOMPARE( ty, p.matrix().dy() );
+
+ p.setClipRect( QRect( 5, 5, 50, 50 ));
+ clipreg = p.clipRegion();
+ hasClipping = p.hasClipping();
+
+ p.drawText( 10, 10, 100, 100, *m,
+ "fooo" );
+
+ QVERIFY( clipreg == p.clipRegion() );
+ QVERIFY( hasClipping == p.hasClipping() );
+ QCOMPARE( tx, p.matrix().dx() );
+ QCOMPARE( ty, p.matrix().dy() );
+ }
+ {
+ QPainter p( w );
+ p.setMatrix( QMatrix( 2, 1, 3, 4, 5, 6 ) );
+ QRegion clipreg = p.clipRegion();
+ bool hasClipping = p.hasClipping();
+ qreal tx = p.matrix().dx();
+ qreal ty = p.matrix().dy();
+
+ p.drawText( 10, 10, 100, 100, *m,
+ "fooo" );
+
+ QVERIFY( clipreg == p.clipRegion() );
+ QVERIFY( hasClipping == p.hasClipping() );
+ QCOMPARE( tx, p.matrix().dx() );
+ QCOMPARE( ty, p.matrix().dy() );
+
+ p.setClipRect(QRect( 5, 5, 50, 50 ));
+ clipreg = p.clipRegion();
+ hasClipping = p.hasClipping();
+
+ p.drawText( 10, 10, 100, 100, *m,
+ "fooo" );
+
+ QVERIFY( clipreg == p.clipRegion() );
+ QVERIFY( hasClipping == p.hasClipping() );
+ QCOMPARE( tx, p.matrix().dx() );
+ QCOMPARE( ty, p.matrix().dy() );
+ }
+ ++m;
+ }
+ delete w;
+}
+
+/* tests the bounding rect calculations in qt_format_text, making sure
+ the bounding rect has a reasonable value.
+*/
+void tst_QPainter::qt_format_text_boundingRect()
+{
+ QVERIFY(1);
+ QSKIP( "Needs fixing...", SkipAll);
+
+ {
+ const char * strings[] = {
+ "a\n\nb",
+ "abc",
+ "a\n \nb",
+ "this is a longer string",
+ "\327\222\327\223\327\233\327\223\327\222\327\233\327\222\327\223\327\233",
+ "aa\327\222\327\233aa",
+ "\327\222\327\223\327\233\327\223\327\222\327\233\327\222\327\223\327\233",
+ "\327\222\327\233aa",
+ "linebreakatend\n",
+ "some text longer than 30 chars with a line break at the end\n",
+ "some text\nwith line breaks\nin the middle\nand at the end\n",
+ "foo\n\n\nfoo",
+ 0
+ };
+
+ int modes[] = { Qt::AlignVCenter|Qt::TextSingleLine,
+ Qt::AlignVCenter|Qt::TextSingleLine|Qt::TextDontClip,
+ Qt::AlignVCenter|Qt::TextWordWrap,
+ Qt::AlignVCenter|Qt::TextWordWrap|Qt::TextDontClip,
+ Qt::AlignLeft,
+ Qt::AlignCenter,
+ Qt::AlignRight,
+ 0
+ };
+
+ QFont f;
+ for(int i = 5; i < 15; ++i) {
+ f.setPointSize(i);
+ QFontMetrics fm(f);
+ const char **str = strings;
+ while( *str ) {
+ int *m = modes;
+ while( *m ) {
+ QRect br = fm.boundingRect( 0, 0, 2000, 100, *m, QString::fromUtf8( *str ) );
+ QVERIFY( br.width() < 800 );
+
+ QRect br2 = fm.boundingRect( br.x(), br.y(), br.width(), br.height(), *m, QString::fromUtf8( *str ) );
+ QCOMPARE( br, br2 );
+#if 0
+ {
+ QPrinter printer;
+ printer.setOutputToFile(TRUE);
+ printer.setOutputFileName("tmp.prn");
+ QPainter p(&printer);
+ QRect pbr = p.fontMetrics().boundingRect( 0, 0, 2000, 100, *m, QString::fromUtf8( *str ) );
+ QCOMPARE(pbr, br);
+ }
+#endif
+#if !defined(QT_NO_PRINTER) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ {
+ QPrinter printer(QPrinter::HighResolution);
+ if (printer.printerName().isEmpty()) {
+ QSKIP( "No printers installed, skipping bounding rect test",
+ SkipSingle );
+ break;
+ }
+
+ printer.setOutputFileName("tmp.prn");
+ QPainter p(&printer);
+ QRect pbr = p.fontMetrics().boundingRect( 0, 0, 12000, 600, *m, QString::fromUtf8( *str ) );
+ QVERIFY(pbr.width() > 2*br.width());
+ QVERIFY(pbr.height() > 2*br.height());
+ }
+#endif
+ ++m;
+ }
+ ++str;
+ }
+ }
+ }
+
+ {
+ const char * strings[] = {
+ "a",
+ "a\nb",
+ "a\n\nb",
+ "abc",
+// "a\n \nb",
+ "this is a longer string",
+// "\327\222\327\223\327\233\327\223\327\222\327\233\327\222\327\223\327\233",
+// "aa\327\222\327\233aa",
+// "\327\222\327\223\327\233\327\223\327\222\327\233\327\222\327\223\327\233",
+// "\327\222\327\233aa",
+// "linebreakatend\n",
+// "some text longer than 30 chars with a line break at the end\n",
+// "some text\nwith line breaks\nin the middle\nand at the end\n",
+ "foo\n\n\nfoo",
+ "a\n\n\n\n\nb",
+ "a\n\n\n\n\n\nb",
+// "\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"
+// "\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",
+ 0
+ };
+
+ int modes[] = { Qt::AlignVCenter,
+ Qt::AlignLeft,
+ Qt::AlignCenter,
+ Qt::AlignRight,
+ 0
+ };
+
+
+ QFont f;
+ for(int i = 5; i < 15; ++i) {
+ f.setPointSize(i);
+ QFontMetrics fm(f);
+ const char **str = strings;
+ while( *str ) {
+ int *m = modes;
+ while( *m ) {
+ QString s = QString::fromUtf8(*str);
+ QRect br = fm.boundingRect(0, 0, 1000, 1000, *m, s );
+ int lines =
+ s.count("\n");
+ int expectedHeight = fm.height()+lines*fm.lineSpacing();
+ QCOMPARE(br.height(), expectedHeight);
+ ++m;
+ }
+ ++str;
+ }
+ QRect br = fm.boundingRect(0, 0, 100, 0, Qt::TextWordWrap,
+ "A paragraph with gggggggggggggggggggggggggggggggggggg in the middle.");
+ QVERIFY(br.height() >= fm.height()+2*fm.lineSpacing());
+ }
+ }
+}
+
+
+static const char* const maskSource_data[] = {
+"16 13 6 1",
+". c None",
+"d c #000000",
+"# c #999999",
+"c c #cccccc",
+"b c #ffff00",
+"a c #ffffff",
+"...#####........",
+"..#aaaaa#.......",
+".#abcbcba######.",
+".#acbcbcaaaaaa#d",
+".#abcbcbcbcbcb#d",
+"#############b#d",
+"#aaaaaaaaaa##c#d",
+"#abcbcbcbcbbd##d",
+".#abcbcbcbcbcd#d",
+".#acbcbcbcbcbd#d",
+"..#acbcbcbcbb#dd",
+"..#############d",
+"...ddddddddddddd"};
+
+static const char* const maskResult_data[] = {
+"16 13 6 1",
+". c #ff0000",
+"d c #000000",
+"# c #999999",
+"c c #cccccc",
+"b c #ffff00",
+"a c #ffffff",
+"...#####........",
+"..#aaaaa#.......",
+".#abcbcba######.",
+".#acbcbcaaaaaa#d",
+".#abcbcbcbcbcb#d",
+"#############b#d",
+"#aaaaaaaaaa##c#d",
+"#abcbcbcbcbbd##d",
+".#abcbcbcbcbcd#d",
+".#acbcbcbcbcbd#d",
+"..#acbcbcbcbb#dd",
+"..#############d",
+"...ddddddddddddd"};
+
+
+void tst_QPainter::drawPixmap_comp_data()
+{
+ if (qApp->desktop()->depth() < 24) {
+ QSKIP("Test only works on 32 bit displays", SkipAll);
+ return;
+ }
+
+ QTest::addColumn<uint>("dest");
+ QTest::addColumn<uint>("source");
+
+ QTest::newRow("0% on 0%, 1") << 0x00000000u<< 0x00000000u;
+ QTest::newRow("0% on 0%, 2") << 0x00007fffu << 0x00ff007fu;
+
+ QTest::newRow("50% on a=0%") << 0x00000000u << 0x7fff0000u;
+ QTest::newRow("50% on a=50%") << 0x7f000000u << 0x7fff0000u;
+ QTest::newRow("50% on deadbeef") << 0xdeafbeefu << 0x7fff0000u;
+ QTest::newRow("deadbeef on a=0%") << 0x00000000u << 0xdeadbeefu;
+ QTest::newRow("deadbeef on a=50%") << 0x7f000000u << 0xdeadbeefu;
+ QTest::newRow("50% blue on 50% red") << 0x7fff0000u << 0x7f0000ffu;
+ QTest::newRow("50% blue on 50% green") << 0x7f00ff00u << 0x7f0000ffu;
+ QTest::newRow("50% red on 50% green") << 0x7f00ff00u << 0x7fff0000u;
+ QTest::newRow("0% on 50%") << 0x7fff00ffu << 0x00ffffffu;
+ QTest::newRow("100% on deadbeef") << 0xdeafbeefu << 0xffabcdefu;
+ QTest::newRow("100% on a=0%") << 0x00000000u << 0xffabcdefu;
+}
+
+QRgb qt_compose_alpha(QRgb source, QRgb dest)
+{
+ int r1 = qRed(dest), g1 = qGreen(dest), b1 = qBlue(dest), a1 = qAlpha(dest);
+ int r2 = qRed(source), g2 = qGreen(source), b2 = qBlue(source), a2 = qAlpha(source);
+
+ int alpha = qMin(a2 + ((255 - a2) * a1 + 127) / 255, 255);
+ if (alpha == 0)
+ return qRgba(0, 0, 0, 0);
+
+ return qRgba(
+ qMin((r2 * a2 + (255 - a2) * r1 * a1 / 255) / alpha, 255),
+ qMin((g2 * a2 + (255 - a2) * g1 * a1 / 255) / alpha, 255),
+ qMin((b2 * a2 + (255 - a2) * b1 * a1 / 255) / alpha, 255),
+ alpha);
+}
+
+/* Tests that drawing masked pixmaps works
+*/
+void tst_QPainter::drawPixmap_comp()
+{
+#ifdef Q_WS_MAC
+ QSKIP("Mac has other ideas about alpha composition", SkipAll);
+#endif
+
+ QFETCH(uint, dest);
+ QFETCH(uint, source);
+
+ QRgb expected = qt_compose_alpha(source, dest);
+
+ QColor c1(qRed(dest), qGreen(dest), qBlue(dest), qAlpha(dest));
+ QColor c2(qRed(source), qGreen(source), qBlue(source), qAlpha(source));
+
+ QPixmap destPm(10, 10), srcPm(10, 10);
+ destPm.fill(c1);
+ srcPm.fill(c2);
+
+#if defined(Q_WS_X11)
+ if (!destPm.x11PictureHandle())
+ QSKIP("Requires XRender support", SkipAll);
+#endif
+
+ QPainter p(&destPm);
+ p.drawPixmap(0, 0, srcPm);
+ p.end();
+
+ QImage result = destPm.toImage().convertToFormat(QImage::Format_ARGB32);
+ bool different = false;
+ for (int y=0; y<result.height(); ++y)
+ for (int x=0; x<result.width(); ++x) {
+ bool diff;
+ if (qAlpha(expected) == 0) {
+ diff = qAlpha(result.pixel(x, y)) != 0;
+ } else {
+ // Compensate for possible roundoff / platform fudge
+ int off = 1;
+ QRgb pix = result.pixel(x, y);
+ diff = (qAbs(qRed(pix) - qRed(expected)) > off)
+ || (qAbs(qGreen(pix) - qGreen(expected)) > off)
+ || (qAbs(qBlue(pix) - qBlue(expected)) > off)
+ || (qAbs(qAlpha(pix) - qAlpha(expected)) > off);
+ }
+ if (diff && !different)
+ qDebug( "Different at %d,%d pixel [%d,%d,%d,%d] expected [%d,%d,%d,%d]", x, y,
+ qRed(result.pixel(x, y)), qGreen(result.pixel(x, y)),
+ qBlue(result.pixel(x, y)), qAlpha(result.pixel(x, y)),
+ qRed(expected), qGreen(expected), qBlue(expected), qAlpha(expected));
+ different |= diff;
+ }
+
+ QVERIFY(!different);
+}
+
+void tst_QPainter::saveAndRestore_data()
+{
+ QVERIFY(1);
+
+ QTest::addColumn<QFont>("font");
+ QTest::addColumn<QPen>("pen");
+ QTest::addColumn<QBrush>("brush");
+ QTest::addColumn<QColor>("backgroundColor");
+ QTest::addColumn<int>("backgroundMode");
+ QTest::addColumn<QPoint>("brushOrigin");
+ QTest::addColumn<QRegion>("clipRegion");
+ QTest::addColumn<QRect>("window");
+ QTest::addColumn<QRect>("viewport");
+
+ QPixmap pixmap(1, 1);
+ QPainter p(&pixmap);
+ QFont font = p.font();
+ QPen pen = p.pen();
+ QBrush brush = p.brush();
+ QColor backgroundColor = p.background().color();
+ Qt::BGMode backgroundMode = p.backgroundMode();
+ QPoint brushOrigin = p.brushOrigin();
+ QRegion clipRegion = p.clipRegion();
+ QRect window = p.window();
+ QRect viewport = p.viewport();
+
+ QTest::newRow("Original") << font << pen << brush << backgroundColor << int(backgroundMode)
+ << brushOrigin << clipRegion << window << viewport;
+
+ QFont font2 = font;
+ font2.setPointSize( 24 );
+ QTest::newRow("Modified font.pointSize, brush, backgroundColor, backgroundMode")
+ << font2 << pen << QBrush(Qt::red) << QColor(Qt::blue) << int(Qt::TransparentMode)
+ << brushOrigin << clipRegion << window << viewport;
+
+ font2 = font;
+ font2.setPixelSize( 20 );
+ QTest::newRow("Modified font.pixelSize, brushOrigin, pos")
+ << font2 << pen << brush << backgroundColor << int(backgroundMode)
+ << QPoint( 50, 32 ) << clipRegion << window << viewport;
+
+ QTest::newRow("Modified clipRegion, window, viewport")
+ << font << pen << brush << backgroundColor << int(backgroundMode)
+ << brushOrigin << clipRegion.subtracted(QRect(10,10,50,30))
+ << QRect(-500, -500, 500, 500 ) << QRect( 0, 0, 50, 50 );
+}
+
+void tst_QPainter::saveAndRestore()
+{
+ QFETCH( QFont, font );
+ QFETCH( QPen, pen );
+ QFETCH( QBrush, brush );
+ QFETCH( QColor, backgroundColor );
+ QFETCH( int, backgroundMode );
+ QFETCH( QPoint, brushOrigin );
+ QFETCH( QRegion, clipRegion );
+ QFETCH( QRect, window );
+ QFETCH( QRect, viewport );
+
+ QPixmap pixmap(1, 1);
+ QPainter painter(&pixmap);
+
+ QFont font_org = painter.font();
+ QPen pen_org = painter.pen();
+ QBrush brush_org = painter.brush();
+ QColor backgroundColor_org = painter.background().color();
+ Qt::BGMode backgroundMode_org = painter.backgroundMode();
+ QPoint brushOrigin_org = painter.brushOrigin();
+ QRegion clipRegion_org = painter.clipRegion();
+ QRect window_org = painter.window();
+ QRect viewport_org = painter.viewport();
+
+ painter.save();
+ painter.setFont( font );
+ painter.setPen( QPen(pen) );
+ painter.setBrush( brush );
+ painter.setBackground( backgroundColor );
+ painter.setBackgroundMode( (Qt::BGMode)backgroundMode );
+ painter.setBrushOrigin( brushOrigin );
+ painter.setClipRegion( clipRegion );
+ painter.setWindow( window );
+ painter.setViewport( viewport );
+ painter.restore();
+
+ QCOMPARE( painter.font(), font_org );
+ QCOMPARE( painter.font().pointSize(), font_org.pointSize() );
+ QCOMPARE( painter.font().pixelSize(), font_org.pixelSize() );
+ QCOMPARE( painter.pen(), pen_org );
+ QCOMPARE( painter.brush(), brush_org );
+ QCOMPARE( painter.background().color(), backgroundColor_org );
+ QCOMPARE( painter.backgroundMode(), backgroundMode_org );
+ QCOMPARE( painter.brushOrigin(), brushOrigin_org );
+ QCOMPARE( painter.clipRegion(), clipRegion_org );
+ QCOMPARE( painter.window(), window_org );
+ QCOMPARE( painter.viewport(), viewport_org );
+}
+
+/*
+ Helper functions
+*/
+
+QColor tst_QPainter::baseColor( int k, int intensity )
+{
+ int r = ( k & 1 ) * intensity;
+ int g = ( (k>>1) & 1 ) * intensity;
+ int b = ( (k>>2) & 1 ) * intensity;
+ return QColor( r, g, b );
+}
+
+QImage tst_QPainter::getResImage( const QString &dir, const QString &addition, const QString &extension )
+{
+ QImage res;
+ QString resFilename = dir + QString( "/res_%1." ).arg( addition ) + extension;
+ if ( !res.load( resFilename ) ) {
+ QWARN(QString("Could not load result data %s %1").arg(resFilename).toLatin1());
+ return QImage();
+ }
+ return res;
+}
+
+QBitmap tst_QPainter::getBitmap( const QString &dir, const QString &filename, bool mask )
+{
+ QBitmap bm;
+ QString bmFilename = dir + QString( "/%1.xbm" ).arg( filename );
+ if ( !bm.load( bmFilename ) ) {
+ QWARN(QString("Could not load bitmap '%1'").arg(bmFilename).toLatin1());
+ return QBitmap();
+ }
+ if ( mask ) {
+ QBitmap mask;
+ QString maskFilename = dir + QString( "/%1-mask.xbm" ).arg( filename );
+ if ( !mask.load( maskFilename ) ) {
+ QWARN(QString("Could not load mask '%1'").arg(maskFilename).toLatin1());
+ return QBitmap();
+ }
+ bm.setMask( mask );
+ }
+ return bm;
+}
+
+static int getPaintedPixels(const QImage &image, const QColor &background)
+{
+ uint color = background.rgba();
+
+ int pixels = 0;
+
+ for (int y = 0; y < image.height(); ++y)
+ for (int x = 0; x < image.width(); ++x)
+ if (image.pixel(x, y) != color)
+ ++pixels;
+
+ return pixels;
+}
+
+static QRect getPaintedSize(const QImage &image, const QColor &background)
+{
+ // not the fastest but at least it works..
+ int xmin = image.width() + 1;
+ int xmax = -1;
+ int ymin = image.height() +1;
+ int ymax = -1;
+
+ uint color = background.rgba();
+
+ for ( int y = 0; y < image.height(); ++y ) {
+ for ( int x = 0; x < image.width(); ++x ) {
+ QRgb pixel = image.pixel( x, y );
+ if ( pixel != color && x < xmin )
+ xmin = x;
+ if ( pixel != color && x > xmax )
+ xmax = x;
+ if ( pixel != color && y < ymin )
+ ymin = y;
+ if ( pixel != color && y > ymax )
+ ymax = y;
+ }
+ }
+
+ return QRect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
+}
+
+static QRect getPaintedSize(const QPixmap &pm, const QColor &background)
+{
+ return getPaintedSize(pm.toImage(), background);
+}
+
+void tst_QPainter::initFrom()
+{
+ QWidget *widget = new QWidget();
+ QPalette pal = widget->palette();
+ pal.setColor(QPalette::Foreground, QColor(255, 0, 0));
+ pal.setBrush(QPalette::Background, QColor(0, 255, 0));
+ widget->setPalette(pal);
+
+ QFont font = widget->font();
+ font.setPointSize(26);
+ font.setItalic(true);
+ widget->setFont(font);
+
+ QPixmap pm(100, 100);
+ QPainter p(&pm);
+ p.initFrom(widget);
+
+ QCOMPARE(p.font(), font);
+ QCOMPARE(p.pen().color(), pal.color(QPalette::Foreground));
+ QCOMPARE(p.background(), pal.background());
+
+ delete widget;
+}
+
+void tst_QPainter::drawBorderPixmap()
+{
+ QPixmap src(79,79);
+ src.fill(Qt::transparent);
+
+ QImage pm(200,200,QImage::Format_RGB32);
+ QPainter p(&pm);
+ p.setTransform(QTransform(-1,0,0,-1,173.5,153.5));
+ qDrawBorderPixmap(&p, QRect(0,0,75,105), QMargins(39,39,39,39), src, QRect(0,0,79,79), QMargins(39,39,39,39),
+ QTileRules(Qt::StretchTile,Qt::StretchTile), 0);
+}
+
+void tst_QPainter::drawPixmapFragments()
+{
+ QPixmap origPixmap(20, 20);
+ QPixmap resPixmap(20, 20);
+ QPainter::PixmapFragment fragments[4] = { {15, 15, 0, 0, 10, 10, 1, 1, 0, 1},
+ { 5, 15, 10, 0, 10, 10, 1, 1, 0, 1},
+ {15, 5, 0, 10, 10, 10, 1, 1, 0, 1},
+ { 5, 5, 10, 10, 10, 10, 1, 1, 0, 1} };
+ {
+ QPainter p(&origPixmap);
+ p.fillRect(0, 0, 10, 10, Qt::red);
+ p.fillRect(10, 0, 10, 10, Qt::green);
+ p.fillRect(0, 10, 10, 10, Qt::blue);
+ p.fillRect(10, 10, 10, 10, Qt::yellow);
+ }
+ {
+ QPainter p(&resPixmap);
+ p.drawPixmapFragments(fragments, 4, origPixmap);
+ }
+
+ QImage origImage = origPixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ QImage resImage = resPixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+
+ QVERIFY(resImage.size() == resPixmap.size());
+ QVERIFY(resImage.pixel(5, 5) == origImage.pixel(15, 15));
+ QVERIFY(resImage.pixel(5, 15) == origImage.pixel(15, 5));
+ QVERIFY(resImage.pixel(15, 5) == origImage.pixel(5, 15));
+ QVERIFY(resImage.pixel(15, 15) == origImage.pixel(5, 5));
+
+
+ QPainter::PixmapFragment fragment = QPainter::PixmapFragment::create(QPointF(20, 20), QRectF(30, 30, 2, 2));
+ QVERIFY(fragment.x == 20);
+ QVERIFY(fragment.y == 20);
+ QVERIFY(fragment.sourceLeft == 30);
+ QVERIFY(fragment.sourceTop == 30);
+ QVERIFY(fragment.width == 2);
+ QVERIFY(fragment.height == 2);
+ QVERIFY(fragment.scaleX == 1);
+ QVERIFY(fragment.scaleY == 1);
+ QVERIFY(fragment.rotation == 0);
+ QVERIFY(fragment.opacity == 1);
+}
+
+void tst_QPainter::drawLine_data()
+{
+ QTest::addColumn<QLine>("line");
+
+ QTest::newRow("0-45") << QLine(0, 20, 100, 0);
+ QTest::newRow("45-90") << QLine(0, 100, 20, 0);
+ QTest::newRow("90-135") << QLine(20, 100, 0, 0);
+ QTest::newRow("135-180") << QLine(100, 20, 0, 0);
+ QTest::newRow("180-225") << QLine(100, 0, 0, 20);
+ QTest::newRow("225-270") << QLine(20, 0, 0, 100);
+ QTest::newRow("270-315") << QLine(0, 0, 20, 100);
+ QTest::newRow("315-360") << QLine(0, 0, 100, 20);
+}
+
+void tst_QPainter::drawLine()
+{
+ const int offset = 5;
+ const int epsilon = 1; // allow for one pixel difference
+
+ QFETCH(QLine, line);
+
+ QPixmap pixmapUnclipped(qMin(line.x1(), line.x2())
+ + 2*offset + qAbs(line.dx()),
+ qMin(line.y1(), line.y2())
+ + 2*offset + qAbs(line.dy()));
+
+ { // unclipped
+ pixmapUnclipped.fill(Qt::white);
+ QPainter p(&pixmapUnclipped);
+ p.translate(offset, offset);
+ p.setPen(QPen(Qt::black));
+ p.drawLine(line);
+ p.end();
+
+ const QRect painted = getPaintedSize(pixmapUnclipped, Qt::white);
+
+ QLine l = line;
+ l.translate(offset, offset);
+ QVERIFY(qAbs(painted.width() - qAbs(l.dx())) <= epsilon);
+ QVERIFY(qAbs(painted.height() - qAbs(l.dy())) <= epsilon);
+ QVERIFY(qAbs(painted.top() - qMin(l.y1(), l.y2())) <= epsilon);
+ QVERIFY(qAbs(painted.left() - qMin(l.x1(), l.x2())) <= epsilon);
+ QVERIFY(qAbs(painted.bottom() - qMax(l.y1(), l.y2())) <= epsilon);
+ QVERIFY(qAbs(painted.right() - qMax(l.x1(), l.x2())) <= epsilon);
+ }
+
+ QPixmap pixmapClipped(qMin(line.x1(), line.x2())
+ + 2*offset + qAbs(line.dx()),
+ qMin(line.y1(), line.y2())
+ + 2*offset + qAbs(line.dy()));
+ { // clipped
+ const QRect clip = QRect(line.p1(), line.p2()).normalized();
+
+ pixmapClipped.fill(Qt::white);
+ QPainter p(&pixmapClipped);
+ p.translate(offset, offset);
+ p.setClipRect(clip);
+ p.setPen(QPen(Qt::black));
+ p.drawLine(line);
+ p.end();
+ }
+
+ const QImage unclipped = pixmapUnclipped.toImage();
+ const QImage clipped = pixmapClipped.toImage();
+ QCOMPARE(unclipped, clipped);
+}
+
+void tst_QPainter::drawLine_clipped()
+{
+ QImage image(16, 1, QImage::Format_ARGB32_Premultiplied);
+ image.fill(0x0);
+
+ QPainter p(&image);
+ p.setPen(QPen(Qt::black, 10));
+
+ // this should fill the whole image
+ p.drawLine(-1, -1, 17, 1);
+ p.end();
+
+ for (int x = 0; x < 16; ++x)
+ QCOMPARE(image.pixel(x, 0), 0xff000000);
+}
+
+void tst_QPainter::drawLine_task121143()
+{
+ QPen pen(Qt::black);
+
+ QImage image(5, 5, QImage::Format_ARGB32_Premultiplied);
+ image.fill(0xffffffff);
+ QPainter p(&image);
+ p.setPen(pen);
+ p.drawLine(QLine(0, 0+4, 0+4, 0));
+ p.end();
+
+ QImage expected(5, 5, QImage::Format_ARGB32_Premultiplied);
+ expected.fill(0xffffffff);
+ for (int x = 0; x < 5; ++x)
+ expected.setPixel(x, 5-x-1, pen.color().rgb());
+
+ QCOMPARE(image, expected);
+}
+
+void tst_QPainter::drawLine_task190634()
+{
+ QPen pen(Qt::black, 3);
+
+ QImage image(32, 32, QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&image);
+ p.fillRect(0, 0, image.width(), image.height(), Qt::white);
+
+ p.setPen(pen);
+ p.drawLine(QLineF(2, -1.6, 10, -1.6));
+ p.end();
+
+ const uint *data = reinterpret_cast<uint *>(image.bits());
+
+ for (int i = 0; i < image.width() * image.height(); ++i)
+ QCOMPARE(data[i], 0xffffffff);
+
+ p.begin(&image);
+ p.fillRect(0, 0, image.width(), image.height(), Qt::white);
+
+ p.setPen(pen);
+ p.drawLine(QLineF(-1.6, 2, -1.6, 10));
+ p.end();
+
+ data = reinterpret_cast<uint *>(image.bits());
+
+ for (int i = 0; i < image.width() * image.height(); ++i)
+ QCOMPARE(data[i], 0xffffffff);
+
+ p.begin(&image);
+ p.fillRect(0, 0, image.width(), image.height(), Qt::white);
+
+ p.setPen(pen);
+ p.drawLine( QPoint(2,-2), QPoint(3,-5) );
+ p.end();
+
+ data = reinterpret_cast<uint *>(image.bits());
+
+ for (int i = 0; i < image.width() * image.height(); ++i)
+ QCOMPARE(data[i], 0xffffffff);
+}
+
+void tst_QPainter::drawLine_task229459()
+{
+ QImage image(32, 32, QImage::Format_ARGB32_Premultiplied);
+ image.fill(0x0);
+ QPen pen(Qt::black, 64);
+
+ QPainter p(&image);
+ p.setPen(pen);
+ p.drawLine(-8, -8, 10000000, 10000000);
+ p.end();
+
+ QImage expected = image;
+ expected.fill(0xff000000);
+
+ QCOMPARE(image, expected);
+}
+
+void tst_QPainter::drawLine_task234891()
+{
+ QImage img(100, 1000, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0x0);
+ QImage expected = img;
+
+ QPainter p(&img);
+ p.setPen(QPen(QBrush(QColor(255,0,0)), 6));
+ p.drawLine(QPointF(25000,100),QPointF(30000,105));
+
+ p.setPen(QPen(QBrush(QColor(0,255,0)), 6));
+ p.drawLine(QPointF(30000,150),QPointF(35000,155));
+
+ p.setPen(QPen(QBrush(QColor(0,0,255)), 6));
+ p.drawLine(QPointF(65000,200),QPointF(66000,205));
+
+ QCOMPARE(expected, img);
+}
+
+void tst_QPainter::drawLine_task216948()
+{
+ QImage img(1, 10, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0x0);
+
+ QPainter p(&img);
+ QLine line(10, 0, 10, 10);
+ p.translate(-10, 0);
+ p.drawLine(line);
+ p.end();
+
+ for (int i = 0; i < img.height(); ++i)
+ QCOMPARE(img.pixel(0, i), QColor(Qt::black).rgba());
+}
+
+void tst_QPainter::drawRect()
+{
+ QFETCH(QRect, rect);
+ QFETCH(bool, usePen);
+
+ QPixmap pixmap(rect.x() + rect.width() + 10,
+ rect.y() + rect.height() + 10);
+ {
+ pixmap.fill(Qt::white);
+ QPainter p(&pixmap);
+ p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
+ p.setBrush(Qt::black);
+ p.drawRect(rect);
+ p.end();
+
+ int increment = usePen ? 1 : 0;
+
+ const QRect painted = getPaintedSize(pixmap, Qt::white);
+ QCOMPARE(painted.width(), rect.width() + increment);
+ QCOMPARE(painted.height(), rect.height() + increment);
+ }
+}
+
+void tst_QPainter::drawRect2()
+{
+ QImage image(64, 64, QImage::Format_ARGB32_Premultiplied);
+ {
+ image.fill(0xffffffff);
+
+ QTransform transform(0.368567, 0, 0, 0, 0.368567, 0, 0.0289, 0.0289, 1);
+
+ QPainter p(&image);
+ p.setTransform(transform);
+ p.setBrush(Qt::red);
+ p.setPen(Qt::NoPen);
+ p.drawRect(QRect(14, 14, 39, 39));
+ p.end();
+
+ QRect fill = getPaintedSize(image, Qt::white);
+ image.fill(0xffffffff);
+
+ p.begin(&image);
+ p.setTransform(transform);
+ p.drawRect(QRect(14, 14, 39, 39));
+ p.end();
+
+ QRect stroke = getPaintedSize(image, Qt::white);
+ QCOMPARE(stroke.adjusted(1, 1, 0, 0), fill.adjusted(0, 0, 1, 1));
+ }
+}
+
+void tst_QPainter::fillRect()
+{
+ QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
+ image.fill(QColor(0, 0, 0, 0).rgba());
+
+ QPainter p(&image);
+
+ p.fillRect(0, 0, 100, 100, QColor(255, 0, 0, 127));
+
+// pixmap.save("bla1.png", "PNG");
+ QCOMPARE(getPaintedSize(image, QColor(0, 0, 0, 0)),
+ QRect(0, 0, 100, 100));
+ QCOMPARE(getPaintedSize(image, QColor(127, 0, 0, 127)).isValid(),
+ QRect().isValid());
+
+ p.setCompositionMode(QPainter::CompositionMode_SourceIn);
+ p.fillRect(50, 0, 50, 100, QColor(0, 0, 255, 255));
+
+ QCOMPARE(getPaintedSize(image, QColor(127, 0, 0, 127)),
+ QRect(50, 0, 50, 100));
+ QCOMPARE(getPaintedSize(image, QColor(0, 0, 127, 127)),
+ QRect(0, 0, 50, 100));
+}
+
+void tst_QPainter::fillRect2()
+{
+ QRgb background = 0x0;
+
+ QImage img(1, 20, QImage::Format_ARGB32_Premultiplied);
+ img.fill(background);
+
+ QPainter p(&img);
+
+ QRectF rect(0, 1, 1.2, 18);
+ p.fillRect(rect, Qt::black);
+
+ p.end();
+
+ QCOMPARE(img.pixel(0, 0), background);
+ QCOMPARE(img.pixel(0, img.height() - 1), background);
+
+ QCOMPARE(img.pixel(0, 1), img.pixel(0, 2));
+ QCOMPARE(img.pixel(0, img.height() - 2), img.pixel(0, img.height() - 3));
+}
+
+void tst_QPainter::fillRect3()
+{
+ QImage img(1, 1, QImage::Format_ARGB32_Premultiplied);
+ img.fill(QColor(Qt::black).rgba());
+
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(img.rect(), Qt::transparent);
+ p.end();
+
+ QCOMPARE(img.pixel(0, 0), 0U);
+}
+
+void tst_QPainter::fillRect4()
+{
+ QImage image(100, 1, QImage::Format_ARGB32_Premultiplied);
+ image.fill(0x0);
+
+ QImage expected = image;
+ expected.fill(0xffffffff);
+
+ QPainter p(&image);
+ p.scale(1.1, 1);
+ p.setPen(Qt::NoPen);
+
+ for (int i = 0; i < 33; ++i)
+ p.fillRect(QRectF(3 * i, 0, 3, 1), Qt::white);
+
+ p.end();
+
+ QCOMPARE(image, expected);
+}
+
+void tst_QPainter::drawPath_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<QRect>("expectedBounds");
+ QTest::addColumn<int>("expectedPixels");
+
+ {
+ QPainterPath p;
+ p.addRect(2, 2, 10, 10);
+ QTest::newRow("int-aligned rect") << p << QRect(2, 2, 10, 10) << 10 * 10;
+ }
+
+ {
+ QPainterPath p;
+ p.addRect(2.25, 2.25, 10, 10);
+ QTest::newRow("non-aligned rect") << p << QRect(3, 3, 10, 10) << 10 * 10;
+ }
+
+ {
+ QPainterPath p;
+ p.addRect(2.25, 2.25, 10.5, 10.5);
+ QTest::newRow("non-aligned rect 2") << p << QRect(3, 3, 10, 10) << 10 * 10;
+ }
+
+ {
+ QPainterPath p;
+ p.addRect(2.5, 2.5, 10, 10);
+ QTest::newRow("non-aligned rect 3") << p << QRect(3, 3, 10, 10) << 10 * 10;
+ }
+
+ {
+ QPainterPath p;
+ p.addRect(2, 2, 10, 10);
+ p.addRect(4, 4, 6, 6);
+ QTest::newRow("rect-in-rect") << p << QRect(2, 2, 10, 10) << 10 * 10 - 6 * 6;
+ }
+
+ {
+ QPainterPath p;
+ p.addRect(2, 2, 10, 10);
+ p.addRect(4, 4, 6, 6);
+ p.addRect(6, 6, 2, 2);
+ QTest::newRow("rect-in-rect-in-rect") << p << QRect(2, 2, 10, 10) << 10 * 10 - 6 * 6 + 2 * 2;
+ }
+}
+
+void tst_QPainter::drawPath()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(QRect, expectedBounds);
+ QFETCH(int, expectedPixels);
+
+ const int offset = 2;
+
+ QImage image(expectedBounds.width() + 2 * offset, expectedBounds.height() + 2 * offset,
+ QImage::Format_ARGB32_Premultiplied);
+ image.fill(QColor(Qt::white).rgb());
+
+ QPainter p(&image);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::black);
+ p.translate(offset - expectedBounds.left(), offset - expectedBounds.top());
+ p.drawPath(path);
+ p.end();
+
+ const QRect paintedBounds = getPaintedSize(image, Qt::white);
+
+ QCOMPARE(paintedBounds.x(), offset);
+ QCOMPARE(paintedBounds.y(), offset);
+ QCOMPARE(paintedBounds.width(), expectedBounds.width());
+ QCOMPARE(paintedBounds.height(), expectedBounds.height());
+
+ if (expectedPixels != -1) {
+ int paintedPixels = getPaintedPixels(image, Qt::white);
+ QCOMPARE(paintedPixels, expectedPixels);
+ }
+}
+
+void tst_QPainter::drawPath2()
+{
+ const int w = 50;
+
+ for (int h = 5; h < 200; ++h) {
+ QPainterPath p1, p2;
+ p1.lineTo(w, 0);
+ p1.lineTo(w, h);
+
+ p2.lineTo(w, h);
+ p2.lineTo(0, h);
+
+ const int offset = 2;
+
+ QImage image(w + 2 * offset, h + 2 * offset,
+ QImage::Format_ARGB32_Premultiplied);
+ image.fill(QColor(Qt::white).rgb());
+
+ QPainter p(&image);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::black);
+ p.translate(offset, offset);
+ p.drawPath(p1);
+ p.end();
+
+ const int p1Pixels = getPaintedPixels(image, Qt::white);
+
+ image.fill(QColor(Qt::white).rgb());
+ p.begin(&image);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::black);
+ p.translate(offset, offset);
+ p.drawPath(p2);
+ p.end();
+
+ const int p2Pixels = getPaintedPixels(image, Qt::white);
+
+ QCOMPARE(p1Pixels + p2Pixels, w * h);
+ }
+}
+
+void tst_QPainter::drawPath3()
+{
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
+ QImage imgA(400, 400, QImage::Format_RGB32);
+#else
+ QImage imgA(100, 100, QImage::Format_RGB32);
+#endif
+ imgA.fill(0xffffff);
+ QImage imgB = imgA;
+
+ QPainterPath path;
+ for (int y = 0; y < imgA.height(); ++y) {
+ for (int x = 0; x < imgA.width(); ++x) {
+ if ((x + y) & 1) {
+ imgA.setPixel(x, y, 0);
+ path.addRect(x, y, 1, 1);
+ }
+ }
+ }
+
+ QPainter p(&imgB);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::black);
+
+ p.drawPath(path);
+ p.end();
+
+ QVERIFY(imgA == imgB);
+
+ imgA.invertPixels();
+ imgB.fill(0xffffff);
+
+ p.begin(&imgB);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::black);
+
+ QRectF rect(0, 0, imgA.width(), imgA.height());
+ path.addRect(rect.adjusted(-10, -10, 10, 10));
+ p.drawPath(path);
+ p.end();
+
+ QVERIFY(imgA == imgB);
+
+ path.setFillRule(Qt::WindingFill);
+ imgB.fill(0xffffff);
+
+ p.begin(&imgB);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::black);
+ QRect clip = rect.adjusted(10, 10, -10, -10).toRect();
+ p.setClipRect(clip);
+ p.drawPath(path);
+ p.end();
+
+ QCOMPARE(getPaintedPixels(imgB, Qt::white), clip.width() * clip.height());
+}
+
+void tst_QPainter::drawEllipse_data()
+{
+ QTest::addColumn<QSize>("size");
+ QTest::addColumn<bool>("usePen");
+
+ // The current drawEllipse algorithm (drawEllipse_midpoint_i in
+ // qpaintengine_raster.cpp) draws ellipses that are too wide if the
+ // ratio between width and hight is too large/small (task 114874). Those
+ // ratios are therefore currently avoided.
+ for (int w = 10; w < 128; w += 7) {
+ for (int h = w/2; h < qMin(2*w, 128); h += 13) {
+ QString s = QString("%1x%2").arg(w).arg(h);
+ QTest::newRow(QString("%1 with pen").arg(s).toLatin1()) << QSize(w, h) << true;
+ QTest::newRow(QString("%1 no pen").arg(s).toLatin1()) << QSize(w, h) << false;
+ }
+ }
+}
+
+void tst_QPainter::drawEllipse()
+{
+ QFETCH(QSize, size);
+ QFETCH(bool, usePen);
+
+ const int offset = 10;
+ QRect rect(QPoint(offset, offset), size);
+
+ QImage image(size.width() + 2 * offset, size.height() + 2 * offset,
+ QImage::Format_ARGB32_Premultiplied);
+ image.fill(QColor(Qt::white).rgb());
+
+ QPainter p(&image);
+ p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
+ p.setBrush(Qt::black);
+ p.drawEllipse(rect);
+ p.end();
+
+ QPixmap pixmap = QPixmap::fromImage(image);
+
+ const QRect painted = getPaintedSize(pixmap, Qt::white);
+
+ QCOMPARE(painted.x(), rect.x());
+ QCOMPARE(painted.y(), rect.y() + (usePen ? 0 : 1));
+ QCOMPARE(painted.width(), size.width() + (usePen ? 1 : 0));
+ QCOMPARE(painted.height(), size.height() + (usePen ? 1 : -1));
+}
+
+void tst_QPainter::drawClippedEllipse_data()
+{
+ QTest::addColumn<QRect>("rect");
+
+ for (int w = 20; w < 128; w += 7) {
+ for (int h = w/2; h < qMin(2*w, 128); h += 13) {
+ QString s = QString("%1x%2").arg(w).arg(h);
+ QTest::newRow(QString("%1 top").arg(s).toLatin1()) << QRect(0, -h/2, w, h);
+ QTest::newRow(QString("%1 topright").arg(s).toLatin1()) << QRect(w/2, -h/2, w, h);
+ QTest::newRow(QString("%1 right").arg(s).toLatin1()) << QRect(w/2, 0, w, h);
+ QTest::newRow(QString("%1 bottomright").arg(s).toLatin1()) << QRect(w/2, h/2, w, h);
+ QTest::newRow(QString("%1 bottom").arg(s).toLatin1()) << QRect(0, h/2, w, h);
+ QTest::newRow(QString("%1 bottomleft").arg(s).toLatin1()) << QRect(-w/2, h/2, w, h);
+ QTest::newRow(QString("%1 left").arg(s).toLatin1()) << QRect(-w/2, 0, w, h);
+ QTest::newRow(QString("%1 topleft").arg(s).toLatin1()) << QRect(-w/2, -h/2, w, h);
+ }
+ }
+}
+
+void tst_QPainter::drawClippedEllipse()
+{
+ QFETCH(QRect, rect);
+ if (sizeof(qreal) != sizeof(double))
+ QSKIP("Test only works for qreal==double", SkipAll);
+ QImage image(rect.width() + 1, rect.height() + 1,
+ QImage::Format_ARGB32_Premultiplied);
+ QRect expected = QRect(rect.x(), rect.y(), rect.width()+1, rect.height()+1)
+ & QRect(0, 0, image.width(), image.height());
+
+
+ image.fill(QColor(Qt::white).rgb());
+ QPainter p(&image);
+ p.drawEllipse(rect);
+ p.end();
+
+ QPixmap pixmap = QPixmap::fromImage(image);
+ const QRect painted = getPaintedSize(pixmap, Qt::white);
+
+ QCOMPARE(painted.x(), expected.x());
+ QCOMPARE(painted.y(), expected.y());
+ QCOMPARE(painted.width(), expected.width());
+ QCOMPARE(painted.height(), expected.height());
+
+}
+
+void tst_QPainter::drawRoundRect()
+{
+ QFETCH(QRect, rect);
+ QFETCH(bool, usePen);
+
+#ifdef Q_WS_MAC
+ if (QTest::currentDataTag() == QByteArray("rect(6, 12, 3, 14) with pen") ||
+ QTest::currentDataTag() == QByteArray("rect(6, 17, 3, 25) with pen") ||
+ QTest::currentDataTag() == QByteArray("rect(10, 6, 10, 3) with pen") ||
+ QTest::currentDataTag() == QByteArray("rect(10, 12, 10, 14) with pen") ||
+ QTest::currentDataTag() == QByteArray("rect(13, 45, 17, 80) with pen") ||
+ QTest::currentDataTag() == QByteArray("rect(13, 50, 17, 91) with pen") ||
+ QTest::currentDataTag() == QByteArray("rect(17, 6, 24, 3) with pen") ||
+ QTest::currentDataTag() == QByteArray("rect(24, 12, 38, 14) with pen"))
+ QSKIP("The Mac paint engine is off-by-one on certain rect sizes", SkipSingle);
+#endif
+ QPixmap pixmap(rect.x() + rect.width() + 10,
+ rect.y() + rect.height() + 10);
+ {
+ pixmap.fill(Qt::white);
+ QPainter p(&pixmap);
+ p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
+ p.setBrush(Qt::black);
+ p.drawRoundRect(rect);
+ p.end();
+
+ int increment = usePen ? 1 : 0;
+
+ const QRect painted = getPaintedSize(pixmap, Qt::white);
+ QCOMPARE(painted.width(), rect.width() + increment);
+ QCOMPARE(painted.height(), rect.height() + increment);
+ }
+}
+
+Q_DECLARE_METATYPE(QImage::Format)
+
+void tst_QPainter::qimageFormats_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::newRow("QImage::Format_RGB32") << QImage::Format_RGB32;
+ QTest::newRow("QImage::Format_ARGB32") << QImage::Format_ARGB32;
+ QTest::newRow("QImage::Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied;
+ QTest::newRow("QImage::Format_RGB16") << QImage::Format_RGB16;
+ QTest::newRow("Qimage::Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied;
+ QTest::newRow("Qimage::Format_RGB666") << QImage::Format_RGB666;
+ QTest::newRow("Qimage::Format_RGB555") << QImage::Format_RGB555;
+ QTest::newRow("Qimage::Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied;
+ QTest::newRow("Qimage::Format_RGB888") << QImage::Format_RGB888;
+}
+
+/*
+ Tests that QPainter can paint on various QImage formats.
+*/
+void tst_QPainter::qimageFormats()
+{
+ QFETCH(QImage::Format, format);
+
+ const QSize size(100, 100);
+ QImage image(size, format);
+ image.fill(0);
+
+ const QColor testColor(Qt::red);
+ QPainter p(&image);
+ QVERIFY(p.isActive());
+ p.setBrush(QBrush(testColor));
+ p.drawRect(QRect(QPoint(0,0), size));
+ QCOMPARE(image.pixel(50, 50), testColor.rgb());
+}
+
+void tst_QPainter::fillData()
+{
+ QTest::addColumn<QRect>("rect");
+ QTest::addColumn<bool>("usePen");
+
+ for (int w = 3; w < 50; w += 7) {
+ for (int h = 3; h < 50; h += 11) {
+ int x = w/2 + 5;
+ int y = h/2 + 5;
+ QTest::newRow(QString("rect(%1, %2, %3, %4) with pen").arg(x).arg(y).arg(w).arg(h).toLatin1())
+ << QRect(x, y, w, h) << true;
+ QTest::newRow(QString("rect(%1, %2, %3, %4) no pen").arg(x).arg(y).arg(w).arg(h).toLatin1())
+ << QRect(x, y, w, h) << false;
+ }
+ }
+}
+
+/*
+ Test that drawline works properly after setWindow has been called.
+*/
+void tst_QPainter::setWindow()
+{
+ QPixmap pixmap(600, 600);
+ pixmap.fill(QColor(Qt::white));
+
+ QPainter painter(&pixmap);
+ painter.setWindow(0, 0, 3, 3);
+ painter.drawLine(1, 1, 2, 2);
+
+ const QRect painted = getPaintedSize(pixmap, Qt::white);
+ QVERIFY(195 < painted.y() && painted.y() < 205); // correct value is around 200
+ QVERIFY(195 < painted.height() && painted.height() < 205); // correct value is around 200
+}
+
+void tst_QPainter::combinedMatrix()
+{
+ QPixmap pm(64, 64);
+
+ QPainter p(&pm);
+ p.setWindow(0, 0, 1, 1);
+ p.setViewport(32, 0, 32, 32);
+
+ p.translate(0.5, 0.5);
+
+ QMatrix cm = p.combinedMatrix();
+
+ QPointF pt = QPointF(0, 0) * cm;
+
+ QCOMPARE(pt.x(), 48.0);
+ QCOMPARE(pt.y(), 16.0);
+}
+
+void tst_QPainter::textOnTransparentImage()
+{
+ bool foundPixel = false;
+ QImage image(10, 10, QImage::Format_ARGB32_Premultiplied);
+ image.fill(qRgba(0, 0, 0, 0)); // transparent
+ {
+ QPainter painter(&image);
+ painter.setPen(QColor(255, 255, 255));
+ painter.drawText(0, 10, "W");
+ }
+ for (int x = 0; x < image.width(); ++x)
+ for (int y = 0; y < image.height(); ++y)
+ if (image.pixel(x, y) != 0)
+ foundPixel = true;
+ QVERIFY(foundPixel);
+}
+
+void tst_QPainter::renderHints()
+{
+ QImage img(1, 1, QImage::Format_RGB32);
+
+ QPainter p(&img);
+
+ // Turn off all...
+ p.setRenderHints(QPainter::RenderHints(0xffffffff), false);
+ QCOMPARE(p.renderHints(), QPainter::RenderHints(0));
+
+ // Single set/get
+ p.setRenderHint(QPainter::Antialiasing);
+ QVERIFY(p.renderHints() & QPainter::Antialiasing);
+
+ p.setRenderHint(QPainter::Antialiasing, false);
+ QVERIFY(!(p.renderHints() & QPainter::Antialiasing));
+
+ // Multi set/get
+ p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
+ QVERIFY(p.renderHints() & (QPainter::Antialiasing | QPainter::SmoothPixmapTransform));
+
+ p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
+ QVERIFY(!(p.renderHints() & (QPainter::Antialiasing | QPainter::SmoothPixmapTransform)));
+}
+
+int countPixels(const QImage &img, const QRgb &color)
+{
+ int count = 0;
+ for (int y = 0; y < img.height(); ++y) {
+ for (int x = 0; x < img.width(); ++x) {
+ count += ((img.pixel(x, y) & 0xffffff) == color);
+ }
+ }
+ return count;
+}
+
+template <typename T>
+void testClipping(QImage &img)
+{
+ QPainterPath a, b;
+ a.addRect(QRect(2, 2, 4, 4));
+ b.addRect(QRect(4, 4, 4, 4));
+ QPainter p(&img);
+
+ p.end();
+ img.fill(0x0);
+ p.begin(&img);
+ p.setClipPath(a);
+ p.setClipPath(b, Qt::IntersectClip);
+
+ p.setClipping(false);
+ p.setPen(Qt::NoPen);
+ p.setBrush(QColor(0xff0000));
+ p.drawRect(T(0, 0, 10, 10));
+
+ p.setClipping(true);
+ p.setBrush(QColor(0x00ff00));
+ p.drawRect(T(0, 0, 10, 10));
+
+ QCOMPARE(countPixels(img, 0xff0000), 96);
+ QCOMPARE(countPixels(img, 0x00ff00), 4);
+}
+
+void tst_QPainter::disableEnableClipping()
+{
+ QImage img(10, 10, QImage::Format_RGB32);
+
+ testClipping<QRectF>(img);
+ testClipping<QRect>(img);
+}
+
+void tst_QPainter::setClipRect()
+{
+ QImage img(10, 10, QImage::Format_RGB32);
+ // simple test to let valgrind check for buffer overflow
+ {
+ QPainter p(&img);
+ p.setClipRect(-10, -10, 100, 100);
+ p.fillRect(-10, -10, 100, 100, QBrush(QColor(Qt::red)));
+ }
+
+ // rects with negative width/height
+ {
+ QPainter p(&img);
+ p.setClipRect(QRect(10, 10, -10, 10));
+ QVERIFY(p.clipRegion().isEmpty());
+ p.setClipRect(QRect(10, 10, 10, -10));
+ QVERIFY(p.clipRegion().isEmpty());
+ p.setClipRect(QRectF(10.5, 10.5, -10.5, 10.5));
+ QVERIFY(p.clipRegion().isEmpty());
+ p.setClipRect(QRectF(10.5, 10.5, 10.5, -10.5));
+ QVERIFY(p.clipRegion().isEmpty());
+ }
+}
+
+/*
+ This tests the two different clipping approaches in QRasterPaintEngine,
+ one when using a QRegion and one when using a QPainterPath. They should
+ give equal results.
+*/
+void tst_QPainter::setEqualClipRegionAndPath_data()
+{
+ QTest::addColumn<QSize>("deviceSize");
+ QTest::addColumn<QRegion>("region");
+
+ QTest::newRow("empty") << QSize(100, 100) << QRegion();
+ QTest::newRow("simple rect") << QSize(100, 100)
+ << QRegion(QRect(5, 5, 10, 10));
+
+ QVector<QRect> rects;
+ QRegion region;
+
+ rects << QRect(5, 5, 10, 10) << QRect(20, 20, 10, 10);
+ region.setRects(rects.constData(), rects.size());
+ QTest::newRow("two rects") << QSize(100, 100) << region;
+
+ rects.clear();
+ rects << QRect(5, 5, 10, 10) << QRect(20, 5, 10, 10);
+ region.setRects(rects.constData(), rects.size());
+ QTest::newRow("two x-adjacent rects") << QSize(100, 100) << region;
+
+ rects.clear();
+ rects << QRect(0, 0, 10, 100) << QRect(12, 0, 10, 100);
+ region.setRects(rects.constData(), rects.size());
+ QTest::newRow("two x-adjacent rects 2") << QSize(100, 100) << region;
+
+ rects.clear();
+ rects << QRect(0, 0, 10, 100) << QRect(12, 0, 10, 100);
+ region.setRects(rects.constData(), rects.size());
+ QTest::newRow("two x-adjacent rects 3") << QSize(50, 50) << region;
+
+ rects.clear();
+ rects << QRect(0, 0, 10, 100) << QRect(12, 0, 10, 100);
+ region.setRects(rects.constData(), rects.size());
+ QTest::newRow("two x-adjacent rects 4") << QSize(101, 101) << region;
+
+ region = QRegion(QRect(0, 0, 200, 200), QRegion::Ellipse);
+
+ QTest::newRow("ellipse") << QSize(190, 200) << region;
+
+ region ^= QRect(50, 50, 50, 50);
+ QTest::newRow("ellipse 2") << QSize(200, 200) << region;
+}
+
+void tst_QPainter::setEqualClipRegionAndPath()
+{
+ QFETCH(QSize, deviceSize);
+ QFETCH(QRegion, region);
+
+ QPainterPath path;
+ path.addRegion(region);
+
+ QImage img1(deviceSize.width(), deviceSize.height(),
+ QImage::Format_ARGB32);
+ QImage img2(deviceSize.width(), deviceSize.height(),
+ QImage::Format_ARGB32);
+ img1.fill(0x12345678);
+ img2.fill(0x12345678);
+
+ {
+ QPainter p(&img1);
+ p.setClipRegion(region);
+ p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
+ }
+ {
+ QPainter p(&img2);
+ p.setClipPath(path);
+ p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
+ }
+
+#if 0
+ if (img1 != img2) {
+ img1.save("setEqualClipRegionAndPath_1.xpm", "XPM");
+ img2.save("setEqualClipRegionAndPath_2.xpm", "XPM");
+ }
+#endif
+ QCOMPARE(img1, img2);
+
+#if 0
+ // rotated
+ img1.fill(0x12345678);
+ img2.fill(0x12345678);
+
+ {
+ QPainter p(&img1);
+ p.rotate(25);
+ p.setClipRegion(region);
+ p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
+ }
+ {
+ QPainter p(&img2);
+ p.rotate(25);
+ p.setClipPath(path);
+ p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
+ }
+
+#if 1
+ if (img1 != img2) {
+ img1.save("setEqualClipRegionAndPath_1.xpm", "XPM");
+ img2.save("setEqualClipRegionAndPath_2.xpm", "XPM");
+ }
+#endif
+ QCOMPARE(img1, img2);
+#endif
+
+ img1.fill(0x12345678);
+ img2.fill(0x12345678);
+
+ // simple intersectclip
+ img1.fill(0x12345678);
+ img2.fill(0x12345678);
+ {
+ QPainter p(&img1);
+ p.setClipRegion(region);
+ p.setClipRegion(region, Qt::IntersectClip);
+ p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
+ }
+ {
+ QPainter p(&img2);
+ p.setClipPath(path);
+ p.setClipPath(path, Qt::IntersectClip);
+ p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
+ }
+#if 0
+ if (img1 != img2) {
+ img1.save("setEqualClipRegionAndPath_1.png", "PNG");
+ img2.save("setEqualClipRegionAndPath_2.png", "PNG");
+ }
+#endif
+ QCOMPARE(img1, img2);
+
+ img1.fill(0x12345678);
+ img2.fill(0x12345678);
+ {
+ QPainter p(&img1);
+ p.setClipPath(path);
+ p.setClipRegion(region, Qt::IntersectClip);
+ p.fillRect(0, 0, img1.width(), img1.height(), QColor(Qt::red));
+ }
+ {
+ QPainter p(&img2);
+ p.setClipRegion(region);
+ p.setClipPath(path, Qt::IntersectClip);
+ p.fillRect(0, 0, img2.width(), img2.height(), QColor(Qt::red));
+ }
+#if 0
+ if (img1 != img2) {
+ img1.save("setEqualClipRegionAndPath_1.xpm", "XPM");
+ img2.save("setEqualClipRegionAndPath_2.xpm", "XPM");
+ }
+#endif
+ QCOMPARE(img1, img2);
+
+}
+
+void tst_QPainter::clippedFillPath_data()
+{
+ QTest::addColumn<QSize>("imageSize");
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<QRect>("clipRect");
+ QTest::addColumn<QBrush>("brush");
+ QTest::addColumn<QPen>("pen");
+
+ QLinearGradient gradient(QPoint(0, 0), QPoint(100, 100));
+ gradient.setColorAt(0, Qt::red);
+ gradient.setColorAt(1, Qt::blue);
+
+
+ QPen pen2(QColor(223, 223, 0, 223));
+ pen2.setWidth(2);
+
+ QPainterPath path;
+ path.addRect(QRect(15, 15, 50, 50));
+ QTest::newRow("simple rect 0") << QSize(100, 100) << path
+ << QRect(15, 15, 49, 49)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("simple rect 1") << QSize(100, 100) << path
+ << QRect(15, 15, 50, 50)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("simple rect 2") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("simple rect 3") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(QColor(Qt::blue))
+ << QPen(Qt::NoPen);
+ QTest::newRow("simple rect 4") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(gradient)
+ << pen2;
+
+ path = QPainterPath();
+ path.addEllipse(QRect(15, 15, 50, 50));
+ QTest::newRow("ellipse 0") << QSize(100, 100) << path
+ << QRect(15, 15, 49, 49)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("ellipse 1") << QSize(100, 100) << path
+ << QRect(15, 15, 50, 50)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("ellipse 2") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("ellipse 3") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(QColor(Qt::blue))
+ << QPen(Qt::NoPen);
+ QTest::newRow("ellipse 4") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(gradient)
+ << pen2;
+
+ path = QPainterPath();
+ path.addRoundRect(QRect(15, 15, 50, 50), 20);
+ QTest::newRow("round rect 0") << QSize(100, 100) << path
+ << QRect(15, 15, 49, 49)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("round rect 1") << QSize(100, 100) << path
+ << QRect(15, 15, 50, 50)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("round rect 2") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("round rect 3") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(QColor(Qt::blue))
+ << QPen(Qt::NoPen);
+ QTest::newRow("round rect 4") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(gradient)
+ << pen2;
+
+ path = QPainterPath();
+ path.moveTo(15, 50);
+ path.cubicTo(40, 50, 40, 15, 65, 50);
+ path.lineTo(15, 50);
+ QTest::newRow("cubic 0") << QSize(100, 100) << path
+ << QRect(15, 15, 49, 49)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("cubic 1") << QSize(100, 100) << path
+ << QRect(15, 15, 50, 50)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("cubic 2") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(Qt::NoBrush)
+ << QPen(Qt::black);
+ QTest::newRow("cubic 3") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(QColor(Qt::blue))
+ << QPen(Qt::NoPen);
+ QTest::newRow("cubic 4") << QSize(100, 100) << path
+ << QRect(15, 15, 51, 51)
+ << QBrush(gradient)
+ << pen2;
+}
+
+void tst_QPainter::clippedFillPath()
+{
+ QFETCH(QSize, imageSize);
+ QFETCH(QPainterPath, path);
+ QFETCH(QRect, clipRect);
+ QPainterPath clipPath;
+ clipPath.addRect(clipRect);
+ QFETCH(QBrush, brush);
+ QFETCH(QPen, pen);
+
+ const int width = imageSize.width();
+ const int height = imageSize.height();
+
+ QImage clippedRect(width, height, QImage::Format_ARGB32_Premultiplied);
+ clippedRect.fill(0x12345678);
+ {
+ QPainter painter(&clippedRect);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ painter.setClipRect(clipRect);
+ painter.drawPath(path);
+ }
+
+ QImage clippedPath(width, height, QImage::Format_ARGB32_Premultiplied);
+ clippedPath.fill(0x12345678);
+ {
+ QPainter painter(&clippedPath);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ painter.setClipPath(clipPath);
+ painter.drawPath(path);
+ }
+
+#if 0
+ if (clippedRect != clippedPath) {
+ clippedRect.save(QString("clippedRect.png"), "PNG");
+ clippedPath.save(QString("clippedPath.png"), "PNG");
+ }
+#endif
+ QCOMPARE(clippedRect, clippedPath);
+
+ // repeat with antialiasing
+
+ clippedRect.fill(0x12345678);
+ {
+ QPainter painter(&clippedRect);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ painter.setClipRect(clipRect);
+ painter.drawPath(path);
+ }
+
+ clippedPath.fill(0x12345678);
+ {
+ QPainter painter(&clippedPath);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ painter.setClipPath(clipPath);
+ painter.drawPath(path);
+ }
+
+#if 1
+ if (clippedRect != clippedPath) {
+ clippedRect.save(QString("clippedRect.png"), "PNG");
+ clippedPath.save(QString("clippedPath.png"), "PNG");
+ }
+#endif
+ QCOMPARE(clippedRect, clippedPath);
+
+}
+
+void tst_QPainter::clippedLines_data()
+{
+ QTest::addColumn<QSize>("imageSize");
+ QTest::addColumn<QLineF>("line");
+ QTest::addColumn<QRect>("clipRect");
+ QTest::addColumn<QPen>("pen");
+
+ QPen pen2(QColor(223, 223, 0, 223));
+ pen2.setWidth(2);
+
+ QVector<QLineF> lines;
+ lines << QLineF(15, 15, 65, 65)
+ << QLineF(14, 14, 66, 66)
+ << QLineF(16, 16, 64, 64)
+ << QLineF(65, 65, 15, 15)
+ << QLineF(66, 66, 14, 14)
+ << QLineF(64, 64, 14, 14)
+ << QLineF(15, 50, 15, 64)
+ << QLineF(15, 50, 15, 65)
+ << QLineF(15, 50, 15, 66)
+ << QLineF(15, 50, 64, 50)
+ << QLineF(15, 50, 65, 50)
+ << QLineF(15, 50, 66, 50);
+
+ foreach (QLineF line, lines) {
+ QString desc = QString("line (%1, %2, %3, %4) %5").arg(line.x1())
+ .arg(line.y1()).arg(line.x2()).arg(line.y2());
+ QTest::newRow(qPrintable(desc.arg(0))) << QSize(100, 100) << line
+ << QRect(15, 15, 49, 49)
+ << QPen(Qt::black);
+ QTest::newRow(qPrintable(desc.arg(1))) << QSize(100, 100) << line
+ << QRect(15, 15, 50, 50)
+ << QPen(Qt::black);
+ QTest::newRow(qPrintable(desc.arg(2))) << QSize(100, 100) << line
+ << QRect(15, 15, 51, 51)
+ << QPen(Qt::black);
+ QTest::newRow(qPrintable(desc.arg(3))) << QSize(100, 100) << line
+ << QRect(15, 15, 51, 51)
+ << QPen(Qt::NoPen);
+ QTest::newRow(qPrintable(desc.arg(4))) << QSize(100, 100) << line
+ << QRect(15, 15, 51, 51)
+ << pen2;
+ }
+}
+
+void tst_QPainter::clippedLines()
+{
+ QFETCH(QSize, imageSize);
+ QFETCH(QLineF, line);
+ QFETCH(QRect, clipRect);
+ QPainterPath clipPath;
+ clipPath.addRect(clipRect);
+ QFETCH(QPen, pen);
+
+ const int width = imageSize.width();
+ const int height = imageSize.height();
+
+ QImage clippedRect(width, height, QImage::Format_ARGB32_Premultiplied);
+ clippedRect.fill(0x12345678);
+ {
+ QPainter painter(&clippedRect);
+ painter.setPen(pen);
+ painter.setClipRect(clipRect);
+ painter.drawLine(line);
+ painter.drawLine(line.toLine());
+ }
+
+ QImage clippedPath(width, height, QImage::Format_ARGB32_Premultiplied);
+ clippedPath.fill(0x12345678);
+ {
+ QPainter painter(&clippedPath);
+ painter.setPen(pen);
+ painter.setClipPath(clipPath);
+ painter.drawLine(line);
+ painter.drawLine(line.toLine());
+ }
+
+#if 0
+ if (clippedRect != clippedPath) {
+ clippedRect.save(QString("clippedRect.png"), "PNG");
+ clippedPath.save(QString("clippedPath.png"), "PNG");
+ }
+#endif
+ QCOMPARE(clippedRect, clippedPath);
+
+ // repeat with antialiasing
+ clippedRect.fill(0x12345678);
+ {
+ QPainter painter(&clippedRect);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setPen(pen);
+ painter.setClipRect(clipRect);
+ painter.drawLine(line);
+ painter.drawLine(line.toLine());
+ }
+
+ clippedPath.fill(0x12345678);
+ {
+ QPainter painter(&clippedPath);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setPen(pen);
+ painter.setClipPath(clipPath);
+ painter.drawLine(line);
+ painter.drawLine(line.toLine());
+ }
+
+#if 0
+ if (clippedRect != clippedPath) {
+ clippedRect.save(QString("clippedRect.png"), "PNG");
+ clippedPath.save(QString("clippedPath.png"), "PNG");
+ }
+#endif
+ QCOMPARE(clippedRect, clippedPath);
+}
+
+void tst_QPainter::clippedPolygon_data()
+{
+ clippedFillPath_data();
+};
+
+void tst_QPainter::clippedPolygon()
+{
+ QFETCH(QSize, imageSize);
+ QFETCH(QPainterPath, path);
+ QPolygonF polygon = path.toFillPolygon();
+ QFETCH(QRect, clipRect);
+ QPainterPath clipPath;
+ clipPath.addRect(clipRect);
+ QFETCH(QPen, pen);
+ QFETCH(QBrush, brush);
+
+ const int width = imageSize.width();
+ const int height = imageSize.height();
+
+ QImage clippedRect(width, height, QImage::Format_ARGB32_Premultiplied);
+ clippedRect.fill(0x12345678);
+ {
+ QPainter painter(&clippedRect);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ painter.setClipRect(clipRect);
+ painter.drawPolygon(polygon);
+ painter.drawPolygon(polygon.toPolygon());
+ }
+
+ QImage clippedPath(width, height, QImage::Format_ARGB32_Premultiplied);
+ clippedPath.fill(0x12345678);
+ {
+ QPainter painter(&clippedPath);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ painter.setClipRect(clipRect);
+ painter.drawPolygon(polygon);
+ painter.drawPolygon(polygon.toPolygon());
+ }
+
+#if 0
+ if (clippedRect != clippedPath) {
+ clippedRect.save(QString("clippedRect.png"), "PNG");
+ clippedPath.save(QString("clippedPath.png"), "PNG");
+ }
+#endif
+ QCOMPARE(clippedRect, clippedPath);
+
+ // repeat with antialiasing
+
+ clippedRect.fill(0x12345678);
+ {
+ QPainter painter(&clippedRect);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ painter.setClipRect(clipRect);
+ painter.drawPolygon(polygon);
+ painter.drawPolygon(polygon.toPolygon());
+ }
+
+ clippedPath.fill(0x12345678);
+ {
+ QPainter painter(&clippedPath);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setPen(pen);
+ painter.setBrush(brush);
+ painter.setClipRect(clipRect);
+ painter.drawPolygon(polygon);
+ painter.drawPolygon(polygon.toPolygon());
+ }
+
+#if 0
+ if (clippedRect != clippedPath) {
+ clippedRect.save(QString("clippedRect.png"), "PNG");
+ clippedPath.save(QString("clippedPath.png"), "PNG");
+ }
+#endif
+ QCOMPARE(clippedRect, clippedPath);
+}
+
+// this just draws some text that should be clipped in the raster
+// paint engine.
+void tst_QPainter::clippedText()
+{
+ for (char ch = 'A'; ch < 'Z'; ++ch) {
+ //qDebug() << ch;
+ QFont f;
+ f.setPixelSize(24);
+ QFontMetrics metrics(f);
+ QRect textRect = metrics.boundingRect(QChar(ch));
+
+ if (textRect.width() <= 8)
+ continue;
+ if (textRect.height() <= 8)
+ continue;
+
+ QRect imageRect = textRect.adjusted(4, 4, -4, -4);
+
+ QImage image(imageRect.size(), QImage::Format_ARGB32_Premultiplied);
+
+ image.fill(qRgba(255, 255, 255, 255));
+ {
+ QPainter painter(&image);
+ painter.setFont(f);
+ painter.setPen(Qt::black);
+
+ painter.drawText(0, 0, QChar(ch));
+ }
+
+ image.fill(qRgba(255, 255, 255, 255));
+ {
+ QPainter painter(&image);
+ painter.setFont(f);
+ painter.setPen(Qt::black);
+
+ painter.drawText(-imageRect.topLeft(), QChar(ch));
+ }
+
+ bool foundPixel = false;
+ for (int x = 0; x < image.width(); ++x)
+ for (int y = 0; y < image.height(); ++y)
+ if (image.pixel(x, y) != 0)
+ foundPixel = true;
+ // can't QVERIFY(foundPixel) as sometimes all pixels are clipped
+ // away. For example for 'O'
+ // just call /some/ function to prevent the compiler from optimizing
+ // foundPixel away
+ QString::number(foundPixel);
+
+ //image.save(QString("debug") + ch + ".xpm");
+ }
+
+ QVERIFY(true); // reached, don't trigger any valgrind errors
+}
+
+void tst_QPainter::setOpacity_data()
+{
+ QTest::addColumn<QImage::Format>("destFormat");
+ QTest::addColumn<QImage::Format>("srcFormat");
+
+ QTest::newRow("ARGB32P on ARGB32P") << QImage::Format_ARGB32_Premultiplied
+ << QImage::Format_ARGB32_Premultiplied;
+
+ QTest::newRow("ARGB32 on ARGB32") << QImage::Format_ARGB32
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("RGB32 on RGB32") << QImage::Format_RGB32
+ << QImage::Format_RGB32;
+
+ QTest::newRow("RGB16 on RGB16") << QImage::Format_RGB16
+ << QImage::Format_RGB16;
+
+ QTest::newRow("ARGB8565_Premultiplied on ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied
+ << QImage::Format_ARGB8565_Premultiplied;
+
+ QTest::newRow("RGB555 on RGB555") << QImage::Format_RGB555
+ << QImage::Format_RGB555;
+
+ QTest::newRow("RGB666 on RGB666") << QImage::Format_RGB666
+ << QImage::Format_RGB666;
+
+ QTest::newRow("ARGB8555_Premultiplied on ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied
+ << QImage::Format_ARGB8555_Premultiplied;
+
+ QTest::newRow("RGB888 on RGB888") << QImage::Format_RGB888
+ << QImage::Format_RGB888;
+
+ QTest::newRow("RGB32 on RGB16") << QImage::Format_RGB16
+ << QImage::Format_RGB32;
+
+ QTest::newRow("RGB32 on ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied
+ << QImage::Format_RGB32;
+
+ QTest::newRow("RGB32 on RGB666") << QImage::Format_RGB666
+ << QImage::Format_RGB32;
+
+ QTest::newRow("RGB32 on RGB555") << QImage::Format_RGB555
+ << QImage::Format_RGB32;
+
+ QTest::newRow("RGB32 on ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied
+ << QImage::Format_RGB32;
+
+ QTest::newRow("RGB32 on RGB888") << QImage::Format_RGB888
+ << QImage::Format_RGB32;
+
+ QTest::newRow("RGB16 on RGB32") << QImage::Format_RGB32
+ << QImage::Format_RGB16;
+
+ QTest::newRow("ARGB8565_Premultiplied on RGB32") << QImage::Format_RGB32
+ << QImage::Format_ARGB8565_Premultiplied;
+
+ QTest::newRow("RGB666 on RGB32") << QImage::Format_RGB32
+ << QImage::Format_RGB666;
+
+ QTest::newRow("RGB555 on RGB32") << QImage::Format_RGB32
+ << QImage::Format_RGB555;
+
+ QTest::newRow("ARGB8555_Premultiplied on RGB32") << QImage::Format_RGB32
+ << QImage::Format_ARGB8555_Premultiplied;
+
+ QTest::newRow("RGB888 on RGB32") << QImage::Format_RGB32
+ << QImage::Format_RGB888;
+
+ QTest::newRow("RGB555 on RGB888") << QImage::Format_RGB888
+ << QImage::Format_RGB555;
+
+ QTest::newRow("RGB666 on RGB888") << QImage::Format_RGB888
+ << QImage::Format_RGB666;
+
+ QTest::newRow("RGB444 on RGB444") << QImage::Format_RGB444
+ << QImage::Format_RGB444;
+}
+
+void tst_QPainter::setOpacity()
+{
+ QFETCH(QImage::Format, destFormat);
+ QFETCH(QImage::Format, srcFormat);
+
+ const QSize imageSize(12, 12);
+ const QRect imageRect(QPoint(0, 0), imageSize);
+ QColor destColor = Qt::black;
+ QColor srcColor = Qt::white;
+
+ QImage dest(imageSize, destFormat);
+ QImage src(imageSize, srcFormat);
+
+ QPainter p;
+ p.begin(&dest);
+ p.fillRect(imageRect, destColor);
+ p.end();
+
+ p.begin(&src);
+ p.fillRect(imageRect, srcColor);
+ p.end();
+
+ p.begin(&dest);
+ p.setOpacity(0.5);
+ p.drawImage(imageRect, src, imageRect);
+ p.end();
+
+ QImage actual = dest.convertToFormat(QImage::Format_RGB32);
+
+ for (int y = 0; y < actual.height(); ++y) {
+ QRgb *p = (QRgb *)actual.scanLine(y);
+ for (int x = 0; x < actual.width(); ++x) {
+ QVERIFY(qAbs(qRed(p[x]) - 127) <= 0xf);
+ QVERIFY(qAbs(qGreen(p[x]) - 127) <= 0xf);
+ QVERIFY(qAbs(qBlue(p[x]) - 127) <= 0xf);
+ }
+ }
+}
+
+void tst_QPainter::drawhelper_blend_untransformed_data()
+{
+ setOpacity_data();
+}
+
+void tst_QPainter::drawhelper_blend_untransformed()
+{
+ QFETCH(QImage::Format, destFormat);
+ QFETCH(QImage::Format, srcFormat);
+
+ const int size = 128;
+ const QSize imageSize(size, size);
+ const QRect paintRect(1, 0, size - 2, size); // needs alignment and tailing
+
+ QColor destColor(127, 127, 127);
+ QColor srcColor(Qt::white);
+
+ QImage dest(imageSize, destFormat);
+ QImage src(imageSize, srcFormat);
+
+ QPainter p;
+ p.begin(&src);
+ p.fillRect(paintRect, srcColor);
+ p.end();
+
+ QList<qreal> opacities = (QList<qreal>() << 0.0 << 0.1 << 0.01 << 0.4
+ << 0.5 << 0.6 << 0.9 << 1.0);
+ foreach (qreal opacity, opacities) {
+ p.begin(&dest);
+ p.fillRect(paintRect, destColor);
+
+ p.setOpacity(opacity);
+ p.drawImage(paintRect, src, paintRect);
+ p.end();
+
+ // sanity check: make sure all pixels are equal
+ QImage expected(size - 2, size, destFormat);
+ p.begin(&expected);
+ p.fillRect(0, 0, expected.width(), expected.height(),
+ QColor(dest.pixel(1, 0)));
+ p.end();
+
+ const QImage subDest(dest.bits() + dest.depth() / 8,
+ dest.width() - 2, dest.height(),
+ dest.bytesPerLine(), dest.format());
+
+ if (dest.format() == QImage::Format_ARGB8565_Premultiplied ||
+ dest.format() == QImage::Format_ARGB8555_Premultiplied) {
+ // Test skipped due to rounding errors...
+ continue;
+ }
+#if 0
+ if (subDest != expected) {
+ qDebug() << "size" << size << "opacity" << opacity;
+ for (int j = 0; j < expected.height(); ++j) {
+ for (int i = 0; i < expected.width(); ++i) {
+ if (expected.pixel(i,j) != subDest.pixel(i,j))
+ qDebug() << i << j << hex << expected.pixel(i, j)
+ << subDest.pixel(i, j);
+ }
+ }
+ }
+#endif
+ QCOMPARE(subDest, expected);
+ }
+}
+
+void tst_QPainter::drawhelper_blend_tiled_untransformed_data()
+{
+ setOpacity_data();
+}
+
+void tst_QPainter::drawhelper_blend_tiled_untransformed()
+{
+ QFETCH(QImage::Format, destFormat);
+ QFETCH(QImage::Format, srcFormat);
+
+ const int size = 128;
+ const QSize imageSize(size, size);
+ const QRect paintRect(1, 0, size - 2, size); // needs alignment and tailing
+
+ QColor destColor(127, 127, 127);
+ QColor srcColor(Qt::white);
+
+ QImage dest(imageSize, destFormat);
+ QImage src(imageSize / 2, srcFormat);
+
+ QPainter p;
+ p.begin(&src);
+ p.fillRect(QRect(QPoint(0, 0), imageSize/ 2), srcColor);
+ p.end();
+
+ const QBrush brush(src);
+
+ QList<qreal> opacities = (QList<qreal>() << 0.0 << 0.1 << 0.01 << 0.4
+ << 0.5 << 0.6 << 0.9 << 1.0);
+ foreach (qreal opacity, opacities) {
+ p.begin(&dest);
+ p.fillRect(paintRect, destColor);
+
+ p.setOpacity(opacity);
+ p.fillRect(paintRect, brush);
+ p.end();
+
+ // sanity check: make sure all pixels are equal
+ QImage expected(size - 2, size, destFormat);
+ p.begin(&expected);
+ p.fillRect(0, 0, expected.width(), expected.height(),
+ QColor(dest.pixel(1, 0)));
+ p.end();
+
+ const QImage subDest(dest.bits() + dest.depth() / 8,
+ dest.width() - 2, dest.height(),
+ dest.bytesPerLine(), dest.format());
+
+ if (dest.format() == QImage::Format_ARGB8565_Premultiplied ||
+ dest.format() == QImage::Format_ARGB8555_Premultiplied) {
+ // Skipping test due to rounding errors. Test needs rewrite
+ continue;
+ }
+#if 0
+ if (subDest != expected) {
+ qDebug() << "size" << size << "opacity" << opacity;
+ for (int j = 0; j < expected.height(); ++j) {
+ for (int i = 0; i < expected.width(); ++i) {
+ if (expected.pixel(i,j) != subDest.pixel(i,j))
+ qDebug() << i << j << hex << expected.pixel(i, j)
+ << subDest.pixel(i, j);
+ }
+ }
+ }
+#endif
+ QCOMPARE(subDest, expected);
+ }
+}
+
+static QPaintEngine::PaintEngineFeatures no_porter_duff()
+{
+ QPaintEngine::PaintEngineFeatures features = QPaintEngine::AllFeatures;
+ return features & ~QPaintEngine::PorterDuff;
+}
+
+class DummyPaintEngine : public QPaintEngine, public QPaintDevice
+{
+public:
+ DummyPaintEngine() : QPaintEngine(no_porter_duff()) {}
+ virtual bool begin(QPaintDevice *) { return true; }
+ virtual bool end() { return true; }
+
+ virtual void updateState(const QPaintEngineState &) {}
+ virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) {}
+
+ virtual Type type() const { return User; }
+
+ virtual QPaintEngine *paintEngine() const { return (QPaintEngine *)this; }
+
+ virtual int metric(PaintDeviceMetric metric) const { Q_UNUSED(metric); return 0; };
+};
+
+static bool success;
+
+void porterDuff_warningChecker(QtMsgType type, const char *msg)
+{
+ if (type == QtWarningMsg && msg == QLatin1String("QPainter::setCompositionMode: PorterDuff modes not supported on device"))
+ success = false;
+}
+
+void tst_QPainter::porterDuff_warning()
+{
+ QtMsgHandler old = qInstallMsgHandler(porterDuff_warningChecker);
+ DummyPaintEngine dummy;
+ QPainter p(&dummy);
+
+ success = true;
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ QVERIFY(success);
+
+ success = true;
+ p.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ QVERIFY(success);
+
+ success = true;
+ p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
+ QVERIFY(!success);
+
+ QVERIFY(qInstallMsgHandler(old) == porterDuff_warningChecker);
+}
+
+class quint24
+{
+public:
+ inline quint24(quint32 v)
+ {
+ data[0] = qBlue(v);
+ data[1] = qGreen(v);
+ data[2] = qRed(v);
+ }
+
+ inline operator quint32 ()
+ {
+ return qRgb(data[2], data[1], data[0]);
+ }
+
+ inline bool operator==(const quint24 &v) const {
+ return (data[0] == v.data[0] && data[1] == v.data[1] && data[2] == v.data[2]);
+ }
+
+ uchar data[3];
+} Q_PACKED;
+
+void tst_QPainter::drawhelper_blend_color()
+{
+ QImage dest(32, 32, QImage::Format_ARGB8555_Premultiplied);
+ dest.fill(0xff000000);
+
+ {
+ QPainter p(&dest);
+ p.fillRect(0, 0, dest.width(), dest.height(), QColor(255, 0, 0, 127));
+ }
+
+ QImage expected(32, 32, QImage::Format_ARGB8555_Premultiplied);
+ expected.fill(0xff3c007f);
+
+ QCOMPARE(dest.pixel(1, 1), expected.pixel(1, 1));
+ QCOMPARE(dest, expected);
+}
+
+class ViewportTestWidget : public QWidget
+{
+public:
+ ViewportTestWidget(QWidget *parent = 0) : QWidget(parent), hasPainted(false) {}
+ QSize sizeHint() const {
+ return QSize(100, 100);
+ }
+
+ QRect viewport;
+ bool hasPainted;
+
+protected:
+ void paintEvent(QPaintEvent *) {
+ hasPainted = true;
+ QPainter p(this);
+ viewport = p.viewport();
+ }
+};
+
+void tst_QPainter::childWidgetViewport()
+{
+ QWidget parent;
+ parent.setAutoFillBackground(true);
+ parent.resize(200, 200);
+ ViewportTestWidget child(&parent);
+ child.setAutoFillBackground(true);
+ parent.show();
+ parent.update();
+ qApp->processEvents();
+
+ if (child.hasPainted) {
+ QCOMPARE(child.viewport, QRect(QPoint(0, 0), child.sizeHint()));
+ } else {
+ qWarning("Failed to ensure that paintEvent has been run. Could not run test.");
+ }
+}
+
+void tst_QPainter::fillRect_objectBoundingModeGradient()
+{
+ QImage a(10, 10, QImage::Format_ARGB32_Premultiplied);
+ a.fill(0x0);
+ QImage b = a;
+
+ QLinearGradient g(QPoint(0, 0), QPoint(0, 1));
+ g.setColorAt(0, Qt::red);
+ g.setColorAt(1, Qt::blue);
+ g.setCoordinateMode(QGradient::ObjectBoundingMode);
+
+ QPainter p(&a);
+ p.fillRect(QRect(0, 0, a.width(), a.height()), g);
+ p.end();
+
+ QPainterPath path;
+ path.addRect(0, 0, a.width(), a.height());
+
+ p.begin(&b);
+ p.fillPath(path, g);
+ p.end();
+
+ QCOMPARE(a, b);
+}
+
+void tst_QPainter::fillRect_stretchToDeviceMode()
+{
+ QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
+
+ QLinearGradient g(QPoint(0, 0), QPoint(0, 1));
+ g.setCoordinateMode(QGradient::StretchToDeviceMode);
+
+ QPainter p(&img);
+ p.fillRect(img.rect(), g);
+ p.end();
+
+ for (int i = 1; i < img.height(); ++i)
+ QVERIFY(img.pixel(0, i) != img.pixel(0, i-1));
+}
+
+void tst_QPainter::monoImages()
+{
+ Qt::GlobalColor colorPairs[][2] = {
+ { Qt::white, Qt::black },
+ { Qt::color0, Qt::color1 },
+ { Qt::red, Qt::blue }
+ };
+
+ const int numColorPairs = sizeof(colorPairs) / sizeof(QRgb[2]);
+
+ QImage transparent(2, 2, QImage::Format_ARGB32_Premultiplied);
+ transparent.fill(0x0);
+
+ for (int i = 1; i < QImage::NImageFormats; ++i) {
+ for (int j = 0; j < numColorPairs; ++j) {
+ const QImage::Format format = QImage::Format(i);
+ if (format == QImage::Format_Indexed8)
+ continue;
+
+ QImage img(2, 2, format);
+
+ if (img.colorCount() > 0) {
+ img.setColor(0, QColor(colorPairs[j][0]).rgba());
+ img.setColor(1, QColor(colorPairs[j][1]).rgba());
+ }
+
+ img.fill(0x0);
+ QPainter p(&img);
+ p.fillRect(0, 0, 2, 2, colorPairs[j][0]);
+ p.fillRect(0, 0, 1, 1, colorPairs[j][1]);
+ p.fillRect(1, 1, 1, 1, colorPairs[j][1]);
+ p.end();
+
+ QImage original = img;
+
+ p.begin(&img);
+ p.drawImage(0, 0, transparent);
+ p.end();
+
+ // drawing a transparent image on top of another image
+ // should not change the image
+ QCOMPARE(original, img);
+
+ if (img.colorCount() == 0)
+ continue;
+
+ for (int k = 0; k < 2; ++k) {
+ QPainter p(&img);
+ p.fillRect(0, 0, 2, 2, colorPairs[j][k]);
+ p.end();
+
+ QImage argb32p(2, 2, QImage::Format_ARGB32_Premultiplied);
+ p.begin(&argb32p);
+ p.fillRect(0, 0, 2, 2, colorPairs[j][k]);
+ p.end();
+
+ QCOMPARE(argb32p, img.convertToFormat(argb32p.format()));
+
+ // drawing argb32p image on mono image
+ p.begin(&img);
+ p.drawImage(0, 0, argb32p);
+ p.end();
+
+ QCOMPARE(argb32p, img.convertToFormat(argb32p.format()));
+
+ // drawing mono image on argb32p image
+ p.begin(&argb32p);
+ p.drawImage(0, 0, img);
+ p.end();
+
+ QCOMPARE(argb32p, img.convertToFormat(argb32p.format()));
+ }
+ }
+ }
+}
+
+#if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_CC_MSVC) && !defined(Q_OS_SOLARIS) && !defined(Q_OS_SYMBIAN)
+#include <fenv.h>
+
+static const QString fpeExceptionString(int exception)
+{
+#ifdef FE_INEXACT
+ if (exception & FE_INEXACT)
+ return QLatin1String("Inexact result");
+#endif
+ if (exception & FE_UNDERFLOW)
+ return QLatin1String("Underflow");
+ if (exception & FE_OVERFLOW)
+ return QLatin1String("Overflow");
+ if (exception & FE_DIVBYZERO)
+ return QLatin1String("Divide by zero");
+ if (exception & FE_INVALID)
+ return QLatin1String("Invalid operation");
+ return QLatin1String("No exception");
+}
+
+class FpExceptionChecker
+{
+public:
+ FpExceptionChecker(int exceptionMask)
+ : m_exceptionMask(exceptionMask)
+ {
+ feclearexcept(m_exceptionMask);
+ }
+
+ ~FpExceptionChecker()
+ {
+ const int exceptions = fetestexcept(m_exceptionMask);
+ QVERIFY2(!exceptions, qPrintable(QLatin1String("Floating point exception: ") + fpeExceptionString(exceptions)));
+ }
+
+private:
+ int m_exceptionMask;
+};
+
+void fpe_rasterizeLine_task232012()
+{
+ FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
+ QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0x0);
+ QPainter p(&img);
+
+ p.setBrush(Qt::black);
+ p.drawRect(QRectF(0, 0, 5, 0));
+ p.drawRect(QRectF(0, 0, 0, 5));
+}
+
+void fpe_pixmapTransform()
+{
+ FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
+
+ QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
+
+ QPainter p(&img);
+
+ const qreal scaleFactor = 0.001;
+ const int translateDistance = 1000000;
+
+ p.setPen(Qt::red);
+ p.setBrush(QBrush(Qt::red,Qt::Dense6Pattern));
+
+ for (int i = 0; i < 2; ++i) {
+ p.setRenderHint(QPainter::SmoothPixmapTransform, i);
+
+ p.resetTransform();
+ p.scale(1.1, 1.1);
+ p.translate(translateDistance, 0);
+ p.drawRect(-translateDistance, 0, 100, 100);
+
+ p.resetTransform();
+ p.scale(scaleFactor, scaleFactor);
+ p.drawRect(QRectF(0, 0, 1 / scaleFactor, 1 / scaleFactor));
+ }
+}
+
+void fpe_zeroLengthLines()
+{
+ FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
+
+ QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
+
+ QPainter p(&img);
+
+ p.setPen(QPen(Qt::black, 3));
+ p.drawLine(64, 64, 64, 64);
+}
+
+void fpe_divByZero()
+{
+ FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
+
+ QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
+
+ QPainter p(&img);
+
+ p.setRenderHint(QPainter::Antialiasing);
+
+ p.drawRect(QRectF(10, 10, 100, 0));
+ p.drawRect(QRectF(10, 10, 0, 100));
+
+ p.drawRect(QRect(10, 10, 100, 0));
+ p.drawRect(QRect(10, 10, 0, 100));
+
+ p.fillRect(QRectF(10, 10, 100, 0), Qt::black);
+ p.fillRect(QRectF(10, 10, 0, 100), Qt::black);
+
+ p.fillRect(QRect(10, 10, 100, 0), Qt::black);
+ p.fillRect(QRect(10, 10, 0, 100), Qt::black);
+}
+
+void fpe_steepSlopes()
+{
+ FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
+
+ QImage img(1024, 1024, QImage::Format_ARGB32_Premultiplied);
+
+ QFETCH(QTransform, transform);
+ QFETCH(QLineF, line);
+ QFETCH(bool, antialiased);
+
+ QPainter p(&img);
+
+ p.setPen(QPen(Qt::black, 1));
+ p.setRenderHint(QPainter::Antialiasing, antialiased);
+ p.setTransform(transform);
+
+ p.drawLine(line);
+}
+
+void fpe_radialGradients()
+{
+ FpExceptionChecker checker(FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO);
+
+ QImage img(21, 21, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+
+ double m = img.width() * 0.5;
+
+ QPainter p(&img);
+ p.setRenderHints(QPainter::Antialiasing);
+ p.setPen(Qt::NoPen);
+ p.setBrush(QRadialGradient(m, m, m));
+ p.drawEllipse(img.rect());
+}
+
+#define FPE_TEST(x) \
+void tst_QPainter::x() \
+{ \
+ ::x(); \
+}
+#else
+#define FPE_TEST(x) \
+void tst_QPainter::x() \
+{ \
+ QSKIP("Floating point exception checking (fenv.h) not available", SkipAll); \
+}
+#endif
+
+FPE_TEST(fpe_rasterizeLine_task232012)
+FPE_TEST(fpe_pixmapTransform)
+FPE_TEST(fpe_zeroLengthLines)
+FPE_TEST(fpe_divByZero)
+FPE_TEST(fpe_steepSlopes)
+FPE_TEST(fpe_radialGradients)
+
+void tst_QPainter::fpe_steepSlopes_data()
+{
+ QTest::addColumn<QTransform>("transform");
+ QTest::addColumn<QLineF>("line");
+ QTest::addColumn<bool>("antialiased");
+
+ {
+ const qreal dsin = 0.000014946676875461832484392500630665523431162000633776187896728515625;
+ const qreal dcos = 0.9999999998882984630910186751862056553363800048828125;
+
+ const QTransform transform = QTransform(QMatrix(dcos, dsin, -dsin, dcos, 64, 64));
+ const QLineF line(2, 2, 2, 6);
+
+ QTest::newRow("task 207147 aa") << transform << line << true;
+ QTest::newRow("task 207147 no aa") << transform << line << false;
+ }
+
+ {
+ QTransform transform;
+ transform.rotate(0.0000001);
+ const QLineF line(5, 5, 10, 5);
+
+ QTest::newRow("task 166702 aa") << transform << line << true;
+ QTest::newRow("task 166702 no aa") << transform << line << false;
+ }
+
+ {
+ const QTransform transform;
+ const QLineF line(2.5, 2.5, 2.5 + 1/256., 60000.5);
+
+ QTest::newRow("steep line aa") << transform << line << true;
+ QTest::newRow("steep line no aa") << transform << line << false;
+ }
+
+ {
+ const QTransform transform;
+ const QLineF line(2.5, 2.5, 2.5 + 1/256., 1024);
+
+ QTest::newRow("steep line 2 aa") << transform << line << true;
+ QTest::newRow("steep line 2 no aa") << transform << line << false;
+ }
+
+ {
+ const QTransform transform;
+ const QLineF line(2.5, 2.5, 2.5 + 1/64., 1024);
+
+ QTest::newRow("steep line 3 aa") << transform << line << true;
+ QTest::newRow("steep line 3 no aa") << transform << line << false;
+ }
+}
+
+qreal randf()
+{
+ return rand() / (RAND_MAX + 1.0);
+}
+
+QPointF randInRect(const QRectF &rect)
+{
+ const qreal x = rect.left() + rect.width() * randf();
+ const qreal y = rect.top() + rect.height() * randf();
+
+ return QPointF(x, y);
+}
+
+void tst_QPainter::rasterizer_asserts()
+{
+ QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
+
+ QRectF middle(QPointF(0, 0), img.size());
+ QRectF left = middle.translated(-middle.width(), 0);
+ QRectF right = middle.translated(middle.width(), 0);
+
+ QPainter p(&img);
+ img.fill(Qt::white);
+ p.setCompositionMode(QPainter::CompositionMode_Destination);
+ for (int i = 0; i < 100000; ++i) {
+ QPainterPath path;
+ path.moveTo(randInRect(middle));
+ path.lineTo(randInRect(left));
+ path.lineTo(randInRect(right));
+
+ p.fillPath(path, Qt::black);
+ }
+}
+
+void tst_QPainter::rasterizer_negativeCoords()
+{
+ QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0x0);
+
+ QImage original = img;
+
+ QPainter p(&img);
+ p.rotate(90);
+ p.fillRect(0, 0, 70, 50, Qt::black);
+
+ // image should not have changed
+ QCOMPARE(img.pixel(0, 0), 0x0U);
+ QCOMPARE(img, original);
+}
+
+void tst_QPainter::blendOverFlow_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<int>("width");
+ QTest::addColumn<int>("height");
+
+ QImage::Format format = QImage::Format_ARGB8555_Premultiplied;
+ QTest::newRow("555,1,1") << format << 1 << 1;
+ QTest::newRow("555,2,2") << format << 2 << 2;
+ QTest::newRow("555,10,10") << format << 10 << 10;
+
+ format = QImage::Format_ARGB8565_Premultiplied;
+ QTest::newRow("565,1,1") << format << 1 << 1;
+ QTest::newRow("565,2,2") << format << 2 << 2;
+ QTest::newRow("565,10,10") << format << 10 << 10;
+}
+
+void tst_QPainter::blendOverFlow()
+{
+ QFETCH(QImage::Format, format);
+ QFETCH(int, width);
+ QFETCH(int, height);
+
+ QImage dest(width, height, format);
+ QImage src(width, height, format);
+
+ {
+ QPainter p(&dest);
+ p.fillRect(0, 0, width, height, Qt::green);
+ }
+ QImage expected = dest;
+
+ {
+ QPainter p(&src);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(0, 0, width, height, QColor(0, 255, 0, 6));
+ }
+
+ {
+ QPainter p(&dest);
+ p.drawImage(0, 0, src);
+ }
+
+ QCOMPARE(dest.pixel(0, 0), expected.pixel(0, 0));
+ QCOMPARE(dest, expected);
+}
+
+void tst_QPainter::largeImagePainting_data()
+{
+ QTest::addColumn<int>("width");
+ QTest::addColumn<int>("height");
+ QTest::addColumn<bool>("antialiased");
+
+ QTest::newRow("tall") << 1 << 32767 << false;
+ QTest::newRow("tall aa") << 1 << 32767 << true;
+ QTest::newRow("wide") << 32767 << 1 << false;
+ QTest::newRow("wide aa") << 32767 << 1 << true;
+}
+
+void tst_QPainter::largeImagePainting()
+{
+ QPainterPath path;
+ path.addRect(0, 0, 1, 1);
+ path.addRect(2, 0, 1, 1);
+ path.addRect(0, 2, 1, 1);
+
+ QFETCH(int, width);
+ QFETCH(int, height);
+ QFETCH(bool, antialiased);
+
+ QImage img(width, height, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0x0);
+
+ QPainter p(&img);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::white);
+
+ p.setRenderHint(QPainter::Antialiasing, antialiased);
+
+ for (int i = 0; i < img.width(); i += 4) {
+ p.drawPath(path);
+ p.translate(4, 0);
+ }
+
+ p.resetMatrix();
+
+ for (int i = 4; i < img.height(); i += 4) {
+ p.translate(0, 4);
+ p.drawPath(path);
+ }
+
+ for (int i = 0; i < img.width(); ++i) {
+ if (i % 2)
+ QCOMPARE(img.pixel(i, 0), 0x0U);
+ else
+ QCOMPARE(img.pixel(i, 0), 0xffffffffU);
+ }
+
+ for (int i = 1; i < img.height(); ++i) {
+ if (i % 2)
+ QCOMPARE(img.pixel(0, i), 0x0U);
+ else
+ QCOMPARE(img.pixel(0, i), 0xffffffffU);
+ }
+}
+
+void tst_QPainter::imageScaling_task206785()
+{
+ QImage src(32, 2, QImage::Format_ARGB32_Premultiplied);
+ src.fill(0xffffffff);
+
+ QImage dst(128, 128, QImage::Format_ARGB32_Premultiplied);
+
+ QImage expected(128, 128, QImage::Format_ARGB32_Premultiplied);
+ expected.fill(0xffffffff);
+
+ for (int i = 1; i < 5; ++i) {
+ qreal scale = i / qreal(5);
+
+ dst.fill(0xff000000);
+
+ QPainter p(&dst);
+ p.scale(dst.width() / qreal(src.width()), scale);
+
+ for (int y = 0; y * scale < dst.height(); ++y)
+ p.drawImage(0, y, src);
+
+ p.end();
+
+ QCOMPARE(dst, expected);
+ }
+}
+
+#define FOR_EACH_NEIGHBOR_8 for (int dx = -1; dx <= 1; ++dx) for (int dy = -1; dy <= 1; ++dy) if (dx != 0 || dy != 0)
+#define FOR_EACH_NEIGHBOR_4 for (int dx = -1; dx <= 1; ++dx) for (int dy = -1; dy <= 1; ++dy) if ((dx == 0) != (dy == 0))
+
+uint qHash(const QPoint &point)
+{
+ return qHash(qMakePair(point.x(), point.y()));
+}
+
+bool verifyOutlineFillConsistency(const QImage &img, QRgb outside, QRgb inside, QRgb outline)
+{
+ if (img.pixel(img.width() / 2, img.height() / 2) != inside)
+ return false;
+
+ int x = img.width() / 2;
+ int y = img.height() / 2;
+
+ while (img.pixel(++x, y) == inside)
+ ;
+
+ if (img.pixel(x, y) != outline)
+ return false;
+
+ QQueue<QPoint> discovered;
+ discovered.enqueue(QPoint(x, y));
+
+ QVector<bool> visited(img.width() * img.height());
+ visited.fill(false);
+
+ while (!discovered.isEmpty()) {
+ QPoint p = discovered.dequeue();
+ QRgb pixel = img.pixel(p.x(), p.y());
+
+ bool &v = visited[p.y() * img.width() + p.x()];
+ if (v)
+ continue;
+ v = true;
+
+ if (pixel == outline) {
+ FOR_EACH_NEIGHBOR_8 {
+ QPoint x(p.x() + dx, p.y() + dy);
+ discovered.enqueue(x);
+ }
+ } else {
+ FOR_EACH_NEIGHBOR_4 {
+ if ((dx == 0) == (dy == 0))
+ continue;
+ QRgb neighbor = img.pixel(p.x() + dx, p.y() + dy);
+ if ((pixel == inside && neighbor == outside) ||
+ (pixel == outside && neighbor == inside))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+#undef FOR_EACH_NEIGHBOR_8
+#undef FOR_EACH_NEIGHBOR_4
+
+void tst_QPainter::outlineFillConsistency()
+{
+ QSKIP("currently broken...", SkipAll);
+ return;
+
+ QImage dst(256, 256, QImage::Format_ARGB32_Premultiplied);
+
+ QPolygonF poly;
+ poly << QPointF(5, -100) << QPointF(-70, 20) << QPointF(95, 25);
+
+ QPen pen(Qt::red);
+ QBrush brush(Qt::black);
+
+ QRgb background = 0xffffffff;
+ for (int i = 0; i < 360; ++i) {
+ dst.fill(background);
+
+ QPainter p(&dst);
+ p.translate(dst.width() / 2, dst.height() / 2);
+
+ QPolygonF copy = poly;
+ for (int j = 0; j < copy.size(); ++j)
+ copy[j] = QTransform().rotate(i).map(copy[j]);
+
+ p.setPen(pen);
+ p.setBrush(brush);
+ p.drawPolygon(copy);
+ p.end();
+
+#if 0
+ if (!verifyOutlineFillConsistency(dst, background, p.brush().color().rgba(), p.pen().color().rgba()))
+ dst.save(QString("outlineFillConsistency-%1.png").arg(i));
+#endif
+
+ QVERIFY(verifyOutlineFillConsistency(dst, background, brush.color().rgba(), pen.color().rgba()));
+ }
+}
+
+void tst_QPainter::drawImage_task217400_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+
+ QTest::newRow("444") << QImage::Format_ARGB4444_Premultiplied;
+ QTest::newRow("555") << QImage::Format_ARGB8555_Premultiplied;
+ QTest::newRow("565") << QImage::Format_ARGB8565_Premultiplied;
+// QTest::newRow("666") << QImage::Format_ARGB6666_Premultiplied;
+ QTest::newRow("888p") << QImage::Format_ARGB32_Premultiplied;
+ QTest::newRow("888") << QImage::Format_ARGB32;
+}
+
+void tst_QPainter::drawImage_task217400()
+{
+ QFETCH(QImage::Format, format);
+
+ const QImage src = QImage(QString(SRCDIR) + "/task217400.png")
+ .convertToFormat(format);
+ QVERIFY(!src.isNull());
+
+ QImage expected(src.size(), format);
+ {
+ QPainter p(&expected);
+ p.fillRect(0, 0, expected.width(), expected.height(), Qt::white);
+ p.drawImage(0, 0, src);
+ }
+
+ for (int i = 1; i <= 4; ++i) {
+ QImage dest(src.width() + i, src.height(), format);
+ {
+ QPainter p(&dest);
+ p.fillRect(0, 0, dest.width(), dest.height(), Qt::white);
+ p.drawImage(i, 0, src);
+ }
+
+ const QImage result = dest.copy(i, 0, src.width(), src.height());
+
+#if 0
+ if (result != expected) {
+ qDebug("i=%i", i);
+ result.save("result.png");
+ expected.save("expected.png");
+ }
+#endif
+ QCOMPARE(result, expected);
+ }
+}
+
+void tst_QPainter::drawImage_task258776()
+{
+ QImage src(16, 16, QImage::Format_RGB888);
+ QImage dest(33, 33, QImage::Format_RGB888);
+ src.fill(0x00ff00);
+ dest.fill(0x0000ff);
+
+ QPainter painter(&dest);
+ painter.drawImage(QRectF(0.499, 0.499, 32, 32), src, QRectF(0, 0, 16, 16));
+ painter.end();
+
+ QImage expected(33, 33, QImage::Format_RGB32);
+ expected.fill(0xff0000);
+
+ painter.begin(&expected);
+ painter.drawImage(QRectF(0, 0, 32, 32), src);
+ painter.end();
+
+ dest = dest.convertToFormat(QImage::Format_RGB32);
+
+ dest.save("dest.png");
+ expected.save("expected.png");
+ QCOMPARE(dest, expected);
+}
+
+void tst_QPainter::clipRectSaveRestore()
+{
+ QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0x0);
+
+ QPainter p(&img);
+ p.setClipRect(QRect(0, 0, 10, 10));
+ p.save();
+ p.setClipRect(QRect(5, 5, 5, 5), Qt::IntersectClip);
+ p.restore();
+ p.fillRect(0, 0, 64, 64, Qt::black);
+ p.end();
+
+ QCOMPARE(img.pixel(0, 0), QColor(Qt::black).rgba());
+}
+
+void tst_QPainter::clippedImage()
+{
+ QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0x0);
+
+ QImage src(16, 16, QImage::Format_RGB32);
+ src.fill(QColor(Qt::red).rgba());
+
+ QPainter p(&img);
+ p.setClipRect(QRect(1, 1, 14, 14));
+ p.drawImage(0, 0, src);
+ p.end();
+
+ QCOMPARE(img.pixel(0, 0), 0x0U);
+ QCOMPARE(img.pixel(1, 1), src.pixel(1, 1));
+}
+
+void tst_QPainter::stateResetBetweenQPainters()
+{
+ QImage img(16, 16, QImage::Format_ARGB32);
+
+ {
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(0, 0, 16, 16, Qt::red);
+ }
+
+ {
+ QPainter p2(&img);
+ p2.fillRect(0, 0, 16, 16, QColor(0, 0, 255, 63));
+ }
+
+ img.save("foo.png");
+
+ QVERIFY(img.pixel(0, 0) != qRgba(0, 0, 255, 63));
+ QVERIFY(qRed(img.pixel(0, 0)) > 0); // We didn't erase the red channel...
+ QVERIFY(qBlue(img.pixel(0, 0)) < 255); // We blended the blue channel
+}
+
+void tst_QPainter::drawRect_task215378()
+{
+ QImage img(11, 11, QImage::Format_ARGB32_Premultiplied);
+ img.fill(QColor(Qt::white).rgba());
+
+ QPainter p(&img);
+ p.setPen(QColor(127, 127, 127, 127));
+ p.drawRect(0, 0, 10, 10);
+ p.end();
+
+ QCOMPARE(img.pixel(0, 0), img.pixel(1, 0));
+ QCOMPARE(img.pixel(0, 0), img.pixel(0, 1));
+ QVERIFY(img.pixel(0, 0) != img.pixel(1, 1));
+}
+
+void tst_QPainter::drawRect_task247505()
+{
+ QImage a(10, 10, QImage::Format_ARGB32_Premultiplied);
+ a.fill(0);
+ QImage b = a;
+
+ QPainter p(&a);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::black);
+ p.drawRect(QRectF(10, 0, -10, 10));
+ p.end();
+ p.begin(&b);
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::black);
+ p.drawRect(QRectF(0, 0, 10, 10));
+ p.end();
+
+ QCOMPARE(a, b);
+}
+
+void tst_QPainter::drawImage_data()
+{
+ QTest::addColumn<int>("x");
+ QTest::addColumn<int>("y");
+ QTest::addColumn<int>("w");
+ QTest::addColumn<int>("h");
+ QTest::addColumn<QImage::Format>("srcFormat");
+ QTest::addColumn<QImage::Format>("dstFormat");
+
+ for (int srcFormat = QImage::Format_Mono; srcFormat < QImage::NImageFormats; ++srcFormat) {
+ for (int dstFormat = QImage::Format_Mono; dstFormat < QImage::NImageFormats; ++dstFormat) {
+ if (dstFormat == QImage::Format_Indexed8)
+ continue;
+ for (int odd_x = 0; odd_x <= 1; ++odd_x) {
+ for (int odd_width = 0; odd_width <= 1; ++odd_width) {
+ QString description =
+ QString("srcFormat %1, dstFormat %2, odd x: %3, odd width: %4")
+ .arg(srcFormat).arg(dstFormat).arg(odd_x).arg(odd_width);
+
+ QTest::newRow(qPrintable(description)) << (10 + odd_x) << 10 << (20 + odd_width) << 20
+ << QImage::Format(srcFormat)
+ << QImage::Format(dstFormat);
+ }
+ }
+ }
+ }
+}
+
+bool verifyImage(const QImage &img, int x, int y, int w, int h, uint background)
+{
+ int imgWidth = img.width();
+ int imgHeight = img.height();
+ for (int i = 0; i < imgHeight; ++i) {
+ for (int j = 0; j < imgWidth; ++j) {
+ uint pixel = img.pixel(j, i);
+ bool outside = j < x || j >= (x + w) || i < y || i >= (y + h);
+ if (outside != (pixel == background)) {
+ //printf("%d %d, expected %x, got %x, outside: %d\n", x, y, background, pixel, outside);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void tst_QPainter::drawImage()
+{
+ QFETCH(int, x);
+ QFETCH(int, y);
+ QFETCH(int, w);
+ QFETCH(int, h);
+ QFETCH(QImage::Format, srcFormat);
+ QFETCH(QImage::Format, dstFormat);
+
+ QImage dst(40, 40, QImage::Format_RGB32);
+ dst.fill(0xffffffff);
+
+ dst = dst.convertToFormat(dstFormat);
+ uint background = dst.pixel(0, 0);
+
+ QImage src(w, h, QImage::Format_RGB32);
+ src.fill(0xff000000);
+ src = src.convertToFormat(srcFormat);
+
+ QPainter p(&dst);
+ p.drawImage(x, y, src);
+ p.end();
+
+ QVERIFY(verifyImage(dst, x, y, w, h, background));
+}
+
+void tst_QPainter::imageCoordinateLimit()
+{
+ QImage img(64, 40000, QImage::Format_MonoLSB);
+ QPainter p(&img);
+ p.drawText(10, 36000, QLatin1String("foo"));
+ p.setPen(QPen(Qt::black, 2));
+ p.drawLine(10, 0, 60, 40000);
+
+ p.setRenderHint(QPainter::Antialiasing);
+ p.drawLine(10, 0, 60, 40000);
+}
+
+
+void tst_QPainter::imageBlending_data()
+{
+ QTest::addColumn<QImage::Format>("sourceFormat");
+ QTest::addColumn<QImage::Format>("destFormat");
+ QTest::addColumn<int>("error");
+
+ int error_rgb565 = ((1<<3) + (1<<2) + (1<<3));
+ QTest::newRow("rgb565_on_rgb565") << QImage::Format_RGB16
+ << QImage::Format_RGB16
+ << 0;
+ QTest::newRow("argb8565_on_rgb565") << QImage::Format_ARGB8565_Premultiplied
+ << QImage::Format_RGB16
+ << error_rgb565;
+
+ QTest::newRow("rgb32_on_rgb565") << QImage::Format_RGB32
+ << QImage::Format_RGB16
+ << error_rgb565;
+
+ QTest::newRow("argb32pm_on_rgb565") << QImage::Format_ARGB32_Premultiplied
+ << QImage::Format_RGB16
+ << error_rgb565;
+}
+
+int diffColor(quint32 ap, quint32 bp)
+{
+ int a = qAlpha(ap) - qAlpha(bp);
+ int r = qRed(ap) - qRed(bp);
+ int b = qBlue(ap) - qBlue(bp);
+ int g = qBlue(ap) - qBlue(bp);
+
+ return qAbs(a) + qAbs(r) + qAbs(g) + qAbs(b);
+}
+
+// this test assumes premultiplied pixels...
+
+void tst_QPainter::imageBlending()
+{
+ QFETCH(QImage::Format, sourceFormat);
+ QFETCH(QImage::Format, destFormat);
+ QFETCH(int, error);
+
+ QImage dest;
+ {
+ QImage orig_dest(6, 6, QImage::Format_ARGB32_Premultiplied);
+ orig_dest.fill(0);
+ QPainter p(&orig_dest);
+ p.fillRect(0, 0, 6, 3, QColor::fromRgbF(1, 0, 0));
+ p.fillRect(3, 0, 3, 6, QColor::fromRgbF(0, 0, 1, 0.5));
+ p.end();
+ dest = orig_dest.convertToFormat(destFormat);
+
+ // An image like this: (r = red, m = magenta, b = light alpha blue, 0 = transparent)
+ // r r r m m m
+ // r r r m m m
+ // r r r m m m
+ // 0 0 0 b b b
+ // 0 0 0 b b b
+ // 0 0 0 b b b
+ }
+
+ QImage source;
+ {
+ QImage orig_source(6, 6, QImage::Format_ARGB32_Premultiplied);
+ orig_source.fill(0);
+ QPainter p(&orig_source);
+ p.fillRect(1, 1, 4, 4, QColor::fromRgbF(0, 1, 0, 0.5));
+ p.fillRect(2, 2, 2, 2, QColor::fromRgbF(0, 1, 0));
+ p.end();
+ source = orig_source.convertToFormat(sourceFormat);
+
+ // An image like this: (0 = transparent, . = green at 0.5 alpha, g = opaque green.
+ // 0 0 0 0 0 0
+ // 0 . . . . 0
+ // 0 . g g . 0
+ // 0 . g g . 0
+ // 0 . . . . 0
+ // 0 0 0 0 0 0
+ }
+
+ QPainter p(&dest);
+ p.drawImage(0, 0, source);
+ p.end();
+
+ // resulting image:
+ // r r r m m m
+ // r r. r. m. m. m
+ // r r. g g m. m
+ // 0 . g g b. b
+ // 0 . . b. b. b
+ // 0 0 0 b b b
+
+ // the g pixels, always green..
+ QVERIFY(diffColor(dest.pixel(2, 2), 0xff00ff00) <= error); // g
+
+ if (source.hasAlphaChannel()) {
+ QVERIFY(diffColor(dest.pixel(0, 0), 0xffff0000) <= error); // r
+ QVERIFY(diffColor(dest.pixel(5, 0), 0xff7f007f) <= error); // m
+ QVERIFY(diffColor(dest.pixel(1, 1), 0xff7f7f00) <= error); // r.
+ QVERIFY(diffColor(dest.pixel(4, 1), 0xff3f7f3f) <= error); // m.
+ if (dest.hasAlphaChannel()) {
+ QVERIFY(diffColor(dest.pixel(1, 3), 0x7f007f00) <= error); // .
+ QVERIFY(diffColor(dest.pixel(4, 3), 0x7f007f3f) <= error); // b.
+ QVERIFY(diffColor(dest.pixel(4, 3), 0x7f007f3f) <= error); // b.
+ QVERIFY(diffColor(dest.pixel(4, 4), 0x7f00007f) <= error); // b
+ QVERIFY(diffColor(dest.pixel(4, 0), 0) <= 0); // 0
+ }
+ } else {
+ QVERIFY(diffColor(dest.pixel(0, 0), 0xff000000) <= 0);
+ QVERIFY(diffColor(dest.pixel(1, 1), 0xff007f00) <= error);
+ }
+}
+
+void tst_QPainter::imageBlending_clipped()
+{
+ QImage src(20, 20, QImage::Format_RGB16);
+ QPainter p(&src);
+ p.fillRect(src.rect(), Qt::red);
+ p.end();
+
+ QImage dst(40, 20, QImage::Format_RGB16);
+ p.begin(&dst);
+ p.fillRect(dst.rect(), Qt::white);
+ p.end();
+
+ QImage expected = dst;
+
+ p.begin(&dst);
+ p.setClipRect(QRect(23, 0, 20, 20));
+
+ // should be completely clipped
+ p.drawImage(QRectF(3, 0, 20, 20), src);
+ p.end();
+
+ // dst should be left unchanged
+ QCOMPARE(dst, expected);
+}
+
+void tst_QPainter::paintOnNullPixmap()
+{
+ QPixmap pix(16, 16);
+
+ QPixmap textPixmap;
+ QPainter p(&textPixmap);
+ p.drawPixmap(10, 10, pix);
+ p.end();
+
+ QPixmap textPixmap2(16,16);
+ p.begin(&textPixmap2);
+ p.end();
+}
+
+void tst_QPainter::checkCompositionMode()
+{
+ QImage refImage(50,50,QImage::Format_ARGB32);
+ QPainter painter(&refImage);
+ painter.fillRect(QRect(0,0,50,50),Qt::blue);
+
+ QImage testImage(50,50,QImage::Format_ARGB32);
+ QPainter p(&testImage);
+ p.fillRect(QRect(0,0,50,50),Qt::red);
+ p.save();
+ p.setCompositionMode(QPainter::CompositionMode_SourceOut);
+ p.restore();
+ p.fillRect(QRect(0,0,50,50),Qt::blue);
+
+ QCOMPARE(refImage.pixel(20,20),testImage.pixel(20,20));
+}
+
+static QLinearGradient inverseGradient(QLinearGradient g)
+{
+ QLinearGradient g2 = g;
+
+ QGradientStops stops = g.stops();
+
+ QGradientStops inverse;
+ foreach (QGradientStop stop, stops)
+ inverse << QGradientStop(1 - stop.first, stop.second);
+
+ g2.setStops(inverse);
+ return g2;
+}
+
+void tst_QPainter::linearGradientSymmetry_data()
+{
+ QTest::addColumn<QGradientStops>("stops");
+
+ if (sizeof(qreal) != sizeof(float)) {
+ QGradientStops stops;
+ stops << qMakePair(qreal(0.0), QColor(Qt::blue));
+ stops << qMakePair(qreal(0.2), QColor(220, 220, 220, 0));
+ stops << qMakePair(qreal(0.6), QColor(Qt::red));
+ stops << qMakePair(qreal(0.9), QColor(220, 220, 220, 255));
+ stops << qMakePair(qreal(1.0), QColor(Qt::black));
+ QTest::newRow("multiple stops") << stops;
+ }
+
+ {
+ QGradientStops stops;
+ stops << qMakePair(qreal(0.0), QColor(Qt::blue));
+ stops << qMakePair(qreal(1.0), QColor(Qt::black));
+ QTest::newRow("two stops") << stops;
+ }
+
+ if (sizeof(qreal) != sizeof(float)) {
+ QGradientStops stops;
+ stops << qMakePair(qreal(0.3), QColor(Qt::blue));
+ stops << qMakePair(qreal(0.6), QColor(Qt::black));
+ QTest::newRow("two stops 2") << stops;
+ }
+}
+
+void tst_QPainter::linearGradientSymmetry()
+{
+#ifdef Q_WS_QWS
+ QSKIP("QWS has limited resolution in the gradient color table", SkipAll);
+#else
+ QFETCH(QGradientStops, stops);
+
+ QImage a(64, 8, QImage::Format_ARGB32_Premultiplied);
+ QImage b(64, 8, QImage::Format_ARGB32_Premultiplied);
+
+ a.fill(0);
+ b.fill(0);
+
+ QLinearGradient gradient(QRectF(b.rect()).topLeft(), QRectF(b.rect()).topRight());
+ gradient.setStops(stops);
+
+ QPainter pa(&a);
+ pa.fillRect(a.rect(), gradient);
+ pa.end();
+
+ QPainter pb(&b);
+ pb.fillRect(b.rect(), inverseGradient(gradient));
+ pb.end();
+
+ b = b.mirrored(true);
+ QCOMPARE(a, b);
+#endif
+}
+
+void tst_QPainter::gradientInterpolation()
+{
+ QImage image(256, 8, QImage::Format_ARGB32_Premultiplied);
+ QPainter painter;
+
+ QLinearGradient gradient(QRectF(image.rect()).topLeft(), QRectF(image.rect()).topRight());
+ gradient.setColorAt(0.0, QColor(255, 0, 0, 0));
+ gradient.setColorAt(1.0, Qt::blue);
+
+ image.fill(0);
+ painter.begin(&image);
+ painter.fillRect(image.rect(), gradient);
+ painter.end();
+
+ const QRgb *line = reinterpret_cast<QRgb *>(image.scanLine(3));
+
+ for (int i = 0; i < 256; ++i) {
+ QCOMPARE(qAlpha(line[i]), qBlue(line[i])); // bright blue
+ QVERIFY(qAbs(qAlpha(line[i]) - i) < 3); // linear alpha
+ QCOMPARE(qRed(line[i]), 0); // no red component
+ QCOMPARE(qGreen(line[i]), 0); // no green component
+ }
+
+ gradient.setInterpolationMode(QGradient::ComponentInterpolation);
+
+ image.fill(0);
+ painter.begin(&image);
+ painter.fillRect(image.rect(), gradient);
+ painter.end();
+
+ for (int i = 1; i < 256; ++i) {
+ if (i < 128) {
+ QVERIFY(qRed(line[i]) >= qBlue(line[i])); // red is dominant
+ } else {
+ QVERIFY(qRed(line[i]) <= qBlue(line[i])); // blue is dominant
+ }
+ 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
+ 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
+ QVERIFY(qAbs(qAlpha(line[i]) - i) < 3); // linear alpha
+ QCOMPARE(qGreen(line[i]), 0); // no green component
+ }
+}
+
+void tst_QPainter::drawPolygon()
+{
+ QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
+
+ QPainterPathStroker stroker;
+ stroker.setWidth(1.5);
+
+ QPainterPath path;
+ path.moveTo(2, 34);
+ path.lineTo(34, 2);
+
+ QPolygonF poly = stroker.createStroke(path).toFillPolygon();
+
+ img.fill(0xffffffff);
+ QPainter p(&img);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setBrush(Qt::red);
+ p.setPen(Qt::NoPen);
+ p.drawPolygon(poly);
+ p.translate(64, 64);
+ p.drawPolygon(poly);
+ p.end();
+
+ QImage a = img.copy();
+
+ img.fill(0xffffffff);
+ p.begin(&img);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setBrush(Qt::red);
+ p.setPen(Qt::NoPen);
+ p.translate(64, 64);
+ p.drawPolygon(poly);
+ p.resetTransform();
+ p.drawPolygon(poly);
+ p.end();
+
+ QCOMPARE(a, img);
+}
+
+void tst_QPainter::inactivePainter()
+{
+ // This test succeeds if it doesn't segfault.
+
+ QPainter p;
+ QPainterPath path;
+ QRegion region(QRect(20, 20, 60, 40));
+ QPolygonF polygon(QVector<QPointF>() << QPointF(0, 0) << QPointF(12, 0) << QPointF(8, 6));
+ path.addPolygon(polygon);
+
+ p.save();
+ p.restore();
+
+ p.background();
+ p.setBackground(QBrush(Qt::blue));
+
+ p.brush();
+ p.setBrush(Qt::red);
+ p.setBrush(Qt::NoBrush);
+ p.setBrush(QBrush(Qt::white, Qt::DiagCrossPattern));
+
+ p.backgroundMode();
+ p.setBackgroundMode(Qt::OpaqueMode);
+
+ p.boundingRect(QRectF(0, 0, 100, 20), Qt::AlignCenter, QLatin1String("Hello, World!"));
+ p.boundingRect(QRect(0, 0, 100, 20), Qt::AlignCenter, QLatin1String("Hello, World!"));
+
+ p.brushOrigin();
+ p.setBrushOrigin(QPointF(12, 34));
+ p.setBrushOrigin(QPoint(12, 34));
+
+ p.clipPath();
+ p.clipRegion();
+ p.hasClipping();
+ p.setClipPath(path);
+ p.setClipRect(QRectF(42, 42, 42, 42));
+ p.setClipRect(QRect(42, 42, 42, 42));
+ p.setClipRegion(region);
+ p.setClipping(true);
+
+ p.combinedMatrix();
+ p.combinedTransform();
+
+ p.compositionMode();
+ p.setCompositionMode(QPainter::CompositionMode_Plus);
+
+ p.device();
+ p.deviceMatrix();
+ p.deviceTransform();
+
+ p.font();
+ p.setFont(QFont(QLatin1String("Times"), 24));
+
+ p.fontInfo();
+ p.fontMetrics();
+
+ p.layoutDirection();
+ p.setLayoutDirection(Qt::RightToLeft);
+
+ p.opacity();
+ p.setOpacity(0.75);
+
+ p.pen();
+ p.setPen(QPen(Qt::red));
+ p.setPen(Qt::green);
+ p.setPen(Qt::NoPen);
+
+ p.renderHints();
+ p.setRenderHint(QPainter::Antialiasing, true);
+ p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
+
+ p.resetMatrix();
+ p.resetTransform();
+ p.rotate(1);
+ p.scale(2, 2);
+ p.shear(-1, 1);
+ p.translate(3, 14);
+
+ p.viewTransformEnabled();
+ p.setViewTransformEnabled(true);
+
+ p.viewport();
+ p.setViewport(QRect(10, 10, 620, 460));
+
+ p.window();
+ p.setWindow(QRect(10, 10, 620, 460));
+
+ p.worldMatrix();
+ p.setWorldMatrix(QMatrix().translate(43, 21), true);
+ p.setWorldMatrixEnabled(true);
+
+ p.transform();
+ p.setTransform(QTransform().translate(12, 34), true);
+
+ p.worldTransform();
+ p.setWorldTransform(QTransform().scale(0.5, 0.5), true);
+}
+
+bool testCompositionMode(int src, int dst, int expected, QPainter::CompositionMode op, qreal opacity = 1.0)
+{
+ // The test image needs to be large enough to test SIMD code
+ const QSize imageSize(100, 100);
+
+ QImage actual(imageSize, QImage::Format_ARGB32_Premultiplied);
+ actual.fill(QColor(dst, dst, dst).rgb());
+
+ QPainter p(&actual);
+ p.setCompositionMode(op);
+ p.setOpacity(opacity);
+ p.fillRect(QRect(QPoint(), imageSize), QColor(src, src, src));
+ p.end();
+
+ if (qRed(actual.pixel(0, 0)) != expected) {
+ qDebug("Fail: mode %d, src[%d] dst [%d] actual [%d] expected [%d]", op,
+ src, dst, qRed(actual.pixel(0, 0)), expected);
+ return false;
+ } else {
+ QImage refImage(imageSize, QImage::Format_ARGB32_Premultiplied);
+ refImage.fill(QColor(expected, expected, expected).rgb());
+ return actual == refImage;
+ }
+}
+
+void tst_QPainter::extendedBlendModes()
+{
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Plus));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Plus));
+ QVERIFY(testCompositionMode(127, 128, 255, QPainter::CompositionMode_Plus));
+ QVERIFY(testCompositionMode(127, 0, 127, QPainter::CompositionMode_Plus));
+ QVERIFY(testCompositionMode( 0, 127, 127, QPainter::CompositionMode_Plus));
+ QVERIFY(testCompositionMode(255, 0, 255, QPainter::CompositionMode_Plus));
+ QVERIFY(testCompositionMode( 0, 255, 255, QPainter::CompositionMode_Plus));
+ QVERIFY(testCompositionMode(128, 128, 255, QPainter::CompositionMode_Plus));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(127, 128, 165, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(127, 0, 37, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode( 0, 127, 127, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(255, 0, 75, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode( 0, 255, 255, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(128, 128, 166, QPainter::CompositionMode_Plus, 0.3));
+ QVERIFY(testCompositionMode(186, 200, 255, QPainter::CompositionMode_Plus, 0.3));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Multiply));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Multiply));
+ QVERIFY(testCompositionMode(127, 255, 127, QPainter::CompositionMode_Multiply));
+ QVERIFY(testCompositionMode(255, 127, 127, QPainter::CompositionMode_Multiply));
+ QVERIFY(testCompositionMode( 63, 255, 63, QPainter::CompositionMode_Multiply));
+ QVERIFY(testCompositionMode(255, 63, 63, QPainter::CompositionMode_Multiply));
+ QVERIFY(testCompositionMode(127, 127, 63, QPainter::CompositionMode_Multiply));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Screen));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Screen));
+ QVERIFY(testCompositionMode( 63, 255, 255, QPainter::CompositionMode_Screen));
+ QVERIFY(testCompositionMode(255, 63, 255, QPainter::CompositionMode_Screen));
+ QVERIFY(testCompositionMode( 63, 0, 63, QPainter::CompositionMode_Screen));
+ QVERIFY(testCompositionMode( 0, 63, 63, QPainter::CompositionMode_Screen));
+ QVERIFY(testCompositionMode(127, 127, 191, QPainter::CompositionMode_Screen));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Overlay));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Overlay));
+ QVERIFY(testCompositionMode( 63, 63, 31, QPainter::CompositionMode_Overlay));
+ QVERIFY(testCompositionMode( 63, 255, 255, QPainter::CompositionMode_Overlay));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Darken));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Darken));
+ QVERIFY(testCompositionMode( 63, 63, 63, QPainter::CompositionMode_Darken));
+ QVERIFY(testCompositionMode( 63, 255, 63, QPainter::CompositionMode_Darken));
+ QVERIFY(testCompositionMode(255, 63, 63, QPainter::CompositionMode_Darken));
+ QVERIFY(testCompositionMode( 63, 127, 63, QPainter::CompositionMode_Darken));
+ QVERIFY(testCompositionMode(127, 63, 63, QPainter::CompositionMode_Darken));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_Lighten));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Lighten));
+ QVERIFY(testCompositionMode( 63, 63, 63, QPainter::CompositionMode_Lighten));
+ QVERIFY(testCompositionMode( 63, 255, 255, QPainter::CompositionMode_Lighten));
+ QVERIFY(testCompositionMode(255, 63, 255, QPainter::CompositionMode_Lighten));
+ QVERIFY(testCompositionMode( 63, 127, 127, QPainter::CompositionMode_Lighten));
+ QVERIFY(testCompositionMode(127, 63, 127, QPainter::CompositionMode_Lighten));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_ColorDodge));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_ColorDodge));
+ QVERIFY(testCompositionMode( 63, 127, 169, QPainter::CompositionMode_ColorDodge));
+ QVERIFY(testCompositionMode(191, 127, 255, QPainter::CompositionMode_ColorDodge));
+ QVERIFY(testCompositionMode(127, 191, 255, QPainter::CompositionMode_ColorDodge));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_ColorBurn));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_ColorBurn));
+ QVERIFY(testCompositionMode(127, 127, 0, QPainter::CompositionMode_ColorBurn));
+ QVERIFY(testCompositionMode(128, 128, 2, QPainter::CompositionMode_ColorBurn));
+ QVERIFY(testCompositionMode(191, 127, 84, QPainter::CompositionMode_ColorBurn));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_HardLight));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_HardLight));
+ QVERIFY(testCompositionMode(127, 127, 127, QPainter::CompositionMode_HardLight));
+ QVERIFY(testCompositionMode( 63, 63, 31, QPainter::CompositionMode_HardLight));
+ QVERIFY(testCompositionMode(127, 63, 63, QPainter::CompositionMode_HardLight));
+
+ QVERIFY(testCompositionMode(255, 255, 255, QPainter::CompositionMode_SoftLight));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_SoftLight));
+ QVERIFY(testCompositionMode(127, 127, 126, QPainter::CompositionMode_SoftLight));
+ QVERIFY(testCompositionMode( 63, 63, 39, QPainter::CompositionMode_SoftLight));
+ QVERIFY(testCompositionMode(127, 63, 62, QPainter::CompositionMode_SoftLight));
+
+ QVERIFY(testCompositionMode(255, 255, 0, QPainter::CompositionMode_Difference));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Difference));
+ QVERIFY(testCompositionMode(255, 0, 255, QPainter::CompositionMode_Difference));
+ QVERIFY(testCompositionMode(127, 127, 0, QPainter::CompositionMode_Difference));
+ QVERIFY(testCompositionMode(127, 128, 1, QPainter::CompositionMode_Difference));
+ QVERIFY(testCompositionMode(127, 63, 64, QPainter::CompositionMode_Difference));
+ QVERIFY(testCompositionMode( 0, 127, 127, QPainter::CompositionMode_Difference));
+
+ QVERIFY(testCompositionMode(255, 255, 0, QPainter::CompositionMode_Exclusion));
+ QVERIFY(testCompositionMode( 0, 0, 0, QPainter::CompositionMode_Exclusion));
+ QVERIFY(testCompositionMode(255, 0, 255, QPainter::CompositionMode_Exclusion));
+ QVERIFY(testCompositionMode(127, 127, 127, QPainter::CompositionMode_Exclusion));
+ QVERIFY(testCompositionMode( 63, 127, 127, QPainter::CompositionMode_Exclusion));
+ QVERIFY(testCompositionMode( 63, 63, 95, QPainter::CompositionMode_Exclusion));
+ QVERIFY(testCompositionMode(191, 191, 96, QPainter::CompositionMode_Exclusion));
+}
+
+void tst_QPainter::zeroOpacity()
+{
+ QImage source(1, 1, QImage::Format_ARGB32_Premultiplied);
+ source.fill(0xffffffff);
+
+ QImage target(1, 1, QImage::Format_RGB32);
+ target.fill(0xff000000);
+
+ QPainter p(&target);
+ p.setOpacity(0.0);
+ p.drawImage(0, 0, source);
+ p.end();
+
+ QCOMPARE(target.pixel(0, 0), 0xff000000);
+}
+
+void tst_QPainter::clippingBug()
+{
+ QImage img(32, 32, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+
+ QImage expected = img;
+ QPainter p(&expected);
+ p.fillRect(1, 1, 30, 30, Qt::red);
+ p.end();
+
+ QPainterPath path;
+ path.addRect(1, 1, 30, 30);
+ path.addRect(1, 1, 30, 30);
+ path.addRect(1, 1, 30, 30);
+
+ p.begin(&img);
+ p.setClipPath(path);
+ p.fillRect(0, 0, 32, 32, Qt::red);
+ p.end();
+
+ QCOMPARE(img, expected);
+}
+
+void tst_QPainter::emptyClip()
+{
+ QImage img(64, 64, QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&img);
+ p.setRenderHints(QPainter::Antialiasing);
+ p.setClipRect(0, 32, 64, 0);
+ p.fillRect(0, 0, 64, 64, Qt::white);
+
+ QPainterPath path;
+ path.lineTo(64, 0);
+ path.lineTo(64, 64);
+ path.lineTo(40, 64);
+ path.lineTo(40, 80);
+ path.lineTo(0, 80);
+
+ p.fillPath(path, Qt::green);
+}
+
+void tst_QPainter::drawImage_1x1()
+{
+ QImage source(1, 1, QImage::Format_ARGB32_Premultiplied);
+ source.fill(0xffffffff);
+
+ QImage img(32, 32, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0xff000000);
+ QPainter p(&img);
+ p.drawImage(QRectF(0.9, 0.9, 32, 32), source);
+ p.end();
+
+ QImage expected = img;
+ expected.fill(0xff000000);
+ p.begin(&expected);
+ p.fillRect(1, 1, 31, 31, Qt::white);
+ p.end();
+
+ QCOMPARE(img, expected);
+}
+
+void tst_QPainter::taskQT4444_dontOverflowDashOffset()
+{
+ QPainter p;
+
+ QPen pen;
+ pen.setWidth(2);
+ pen.setStyle(Qt::DashDotLine);
+
+ QPointF point[4];
+ point[0] = QPointF(182.50868749707968,347.78457234212630);
+ point[1] = QPointF(182.50868749707968,107.22501998401277);
+ point[2] = QPointF(182.50868749707968,107.22501998401277);
+ point[3] = QPointF(520.46600762283651,107.22501998401277);
+
+ QImage crashImage(QSize(1000, 120), QImage::Format_ARGB32_Premultiplied);
+ p.begin(&crashImage);
+ p.setPen(pen);
+ p.drawLines(point, 2);
+ p.end();
+
+ QVERIFY(true); // Don't crash
+}
+
+void tst_QPainter::painterBegin()
+{
+ QImage nullImage;
+ QImage indexed8Image(16, 16, QImage::Format_Indexed8);
+ QImage rgb32Image(16, 16, QImage::Format_RGB32);
+ QImage argb32Image(16, 16, QImage::Format_ARGB32_Premultiplied);
+
+ QPainter p;
+
+ // Painting on null image should fail.
+ QVERIFY(!p.begin(&nullImage));
+
+ // Check that the painter is not messed up by using it on another image.
+ QVERIFY(p.begin(&rgb32Image));
+ QVERIFY(p.end());
+
+ // If painting on indexed8 image fails, the painter state should still be OK.
+ if (p.begin(&indexed8Image))
+ QVERIFY(p.end());
+ QVERIFY(p.begin(&rgb32Image));
+ QVERIFY(p.end());
+
+ // Try opening a painter on the two different images.
+ QVERIFY(p.begin(&rgb32Image));
+ QVERIFY(!p.begin(&argb32Image));
+ QVERIFY(p.end());
+
+ // Try opening two painters on the same image.
+ QVERIFY(p.begin(&rgb32Image));
+ QPainter q;
+ QVERIFY(!q.begin(&rgb32Image));
+ QVERIFY(!q.end());
+ QVERIFY(p.end());
+
+ // Try ending an inactive painter.
+ QVERIFY(!p.end());
+}
+
+void tst_QPainter::setPenColor(QPainter& p)
+{
+ p.setPen(Qt::NoPen);
+
+ // Setting color, then style
+ // Should work even though the pen is "NoPen with color", temporarily.
+ QPen newPen(p.pen());
+ newPen.setColor(Qt::red);
+ QCOMPARE(p.pen().style(), newPen.style());
+ QCOMPARE(p.pen().style(), Qt::NoPen);
+ p.setPen(newPen);
+
+ QCOMPARE(p.pen().color().name(), QString("#ff0000"));
+
+ QPen newPen2(p.pen());
+ newPen2.setStyle(Qt::SolidLine);
+ p.setPen(newPen2);
+
+ QCOMPARE(p.pen().color().name(), QString("#ff0000"));
+}
+
+void tst_QPainter::setPenColorOnImage()
+{
+ QImage img(QSize(10, 10), QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&img);
+ setPenColor(p);
+}
+
+void tst_QPainter::setPenColorOnPixmap()
+{
+ QPixmap pix(10, 10);
+ QPainter p(&pix);
+ setPenColor(p);
+}
+
+class TestProxy : public QGraphicsProxyWidget
+{
+public:
+ TestProxy() : QGraphicsProxyWidget() {}
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ QGraphicsProxyWidget::paint(painter, option, widget);
+ deviceTransform = painter->deviceTransform();
+ }
+ QTransform deviceTransform;
+};
+
+class TestWidget : public QWidget
+{
+Q_OBJECT
+public:
+ TestWidget() : QWidget(), painted(false) {}
+ void paintEvent(QPaintEvent *)
+ {
+ QPainter p(this);
+ deviceTransform = p.deviceTransform();
+ worldTransform = p.worldTransform();
+ painted = true;
+ }
+ QTransform deviceTransform;
+ QTransform worldTransform;
+ bool painted;
+};
+
+void tst_QPainter::QTBUG5939_attachPainterPrivate()
+{
+ QWidget *w = new QWidget();
+ QGraphicsScene *scene = new QGraphicsScene();
+ QGraphicsView *view = new QGraphicsView(scene, w);
+ view->move(50 ,50);
+ TestProxy *proxy = new TestProxy();
+ TestWidget *widget = new TestWidget();
+ proxy->setWidget(widget);
+ scene->addItem(proxy);
+ proxy->rotate(45);
+ w->resize(scene->sceneRect().size().toSize());
+
+ w->show();
+ QTRY_VERIFY(widget->painted);
+
+ QVERIFY(widget->worldTransform.isIdentity());
+ QCOMPARE(widget->deviceTransform, proxy->deviceTransform);
+}
+
+void tst_QPainter::clipBoundingRect()
+{
+ QPixmap pix(500, 500);
+
+ QPainter p(&pix);
+
+ // Test a basic rectangle
+ p.setClipRect(100, 100, 200, 100);
+ QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200)));
+ p.setClipRect(120, 120, 20, 20, Qt::IntersectClip);
+ QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+
+ // Test a basic float rectangle
+ p.setClipRect(QRectF(100, 100, 200, 100));
+ QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200)));
+ p.setClipRect(QRectF(120, 120, 20, 20), Qt::IntersectClip);
+ QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+
+ // Test a basic path + region
+ QPainterPath path;
+ path.addRect(100, 100, 200, 100);
+ p.setClipPath(path);
+ QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200)));
+ p.setClipRegion(QRegion(120, 120, 20, 20), Qt::IntersectClip);
+ QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100)));
+
+ p.setClipRect(0, 0, 500, 500);
+ p.translate(250, 250);
+ for (int i=0; i<360; ++i) {
+ p.rotate(1);
+ p.setClipRect(-100, -100, 200, 200, Qt::IntersectClip);
+ }
+ QVERIFY(p.clipBoundingRect().contains(QRectF(-100, -100, 200, 200)));
+ QVERIFY(!p.clipBoundingRect().contains(QRectF(-250, -250, 500, 500)));
+
+}
+
+void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053()
+{
+#if !defined(Q_WS_MAC) || !defined(QT_MAC_USE_COCOA)
+ QSKIP("Only Mac/Cocoa supports sub pixel positions in raster engine currently", SkipAll);
+#endif
+ QFontMetricsF fm(qApp->font());
+
+ QImage baseLine(fm.width(QChar::fromLatin1('e')), fm.height(), QImage::Format_RGB32);
+ baseLine.fill(Qt::white);
+ {
+ QPainter p(&baseLine);
+ p.drawText(0, fm.ascent(), QString::fromLatin1("e"));
+ }
+
+ bool foundDifferentRasterization = false;
+ for (int i=1; i<12; ++i) {
+ QImage comparison(baseLine.size(), QImage::Format_RGB32);
+ comparison.fill(Qt::white);
+
+ {
+ QPainter p(&comparison);
+ p.drawText(QPointF(i / 12.0, fm.ascent()), QString::fromLatin1("e"));
+ }
+
+ if (comparison != baseLine) {
+ foundDifferentRasterization = true;
+ break;
+ }
+ }
+
+ QVERIFY(foundDifferentRasterization);
+}
+
+void tst_QPainter::drawPointScaled()
+{
+ QImage image(32, 32, QImage::Format_RGB32);
+ image.fill(0xffffffff);
+
+ QPainter p(&image);
+
+ p.scale(0.1, 0.1);
+
+ QPen pen;
+ pen.setWidth(1000);
+ pen.setColor(Qt::red);
+
+ p.setPen(pen);
+ p.drawPoint(0, 0);
+ p.end();
+
+ QCOMPARE(image.pixel(16, 16), 0xffff0000);
+}
+
+class GradientProducer : public QThread
+{
+protected:
+ void run();
+};
+
+void GradientProducer::run()
+{
+ QImage image(1, 1, QImage::Format_RGB32);
+ QPainter p(&image);
+
+ for (int i = 0; i < 1000; ++i) {
+ QLinearGradient g;
+ g.setColorAt(0, QColor(i % 256, 0, 0));
+ g.setColorAt(1, Qt::white);
+
+ p.fillRect(image.rect(), g);
+ }
+}
+
+void tst_QPainter::QTBUG14614_gradientCacheRaceCondition()
+{
+ const int threadCount = 16;
+ GradientProducer producers[threadCount];
+ for (int i = 0; i < threadCount; ++i)
+ producers[i].start();
+ for (int i = 0; i < threadCount; ++i)
+ producers[i].wait();
+}
+
+void tst_QPainter::drawTextOpacity()
+{
+ QImage image(32, 32, QImage::Format_RGB32);
+ image.fill(0xffffffff);
+
+ QPainter p(&image);
+ p.setPen(QColor("#6F6F6F"));
+ p.setOpacity(0.5);
+ p.drawText(5, 30, QLatin1String("Qt"));
+ p.end();
+
+ QImage copy = image;
+ image.fill(0xffffffff);
+
+ p.begin(&image);
+ p.setPen(QColor("#6F6F6F"));
+ p.drawLine(-10, -10, -1, -1);
+ p.setOpacity(0.5);
+ p.drawText(5, 30, QLatin1String("Qt"));
+ p.end();
+
+ QCOMPARE(image, copy);
+}
+
+void tst_QPainter::QTBUG17053_zeroDashPattern()
+{
+ QImage image(32, 32, QImage::Format_RGB32);
+ image.fill(0xffffffff);
+
+ QImage original = image;
+
+ QVector<qreal> pattern;
+ pattern << qreal(0) << qreal(0);
+
+ QPainter p(&image);
+ QPen pen(Qt::black, 2.0);
+ pen.setDashPattern(pattern);
+
+ p.setPen(pen);
+ p.drawLine(0, 0, image.width(), image.height());
+
+ QCOMPARE(image, original);
+}
+
+class TextDrawerThread : public QThread
+{
+public:
+ void run();
+ QImage rendering;
+};
+
+void TextDrawerThread::run()
+{
+ rendering = QImage(100, 100, QImage::Format_ARGB32_Premultiplied);
+ rendering.fill(0);
+ QPainter p(&rendering);
+ p.fillRect(10, 10, 100, 100, Qt::blue);
+ p.setPen(Qt::green);
+ p.drawText(20, 20, "some text");
+ p.end();
+}
+
+void tst_QPainter::drawTextOutsideGuiThread()
+{
+ if (!QFontDatabase::supportsThreadedFontRendering())
+ QSKIP("No threaded font rendering", SkipAll);
+
+ QImage referenceRendering(100, 100, QImage::Format_ARGB32_Premultiplied);
+ referenceRendering.fill(0);
+ QPainter p(&referenceRendering);
+ p.fillRect(10, 10, 100, 100, Qt::blue);
+ p.setPen(Qt::green);
+ p.drawText(20, 20, "some text");
+ p.end();
+
+ TextDrawerThread t;
+ t.start();
+ t.wait();
+
+ QCOMPARE(referenceRendering, t.rendering);
+}
+
+QTEST_MAIN(tst_QPainter)
+
+#include "tst_qpainter.moc"
diff --git a/tests/auto/gui/painting/qpainter/utils/createImages/createImages.pro b/tests/auto/gui/painting/qpainter/utils/createImages/createImages.pro
new file mode 100644
index 0000000000..ce2d341e92
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/utils/createImages/createImages.pro
@@ -0,0 +1,11 @@
+######################################################################
+# Automatically generated by qmake (1.02a) Thu Apr 18 18:56:53 2002
+######################################################################
+
+TEMPLATE = app
+CONFIG -= moc
+
+# Input
+SOURCES += main.cpp
+
+
diff --git a/tests/auto/gui/painting/qpainter/utils/createImages/main.cpp b/tests/auto/gui/painting/qpainter/utils/createImages/main.cpp
new file mode 100644
index 0000000000..418c385717
--- /dev/null
+++ b/tests/auto/gui/painting/qpainter/utils/createImages/main.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qapplication.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qbitmap.h>
+
+static QColor baseColor( int k, int intensity )
+{
+ int r = ( k & 1 ) * intensity;
+ int g = ( (k>>1) & 1 ) * intensity;
+ int b = ( (k>>2) & 1 ) * intensity;
+ return QColor( r, g, b );
+}
+
+static QPixmap createDestPixmap()
+{
+ const int colorbands = 3;
+ const int intensities = 4;
+ QPixmap pm( 32, colorbands*intensities*4 );
+ QPainter painter;
+ painter.begin( &pm );
+ for ( int i=0; i<colorbands; i++ ) {
+ for ( int j=0; j<intensities; j++ ) {
+ int intensity = 255 * (j+1) / intensities; // 25%, 50%, 75% and 100%
+ for ( int k=0; k<8; k++ ) {
+ QColor col = baseColor( k, intensity );
+ painter.setPen( QPen( col, 1 ) );
+ painter.setBrush( col );
+ painter.drawRect( k*4, j*4 + i*intensities*4, 4, 4 );
+ }
+ }
+ }
+ painter.end();
+ return pm;
+}
+
+static QBitmap createDestBitmap()
+{
+ // create a bitmap that looks like:
+ // (0 is color0 and 1 is color1)
+ // 00001111
+ // 00001111
+ // 00001111
+ // 00001111
+ // 00001111
+ // 00001111
+ // 00001111
+ // 00001111
+ QBitmap bm( 8, 8 );
+ QPainter painter;
+ painter.begin( &bm );
+ painter.setPen( QPen( Qt::color0, 4 ) );
+ painter.drawLine( 2, 0, 2, 8 );
+ painter.setPen( QPen( Qt::color1, 4 ) );
+ painter.drawLine( 6, 0, 6, 8 );
+ painter.end();
+ return bm;
+}
+
+static QBitmap createSrcBitmap( int size, int border )
+{
+ // create the source bitmap that looks like
+ // (for size=4 and border=2):
+ //
+ //
+ // 1111
+ // 1111
+ // 0000
+ // 0000
+ //
+ //
+ // If \a border is 0, the bitmap does not have a mask, otherwise the inner
+ // part is masked.
+ // \a size specifies the size of the inner (i.e. masked) part. It should be
+ // a multiple of 2.
+ int size2 = size/2;
+ int totalSize = 2 * ( size2 + border );
+ QBitmap bm( totalSize, totalSize );
+ QPainter painter;
+ painter.begin( &bm );
+ painter.setPen( QPen( Qt::color0, 1 ) );
+ painter.setBrush( Qt::color0 );
+ painter.drawRect( border, size2+border, size, size2 );
+ painter.setPen( QPen( Qt::color1, 1 ) );
+ painter.setBrush( Qt::color1 );
+ painter.drawRect( border, border, size, size2 );
+ painter.end();
+ if ( border > 0 ) {
+ QBitmap mask( totalSize, totalSize, TRUE );
+ QPainter painter;
+ painter.begin( &mask );
+ painter.setPen( QPen( Qt::color1, 1 ) );
+ painter.setBrush( Qt::color1 );
+ painter.drawRect( border, border, size, size );
+ painter.end();
+ bm.setMask( mask );
+ }
+ return bm;
+}
+
+
+int main( int argc, char **argv )
+{
+ QApplication a( argc, argv );
+
+ // input for tst_QPainter::drawLine_rop_bitmap()
+ {
+ QBitmap dst = createDestBitmap();
+ dst.save( "../../drawLine_rop_bitmap/dst.xbm", "XBM" );
+ }
+
+ // input for tst_QPainter::drawPixmap_rop_bitmap()
+ {
+ QBitmap dst = createDestBitmap();
+ QBitmap src1 = createSrcBitmap( 4, 2 );
+ QBitmap src2 = createSrcBitmap( 4, 0 );
+ dst.save( "../../drawPixmap_rop_bitmap/dst.xbm", "XBM" );
+ src1.save( "../../drawPixmap_rop_bitmap/src1.xbm", "XBM" );
+ src1.mask()->save( "../../drawPixmap_rop_bitmap/src1-mask.xbm", "XBM" );
+ src2.save( "../../drawPixmap_rop_bitmap/src2.xbm", "XBM" );
+ }
+
+ // input for tst_QPainter::drawPixmap_rop()
+ {
+ QPixmap dst1 = createDestPixmap();
+ QPixmap dst2 = createDestPixmap();
+ dst2.resize( 32, 32 );
+ QBitmap src1 = createSrcBitmap( 32, 0 );
+
+ QBitmap src_tmp = createSrcBitmap( 32, 0 ).xForm( QWMatrix( 1, 0, 0, -1, 0, 0 ) );
+ src_tmp.resize( 32, 48 );
+ QBitmap src2 = src_tmp.xForm( QWMatrix( 1, 0, 0, -1, 0, 0 ) );
+ QBitmap mask( 32, 48, TRUE );
+ {
+ QPainter painter;
+ painter.begin( &mask );
+ painter.setPen( QPen( Qt::color1, 1 ) );
+ painter.setBrush( Qt::color1 );
+ painter.drawRect( 0, 16, 32, 32 );
+ painter.end();
+ }
+ src2.setMask( mask );
+
+ QBitmap src3 = createSrcBitmap( 32, 0 ).xForm( QWMatrix( 1, 0, 0, -1, 0, 0 ) );
+
+ dst1.save( "../../drawPixmap_rop/dst1.png", "PNG" );
+ dst2.save( "../../drawPixmap_rop/dst2.png", "PNG" );
+ src1.save( "../../drawPixmap_rop/src1.xbm", "XBM" );
+ src2.save( "../../drawPixmap_rop/src2.xbm", "XBM" );
+ src2.mask()->save( "../../drawPixmap_rop/src2-mask.xbm", "XBM" );
+ src3.save( "../../drawPixmap_rop/src3.xbm", "XBM" );
+ }
+}
diff --git a/tests/auto/gui/painting/qpainterpath/.gitignore b/tests/auto/gui/painting/qpainterpath/.gitignore
new file mode 100644
index 0000000000..4e0e797989
--- /dev/null
+++ b/tests/auto/gui/painting/qpainterpath/.gitignore
@@ -0,0 +1,2 @@
+tst_qpainterpath
+data
diff --git a/tests/auto/gui/painting/qpainterpath/qpainterpath.pro b/tests/auto/gui/painting/qpainterpath/qpainterpath.pro
new file mode 100644
index 0000000000..9708222c99
--- /dev/null
+++ b/tests/auto/gui/painting/qpainterpath/qpainterpath.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+SOURCES += tst_qpainterpath.cpp
+
+
+
diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp
new file mode 100644
index 0000000000..33315adc06
--- /dev/null
+++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp
@@ -0,0 +1,1332 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qfile.h>
+#include <qpainterpath.h>
+#include <qpen.h>
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QPainterPath : public QObject
+{
+ Q_OBJECT
+
+public:
+
+private slots:
+ void getSetCheck();
+ void swap();
+
+ void contains_QPointF_data();
+ void contains_QPointF();
+
+ void contains_QRectF_data();
+ void contains_QRectF();
+
+ void intersects_QRectF_data();
+ void intersects_QRectF();
+
+ void testContainsAndIntersects_data();
+ void testContainsAndIntersects();
+
+ void testSimplified_data();
+ void testSimplified();
+
+ void testStroker_data();
+ void testStroker();
+
+ void currentPosition();
+
+ void testOperatorEquals();
+ void testOperatorEquals_fuzzy();
+ void testOperatorDatastream();
+
+ void testArcMoveTo_data();
+ void testArcMoveTo();
+ void setElementPositionAt();
+
+ void testOnPath_data();
+ void testOnPath();
+
+ void pointAtPercent_data();
+ void pointAtPercent();
+
+ void angleAtPercent();
+
+ void arcWinding_data();
+ void arcWinding();
+
+ void testToFillPolygons();
+
+ void testNaNandInfinites();
+
+ void closing();
+
+ void operators_data();
+ void operators();
+
+ void connectPathDuplicatePoint();
+ void connectPathMoveTo();
+
+ void translate();
+
+ void lineWithinBounds();
+};
+
+// Testing get/set functions
+void tst_QPainterPath::getSetCheck()
+{
+ QPainterPathStroker obj1;
+ // qreal QPainterPathStroker::width()
+ // void QPainterPathStroker::setWidth(qreal)
+ obj1.setWidth(0.0);
+ QCOMPARE(qreal(1.0), obj1.width()); // Pathstroker sets with to 1 if <= 0
+ obj1.setWidth(0.5);
+ QCOMPARE(qreal(0.5), obj1.width());
+ obj1.setWidth(1.1);
+ QCOMPARE(qreal(1.1), obj1.width());
+
+ // qreal QPainterPathStroker::miterLimit()
+ // void QPainterPathStroker::setMiterLimit(qreal)
+ obj1.setMiterLimit(0.0);
+ QCOMPARE(qreal(0.0), obj1.miterLimit());
+ obj1.setMiterLimit(1.1);
+ QCOMPARE(qreal(1.1), obj1.miterLimit());
+
+ // qreal QPainterPathStroker::curveThreshold()
+ // void QPainterPathStroker::setCurveThreshold(qreal)
+ obj1.setCurveThreshold(0.0);
+ QCOMPARE(qreal(0.0), obj1.curveThreshold());
+ obj1.setCurveThreshold(1.1);
+ QCOMPARE(qreal(1.1), obj1.curveThreshold());
+}
+
+void tst_QPainterPath::swap()
+{
+ QPainterPath p1;
+ p1.addRect( 0, 0,10,10);
+ QPainterPath p2;
+ p2.addRect(10,10,10,10);
+ p1.swap(p2);
+ QCOMPARE(p1.boundingRect().toRect(), QRect(10,10,10,10));
+ QCOMPARE(p2.boundingRect().toRect(), QRect( 0, 0,10,10));
+}
+
+Q_DECLARE_METATYPE(QPainterPath)
+Q_DECLARE_METATYPE(QPointF)
+Q_DECLARE_METATYPE(QRectF)
+
+void tst_QPainterPath::currentPosition()
+{
+ QPainterPath p;
+
+ QCOMPARE(p.currentPosition(), QPointF());
+
+ p.moveTo(100, 100);
+ QCOMPARE(p.currentPosition(), QPointF(100, 100));
+
+ p.lineTo(200, 200);
+ QCOMPARE(p.currentPosition(), QPointF(200, 200));
+
+ p.cubicTo(300, 200, 200, 300, 500, 500);
+ QCOMPARE(p.currentPosition(), QPointF(500, 500));
+}
+
+void tst_QPainterPath::contains_QPointF_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<QPointF>("pt");
+ QTest::addColumn<bool>("contained");
+
+ QPainterPath path;
+ path.addRect(0, 0, 100, 100);
+
+ // #####
+ // # #
+ // # #
+ // # #
+ // #####
+
+ QTest::newRow("[0,0] in [0,0,100,100]") << path << QPointF(0, 0) << true;
+
+ QTest::newRow("[99,0] in [0,0,100,100]") << path << QPointF(99, 0) << true;
+ QTest::newRow("[0,99] in [0,0,100,100]") << path << QPointF(0, 99) << true;
+ QTest::newRow("[99,99] in [0,0,100,100]") << path << QPointF(99, 99) << true;
+
+ QTest::newRow("[99.99,0] in [0,0,100,100]") << path << QPointF(99.99, 0) << true;
+ QTest::newRow("[0,99.99] in [0,0,100,100]") << path << QPointF(0, 99.99) << true;
+ QTest::newRow("[99.99,99.99] in [0,0,100,100]") << path << QPointF(99.99, 99.99) << true;
+
+ QTest::newRow("[0.01,0.01] in [0,0,100,100]") << path << QPointF(0.01, 0.01) << true;
+ QTest::newRow("[0,0.01] in [0,0,100,100]") << path << QPointF(0, 0.01) << true;
+ QTest::newRow("[0.01,0] in [0,0,100,100]") << path << QPointF(0.01, 0) << true;
+
+ QTest::newRow("[-0.01,-0.01] in [0,0,100,100]") << path << QPointF(-0.01, -0.01) << false;
+ QTest::newRow("[-0,-0.01] in [0,0,100,100]") << path << QPointF(0, -0.01) << false;
+ QTest::newRow("[-0.01,0] in [0,0,100,100]") << path << QPointF(-0.01, 0) << false;
+
+
+ QTest::newRow("[-10,0] in [0,0,100,100]") << path << QPointF(-10, 0) << false;
+ QTest::newRow("[100,0] in [0,0,100,100]") << path << QPointF(100, 0) << false;
+
+ QTest::newRow("[0,-10] in [0,0,100,100]") << path << QPointF(0, -10) << false;
+ QTest::newRow("[0,100] in [0,0,100,100]") << path << QPointF(0, 100) << false;
+
+ QTest::newRow("[100.1,0] in [0,0,100,100]") << path << QPointF(100.1, 0) << false;
+ QTest::newRow("[0,100.1] in [0,0,100,100]") << path << QPointF(0, 100.1) << false;
+
+ path.addRect(50, 50, 100, 100);
+
+ // #####
+ // # #
+ // # #####
+ // # # # #
+ // ##### #
+ // # #
+ // #####
+
+ QTest::newRow("[49,49] in 2 rects") << path << QPointF(49,49) << true;
+ QTest::newRow("[50,50] in 2 rects") << path << QPointF(50,50) << false;
+ QTest::newRow("[100,100] in 2 rects") << path << QPointF(100,100) << true;
+
+ path.setFillRule(Qt::WindingFill);
+ QTest::newRow("[50,50] in 2 rects (winding)") << path << QPointF(50,50) << true;
+
+ path.addEllipse(0, 0, 150, 150);
+
+ // #####
+ // ## ##
+ // # #####
+ // # # # #
+ // ##### #
+ // ## ##
+ // #####
+
+ QTest::newRow("[50,50] in complex (winding)") << path << QPointF(50, 50) << true;
+
+ path.setFillRule(Qt::OddEvenFill);
+ QTest::newRow("[50,50] in complex (windinf)") << path << QPointF(50, 50) << true;
+ QTest::newRow("[49,49] in complex") << path << QPointF(49,49) << false;
+ QTest::newRow("[100,100] in complex") << path << QPointF(49,49) << false;
+
+
+ // unclosed triangle
+ path = QPainterPath();
+ path.moveTo(100, 100);
+ path.lineTo(130, 70);
+ path.lineTo(150, 110);
+
+ QTest::newRow("[100,100] in triangle") << path << QPointF(100, 100) << true;
+ QTest::newRow("[140,100] in triangle") << path << QPointF(140, 100) << true;
+ QTest::newRow("[130,80] in triangle") << path << QPointF(130, 80) << true;
+
+ QTest::newRow("[110,80] in triangle") << path << QPointF(110, 80) << false;
+ QTest::newRow("[150,100] in triangle") << path << QPointF(150, 100) << false;
+ QTest::newRow("[120,110] in triangle") << path << QPointF(120, 110) << false;
+
+ QRectF base_rect(0, 0, 20, 20);
+
+ path = QPainterPath();
+ path.addEllipse(base_rect);
+
+ // not strictly precise, but good enougth to verify fair precision.
+ QPainterPath inside;
+ inside.addEllipse(base_rect.adjusted(5, 5, -5, -5));
+ QPolygonF inside_poly = inside.toFillPolygon();
+ for (int i=0; i<inside_poly.size(); ++i)
+ QTest::newRow("inside_ellipse") << path << inside_poly.at(i) << true;
+
+ QPainterPath outside;
+ outside.addEllipse(base_rect.adjusted(-5, -5, 5, 5));
+ QPolygonF outside_poly = outside.toFillPolygon();
+ for (int i=0; i<outside_poly.size(); ++i)
+ QTest::newRow("outside_ellipse") << path << outside_poly.at(i) << false;
+
+ path = QPainterPath();
+ base_rect = QRectF(50, 50, 200, 200);
+ path.addEllipse(base_rect);
+ path.setFillRule(Qt::WindingFill);
+
+ QTest::newRow("topleft outside ellipse") << path << base_rect.topLeft() << false;
+ QTest::newRow("topright outside ellipse") << path << base_rect.topRight() << false;
+ QTest::newRow("bottomright outside ellipse") << path << base_rect.bottomRight() << false;
+ QTest::newRow("bottomleft outside ellipse") << path << base_rect.bottomLeft() << false;
+
+ // Test horizontal curve segment
+ path = QPainterPath();
+ path.moveTo(100, 100);
+ path.cubicTo(120, 100, 180, 100, 200, 100);
+ path.lineTo(150, 200);
+ path.closeSubpath();
+
+ QTest::newRow("horizontal cubic, out left") << path << QPointF(0, 100) << false;
+ QTest::newRow("horizontal cubic, out right") << path << QPointF(300, 100) <<false;
+ QTest::newRow("horizontal cubic, in mid") << path << QPointF(150, 100) << true;
+
+ path = QPainterPath();
+ path.addEllipse(QRectF(-5000.0, -5000.0, 1500000.0, 1500000.0));
+ QTest::newRow("huge ellipse, qreal=float crash") << path << QPointF(1100000.35, 1098000.2) << true;
+
+}
+
+void tst_QPainterPath::contains_QPointF()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(QPointF, pt);
+ QFETCH(bool, contained);
+
+ QCOMPARE(path.contains(pt), contained);
+}
+
+void tst_QPainterPath::contains_QRectF_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<QRectF>("rect");
+ QTest::addColumn<bool>("contained");
+
+ QPainterPath path;
+ path.addRect(0, 0, 100, 100);
+
+ QTest::newRow("same rect") << path << QRectF(0.1, 0.1, 99, 99) << true; // ###
+ QTest::newRow("outside") << path << QRectF(-1, -1, 100, 100) << false;
+ QTest::newRow("covers") << path << QRectF(-1, -1, 102, 102) << false;
+ QTest::newRow("left") << path << QRectF(-10, 50, 5, 5) << false;
+ QTest::newRow("top") << path << QRectF(50, -10, 5, 5) << false;
+ QTest::newRow("right") << path << QRectF(110, 50, 5, 5) << false;
+ QTest::newRow("bottom") << path << QRectF(50, 110, 5, 5) << false;
+
+ path.addRect(50, 50, 100, 100);
+
+ QTest::newRow("r1 top") << path << QRectF(0.1, 0.1, 99, 49) << true;
+ QTest::newRow("r1 left") << path << QRectF(0.1, 0.1, 49, 99) << true;
+ QTest::newRow("r2 right") << path << QRectF(100.01, 50.1, 49, 99) << true;
+ QTest::newRow("r2 bottom") << path << QRectF(50.1, 100.1, 99, 49) << true;
+ QTest::newRow("inside 2 rects") << path << QRectF(51, 51, 48, 48) << false;
+ QTest::newRow("topRight 2 rects") << path << QRectF(100, 0, 49, 49) << false;
+ QTest::newRow("bottomLeft 2 rects") << path << QRectF(0, 100, 49, 49) << false;
+
+ path.setFillRule(Qt::WindingFill);
+ QTest::newRow("inside 2 rects (winding)") << path << QRectF(51, 51, 48, 48) << true;
+
+ path.addEllipse(0, 0, 150, 150);
+ QTest::newRow("topRight 2 rects") << path << QRectF(100, 25, 24, 24) << true;
+ QTest::newRow("bottomLeft 2 rects") << path << QRectF(25, 100, 24, 24) << true;
+
+ path.setFillRule(Qt::OddEvenFill);
+ QTest::newRow("inside 2 rects") << path << QRectF(50, 50, 49, 49) << false;
+}
+
+void tst_QPainterPath::contains_QRectF()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(QRectF, rect);
+ QFETCH(bool, contained);
+
+ QCOMPARE(path.contains(rect), contained);
+}
+
+static inline QPainterPath rectPath(qreal x, qreal y, qreal w, qreal h)
+{
+ QPainterPath path;
+ path.addRect(x, y, w, h);
+ path.closeSubpath();
+ return path;
+}
+
+static inline QPainterPath ellipsePath(qreal x, qreal y, qreal w, qreal h)
+{
+ QPainterPath path;
+ path.addEllipse(x, y, w, h);
+ path.closeSubpath();
+ return path;
+}
+
+static inline QPainterPath linePath(qreal x1, qreal y1, qreal x2, qreal y2)
+{
+ QPainterPath path;
+ path.moveTo(x1, y1);
+ path.lineTo(x2, y2);
+ return path;
+}
+
+void tst_QPainterPath::intersects_QRectF_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<QRectF>("rect");
+ QTest::addColumn<bool>("intersects");
+
+ QPainterPath path;
+ path.addRect(0, 0, 100, 100);
+
+ QTest::newRow("same rect") << path << QRectF(0.1, 0.1, 99, 99) << true; // ###
+ QTest::newRow("outside") << path << QRectF(-1, -1, 100, 100) << true;
+ QTest::newRow("covers") << path << QRectF(-1, -1, 102, 102) << true;
+ QTest::newRow("left") << path << QRectF(-10, 50, 5, 5) << false;
+ QTest::newRow("top") << path << QRectF(50, -10, 5, 5) << false;
+ QTest::newRow("right") << path << QRectF(110, 50, 5, 5) << false;
+ QTest::newRow("bottom") << path << QRectF(50, 110, 5, 5) << false;
+
+ path.addRect(50, 50, 100, 100);
+
+ QTest::newRow("r1 top") << path << QRectF(0.1, 0.1, 99, 49) << true;
+ QTest::newRow("r1 left") << path << QRectF(0.1, 0.1, 49, 99) << true;
+ QTest::newRow("r2 right") << path << QRectF(100.01, 50.1, 49, 99) << true;
+ QTest::newRow("r2 bottom") << path << QRectF(50.1, 100.1, 99, 49) << true;
+ QTest::newRow("inside 2 rects") << path << QRectF(51, 51, 48, 48) << false;
+
+ path.setFillRule(Qt::WindingFill);
+ QTest::newRow("inside 2 rects (winding)") << path << QRectF(51, 51, 48, 48) << true;
+
+ path.addEllipse(0, 0, 150, 150);
+ QTest::newRow("topRight 2 rects") << path << QRectF(100, 25, 24, 24) << true;
+ QTest::newRow("bottomLeft 2 rects") << path << QRectF(25, 100, 24, 24) << true;
+
+ QTest::newRow("horizontal line") << linePath(0, 0, 10, 0) << QRectF(1, -1, 2, 2) << true;
+ QTest::newRow("vertical line") << linePath(0, 0, 0, 10) << QRectF(-1, 1, 2, 2) << true;
+
+ path = QPainterPath();
+ path.addEllipse(QRectF(-5000.0, -5000.0, 1500000.0, 1500000.0));
+ QTest::newRow("huge ellipse, qreal=float crash") << path << QRectF(1100000.35, 1098000.2, 1500000.0, 1500000.0) << true;
+}
+
+void tst_QPainterPath::intersects_QRectF()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(QRectF, rect);
+ QFETCH(bool, intersects);
+
+ QCOMPARE(path.intersects(rect), intersects);
+}
+
+
+void tst_QPainterPath::testContainsAndIntersects_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<QPainterPath>("candidate");
+ QTest::addColumn<bool>("contained");
+ QTest::addColumn<bool>("intersects");
+
+ QTest::newRow("rect vs small ellipse (upper left)") << rectPath(0, 0, 100, 100) << ellipsePath(0, 0, 50, 50) << false << true;
+ QTest::newRow("rect vs small ellipse (upper right)") << rectPath(0, 0, 100, 100) << ellipsePath(50, 0, 50, 50) << false << true;
+ QTest::newRow("rect vs small ellipse (lower right)") << rectPath(0, 0, 100, 100) << ellipsePath(50, 50, 50, 50) << false << true;
+ QTest::newRow("rect vs small ellipse (lower left)") << rectPath(0, 0, 100, 100) << ellipsePath(0, 50, 50, 50) << false << true;
+ QTest::newRow("rect vs small ellipse (centered)") << rectPath(0, 0, 100, 100) << ellipsePath(25, 25, 50, 50) << true << true;
+ QTest::newRow("rect vs equal ellipse") << rectPath(0, 0, 100, 100) << ellipsePath(0, 0, 100, 100) << false << true;
+ QTest::newRow("rect vs big ellipse") << rectPath(0, 0, 100, 100) << ellipsePath(-10, -10, 120, 120) << false << true;
+
+ QPainterPath twoEllipses = ellipsePath(0, 0, 100, 100).united(ellipsePath(200, 0, 100, 100));
+
+ QTest::newRow("rect vs two small ellipses") << rectPath(0, 0, 100, 100) << ellipsePath(25, 25, 50, 50).united(ellipsePath(225, 25, 50, 50)) << false << true;
+ QTest::newRow("rect vs two equal ellipses") << rectPath(0, 0, 100, 100) << twoEllipses << false << true;
+
+ QTest::newRow("rect vs self") << rectPath(0, 0, 100, 100) << rectPath(0, 0, 100, 100) << false << true;
+ QTest::newRow("ellipse vs self") << ellipsePath(0, 0, 100, 100) << ellipsePath(0, 0, 100, 100) << false << true;
+
+ QPainterPath twoRects = rectPath(0, 0, 100, 100).united(rectPath(200, 0, 100, 100));
+ QTest::newRow("two rects vs small ellipse (upper left)") << twoRects << ellipsePath(0, 0, 50, 50) << false << true;
+ QTest::newRow("two rects vs small ellipse (upper right)") << twoRects << ellipsePath(50, 0, 50, 50) << false << true;
+ QTest::newRow("two rects vs small ellipse (lower right)") << twoRects << ellipsePath(50, 50, 50, 50) << false << true;
+ QTest::newRow("two rects vs small ellipse (lower left)") << twoRects << ellipsePath(0, 50, 50, 50) << false << true;
+ QTest::newRow("two rects vs small ellipse (centered)") << twoRects << ellipsePath(25, 25, 50, 50) << true << true;
+ QTest::newRow("two rects vs equal ellipse") << twoRects << ellipsePath(0, 0, 100, 100) << false << true;
+ QTest::newRow("two rects vs big ellipse") << twoRects << ellipsePath(-10, -10, 120, 120) << false << true;
+
+ QTest::newRow("two rects vs two small ellipses") << twoRects << ellipsePath(25, 25, 50, 50).united(ellipsePath(225, 25, 50, 50)) << true << true;
+ QTest::newRow("two rects vs two equal ellipses") << twoRects << ellipsePath(0, 0, 100, 100).united(ellipsePath(200, 0, 100, 100)) << false << true;
+
+ QTest::newRow("two rects vs self") << twoRects << twoRects << false << true;
+ QTest::newRow("two ellipses vs self") << twoEllipses << twoEllipses << false << true;
+
+ QPainterPath windingRect = rectPath(0, 0, 100, 100);
+ windingRect.addRect(25, 25, 100, 50);
+ windingRect.setFillRule(Qt::WindingFill);
+
+ QTest::newRow("rect with winding rule vs tall rect") << windingRect << rectPath(40, 20, 20, 60) << true << true;
+ QTest::newRow("rect with winding rule vs self") << windingRect << windingRect << false << true;
+
+ QPainterPath thickFrame = rectPath(0, 0, 100, 100).subtracted(rectPath(25, 25, 50, 50));
+ QPainterPath thinFrame = rectPath(10, 10, 80, 80).subtracted(rectPath(15, 15, 70, 70));
+
+ QTest::newRow("thin frame in thick frame") << thickFrame << thinFrame << true << true;
+ QTest::newRow("rect in thick frame") << thickFrame << rectPath(40, 40, 20, 20) << false << false;
+ QTest::newRow("rect in thin frame") << thinFrame << rectPath(40, 40, 20, 20) << false << false;
+
+ QPainterPath ellipses;
+ ellipses.addEllipse(0, 0, 10, 10);
+ ellipses.addEllipse(4, 4, 2, 2);
+ ellipses.setFillRule(Qt::WindingFill);
+
+ // the definition of QPainterPath::intersects() and contains() is fill-area based,
+ QTest::newRow("line in rect") << rectPath(0, 0, 100, 100) << linePath(10, 10, 90, 90) << true << true;
+ QTest::newRow("horizontal line in rect") << rectPath(0, 0, 100, 100) << linePath(10, 50, 90, 50) << true << true;
+ QTest::newRow("vertical line in rect") << rectPath(0, 0, 100, 100) << linePath(50, 10, 50, 90) << true << true;
+
+ QTest::newRow("line through rect") << rectPath(0, 0, 100, 100) << linePath(-10, -10, 110, 110) << false << true;
+ QTest::newRow("line through rect 2") << rectPath(0, 0, 100, 100) << linePath(-10, 0, 110, 100) << false << true;
+ QTest::newRow("line through rect 3") << rectPath(0, 0, 100, 100) << linePath(5, 10, 110, 100) << false << true;
+ QTest::newRow("line through rect 4") << rectPath(0, 0, 100, 100) << linePath(-10, 0, 90, 90) << false << true;
+
+ QTest::newRow("horizontal line through rect") << rectPath(0, 0, 100, 100) << linePath(-10, 50, 110, 50) << false << true;
+ QTest::newRow("vertical line through rect") << rectPath(0, 0, 100, 100) << linePath(50, -10, 50, 110) << false << true;
+
+ QTest::newRow("line vs line") << linePath(0, 0, 10, 10) << linePath(10, 0, 0, 10) << false << true;
+
+ QTest::newRow("line in rect with hole") << rectPath(0, 0, 10, 10).subtracted(rectPath(2, 2, 6, 6)) << linePath(4, 4, 6, 6) << false << false;
+ QTest::newRow("line in ellipse") << ellipses << linePath(3, 5, 7, 5) << false << true;
+ QTest::newRow("line in ellipse 2") << ellipses << linePath(4.5, 5, 5.5, 5) << true << true;
+
+ QTest::newRow("winding ellipse") << ellipses << ellipsePath(4, 4, 2, 2) << false << true;
+ QTest::newRow("winding ellipse 2") << ellipses << ellipsePath(4.5, 4.5, 1, 1) << true << true;
+ ellipses.setFillRule(Qt::OddEvenFill);
+ QTest::newRow("odd even ellipse") << ellipses << ellipsePath(4, 4, 2, 2) << false << true;
+ QTest::newRow("odd even ellipse 2") << ellipses << ellipsePath(4.5, 4.5, 1, 1) << false << false;
+}
+
+void tst_QPainterPath::testContainsAndIntersects()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(QPainterPath, candidate);
+ QFETCH(bool, contained);
+ QFETCH(bool, intersects);
+
+ QCOMPARE(path.intersects(candidate), intersects);
+ QCOMPARE(path.contains(candidate), contained);
+}
+
+void tst_QPainterPath::testSimplified_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<int>("elements");
+
+ QTest::newRow("rect") << rectPath(0, 0, 10, 10) << 5;
+
+ QPainterPath twoRects = rectPath(0, 0, 10, 10);
+ twoRects.addPath(rectPath(5, 0, 10, 10));
+ QTest::newRow("two rects (odd)") << twoRects << 10;
+
+ twoRects.setFillRule(Qt::WindingFill);
+ QTest::newRow("two rects (winding)") << twoRects << 5;
+
+ QPainterPath threeSteps = rectPath(0, 0, 10, 10);
+ threeSteps.addPath(rectPath(0, 10, 20, 10));
+ threeSteps.addPath(rectPath(0, 20, 30, 10));
+
+ QTest::newRow("three rects (steps)") << threeSteps << 9;
+}
+
+void tst_QPainterPath::testSimplified()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(int, elements);
+
+ QPainterPath simplified = path.simplified();
+
+ QCOMPARE(simplified.elementCount(), elements);
+
+ QVERIFY(simplified.subtracted(path).isEmpty());
+ QVERIFY(path.subtracted(simplified).isEmpty());
+}
+
+void tst_QPainterPath::testStroker_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<QPen>("pen");
+ QTest::addColumn<QPainterPath>("stroke");
+
+ QTest::newRow("line 1") << linePath(2, 2, 10, 2) << QPen(Qt::black, 2, Qt::SolidLine, Qt::FlatCap) << rectPath(2, 1, 8, 2);
+ QTest::newRow("line 2") << linePath(2, 2, 10, 2) << QPen(Qt::black, 2, Qt::SolidLine, Qt::SquareCap) << rectPath(1, 1, 10, 2);
+
+ QTest::newRow("rect") << rectPath(1, 1, 8, 8) << QPen(Qt::black, 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin) << rectPath(0, 0, 10, 10).subtracted(rectPath(2, 2, 6, 6));
+
+ QTest::newRow("dotted line") << linePath(0, 0, 10, 0) << QPen(Qt::black, 2, Qt::DotLine) << rectPath(-1, -1, 4, 2).united(rectPath(5, -1, 4, 2));
+}
+
+void tst_QPainterPath::testStroker()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(QPen, pen);
+ QFETCH(QPainterPath, stroke);
+
+ QPainterPathStroker stroker;
+ stroker.setWidth(pen.widthF());
+ stroker.setCapStyle(pen.capStyle());
+ stroker.setJoinStyle(pen.joinStyle());
+ stroker.setMiterLimit(pen.miterLimit());
+ stroker.setDashPattern(pen.style());
+ stroker.setDashOffset(pen.dashOffset());
+
+ QPainterPath result = stroker.createStroke(path);
+
+ // check if stroke == result
+ QVERIFY(result.subtracted(stroke).isEmpty());
+ QVERIFY(stroke.subtracted(result).isEmpty());
+}
+
+void tst_QPainterPath::testOperatorEquals()
+{
+ QPainterPath empty1;
+ QPainterPath empty2;
+ QVERIFY(empty1 == empty2);
+
+ QPainterPath rect1;
+ rect1.addRect(100, 100, 100, 100);
+ QVERIFY(rect1 == rect1);
+ QVERIFY(rect1 != empty1);
+
+ QPainterPath rect2;
+ rect2.addRect(100, 100, 100, 100);
+ QVERIFY(rect1 == rect2);
+
+ rect2.setFillRule(Qt::WindingFill);
+ QVERIFY(rect1 != rect2);
+
+ QPainterPath ellipse1;
+ ellipse1.addEllipse(50, 50, 100, 100);
+ QVERIFY(rect1 != ellipse1);
+
+ QPainterPath ellipse2;
+ ellipse2.addEllipse(50, 50, 100, 100);
+ QVERIFY(ellipse1 == ellipse2);
+}
+
+void tst_QPainterPath::testOperatorEquals_fuzzy()
+{
+ // if operator== returns true for two paths it should
+ // also return true when the same transform is applied to both paths
+ {
+ QRectF a(100, 100, 100, 50);
+ QRectF b = a.translated(1e-14, 1e-14);
+
+ QPainterPath pa;
+ pa.addRect(a);
+ QPainterPath pb;
+ pb.addRect(b);
+
+ QVERIFY(pa == pb);
+
+ QTransform transform;
+ transform.translate(-100, -100);
+
+ QVERIFY(transform.map(pa) == transform.map(pb));
+ }
+
+ // higher tolerance for error when path's bounding rect is big
+ {
+ QRectF a(1, 1, 1e6, 0.5e6);
+ QRectF b = a.translated(1e-7, 1e-7);
+
+ QPainterPath pa;
+ pa.addRect(a);
+ QPainterPath pb;
+ pb.addRect(b);
+
+ QVERIFY(pa == pb);
+
+ QTransform transform;
+ transform.translate(-1, -1);
+
+ QVERIFY(transform.map(pa) == transform.map(pb));
+ }
+
+ // operator== should return true for a path that has
+ // been transformed and then inverse transformed
+ {
+ QPainterPath a;
+ a.addRect(0, 0, 100, 100);
+
+ QTransform transform;
+ transform.translate(100, 20);
+ transform.scale(1.5, 1.5);
+
+ QPainterPath b = transform.inverted().map(transform.map(a));
+
+ QVERIFY(a == b);
+ }
+
+ {
+ QPainterPath a;
+ a.lineTo(10, 0);
+ a.lineTo(10, 10);
+ a.lineTo(0, 10);
+
+ QPainterPath b;
+ b.lineTo(10, 0);
+ b.moveTo(10, 10);
+ b.lineTo(0, 10);
+
+ QVERIFY(a != b);
+ }
+}
+
+void tst_QPainterPath::testOperatorDatastream()
+{
+ QPainterPath path;
+ path.addEllipse(0, 0, 100, 100);
+ path.addRect(0, 0, 100, 100);
+ path.setFillRule(Qt::WindingFill);
+
+ // Write out
+ {
+ QFile data("data");
+ bool ok = data.open(QFile::WriteOnly);
+ QVERIFY(ok);
+ QDataStream stream(&data);
+ stream << path;
+ }
+
+ QPainterPath other;
+ // Read in
+ {
+ QFile data("data");
+ bool ok = data.open(QFile::ReadOnly);
+ QVERIFY(ok);
+ QDataStream stream(&data);
+ stream >> other;
+ }
+
+ QVERIFY(other == path);
+}
+
+void tst_QPainterPath::closing()
+{
+ // lineto's
+ {
+ QPainterPath triangle(QPoint(100, 100));
+
+ triangle.lineTo(200, 100);
+ triangle.lineTo(200, 200);
+ QCOMPARE(triangle.elementCount(), 3);
+
+ triangle.closeSubpath();
+ QCOMPARE(triangle.elementCount(), 4);
+ QCOMPARE(triangle.elementAt(3).type, QPainterPath::LineToElement);
+
+ triangle.moveTo(300, 300);
+ QCOMPARE(triangle.elementCount(), 5);
+ QCOMPARE(triangle.elementAt(4).type, QPainterPath::MoveToElement);
+
+ triangle.lineTo(400, 300);
+ triangle.lineTo(400, 400);
+ QCOMPARE(triangle.elementCount(), 7);
+
+ triangle.closeSubpath();
+ QCOMPARE(triangle.elementCount(), 8);
+
+ // this will should trigger implicit moveto...
+ triangle.lineTo(600, 300);
+ QCOMPARE(triangle.elementCount(), 10);
+ QCOMPARE(triangle.elementAt(8).type, QPainterPath::MoveToElement);
+ QCOMPARE(triangle.elementAt(9).type, QPainterPath::LineToElement);
+
+ triangle.lineTo(600, 700);
+ QCOMPARE(triangle.elementCount(), 11);
+ }
+
+ // curveto's
+ {
+ QPainterPath curves(QPoint(100, 100));
+
+ curves.cubicTo(200, 100, 100, 200, 200, 200);
+ QCOMPARE(curves.elementCount(), 4);
+
+ curves.closeSubpath();
+ QCOMPARE(curves.elementCount(), 5);
+ QCOMPARE(curves.elementAt(4).type, QPainterPath::LineToElement);
+
+ curves.moveTo(300, 300);
+ QCOMPARE(curves.elementCount(), 6);
+ QCOMPARE(curves.elementAt(5).type, QPainterPath::MoveToElement);
+
+ curves.cubicTo(400, 300, 300, 400, 400, 400);
+ QCOMPARE(curves.elementCount(), 9);
+
+ curves.closeSubpath();
+ QCOMPARE(curves.elementCount(), 10);
+
+ // should trigger implicit moveto..
+ curves.cubicTo(100, 800, 800, 100, 800, 800);
+ QCOMPARE(curves.elementCount(), 14);
+ QCOMPARE(curves.elementAt(10).type, QPainterPath::MoveToElement);
+ QCOMPARE(curves.elementAt(11).type, QPainterPath::CurveToElement);
+ }
+
+ {
+ QPainterPath rects;
+ rects.addRect(100, 100, 100, 100);
+
+ QCOMPARE(rects.elementCount(), 5);
+ QCOMPARE(rects.elementAt(0).type, QPainterPath::MoveToElement);
+ QCOMPARE(rects.elementAt(4).type, QPainterPath::LineToElement);
+
+ rects.addRect(300, 100, 100,100);
+ QCOMPARE(rects.elementCount(), 10);
+ QCOMPARE(rects.elementAt(5).type, QPainterPath::MoveToElement);
+ QCOMPARE(rects.elementAt(9).type, QPainterPath::LineToElement);
+
+ rects.lineTo(0, 0);
+ QCOMPARE(rects.elementCount(), 12);
+ QCOMPARE(rects.elementAt(10).type, QPainterPath::MoveToElement);
+ QCOMPARE(rects.elementAt(11).type, QPainterPath::LineToElement);
+ }
+
+ {
+ QPainterPath ellipses;
+ ellipses.addEllipse(100, 100, 100, 100);
+
+ QCOMPARE(ellipses.elementCount(), 13);
+ QCOMPARE(ellipses.elementAt(0).type, QPainterPath::MoveToElement);
+ QCOMPARE(ellipses.elementAt(10).type, QPainterPath::CurveToElement);
+
+ ellipses.addEllipse(300, 100, 100,100);
+ QCOMPARE(ellipses.elementCount(), 26);
+ QCOMPARE(ellipses.elementAt(13).type, QPainterPath::MoveToElement);
+ QCOMPARE(ellipses.elementAt(23).type, QPainterPath::CurveToElement);
+
+ ellipses.lineTo(0, 0);
+ QCOMPARE(ellipses.elementCount(), 28);
+ QCOMPARE(ellipses.elementAt(26).type, QPainterPath::MoveToElement);
+ QCOMPARE(ellipses.elementAt(27).type, QPainterPath::LineToElement);
+ }
+
+ {
+ QPainterPath path;
+ path.moveTo(10, 10);
+ path.lineTo(40, 10);
+ path.lineTo(25, 20);
+ path.lineTo(10 + 1e-13, 10 + 1e-13);
+ QCOMPARE(path.elementCount(), 4);
+ path.closeSubpath();
+ QCOMPARE(path.elementCount(), 4);
+ }
+}
+
+void tst_QPainterPath::testArcMoveTo_data()
+{
+ QTest::addColumn<QRectF>("rect");
+ QTest::addColumn<qreal>("angle");
+
+ QList<QRectF> rects;
+ rects << QRectF(100, 100, 100, 100)
+ << QRectF(100, 100, -100, 100)
+ << QRectF(100, 100, 100, -100)
+ << QRectF(100, 100, -100, -100);
+
+ for (int domain=0; domain<rects.size(); ++domain) {
+ for (int i=-360; i<=360; ++i) {
+ QTest::newRow("test") << rects.at(domain) << (qreal) i;
+ }
+
+ // test low angles
+ QTest::newRow("test") << rects.at(domain) << (qreal) 1e-10;
+ QTest::newRow("test") << rects.at(domain) << (qreal)-1e-10;
+ }
+}
+
+void tst_QPainterPath::operators_data()
+{
+ QTest::addColumn<QPainterPath>("test");
+ QTest::addColumn<QPainterPath>("expected");
+
+ QPainterPath a;
+ QPainterPath b;
+ a.addRect(0, 0, 100, 100);
+ b.addRect(50, 50, 100, 100);
+
+ QTest::newRow("a & b") << (a & b) << a.intersected(b);
+ QTest::newRow("a | b") << (a | b) << a.united(b);
+ QTest::newRow("a + b") << (a + b) << a.united(b);
+ QTest::newRow("a - b") << (a - b) << a.subtracted(b);
+
+ QPainterPath c = a;
+ QTest::newRow("a &= b") << (a &= b) << a.intersected(b);
+ c = a;
+ QTest::newRow("a |= b") << (a |= b) << a.united(b);
+ c = a;
+ QTest::newRow("a += b") << (a += b) << a.united(b);
+ c = a;
+ QTest::newRow("a -= b") << (a -= b) << a.subtracted(b);
+}
+
+void tst_QPainterPath::operators()
+{
+ QFETCH(QPainterPath, test);
+ QFETCH(QPainterPath, expected);
+
+ QCOMPARE(test, expected);
+}
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#define ANGLE(t) ((t) * 2 * M_PI / 360.0)
+
+
+static inline bool pathFuzzyCompare(double p1, double p2)
+{
+ return qAbs(p1 - p2) < 0.001;
+}
+
+
+static inline bool pathFuzzyCompare(float p1, float p2)
+{
+ return qAbs(p1 - p2) < 0.001;
+}
+
+
+void tst_QPainterPath::testArcMoveTo()
+{
+ QFETCH(QRectF, rect);
+ QFETCH(qreal, angle);
+
+ QPainterPath path;
+ path.arcMoveTo(rect, angle);
+ path.arcTo(rect, angle, 30);
+ path.arcTo(rect, angle + 30, 30);
+
+ QPointF pos = path.elementAt(0);
+
+ QVERIFY((path.elementCount()-1) % 3 == 0);
+
+ qreal x_radius = rect.width() / 2.0;
+ qreal y_radius = rect.height() / 2.0;
+
+ QPointF shouldBe = rect.center()
+ + QPointF(x_radius * cos(ANGLE(angle)), -y_radius * sin(ANGLE(angle)));
+
+ qreal iw = 1 / rect.width();
+ qreal ih = 1 / rect.height();
+
+ QVERIFY(pathFuzzyCompare(pos.x() * iw, shouldBe.x() * iw));
+ QVERIFY(pathFuzzyCompare(pos.y() * ih, shouldBe.y() * ih));
+}
+
+void tst_QPainterPath::testOnPath_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<qreal>("start");
+ QTest::addColumn<qreal>("middle");
+ QTest::addColumn<qreal>("end");
+
+ QPainterPath path = QPainterPath(QPointF(153, 199));
+ path.cubicTo(QPointF(147, 61), QPointF(414, 18),
+ QPointF(355, 201));
+
+ QTest::newRow("First case") << path
+ << qreal(93.0)
+ << qreal(4.0)
+ << qreal(252.13);
+
+ path = QPainterPath(QPointF(328, 197));
+ path.cubicTo(QPointF(150, 50), QPointF(401, 50),
+ QPointF(225, 197));
+ QTest::newRow("Second case") << path
+ << qreal(140.0)
+ << qreal(0.0)
+ << qreal(220.0);
+
+ path = QPainterPath(QPointF(328, 197));
+ path.cubicTo(QPointF(101 , 153), QPointF(596, 151),
+ QPointF(353, 197));
+ QTest::newRow("Third case") << path
+ << qreal(169.0)
+ << qreal(0.22)
+ << qreal(191.0);
+
+ path = QPainterPath(QPointF(153, 199));
+ path.cubicTo(QPointF(59, 53), QPointF(597, 218),
+ QPointF(355, 201));
+ QTest::newRow("Fourth case") << path
+ << qreal(122.0)
+ << qreal(348.0)
+ << qreal(175.0);
+
+}
+
+#define SIGN(x) ((x < 0)?-1:1)
+void tst_QPainterPath::testOnPath()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(qreal, start);
+ QFETCH(qreal, middle);
+ QFETCH(qreal, end);
+
+ int signStart = SIGN(start);
+ int signMid = SIGN(middle);
+ int signEnd = SIGN(end);
+
+ static const qreal diff = 3;
+
+ qreal angle = path.angleAtPercent(0);
+ QCOMPARE(SIGN(angle), signStart);
+ QVERIFY(qAbs(angle-start) < diff);
+
+ angle = path.angleAtPercent(0.5);
+ QCOMPARE(SIGN(angle), signMid);
+ QVERIFY(qAbs(angle-middle) < diff);
+
+ angle = path.angleAtPercent(1);
+ QCOMPARE(SIGN(angle), signEnd);
+ QVERIFY(qAbs(angle-end) < diff);
+}
+
+void tst_QPainterPath::pointAtPercent_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<qreal>("percent");
+ QTest::addColumn<QPointF>("point");
+
+ QPainterPath path;
+ path.lineTo(100, 0);
+
+ QTest::newRow("Case 1") << path << qreal(0.2) << QPointF(20, 0);
+ QTest::newRow("Case 2") << path << qreal(0.5) << QPointF(50, 0);
+ QTest::newRow("Case 3") << path << qreal(0.0) << QPointF(0, 0);
+ QTest::newRow("Case 4") << path << qreal(1.0) << QPointF(100, 0);
+
+ path = QPainterPath();
+ path.lineTo(0, 100);
+
+ QTest::newRow("Case 5") << path << qreal(0.2) << QPointF(0, 20);
+ QTest::newRow("Case 6") << path << qreal(0.5) << QPointF(0, 50);
+ QTest::newRow("Case 7") << path << qreal(0.0) << QPointF(0, 0);
+ QTest::newRow("Case 8") << path << qreal(1.0) << QPointF(0, 100);
+
+ path.lineTo(300, 100);
+
+ QTest::newRow("Case 9") << path << qreal(0.25) << QPointF(0, 100);
+ QTest::newRow("Case 10") << path << qreal(0.5) << QPointF(100, 100);
+ QTest::newRow("Case 11") << path << qreal(0.75) << QPointF(200, 100);
+
+ path = QPainterPath();
+ path.addEllipse(0, 0, 100, 100);
+
+ QTest::newRow("Case 12") << path << qreal(0.0) << QPointF(100, 50);
+ QTest::newRow("Case 13") << path << qreal(0.25) << QPointF(50, 100);
+ QTest::newRow("Case 14") << path << qreal(0.5) << QPointF(0, 50);
+ QTest::newRow("Case 15") << path << qreal(0.75) << QPointF(50, 0);
+ QTest::newRow("Case 16") << path << qreal(1.0) << QPointF(100, 50);
+
+ path = QPainterPath();
+ QRectF rect(241, 273, 185, 228);
+ path.addEllipse(rect);
+ QTest::newRow("Case 17") << path << qreal(1.0) << QPointF(rect.right(), qreal(0.5) * (rect.top() + rect.bottom()));
+
+ path = QPainterPath();
+ path.moveTo(100, 100);
+ QTest::newRow("Case 18") << path << qreal(0.0) << QPointF(100, 100);
+ QTest::newRow("Case 19") << path << qreal(1.0) << QPointF(100, 100);
+}
+
+void tst_QPainterPath::pointAtPercent()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(qreal, percent);
+ QFETCH(QPointF, point);
+
+ QPointF result = path.pointAtPercent(percent);
+ QVERIFY(pathFuzzyCompare(point.x() , result.x()));
+ QVERIFY(pathFuzzyCompare(point.y() , result.y()));
+}
+
+void tst_QPainterPath::setElementPositionAt()
+{
+ QPainterPath path(QPointF(42., 42.));
+ QCOMPARE(path.elementCount(), 1);
+ QVERIFY(path.elementAt(0).type == QPainterPath::MoveToElement);
+ QCOMPARE(path.elementAt(0).x, qreal(42.));
+ QCOMPARE(path.elementAt(0).y, qreal(42.));
+
+ QPainterPath copy = path;
+ copy.setElementPositionAt(0, qreal(0), qreal(0));
+ QCOMPARE(copy.elementCount(), 1);
+ QVERIFY(copy.elementAt(0).type == QPainterPath::MoveToElement);
+ QCOMPARE(copy.elementAt(0).x, qreal(0));
+ QCOMPARE(copy.elementAt(0).y, qreal(0));
+
+ QCOMPARE(path.elementCount(), 1);
+ QVERIFY(path.elementAt(0).type == QPainterPath::MoveToElement);
+ QCOMPARE(path.elementAt(0).x, qreal(42.));
+ QCOMPARE(path.elementAt(0).y, qreal(42.));
+}
+
+void tst_QPainterPath::angleAtPercent()
+{
+ for (int angle = 0; angle < 360; ++angle) {
+ QLineF line = QLineF::fromPolar(100, angle);
+ QPainterPath path;
+ path.moveTo(line.p1());
+ path.lineTo(line.p2());
+
+ QCOMPARE(path.angleAtPercent(0.5), line.angle());
+ }
+}
+
+void tst_QPainterPath::arcWinding_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ QTest::addColumn<QPointF>("point");
+ QTest::addColumn<bool>("inside");
+
+ QPainterPath a;
+ a.addEllipse(0, 0, 100, 100);
+ a.addRect(50, 50, 100, 100);
+
+ QTest::newRow("Case A (oddeven)") << a << QPointF(55, 55) << false;
+ a.setFillRule(Qt::WindingFill);
+ QTest::newRow("Case A (winding)") << a << QPointF(55, 55) << true;
+
+ QPainterPath b;
+ b.arcMoveTo(0, 0, 100, 100, 10);
+ b.arcTo(0, 0, 100, 100, 10, 360);
+ b.addRect(50, 50, 100, 100);
+
+ QTest::newRow("Case B (oddeven)") << b << QPointF(55, 55) << false;
+ b.setFillRule(Qt::WindingFill);
+ QTest::newRow("Case B (winding)") << b << QPointF(55, 55) << false;
+
+ QPainterPath c;
+ c.arcMoveTo(0, 0, 100, 100, 0);
+ c.arcTo(0, 0, 100, 100, 0, 360);
+ c.addRect(50, 50, 100, 100);
+
+ QTest::newRow("Case C (oddeven)") << c << QPointF(55, 55) << false;
+ c.setFillRule(Qt::WindingFill);
+ QTest::newRow("Case C (winding)") << c << QPointF(55, 55) << false;
+
+ QPainterPath d;
+ d.arcMoveTo(0, 0, 100, 100, 10);
+ d.arcTo(0, 0, 100, 100, 10, -360);
+ d.addRect(50, 50, 100, 100);
+
+ QTest::newRow("Case D (oddeven)") << d << QPointF(55, 55) << false;
+ d.setFillRule(Qt::WindingFill);
+ QTest::newRow("Case D (winding)") << d << QPointF(55, 55) << true;
+
+ QPainterPath e;
+ e.arcMoveTo(0, 0, 100, 100, 0);
+ e.arcTo(0, 0, 100, 100, 0, -360);
+ e.addRect(50, 50, 100, 100);
+
+ QTest::newRow("Case E (oddeven)") << e << QPointF(55, 55) << false;
+ e.setFillRule(Qt::WindingFill);
+ QTest::newRow("Case E (winding)") << e << QPointF(55, 55) << true;
+}
+
+void tst_QPainterPath::arcWinding()
+{
+ QFETCH(QPainterPath, path);
+ QFETCH(QPointF, point);
+ QFETCH(bool, inside);
+
+ QCOMPARE(path.contains(point), inside);
+}
+
+void tst_QPainterPath::testToFillPolygons()
+{
+ QPainterPath path;
+ path.lineTo(QPointF(0, 50));
+ path.lineTo(QPointF(50, 50));
+
+ path.moveTo(QPointF(70, 50));
+ path.lineTo(QPointF(70, 100));
+ path.lineTo(QPointF(40, 100));
+
+ const QList<QPolygonF> polygons = path.toFillPolygons();
+ QCOMPARE(polygons.size(), 2);
+ QCOMPARE(polygons.first().count(QPointF(70, 50)), 0);
+}
+
+void tst_QPainterPath::testNaNandInfinites()
+{
+ QPainterPath path1;
+ QPainterPath path2 = path1;
+
+ QPointF p1 = QPointF(qSNaN(), 1);
+ QPointF p2 = QPointF(qQNaN(), 1);
+ QPointF p3 = QPointF(qQNaN(), 1);
+ QPointF pInf = QPointF(qInf(), 1);
+
+ // all these operations with NaN/Inf should be ignored
+ // can't test operator>> reliably, as we can't create a path with NaN to << later
+
+ path1.moveTo(p1);
+ path1.moveTo(qSNaN(), qQNaN());
+ path1.moveTo(pInf);
+
+ path1.lineTo(p1);
+ path1.lineTo(qSNaN(), qQNaN());
+ path1.lineTo(pInf);
+
+ path1.cubicTo(p1, p2, p3);
+ path1.cubicTo(p1, QPointF(1, 1), QPointF(2, 2));
+ path1.cubicTo(pInf, QPointF(10, 10), QPointF(5, 1));
+
+ path1.quadTo(p1, p2);
+ path1.quadTo(QPointF(1, 1), p3);
+ path1.quadTo(QPointF(1, 1), pInf);
+
+ path1.arcTo(QRectF(p1, p2), 5, 5);
+ path1.arcTo(QRectF(pInf, QPointF(1, 1)), 5, 5);
+
+ path1.addRect(QRectF(p1, p2));
+ path1.addRect(QRectF(pInf, QPointF(1, 1)));
+
+ path1.addEllipse(QRectF(p1, p2));
+ path1.addEllipse(QRectF(pInf, QPointF(1, 1)));
+
+ QCOMPARE(path1, path2);
+
+ path1.lineTo(QPointF(1, 1));
+ QVERIFY(path1 != path2);
+}
+
+void tst_QPainterPath::connectPathDuplicatePoint()
+{
+ QPainterPath a;
+ a.moveTo(10, 10);
+ a.lineTo(20, 20);
+
+ QPainterPath b;
+ b.moveTo(20, 20);
+ b.lineTo(30, 10);
+
+ a.connectPath(b);
+
+ QPainterPath c;
+ c.moveTo(10, 10);
+ c.lineTo(20, 20);
+ c.lineTo(30, 10);
+
+ QCOMPARE(c, a);
+}
+
+void tst_QPainterPath::connectPathMoveTo()
+{
+ QPainterPath path1;
+ QPainterPath path2;
+ QPainterPath path3;
+ QPainterPath path4;
+
+ path1.moveTo(1,1);
+
+ path2.moveTo(4,4);
+ path2.lineTo(5,6);
+ path2.lineTo(6,7);
+
+ path3.connectPath(path2);
+
+ path4.lineTo(5,5);
+
+ path1.connectPath(path2);
+
+ QVERIFY(path1.elementAt(0).type == QPainterPath::MoveToElement);
+ QVERIFY(path2.elementAt(0).type == QPainterPath::MoveToElement);
+ QVERIFY(path3.elementAt(0).type == QPainterPath::MoveToElement);
+ QVERIFY(path4.elementAt(0).type == QPainterPath::MoveToElement);
+}
+
+void tst_QPainterPath::translate()
+{
+ QPainterPath path;
+
+ // Path with no elements.
+ QCOMPARE(path.currentPosition(), QPointF());
+ path.translate(50.5, 50.5);
+ QCOMPARE(path.currentPosition(), QPointF());
+ QCOMPARE(path.translated(50.5, 50.5).currentPosition(), QPointF());
+
+ // path.isEmpty(), but we have one MoveTo element that should be translated.
+ path.moveTo(50, 50);
+ QCOMPARE(path.currentPosition(), QPointF(50, 50));
+ path.translate(99.9, 99.9);
+ QCOMPARE(path.currentPosition(), QPointF(149.9, 149.9));
+ path.translate(-99.9, -99.9);
+ QCOMPARE(path.currentPosition(), QPointF(50, 50));
+ QCOMPARE(path.translated(-50, -50).currentPosition(), QPointF(0, 0));
+
+ // Complex path.
+ QRegion shape(100, 100, 300, 200, QRegion::Ellipse);
+ shape -= QRect(225, 175, 50, 50);
+ QPainterPath complexPath;
+ complexPath.addRegion(shape);
+ QVector<QPointF> untranslatedElements;
+ for (int i = 0; i < complexPath.elementCount(); ++i)
+ untranslatedElements.append(QPointF(complexPath.elementAt(i)));
+
+ const QPainterPath untranslatedComplexPath(complexPath);
+ const QPointF offset(100, 100);
+ complexPath.translate(offset);
+
+ for (int i = 0; i < complexPath.elementCount(); ++i)
+ QCOMPARE(QPointF(complexPath.elementAt(i)) - offset, untranslatedElements.at(i));
+
+ QCOMPARE(complexPath.translated(-offset), untranslatedComplexPath);
+}
+
+
+void tst_QPainterPath::lineWithinBounds()
+{
+ const int iteration_count = 3;
+ volatile const qreal yVal = 0.5;
+ QPointF a(0.0, yVal);
+ QPointF b(1000.0, yVal);
+ QPointF c(2000.0, yVal);
+ QPointF d(3000.0, yVal);
+ QPainterPath path;
+ path.moveTo(QPointF(0, yVal));
+ path.cubicTo(QPointF(1000.0, yVal), QPointF(2000.0, yVal), QPointF(3000.0, yVal));
+ for(int i=0; i<=iteration_count; i++) {
+ qreal actual = path.pointAtPercent(qreal(i) / iteration_count).y();
+ QVERIFY(actual == yVal); // don't use QCOMPARE, don't want fuzzy comparison
+ }
+}
+
+
+QTEST_APPLESS_MAIN(tst_QPainterPath)
+
+#include "tst_qpainterpath.moc"
diff --git a/tests/auto/gui/painting/qpainterpathstroker/.gitignore b/tests/auto/gui/painting/qpainterpathstroker/.gitignore
new file mode 100644
index 0000000000..e171c5da31
--- /dev/null
+++ b/tests/auto/gui/painting/qpainterpathstroker/.gitignore
@@ -0,0 +1 @@
+tst_qpainterpathstroker
diff --git a/tests/auto/gui/painting/qpainterpathstroker/qpainterpathstroker.pro b/tests/auto/gui/painting/qpainterpathstroker/qpainterpathstroker.pro
new file mode 100644
index 0000000000..b6f62a2eee
--- /dev/null
+++ b/tests/auto/gui/painting/qpainterpathstroker/qpainterpathstroker.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+SOURCES += tst_qpainterpathstroker.cpp
+
+
+
diff --git a/tests/auto/gui/painting/qpainterpathstroker/tst_qpainterpathstroker.cpp b/tests/auto/gui/painting/qpainterpathstroker/tst_qpainterpathstroker.cpp
new file mode 100644
index 0000000000..288263e5d7
--- /dev/null
+++ b/tests/auto/gui/painting/qpainterpathstroker/tst_qpainterpathstroker.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qfile.h>
+#include <QPainterPathStroker>
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QPainterPathStroker : public QObject
+{
+ Q_OBJECT
+
+public:
+
+private slots:
+ void strokeEmptyPath();
+};
+
+void tst_QPainterPathStroker::strokeEmptyPath()
+{
+ QPainterPath path;
+ path.moveTo(10, 10);
+ path.lineTo(10, 10);
+ QPainterPathStroker stroker;
+ QCOMPARE(stroker.createStroke(path), path);
+}
+
+QTEST_APPLESS_MAIN(tst_QPainterPathStroker)
+
+#include "tst_qpainterpathstroker.moc"
diff --git a/tests/auto/gui/painting/qpathclipper/.gitignore b/tests/auto/gui/painting/qpathclipper/.gitignore
new file mode 100644
index 0000000000..a689eef0f6
--- /dev/null
+++ b/tests/auto/gui/painting/qpathclipper/.gitignore
@@ -0,0 +1 @@
+tst_qpathclipper
diff --git a/tests/auto/gui/painting/qpathclipper/pathcompare.h b/tests/auto/gui/painting/qpathclipper/pathcompare.h
new file mode 100644
index 0000000000..d80c189665
--- /dev/null
+++ b/tests/auto/gui/painting/qpathclipper/pathcompare.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef PATHCOMPARE_H
+#define PATHCOMPARE_H
+
+#include <qmath.h>
+
+namespace QPathCompare {
+
+static const int precision = 8;
+static const qreal epsilon = qPow(0.1, precision);
+
+static inline bool fuzzyIsZero(qreal x, qreal relative)
+{
+ if (qAbs(relative) < epsilon)
+ return qAbs(x) < epsilon;
+ else
+ return qAbs(x / relative) < epsilon;
+}
+
+static bool fuzzyCompare(const QPointF &a, const QPointF &b)
+{
+ const QPointF delta = a - b;
+
+ const qreal x = qMax(qAbs(a.x()), qAbs(b.x()));
+ const qreal y = qMax(qAbs(a.y()), qAbs(b.y()));
+
+ return fuzzyIsZero(delta.x(), x) && fuzzyIsZero(delta.y(), y);
+}
+
+static bool isClosed(const QPainterPath &path)
+{
+ if (path.elementCount() == 0)
+ return false;
+
+ QPointF first = path.elementAt(0);
+ QPointF last = path.elementAt(path.elementCount() - 1);
+
+ return fuzzyCompare(first, last);
+}
+
+// rotation and direction independent path comparison
+// allows paths to be shifted or reversed relative to each other
+static bool comparePaths(const QPainterPath &actual, const QPainterPath &expected)
+{
+ const int endActual = isClosed(actual) ? actual.elementCount() - 1 : actual.elementCount();
+ const int endExpected = isClosed(expected) ? expected.elementCount() - 1 : expected.elementCount();
+
+ if (endActual != endExpected)
+ return false;
+
+ for (int i = 0; i < endActual; ++i) {
+ int k = 0;
+ for (k = 0; k < endActual; ++k) {
+ int i1 = k;
+ int i2 = (i + k) % endActual;
+
+ QPointF a = actual.elementAt(i1);
+ QPointF b = expected.elementAt(i2);
+
+ if (!fuzzyCompare(a, b))
+ break;
+ }
+
+ if (k == endActual)
+ return true;
+
+ for (k = 0; k < endActual; ++k) {
+ int i1 = k;
+ int i2 = (i + endActual - k) % endActual;
+
+ QPointF a = actual.elementAt(i1);
+ QPointF b = expected.elementAt(i2);
+
+ if (!fuzzyCompare(a, b))
+ break;
+ }
+
+ if (k == endActual)
+ return true;
+ }
+
+ return false;
+}
+
+}
+
+#endif
diff --git a/tests/auto/gui/painting/qpathclipper/paths.cpp b/tests/auto/gui/painting/qpathclipper/paths.cpp
new file mode 100644
index 0000000000..950c34614e
--- /dev/null
+++ b/tests/auto/gui/painting/qpathclipper/paths.cpp
@@ -0,0 +1,734 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "paths.h"
+
+QPainterPath Paths::rect()
+{
+ QPainterPath path;
+
+ path.moveTo(45.885571, 62.857143);
+ path.lineTo(154.11442, 62.857143);
+ path.cubicTo(162.1236, 62.857143,
+ 168.57142, 70.260744,
+ 168.57142, 79.457144);
+ path.lineTo(168.57142, 123.4);
+ path.cubicTo(168.57142, 132.5964,
+ 162.1236, 140,
+ 154.11442, 140);
+ path.lineTo(45.885571, 140);
+ path.cubicTo(37.876394, 140,
+ 31.428572, 132.5964,
+ 31.428572, 123.4);
+ path.lineTo(31.428572, 79.457144);
+ path.cubicTo(31.428572,70.260744,
+ 37.876394,62.857143,
+ 45.885571,62.857143);
+ path.closeSubpath();
+ return path;
+}
+
+QPainterPath Paths::rect6()
+{
+ QPainterPath path;
+
+ path.moveTo(45.885571, 62.857143);
+ path.lineTo(154.11442, 62.857143);
+ path.cubicTo(162.1236, 62.857143,
+ 168.57142, 70.260744,
+ 168.57142, 79.457144);
+ path.lineTo(168.57142, 123.4);
+ path.cubicTo(168.57142, 132.5964,
+ 162.1236, 140,
+ 154.11442, 140);
+ path.lineTo(45.885571, 140);
+ path.closeSubpath();
+ return path;
+}
+
+
+QPainterPath Paths::heart()
+{
+ QPainterPath path;
+ path.moveTo(263.41570, 235.14588);
+ path.cubicTo(197.17570,235.14588,
+ 143.41575,288.90587,
+ 143.41575,355.14588);
+ path.cubicTo(143.41575, 489.90139,
+ 279.34890, 525.23318,
+ 371.97820, 658.45392);
+ path.cubicTo(459.55244,526.05056,
+ 600.54070,485.59932,
+ 600.54070,355.14588);
+ path.cubicTo(600.54070,288.90588, 546.78080,235.14587, 480.54070,235.14588);
+ path.cubicTo(432.49280,235.14588, 391.13910,263.51631, 371.97820,304.33338);
+ path.cubicTo(352.81740,263.51630, 311.46370,235.14587, 263.41570,235.14588);
+ path.closeSubpath();
+ return path;
+}
+
+
+QPainterPath Paths::body()
+{
+ QPainterPath path;
+ path.moveTo(62.500000,15.531250);
+ path.cubicTo(48.633197,15.531250, 37.374999,26.789445, 37.375000,40.656250);
+ path.cubicTo(37.375000,54.523053, 48.633195,65.781252, 62.500000,65.781250);
+ path.cubicTo(76.366803,65.781250, 87.624998,54.523052, 87.625000,40.656250);
+ path.cubicTo(87.625000,26.789447, 76.366802,15.531250, 62.500000,15.531250);
+ path.closeSubpath();
+ path.moveTo(54.437500,65.812500);
+ path.cubicTo(35.184750,65.812499, 19.687500,81.341002, 19.687500,100.59375);
+ path.lineTo(19.687500,155.68750);
+ path.cubicTo(19.687501,167.50351, 25.539122,177.88308, 34.500000,184.15625);
+ path.lineTo(34.500000,254.03125);
+ path.cubicTo(34.499999,257.03306, 46.990615,259.43748, 62.500000,259.43750);
+ path.cubicTo(78.009381,259.43751, 90.468750,257.03307, 90.468750,254.03125);
+ path.lineTo(90.468750,184.15625);
+ path.cubicTo(99.429633,177.88307, 105.28125,167.50352, 105.28125,155.68750);
+ path.lineTo(105.28125,100.59375);
+ path.cubicTo(105.28125,81.341000, 89.784000,65.812500, 70.531250,65.812500);
+ path.lineTo(54.437500,65.812500);
+ path.closeSubpath();
+
+ return path;
+}
+
+
+QPainterPath Paths::mailbox()
+{
+ QPainterPath path;
+ path.moveTo(355.22951,136.82424);
+ path.lineTo(332.03629,112.56585);
+ path.lineTo(325.71086,57.501867);
+ path.cubicTo(325.71086,57.501867, 410.12308,19.428758, 427.45202,29.094560);
+ path.cubicTo(444.78096,38.760366, 443.62570,54.289660, 443.62570,54.289660);
+ path.lineTo(443.62570,100.11509);
+ path.lineTo(355.22951,136.82424);
+ path.closeSubpath();
+
+ return path;
+}
+
+
+QPainterPath Paths::deer()
+{
+ QPainterPath path;
+
+ path.moveTo(39.88,31.658);
+ path.cubicTo(35.632,31.658, 31.398,31.004, 27.871,32.82);
+ path.cubicTo(25.015,34.29, 19.608,34.158, 16.297,34.158);
+ path.cubicTo(14.722,34.158, 17.755,37.718, 17.709,38.922);
+ path.cubicTo(17.578,42.396, 24.612,43.15, 26.755,44.058);
+ path.cubicTo(30.062,45.46, 28.682,47.701, 28.963,50.574);
+ path.cubicTo(29.715,58.243, 26.887,63.745, 24.182,70.589);
+ path.cubicTo(23.365,72.657, 21.772,75.56, 21.972,77.866);
+ path.cubicTo(22.333,82.029, 15.803,77.207, 13.894,76.535);
+ path.cubicTo(10.977,75.508, 5.507,74.071, 2.424,75.331);
+ path.cubicTo(-1.532,76.947, 0.076,80.491, 2.169,82.806);
+ path.cubicTo(6.17,87.234, 2.703,90.713, 3.895,95.363);
+ path.cubicTo(4.321,97.026, 11.682,104.683, 12.858,103.668);
+ path.cubicTo(16.706,100.347, 11.464,98.692, 10.105,96.164);
+ path.cubicTo(9.487,95.015, 8.616,83.742, 8.866,83.759);
+ path.cubicTo(10.018,83.837, 12.591,85.867, 13.671,86.392);
+ path.cubicTo(16.889,87.954, 20.066,89.63, 22.963,91.741);
+ path.cubicTo(29.156,94.47, 35.543,96.965, 42.102,98.676);
+ path.cubicTo(51.085,101.02, 59.407,102.003, 68.009,106.005);
+ path.cubicTo(72.92,108.289, 72.05,113.282, 75.744,117.004);
+ path.cubicTo(79.422,120.709, 84.733,123.053, 88.978,126.053);
+ path.cubicTo(92.402,128.473, 95.422,132.308, 97.334,135.998);
+ path.cubicTo(99.551,140.279, 99.071,146.004, 99.838,150.674);
+ path.cubicTo(100.369,153.91, 104.378,156.321, 106.302,158.859);
+ path.cubicTo(110.471,164.355, 109.86,155.112, 108.163,154.412);
+ path.cubicTo(104.97,153.094, 103.991,146.625, 103.812,143.439);
+ path.cubicTo(103.525,138.336, 105.568,134.331, 101.918,130.346);
+ path.cubicTo(95.104,122.907, 89.488,114.182, 94.711,103.742);
+ path.cubicTo(96.889,99.388, 91.191,95.497, 96.94,94.368);
+ path.cubicTo(99.551,93.856, 102.49,94.367, 104.326,92.034);
+ path.cubicTo(106.639,89.095, 105.063,85.343, 102.943,82.798);
+ path.cubicTo(102.686,82.417, 102.359,82.121, 101.962,81.909);
+ path.cubicTo(102.331,81.909, 101.923,86.98, 100.981,87.628);
+ path.cubicTo(98.868,89.082, 95.569,91.586, 92.88,91.672);
+ path.cubicTo(90.569,91.745, 86.738,89.184, 85.212,87.658);
+ path.cubicTo(84.092,86.538, 80.176,86.157, 78.598,85.83);
+ path.cubicTo(74.737,85.031, 71.741,84.326, 68.012,82.806);
+ path.cubicTo(63.318,80.893, 58.687,78.672, 54.555,75.71);
+ path.cubicTo(44.573,68.555, 42.755,56.146, 44.022,44.495);
+ path.cubicTo(44.295,41.987, 43.169,38.057, 44.617,35.915);
+ path.cubicTo(44.961,35.406, 46.52,35.553, 47.119,35.024);
+ path.cubicTo(47.882,34.35, 49.574,31.822, 49.878,30.792);
+ path.cubicTo(51.126,26.569, 44.36,32.002, 45.336,31.938);
+ path.cubicTo(43.861,32.036, 47.011,22.934, 47.191,22.574);
+ path.cubicTo(47.555,21.846, 52.489,13.123, 49.511,13.222);
+ path.cubicTo(47.643,13.284, 48.563,18.667, 46.354,18.227);
+ path.cubicTo(43.964,17.751, 40.522,11.396, 41.566,9.011);
+ path.cubicTo(43.4,4.819, 39.743,3.905, 39.214,7.564);
+ path.cubicTo(39.112,8.269, 40.893,13.438, 38.159,12.665);
+ path.cubicTo(35.335,11.866, 35.748,-0.125, 34.38,-8.0352391e-15);
+ path.cubicTo(31.991,0.219, 34.074,10.836, 33.361,12.176);
+ path.cubicTo(33.144,12.584, 29.68,8.66, 29.459,7.718);
+ path.cubicTo(28.48,3.558, 28.031,5.106, 26.87,7.752);
+ path.cubicTo(25.333,11.254, 37.159,17.423, 39.292,18.663);
+ path.cubicTo(40.993,19.651, 42.39,20.504, 42.973,22.48);
+ path.cubicTo(43.482,24.205, 44.098,26.568, 42.926,28.191);
+ path.cubicTo(42.092,29.346, 39.88,29.982, 39.88,31.658);
+ return path;
+}
+
+
+QPainterPath Paths::fire()
+{
+ QPainterPath path;
+
+ path.moveTo(362.83759,116.70426);
+ path.cubicTo(342.56574,131.59686, 300.71403,161.23127, 311.38454,218.12635);
+ path.cubicTo(322.05506,275.02144, 358.53432,301.66527, 328.90674,328.73285);
+ path.cubicTo(299.27916,355.80044, 251.48877,339.59410, 255.46042,288.61972);
+ path.cubicTo(258.22374,253.15368, 278.34141,205.10942, 278.34141,205.10942);
+ path.cubicTo(278.34141,205.10942, 234.02455,233.13427, 219.68939,254.01270);
+ path.cubicTo(205.35424,274.89113, 189.71452,330.07842, 208.58356,373.33974);
+ path.cubicTo(227.45261,416.60109, 316.46286,456.33444, 351.12048,514.32780);
+ path.cubicTo(374.10258,552.78425, 355.05815,613.59741, 310.80422,636.59310);
+ path.cubicTo(256.63287,664.74219, 299.16588,580.49238, 285.22551,523.86186);
+ path.cubicTo(273.46790,476.09839, 265.70022,445.12001, 188.03132,432.51681);
+ path.cubicTo(233.72591,465.34901, 242.16068,495.04075, 241.45928,524.11772);
+ path.cubicTo(240.78648,552.00862, 214.39595,634.57293, 177.39967,596.79021);
+ path.cubicTo(140.72642,559.33737, 214.27071,512.68654, 170.92945,471.62081);
+ path.cubicTo(174.73284,501.40284, 145.30515,514.98828, 131.55318,544.54392);
+ path.cubicTo(118.22673,573.18509, 123.55251,610.30651, 139.07596,645.41379);
+ path.cubicTo(181.14122,740.38745, 266.95518,726.23964, 208.75321,797.88229);
+ path.cubicTo(164.01134,852.95649, 162.90150,907.45084, 205.60384,970.81121);
+ path.cubicTo(240.06795,1021.9479, 371.11663,1060.7652, 432.20697,960.93460);
+ path.cubicTo(501.87852,820.00694, 357.14883,780.33174, 386.29974,732.84721);
+ path.cubicTo(405.70205,701.24238, 472.56601,668.86516, 501.09199,644.21233);
+ path.cubicTo(564.18184,587.55421, 561.84437,497.32621, 522.74229,471.25817);
+ path.cubicTo(530.19030,501.05022, 514.99952,542.79339, 483.67099,551.29691);
+ path.cubicTo(423.41173,567.65308, 458.18351,411.79373, 564.02075,393.61925);
+ path.cubicTo(530.91135,366.44998, 501.31413,367.33484, 454.91711,379.11707);
+ path.cubicTo(397.61736,393.57908, 407.64322,315.40944, 494.34643,262.67861);
+ path.cubicTo(549.19500,229.32101, 499.11573,147.63302, 491.66772,136.46100);
+ path.cubicTo(485.38713,213.93294, 435.43515,233.35601, 409.98053,235.72292);
+ path.cubicTo(375.27049,238.95043, 377.84554,214.33812, 396.75003,178.92950);
+ path.cubicTo(416.21172,142.47722, 448.15395,89.429942, 376.51366,44.060977);
+ path.cubicTo(388.13560,71.270572, 395.93673,94.012962, 362.83759,116.70426);
+ path.closeSubpath();
+ return path;
+}
+
+
+QPainterPath Paths::lips()
+{
+ QPainterPath path;
+
+ path.moveTo(177.02257,176.65905);
+ path.cubicTo(154.11895,176.65905, 136.56711,174.32266, 110.41800,155.61729);
+ path.cubicTo(83.894106,136.64382, 70.456540,123.78263, 44.264608,101.00195);
+ path.cubicTo(36.985036,94.670475, 11.607987,76.421189, 0.62503194,72.562763);
+ path.cubicTo(22.778258,60.937514, 46.738237,46.430325, 55.325084,40.325054);
+ path.cubicTo(79.128700,23.400628, 99.203004,0.53294656, 116.15033,0.61582047);
+ path.cubicTo(129.59137,0.68308215, 144.54744,18.524567, 177.02257,18.524567);
+ path.cubicTo(210.04060,18.524567, 224.45379,0.68308215, 237.89483,0.61582047);
+ path.cubicTo(254.84216,0.53294656, 274.91646,23.400628, 298.72008,40.325054);
+ path.cubicTo(307.30692,46.430325, 331.26690,60.937514, 353.42013,72.562763);
+ path.cubicTo(342.43717,76.421189, 317.06013,94.670475, 309.78055,101.00195);
+ path.cubicTo(283.58862,123.78263, 270.15105,136.64382, 243.62716,155.61729);
+ path.cubicTo(217.47805,174.32266, 199.38332,176.65905, 177.02257,176.65905);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::bezier1()
+{
+ QPainterPath path;
+ path.moveTo(50, 50);
+ path.cubicTo(100, 100,
+ 520, 90,
+ 400,400);
+ return path;
+}
+
+QPainterPath Paths::bezier2()
+{
+ QPainterPath path;
+ path.moveTo(200,200);
+ path.cubicTo(200,125, 500,100, 500,500);
+
+ return path;
+}
+
+QPainterPath Paths::random1()
+{
+ QPainterPath path;
+
+ path.moveTo(65.714286,91.428571);
+ path.lineTo(217.14286, 102.85714);
+ path.cubicTo(219.04762, 106.66666,
+ 220.95238, 110.47619,
+ 222.85714,114.28571);
+ path.cubicTo(231.2679, 131.10723,
+ 214.72525, 138.24185,
+ 211.42857,151.42857);
+ path.cubicTo(207.25902, 168.10676,
+ 213.24674, 175.8441,
+ 217.14286,191.42857);
+ path.cubicTo(221.088, 207.20915,
+ 201.21538,205.71429,
+ 188.57143,205.71429);
+ path.cubicTo(170.18303, 205.71429,
+ 161.42918, 197.50045,
+ 145.71429,185.71429);
+ path.cubicTo(113.93441, 161.87938,
+ 132.73699, 182.37652,
+ 137.14286, 200);
+ path.cubicTo(140.37884, 212.94392,
+ 128.50252, 217.16009,
+ 117.14286, 220);
+ path.cubicTo(98.323209, 224.70491,
+ 91.206108, 205.41767,
+ 82.857143, 194.28571);
+ path.cubicTo(77.307286, 186.8859,
+ 84.541768, 158.97578,
+ 85.714286, 154.28571);
+ path.cubicTo(87.843677, 145.76815,
+ 67.066253, 132.78054,
+ 60 , 125.71429);
+ path.cubicTo(54.074503, 119.78879,
+ 64.646395, 95.700137,
+ 65.714286, 91.428571);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::random2()
+{
+ QPainterPath path;
+
+ path.moveTo(314.28571,160);
+ path.cubicTo(434.28571,125.71429,
+ 505.71429,200,
+ 505.71429,200);
+ path.lineTo(454.28571, 305.71429);
+ path.lineTo(337.14286, 302.85714);
+ path.cubicTo(337.14286, 302.85714,
+ 308.57143, 340,
+ 337.14286, 302.85714);
+ path.cubicTo(365.71429, 265.71429,
+ 200, 420,
+ 300, 291.42857);
+ path.cubicTo(400, 162.85714,
+ 254.28571, 240,
+ 254.28571, 240);
+ path.cubicTo(254.28571,240,
+ 240,71.428571,
+ 288.57143,134.28571);
+ path.cubicTo(337.14286,197.14286,
+ 314.28571,162.85714,
+ 314.28571,160);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::bezier3()
+{
+ QPainterPath path;
+ path.moveTo(295, 217);
+ path.cubicTo(364, 57,
+ 377, 34,
+ 456, 222);
+ return path;
+}
+
+QPainterPath Paths::bezier4()
+{
+ QPainterPath path;
+ path.moveTo(200, 125);
+ path.cubicTo(200, 125,
+ 623, 126,
+ 623, 126);
+ return path;
+}
+
+QPainterPath Paths::heart2()
+{
+ QPainterPath path;
+ path.moveTo(263.41570, 235.14588);
+ path.cubicTo(197.17570,235.14588,
+ 143.41575,288.90587,
+ 143.41575,355.14588);
+ path.cubicTo(143.41575, 489.90139,
+ 279.34890, 525.23318,
+ 371.97820, 658.45392);
+ return path;
+}
+
+QPainterPath Paths::rect2()
+{
+ QPainterPath path;
+
+ path.addRect(80, 80, 100, 100);
+
+ return path;
+}
+
+
+QPainterPath Paths::rect3()
+{
+ QPainterPath path;
+
+ path.addRect(100, 40, 100, 100);
+
+ return path;
+}
+
+
+QPainterPath Paths::rect4()
+{
+ QPainterPath path;
+
+ path.addRect(100, 0, 200, 200);
+
+ path.addRect(120, 20, 80, 80);
+
+ return path;
+}
+
+QPainterPath Paths::simpleCurve()
+{
+ QPainterPath path;
+ path.moveTo(74, 160);
+ path.cubicTo( 74, 160,
+ 274, 406,
+ 425, 166);
+ path.cubicTo(577, -73,
+ 77, 160,
+ 74, 160);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::simpleCurve2()
+{
+ QPainterPath path;
+ path.moveTo(54, 140);
+ path.cubicTo( 54, 140,
+ 254, 386,
+ 405, 146);
+ path.cubicTo(557, -93,
+ 57, 140,
+ 54, 140);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::frame1()
+{
+ QPainterPath path;
+ path.moveTo(190.71429, 40.933613);
+ path.lineTo(683.57141, 40.933613);
+ path.cubicTo(697.42141, 40.933613,
+ 708.57141, 52.083613,
+ 708.57141, 65.933613);
+ path.lineTo(708.57141, 375.93361);
+ path.cubicTo(708.57141, 389.78361,
+ 697.42141, 400.93361,
+ 683.57141, 400.93361);
+ path.lineTo(190.71429, 400.93361);
+ path.cubicTo(176.86429, 400.93361,
+ 165.71429, 389.78361,
+ 165.71429,375.93361);
+ path.lineTo(165.71429, 65.933613);
+ path.cubicTo(165.71429,52.083613,
+ 176.86429,40.933613,
+ 190.71429,40.933613);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::frame2()
+{
+ QPainterPath path;
+ path.moveTo(55.114286, 103.79076);
+ path.lineTo(187.74288, 103.79076);
+ path.cubicTo(192.95048, 103.79076,
+ 197.14288, 107.88102,
+ 197.14288, 112.96176);
+ path.lineTo(197.14288, 131.76261);
+ path.cubicTo(197.14288, 136.84335,
+ 192.95048, 140.93361,
+ 187.74288, 140.93361);
+ path.lineTo(55.114286, 140.93361);
+ path.cubicTo(49.906687, 140.93361,
+ 45.714287, 136.84335,
+ 45.714287, 131.76261);
+ path.lineTo(45.714287, 112.96176);
+ path.cubicTo(45.714287, 107.88102,
+ 49.906687, 103.79076,
+ 55.114286, 103.79076);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::frame3()
+{
+ QPainterPath path;
+ path.moveTo(200,80.933609);
+ path.lineTo(682.85715,80.933609);
+ path.lineTo(682.85715,446.6479);
+ path.lineTo(200,446.6479);
+ path.lineTo(200,80.933609);
+ path.closeSubpath();
+ return path;
+}
+
+QPainterPath Paths::frame4()
+{
+ QPainterPath path;
+
+ path.moveTo(88.571434,206.64789);
+ path.lineTo(231.42858,206.64789);
+ path.lineTo(231.42858,246.64789);
+ path.lineTo(88.571434,246.64789);
+ path.lineTo(88.571434,206.64789);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::simpleCurve3()
+{
+ QPainterPath path;
+
+ path.moveTo(0, 0);
+ path.cubicTo(400,0,
+ 0,400,
+ 0,0);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::rect5()
+{
+ QPainterPath path;
+
+ path.addRect(0, 0, 200, 200);
+
+ return path;
+}
+
+QPainterPath Paths::triangle1()
+{
+ QPainterPath path;
+
+ path.moveTo(0, 0);
+ path.lineTo(60, 0);
+ path.lineTo(60, 60);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::triangle2()
+{
+ QPainterPath path;
+
+ path.moveTo(0, 120);
+ path.lineTo(60, 120);
+ path.lineTo(60, 60);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::node()
+{
+ QRectF m_rect;
+ m_rect.setWidth(150);
+ m_rect.setHeight(100);
+
+ QPainterPath shape;
+ shape.addRoundRect(m_rect, 25);
+
+ const int conWidth = 10;
+ const int xOffset = 7;
+
+ QRectF rect(xOffset,
+ conWidth + 20,
+ conWidth, conWidth);
+ shape.addEllipse(rect);
+ //shape.addRect(rect);
+
+ rect = QRectF(m_rect.right() - conWidth - xOffset,
+ conWidth + 20,
+ conWidth, conWidth);
+ shape.addEllipse(rect);
+ //shape.addRect(rect);
+ return shape;
+}
+
+QPainterPath Paths::interRect()
+{
+ QPainterPath path;
+ path.addRect(132, 42, 1, 1);
+ return path;
+}
+
+QPainterPath Paths::bezierFlower()
+{
+ QPainterPath path;
+ path.moveTo(0, 0);
+ path.cubicTo(0, 50, -25, 75, -50, 100);
+ path.closeSubpath();
+ path.moveTo(0, 0);
+ path.cubicTo(0, 50, 25, 75, 50, 100);
+ path.closeSubpath();
+
+ path.moveTo(0, 0);
+ path.cubicTo(0, -50, -25, -75, -50, -100);
+ path.closeSubpath();
+ path.moveTo(0, 0);
+ path.cubicTo(0, -50, 25, -75, 50, -100);
+ path.closeSubpath();
+
+ path.moveTo(0, 0);
+ path.cubicTo(-50, 0, -75, -25, -100, -50);
+ path.closeSubpath();
+ path.moveTo(0, 0);
+ path.cubicTo(-50, 0, -75, 25, -100, 50);
+ path.closeSubpath();
+
+ path.moveTo(0, 0);
+ path.cubicTo(50, 0, 75, -25, 100, -50);
+ path.closeSubpath();
+ path.moveTo(0, 0);
+ path.cubicTo(50, 0, 75, 25, 100, 50);
+ path.closeSubpath();
+
+ return path;
+}
+
+QPainterPath Paths::clover()
+{
+ QPainterPath path;
+ path.moveTo(50, 50);
+ path.lineTo(100, 25);
+ path.lineTo(100, 75);
+ path.lineTo(0, 25);
+ path.lineTo(0, 75);
+ path.lineTo(50, 50);
+ path.lineTo(75, 0);
+ path.lineTo(25, 0);
+ path.lineTo(75, 100);
+ path.lineTo(25, 100);
+ path.lineTo(50, 50);
+ return path;
+}
+
+QPainterPath Paths::ellipses()
+{
+ QPainterPath path;
+ path.addEllipse(0, 0, 100, 100);
+ path.addEllipse(0, 20, 100, 60);
+ path.addEllipse(0, 40, 100, 20);
+ return path;
+}
+
+QPainterPath Paths::windingFill()
+{
+ QPainterPath path;
+ path.addRect(0, 0, 100, 100);
+ path.addRect(50, 25, 100, 50);
+ path.setFillRule(Qt::WindingFill);
+ return path;
+}
+
+QPainterPath Paths::oddEvenFill()
+{
+ QPainterPath path;
+ path.addRect(0, 0, 100, 100);
+ path.moveTo(50, 25);
+ path.lineTo(50, 75);
+ path.lineTo(150, 75);
+ path.lineTo(150, 25);
+ path.lineTo(50, 25);
+ path.setFillRule(Qt::OddEvenFill);
+ return path;
+}
+
+QPainterPath Paths::squareWithHole()
+{
+ QPainterPath path;
+ path.addRect(0, 0, 100, 100);
+ path.addRect(30, 30, 40, 40);
+ return path;
+}
+
+QPainterPath Paths::circleWithHole()
+{
+ QPainterPath path;
+ path.addEllipse(0, 0, 100, 100);
+ path.addEllipse(30, 30, 40, 40);
+ return path;
+}
+
+QPainterPath Paths::bezierQuadrant()
+{
+ QPainterPath path;
+ int d = 1;
+ for (int i = 25; i <= 85; i += 10) {
+ path.moveTo(50, 100);
+ path.cubicTo(50, i, 50 + i* d / 2, 0, 50 + 50 * d, 0);
+ path.lineTo(50 + 50 * d, 100);
+ path.closeSubpath();
+ }
+
+ QMatrix m(2, 0,
+ 0, 2,
+ 0, 0);
+
+ return path;
+}
diff --git a/tests/auto/gui/painting/qpathclipper/paths.h b/tests/auto/gui/painting/qpathclipper/paths.h
new file mode 100644
index 0000000000..89ef785857
--- /dev/null
+++ b/tests/auto/gui/painting/qpathclipper/paths.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef PATHS_H
+#define PATHS_H
+
+#include <QPainterPath>
+
+namespace Paths
+{
+ QPainterPath rect();
+ QPainterPath heart();
+ QPainterPath body();
+ QPainterPath mailbox();
+ QPainterPath deer();
+ QPainterPath fire();
+ QPainterPath lips();
+
+ QPainterPath bezier1();
+ QPainterPath bezier2();
+ QPainterPath bezier3();
+ QPainterPath bezier4();
+
+ QPainterPath random1();
+ QPainterPath random2();
+
+ QPainterPath heart2();
+ QPainterPath rect2();
+ QPainterPath rect3();
+ QPainterPath rect4();
+ QPainterPath rect5();
+ QPainterPath rect6();
+
+ QPainterPath simpleCurve();
+ QPainterPath simpleCurve2();
+ QPainterPath simpleCurve3();
+
+ QPainterPath frame1();
+ QPainterPath frame2();
+ QPainterPath frame3();
+ QPainterPath frame4();
+
+ QPainterPath triangle1();
+ QPainterPath triangle2();
+
+ QPainterPath node();
+ QPainterPath interRect();
+
+ QPainterPath bezierFlower();
+ QPainterPath clover();
+ QPainterPath ellipses();
+ QPainterPath windingFill();
+ QPainterPath oddEvenFill();
+ QPainterPath squareWithHole();
+ QPainterPath circleWithHole();
+ QPainterPath bezierQuadrant();
+}
+#endif
diff --git a/tests/auto/gui/painting/qpathclipper/qpathclipper.pro b/tests/auto/gui/painting/qpathclipper/qpathclipper.pro
new file mode 100644
index 0000000000..2becd7dd03
--- /dev/null
+++ b/tests/auto/gui/painting/qpathclipper/qpathclipper.pro
@@ -0,0 +1,11 @@
+load(qttest_p4)
+INCLUDEPATH += .
+HEADERS += paths.h
+SOURCES += tst_qpathclipper.cpp paths.cpp
+QT += gui-private
+
+requires(contains(QT_CONFIG,private_tests))
+
+unix:!mac:!symbian:LIBS+=-lm
+
+
diff --git a/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp b/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp
new file mode 100644
index 0000000000..57a56b2d1a
--- /dev/null
+++ b/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp
@@ -0,0 +1,1334 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "private/qpathclipper_p.h"
+#include "paths.h"
+#include "pathcompare.h"
+
+#include <QtTest/QtTest>
+
+#include <qpainterpath.h>
+#include <qpolygon.h>
+#include <qdebug.h>
+#include <qpainter.h>
+
+#include <math.h>
+
+class tst_QPathClipper : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QPathClipper();
+ virtual ~tst_QPathClipper();
+
+private:
+ void clipTest(int subjectIndex, int clipIndex, QPathClipper::Operation op);
+
+ QList<QPainterPath> paths;
+
+public slots:
+ void initTestCase();
+
+private slots:
+ void testWingedEdge();
+
+ void testComparePaths();
+
+ void clip_data();
+ void clip();
+
+ void clip2();
+ void clip3();
+
+ void testIntersections();
+ void testIntersections2();
+ void testIntersections3();
+ void testIntersections4();
+ void testIntersections5();
+ void testIntersections6();
+ void testIntersections7();
+ void testIntersections8();
+ void testIntersections9();
+
+ void zeroDerivativeCurves();
+
+ void task204301_data();
+ void task204301();
+
+ void task209056();
+ void task251909();
+
+ void qtbug3778();
+};
+
+Q_DECLARE_METATYPE(QPainterPath)
+Q_DECLARE_METATYPE(QPathClipper::Operation)
+
+tst_QPathClipper::tst_QPathClipper()
+{
+}
+
+tst_QPathClipper::~tst_QPathClipper()
+{
+}
+
+void tst_QPathClipper::initTestCase()
+{
+ paths << Paths::rect();
+ paths << Paths::heart();
+ paths << Paths::body();
+ paths << Paths::mailbox();
+ paths << Paths::deer();
+ paths << Paths::fire();
+
+ paths << Paths::random1();
+ paths << Paths::random2();
+
+ paths << Paths::heart2();
+ paths << Paths::rect2();
+ paths << Paths::rect3();
+ paths << Paths::rect4();
+ paths << Paths::rect5();
+ paths << Paths::rect6();
+
+ paths << Paths::frame1();
+ paths << Paths::frame2();
+ paths << Paths::frame3();
+ paths << Paths::frame4();
+
+ paths << Paths::triangle1();
+ paths << Paths::triangle2();
+
+ paths << Paths::node();
+ paths << Paths::interRect();
+
+ paths << Paths::simpleCurve();
+ paths << Paths::simpleCurve2();
+ paths << Paths::simpleCurve3();
+
+ paths << Paths::bezier1();
+ paths << Paths::bezier2();
+ paths << Paths::bezier3();
+ paths << Paths::bezier4();
+
+ paths << Paths::bezierFlower();
+ paths << Paths::lips();
+ paths << Paths::clover();
+ paths << Paths::ellipses();
+ paths << Paths::windingFill();
+ paths << Paths::oddEvenFill();
+ paths << Paths::squareWithHole();
+ paths << Paths::circleWithHole();
+ paths << Paths::bezierQuadrant();
+
+ // make sure all the bounding rects are centered at the origin
+ for (int i = 0; i < paths.size(); ++i) {
+ QRectF bounds = paths[i].boundingRect();
+
+ QMatrix m(1, 0,
+ 0, 1,
+ -bounds.center().x(), -bounds.center().y());
+
+ paths[i] = m.map(paths[i]);
+ }
+}
+
+static QPainterPath samplePath1()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(200, 246.64789));
+ path.lineTo(QPointF(200, 206.64789));
+ path.lineTo(QPointF(231.42858, 206.64789));
+ path.lineTo(QPointF(231.42858, 246.64789));
+ path.lineTo(QPointF(200, 246.64789));
+ return path;
+}
+
+static QPainterPath samplePath2()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(200, 146.64789));
+ path.lineTo(QPointF(200, 106.64789));
+ path.lineTo(QPointF(231.42858, 106.64789));
+ path.lineTo(QPointF(231.42858, 146.64789));
+ path.lineTo(QPointF(200, 146.64789));
+ return path;
+}
+
+static QPainterPath samplePath3()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(231.42858, 80.933609));
+ path.lineTo(QPointF(200, 80.933609));
+ path.lineTo(QPointF(200, 96.64788999999999));
+ path.lineTo(QPointF(231.42858, 96.64788999999999));
+ path.lineTo(QPointF(231.42858, 80.933609));
+ return path;
+}
+
+static QPainterPath samplePath4()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(288.571434, 80.933609));
+ path.lineTo(QPointF(431.42858, 80.933609));
+ path.lineTo(QPointF(431.42858, 96.64788999999999));
+ path.lineTo(QPointF(288.571434, 96.64788999999999));
+ path.lineTo(QPointF(288.571434, 80.933609));
+ return path;
+}
+
+static QPainterPath samplePath5()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(588.571434, 80.933609));
+ path.lineTo(QPointF(682.85715, 80.933609));
+ path.lineTo(QPointF(682.85715, 96.64788999999999));
+ path.lineTo(QPointF(588.571434, 96.64788999999999));
+ path.lineTo(QPointF(588.571434, 80.933609));
+ return path;
+}
+
+static QPainterPath samplePath6()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(588.571434, 80.933609));
+ path.lineTo(QPointF(200, 80.933609));
+ path.lineTo(QPointF(200, 446.6479));
+ path.lineTo(QPointF(682.85715, 446.6479));
+ path.lineTo(QPointF(682.85715, 96.64788999999999));
+ path.lineTo(QPointF(731.42858, 96.64788999999999));
+ path.lineTo(QPointF(731.42858, 56.64788999999999));
+ path.lineTo(QPointF(588.571434, 56.64788999999999));
+ path.lineTo(QPointF(588.571434, 80.933609));
+ return path;
+}
+
+static QPainterPath samplePath7()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(682.85715, 206.64789));
+ path.lineTo(QPointF(682.85715, 246.64789));
+ path.lineTo(QPointF(588.571434, 246.64789));
+ path.lineTo(QPointF(588.571434, 206.64789));
+ path.lineTo(QPointF(682.85715, 206.64789));
+ return path;
+}
+
+static QPainterPath samplePath8()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(682.85715, 406.64789));
+ path.lineTo(QPointF(682.85715, 446.64789));
+ path.lineTo(QPointF(588.571434, 446.64789));
+ path.lineTo(QPointF(588.571434, 406.64789));
+ path.lineTo(QPointF(682.85715, 406.64789));
+ return path;
+}
+
+static QPainterPath samplePath9()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(682.85715, 426.64789));
+ path.lineTo(QPointF(682.85715, 446.6479));
+ path.lineTo(QPointF(568.571434, 446.6479));
+ path.lineTo(QPointF(568.571434, 426.64789));
+ path.lineTo(QPointF(682.85715, 426.64789));
+ return path;
+}
+
+static QPainterPath samplePath10()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(511.42858, 446.6479));
+ path.lineTo(QPointF(368.571434, 446.6479));
+ path.lineTo(QPointF(368.571434, 426.64789));
+ path.lineTo(QPointF(511.42858, 426.64789));
+ path.lineTo(QPointF(511.42858, 446.6479));
+ return path;
+}
+
+static QPainterPath samplePath13()
+{
+ QPainterPath path;
+ path.moveTo(QPointF(160, 200));
+ path.lineTo(QPointF(100, 200));
+ path.lineTo(QPointF(100, 130));
+ path.lineTo(QPointF(160, 130));
+ path.lineTo(QPointF(160, 200));
+ return path;
+}
+
+static QPainterPath samplePath14()
+{
+ QPainterPath path;
+
+ path.moveTo(160, 80);
+ path.lineTo(160, 180);
+ path.lineTo(100, 180);
+ path.lineTo(100, 80);
+ path.lineTo(160, 80);
+ path.moveTo(160, 80);
+ path.lineTo(160, 100);
+ path.lineTo(120, 100);
+ path.lineTo(120, 80);
+
+ return path;
+}
+
+void tst_QPathClipper::clip_data()
+{
+ //create the testtable instance and define the elements
+ QTest::addColumn<QPainterPath>("subject");
+ QTest::addColumn<QPainterPath>("clip");
+ QTest::addColumn<QPathClipper::Operation>("op");
+ QTest::addColumn<QPainterPath>("result");
+
+ //next we fill it with data
+ QTest::newRow( "simple1" ) << Paths::frame3()
+ << Paths::frame4()
+ << QPathClipper::BoolAnd
+ << samplePath1();
+
+ QTest::newRow( "simple2" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(0, -100)
+ << QPathClipper::BoolAnd
+ << samplePath2();
+
+ QTest::newRow( "simple3" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(0, -150)
+ << QPathClipper::BoolAnd
+ << samplePath3();
+
+ QTest::newRow( "simple4" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(200, -150)
+ << QPathClipper::BoolAnd
+ << samplePath4();
+
+ QTest::newRow( "simple5" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(500, -150)
+ << QPathClipper::BoolAnd
+ << samplePath5();
+
+ QTest::newRow( "simple6" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(500, -150)
+ << QPathClipper::BoolOr
+ << samplePath6();
+
+ QTest::newRow( "simple7" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(500, 0)
+ << QPathClipper::BoolAnd
+ << samplePath7();
+
+ QTest::newRow( "simple8" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(500, 200)
+ << QPathClipper::BoolAnd
+ << samplePath8();
+
+ QTest::newRow( "simple9" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(480, 220)
+ << QPathClipper::BoolAnd
+ << samplePath9();
+
+ QTest::newRow( "simple10" ) << Paths::frame3()
+ << Paths::frame4() * QTransform().translate(280, 220)
+ << QPathClipper::BoolAnd
+ << samplePath10();
+
+ QTest::newRow( "simple_move_to1" ) << Paths::rect4()
+ << Paths::rect2() * QTransform().translate(-20, 50)
+ << QPathClipper::BoolAnd
+ << samplePath13();
+
+ QTest::newRow( "simple_move_to2" ) << Paths::rect4()
+ << Paths::rect2() * QTransform().translate(-20, 0)
+ << QPathClipper::BoolAnd
+ << samplePath14();
+}
+
+// sanity check to make sure comparePaths declared above works
+void tst_QPathClipper::testComparePaths()
+{
+ QPainterPath a;
+ QPainterPath b;
+
+ a.addRect(0, 0, 10, 10);
+ b.addRect(0, 0, 10.00001, 10.00001);
+
+ QVERIFY(!QPathCompare::comparePaths(a, b));
+
+ b = QPainterPath();
+ b.addRect(0, 0, 10.00000000001, 10.00000000001);
+
+ QVERIFY(QPathCompare::comparePaths(a, b));
+
+ b = QPainterPath();
+ b.moveTo(10, 0);
+ b.lineTo(0, 0);
+ b.lineTo(0, 10);
+ b.lineTo(10, 10);
+
+ QVERIFY(QPathCompare::comparePaths(a, b));
+ b.lineTo(10, 0);
+ QVERIFY(QPathCompare::comparePaths(a, b));
+
+ b = QPainterPath();
+ b.moveTo(10, 0);
+ b.lineTo(0, 10);
+ b.lineTo(0, 0);
+ b.lineTo(10, 10);
+
+ QVERIFY(!QPathCompare::comparePaths(a, b));
+}
+
+void tst_QPathClipper::clip()
+{
+ if (sizeof(double) != sizeof(qreal)) {
+ QSKIP("This test only works for qreal=double, otherwise ends in rounding errors", SkipAll);
+ }
+ QFETCH( QPainterPath, subject );
+ QFETCH( QPainterPath, clip );
+ QFETCH( QPathClipper::Operation, op );
+ QFETCH( QPainterPath, result);
+ QPathClipper clipper(subject, clip);
+ QPainterPath x = clipper.clip(op);
+
+ QVERIFY(QPathCompare::comparePaths(x, result));
+}
+
+static inline QPointF randomPointInRect(const QRectF &rect)
+{
+ qreal rx = qrand() / (RAND_MAX + 1.);
+ qreal ry = qrand() / (RAND_MAX + 1.);
+
+ return QPointF(rect.left() + rx * rect.width(),
+ rect.top() + ry * rect.height());
+}
+
+void tst_QPathClipper::clipTest(int subjectIndex, int clipIndex, QPathClipper::Operation op)
+{
+ const QPainterPath &subject = paths[subjectIndex];
+ const QPainterPath &clip = paths[clipIndex];
+ const int count = 40;
+
+ QRectF bounds = subject.boundingRect().united(clip.boundingRect());
+
+ const qreal adjustX = bounds.width() * 0.01;
+ const qreal adjustY = bounds.height() * 0.01;
+
+ // make sure we test some points that are outside both paths as well
+ bounds = bounds.adjusted(-adjustX, -adjustY, adjustX, adjustY);
+
+ const int dim = 256;
+ const qreal scale = qMin(dim / bounds.width(), dim / bounds.height());
+
+ QPathClipper clipper(subject, clip);
+ QPainterPath result = clipper.clip(op);
+
+ // using the image here is a bit of a hacky way to make sure we don't test points that
+ // are too close to the path edges to avoid test fails that are due to numerical errors
+ QImage img(dim, dim, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0x0);
+ QPainter p(&img);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.scale(scale, scale);
+ p.translate(-bounds.topLeft());
+ p.setPen(Qt::black);
+ p.drawPath(subject);
+ p.setPen(Qt::red);
+ p.drawPath(clip);
+ p.end();
+
+ for (int i = 0; i < count; ++i) {
+ QPointF point;
+ QRgb pixel;
+ do {
+ point = randomPointInRect(bounds);
+ const QPointF imagePoint = (point - bounds.topLeft()) * scale;
+
+ pixel = img.pixel(int(imagePoint.x()), int(imagePoint.y()));
+ } while (qAlpha(pixel) > 0);
+
+ const bool inSubject = subject.contains(point);
+ const bool inClip = clip.contains(point);
+
+ const bool inResult = result.contains(point);
+
+ bool expected = false;
+ switch (op) {
+ case QPathClipper::BoolAnd:
+ expected = inSubject && inClip;
+ break;
+ case QPathClipper::BoolOr:
+ expected = inSubject || inClip;
+ break;
+ case QPathClipper::BoolSub:
+ expected = inSubject && !inClip;
+ break;
+ default:
+ break;
+ }
+
+ if (expected != inResult) {
+ char str[256];
+ const char *opStr =
+ op == QPathClipper::BoolAnd ? "and" :
+ op == QPathClipper::BoolOr ? "or" : "sub";
+ sprintf(str, "Expected: %d, actual: %d, subject: %d, clip: %d, op: %s\n",
+ int(expected), int(inResult), subjectIndex, clipIndex, opStr);
+
+ // debugging
+#if 0
+ QRect rect = bounds.toAlignedRect();
+
+ QPainter p(&img);
+ p.scale(scale, scale);
+ p.translate(-bounds.topLeft());
+
+ p.setPen(Qt::NoPen);
+ p.setBrush(QColor(0x700ff00));
+ p.drawPath(result);
+
+ p.setPen(Qt::blue);
+ p.drawPoint(point);
+ p.end();
+
+ char str2[256];
+ sprintf(str2, "fail-%d-%d-%s.png", subjectIndex, clipIndex, opStr);
+ img.save(str2);
+#endif
+ QFAIL(str);
+ }
+ }
+}
+
+void tst_QPathClipper::clip2()
+{
+ if (sizeof(double) != sizeof(qreal))
+ QSKIP("This test only works for qreal=double, otherwise ends in rounding errors", SkipAll);
+
+ int operation = 0;
+
+ for (int i = 0; i < paths.size(); ++i) {
+ for (int j = 0; j <= i; ++j) {
+ QPathClipper::Operation op = QPathClipper::Operation((operation++) % 3);
+ clipTest(i, j, op);
+ }
+ }
+}
+
+void tst_QPathClipper::clip3()
+{
+ int operation = 0;
+
+ // this subset should work correctly for qreal = float
+ for (int i = 0; i < 20; ++i) {
+ for (int j = 0; j <= i; ++j) {
+ QPathClipper::Operation op = QPathClipper::Operation((operation++) % 3);
+ clipTest(i, j, op);
+ }
+ }
+}
+
+void tst_QPathClipper::testIntersections()
+{
+ QPainterPath path1;
+ QPainterPath path2;
+
+ path1.addRect(0, 0, 100, 100);
+ path2.addRect(20, 20, 20, 20);
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+ QVERIFY(path1.contains(path2));
+ QVERIFY(!path2.contains(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addEllipse(0, 0, 100, 100);
+ path2.addEllipse(200, 200, 100, 100);
+ QVERIFY(!path1.intersects(path2));
+ QVERIFY(!path2.intersects(path1));
+ QVERIFY(!path1.contains(path2));
+ QVERIFY(!path2.contains(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addEllipse(0, 0, 100, 100);
+ path2.addEllipse(50, 50, 100, 100);
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+ QVERIFY(!path1.contains(path2));
+ QVERIFY(!path2.contains(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(100, 100, 100, 100);
+ path2.addRect(50, 100, 100, 20);
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+ QVERIFY(!path1.contains(path2));
+ QVERIFY(!path2.contains(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(100, 100, 100, 100);
+ path2.addRect(110, 201, 100, 20);
+ QVERIFY(!path1.intersects(path2));
+ QVERIFY(!path2.intersects(path1));
+ QVERIFY(!path1.contains(path2));
+ QVERIFY(!path2.contains(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(0, 0, 100, 100);
+ path2.addRect(20, 20, 20, 20);
+ path2.addRect(25, 25, 5, 5);
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+ QVERIFY(path1.contains(path2));
+ QVERIFY(!path2.contains(path1));
+}
+
+void tst_QPathClipper::testIntersections2()
+{
+ QPainterPath path1;
+ QPainterPath path2;
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+
+ path1.moveTo(-8,-8);
+ path1.lineTo(107,-8);
+ path1.lineTo(107,107);
+ path1.lineTo(-8,107);
+
+ path2.moveTo(0,0);
+ path2.lineTo(100,0);
+ path2.lineTo(100,100);
+ path2.lineTo(0,100);
+ path2.lineTo(0,0);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+ QVERIFY(path1.contains(path2));
+ QVERIFY(!path2.contains(path1));
+
+ path1.closeSubpath();
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+ QVERIFY(path1.contains(path2));
+ QVERIFY(!path2.contains(path1));
+}
+
+void tst_QPathClipper::testIntersections3()
+{
+ QPainterPath path1 = Paths::node();
+ QPainterPath path2 = Paths::interRect();
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+}
+
+void tst_QPathClipper::testIntersections4()
+{
+ QPainterPath path1;
+ QPainterPath path2;
+
+ path1.moveTo(-5, 0);
+ path1.lineTo(5, 0);
+
+ path2.moveTo(0, -5);
+ path2.lineTo(0, 5);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+}
+
+void tst_QPathClipper::testIntersections5()
+{
+ QPainterPath path1;
+ QPainterPath path2;
+
+ path1.addRect(0, 0, 4, 4);
+ path1.addRect(2, 1, 1, 1);
+ path2.addRect(0.5, 2, 1, 1);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+}
+
+void tst_QPathClipper::testIntersections6()
+{
+ QPainterPath path1;
+ QPainterPath path2;
+
+ path1.moveTo(QPointF(-115.567, -98.3254));
+ path1.lineTo(QPointF(-45.9007, -98.3254));
+ path1.lineTo(QPointF(-45.9007, -28.6588));
+ path1.lineTo(QPointF(-115.567, -28.6588));
+
+ path2.moveTo(QPointF(-110, -110));
+ path2.lineTo(QPointF(110, -110));
+ path2.lineTo(QPointF(110, 110));
+ path2.lineTo(QPointF(-110, 110));
+ path2.lineTo(QPointF(-110, -110));
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+}
+
+
+void tst_QPathClipper::testIntersections7()
+{
+ QPainterPath path1;
+ QPainterPath path2;
+
+ path1.addRect(0, 0, 10, 10);
+ path2.addRect(5, 0, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(0, 0, 10, 10);
+ path2.addRect(0, 5, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(0, 0, 10, 10);
+ path2.addRect(0, 0, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ ///
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(1, 1, 10, 10);
+ path2.addRect(5, 1, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(1, 1, 10, 10);
+ path2.addRect(1, 5, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(1, 1, 10, 10);
+ path2.addRect(1, 1, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(1, 1, 10, 10);
+ path2.addRect(5, 5, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(1, 1, 10, 10);
+ path2.addRect(9, 9, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(1, 1, 10, 10);
+ path2.addRect(10, 10, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(1, 1, 9, 9);
+ path2.addRect(11, 11, 10, 10);
+
+ QVERIFY(!path1.intersects(path2));
+ QVERIFY(!path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(1, 1, 10, 10);
+ path2.addRect(12, 12, 10, 10);
+
+ QVERIFY(!path1.intersects(path2));
+ QVERIFY(!path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(11, 11, 10, 10);
+ path2.addRect(12, 12, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();
+ path2 = QPainterPath();
+ path1.addRect(11, 11, 10, 10);
+ path2.addRect(10, 10, 10, 10);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+}
+
+
+void tst_QPathClipper::testIntersections8()
+{
+ QPainterPath path1 = Paths::node() * QTransform().translate(100, 50);
+ QPainterPath path2 = Paths::node() * QTransform().translate(150, 50);;
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = Paths::node();
+ path2 = Paths::node();
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = Paths::node();
+ path2 = Paths::node() * QTransform().translate(0, 30);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = Paths::node();
+ path2 = Paths::node() * QTransform().translate(30, 0);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = Paths::node();
+ path2 = Paths::node() * QTransform().translate(30, 30);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = Paths::node();
+ path2 = Paths::node() * QTransform().translate(1, 1);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+}
+
+
+void tst_QPathClipper::testIntersections9()
+{
+ QPainterPath path1;
+ QPainterPath path2;
+
+ path1.addRect(QRectF(-1,143, 146, 106));
+ path2.addRect(QRectF(-9,145, 150, 100));
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();;
+ path2 = QPainterPath();
+
+ path1.addRect(QRectF(-1,191, 136, 106));
+ path2.addRect(QRectF(-19,194, 150, 100));
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+
+ path1 = QPainterPath();;
+ path2 = QPainterPath();
+
+ path1.moveTo(-1 , 143);
+ path1.lineTo(148 , 143);
+ path1.lineTo(148 , 250);
+ path1.lineTo(-1 , 250);
+
+ path2.moveTo(-5 , 146);
+ path2.lineTo(145 , 146);
+ path2.lineTo(145 , 246);
+ path2.lineTo(-5 , 246);
+ path2.lineTo(-5 , 146);
+
+ QVERIFY(path1.intersects(path2));
+ QVERIFY(path2.intersects(path1));
+}
+
+QPainterPath pathFromRect(qreal x, qreal y, qreal w, qreal h)
+{
+ QPainterPath path;
+ path.addRect(QRectF(x, y, w, h));
+ return path;
+}
+
+QPainterPath pathFromLine(qreal x1, qreal y1, qreal x2, qreal y2)
+{
+ QPainterPath path;
+ path.moveTo(x1, y1);
+ path.lineTo(x2, y2);
+ return path;
+}
+
+static int loopLength(const QWingedEdge &list, QWingedEdge::TraversalStatus status)
+{
+ int start = status.edge;
+
+ int length = 0;
+ do {
+ ++length;
+ status = list.next(status);
+ } while (status.edge != start);
+
+ return length;
+}
+
+void tst_QPathClipper::testWingedEdge()
+{
+ {
+ QWingedEdge list;
+ int e1 = list.addEdge(QPointF(0, 0), QPointF(10, 0));
+ int e2 = list.addEdge(QPointF(0, 0), QPointF(0, 10));
+ int e3 = list.addEdge(QPointF(0, 0), QPointF(-10, 0));
+ int e4 = list.addEdge(QPointF(0, 0), QPointF(0, -10));
+
+ QCOMPARE(list.edgeCount(), 4);
+ QCOMPARE(list.vertexCount(), 5);
+
+ QWingedEdge::TraversalStatus status = { e1, QPathEdge::RightTraversal, QPathEdge::Forward };
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e1);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e4);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e4);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e3);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e3);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e2);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e2);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e1);
+ }
+ {
+ QWingedEdge list;
+ int e1 = list.addEdge(QPointF(5, 0), QPointF(5, 10));
+ int e2 = list.addEdge(QPointF(5, 0), QPointF(10, 5));
+ int e3 = list.addEdge(QPointF(10, 5), QPointF(5, 10));
+ int e4 = list.addEdge(QPointF(5, 0), QPointF(0, 5));
+ int e5 = list.addEdge(QPointF(0, 5), QPointF(5, 10));
+
+ QCOMPARE(list.edgeCount(), 5);
+ QCOMPARE(list.vertexCount(), 4);
+
+ QWingedEdge::TraversalStatus status = { e1, QPathEdge::RightTraversal, QPathEdge::Forward };
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e5);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e4);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e1);
+
+ QCOMPARE(loopLength(list, status), 3);
+
+ status.flip();
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(loopLength(list, status), 3);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e2);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e3);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e1);
+
+ status = list.next(status);
+ status.flip();
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e2);
+ QCOMPARE(loopLength(list, status), 4);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e4);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Forward);
+ QCOMPARE(status.traversal, QPathEdge::RightTraversal);
+ QCOMPARE(status.edge, e5);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e3);
+
+ status = list.next(status);
+ QCOMPARE(status.direction, QPathEdge::Backward);
+ QCOMPARE(status.traversal, QPathEdge::LeftTraversal);
+ QCOMPARE(status.edge, e2);
+ }
+ {
+ QPainterPath path = pathFromRect(0, 0, 20, 20);
+ QWingedEdge list(path, QPainterPath());
+
+ QCOMPARE(list.edgeCount(), 4);
+ QCOMPARE(list.vertexCount(), 4);
+
+ QWingedEdge::TraversalStatus status = { 0, QPathEdge::RightTraversal, QPathEdge::Forward };
+
+ QPathEdge *edge = list.edge(status.edge);
+ QCOMPARE(QPointF(*list.vertex(edge->first)), QPointF(0, 0));
+ QCOMPARE(QPointF(*list.vertex(edge->second)), QPointF(20, 0));
+
+ status = list.next(status);
+ QCOMPARE(status.edge, 1);
+
+ status = list.next(status);
+ QCOMPARE(status.edge, 2);
+
+ status = list.next(status);
+ QCOMPARE(status.edge, 3);
+
+ status = list.next(status);
+ QCOMPARE(status.edge, 0);
+
+ status.flipDirection();
+ status = list.next(status);
+ QCOMPARE(status.edge, 3);
+
+ status = list.next(status);
+ QCOMPARE(status.edge, 2);
+
+ status = list.next(status);
+ QCOMPARE(status.edge, 1);
+
+ status = list.next(status);
+ QCOMPARE(status.edge, 0);
+
+ QWingedEdge list2(path, pathFromRect(10, 5, 20, 10));
+
+ QCOMPARE(list2.edgeCount(), 12);
+ QCOMPARE(list2.vertexCount(), 10);
+
+ status.flipDirection();
+ QCOMPARE(loopLength(list2, status), 8);
+
+ status = list2.next(status);
+ edge = list2.edge(status.edge);
+ QCOMPARE(QPointF(*list2.vertex(edge->first)), QPointF(20, 0));
+ QCOMPARE(QPointF(*list2.vertex(edge->second)), QPointF(20, 5));
+
+ status = list2.next(status);
+ status.flipTraversal();
+
+ edge = list2.edge(status.edge);
+ QCOMPARE(QPointF(*list2.vertex(edge->first)), QPointF(10, 5));
+ QCOMPARE(QPointF(*list2.vertex(edge->second)), QPointF(20, 5));
+
+ QCOMPARE(loopLength(list2, status), 4);
+
+ status.flipDirection();
+ status = list2.next(status);
+ status.flipTraversal();
+
+ edge = list2.edge(status.edge);
+ QCOMPARE(QPointF(*list2.vertex(edge->first)), QPointF(20, 5));
+ QCOMPARE(QPointF(*list2.vertex(edge->second)), QPointF(20, 15));
+
+ QCOMPARE(loopLength(list2, status), 4);
+ status = list2.next(status);
+ status = list2.next(status);
+
+ edge = list2.edge(status.edge);
+ QCOMPARE(QPointF(*list2.vertex(edge->first)), QPointF(30, 5));
+ QCOMPARE(QPointF(*list2.vertex(edge->second)), QPointF(30, 15));
+ }
+}
+
+void tst_QPathClipper::zeroDerivativeCurves()
+{
+ // zero derivative at end
+ {
+ QPainterPath a;
+ a.cubicTo(100, 0, 100, 100, 100, 100);
+ a.lineTo(100, 200);
+ a.lineTo(0, 200);
+
+ QPainterPath b;
+ b.moveTo(50, 100);
+ b.lineTo(150, 100);
+ b.lineTo(150, 150);
+ b.lineTo(50, 150);
+
+ QPainterPath c = a.united(b);
+ QVERIFY(c.contains(QPointF(25, 125)));
+ QVERIFY(c.contains(QPointF(75, 125)));
+ QVERIFY(c.contains(QPointF(125, 125)));
+ }
+
+ // zero derivative at start
+ {
+ QPainterPath a;
+ a.cubicTo(100, 0, 100, 100, 100, 100);
+ a.lineTo(100, 200);
+ a.lineTo(0, 200);
+
+ QPainterPath b;
+ b.moveTo(50, 100);
+ b.lineTo(150, 100);
+ b.lineTo(150, 150);
+ b.lineTo(50, 150);
+
+ QPainterPath c = a.united(b);
+ QVERIFY(c.contains(QPointF(25, 125)));
+ QVERIFY(c.contains(QPointF(75, 125)));
+ QVERIFY(c.contains(QPointF(125, 125)));
+ }
+}
+
+static bool strictContains(const QPainterPath &a, const QPainterPath &b)
+{
+ return b.subtracted(a) == QPainterPath();
+}
+
+Q_DECLARE_METATYPE(QPolygonF)
+
+void tst_QPathClipper::task204301_data()
+{
+ QTest::addColumn<QPolygonF>("points");
+
+ {
+ QPointF a(51.09013255685567855835, 31.30814891308546066284);
+ QPointF b(98.39898971840739250183, 11.02079074829816818237);
+ QPointF c(91.23911846894770860672, 45.86981737054884433746);
+ QPointF d(66.58616356085985898972, 63.10526528395712375641);
+ QPointF e(82.08219456479714892794, 94.90238165489137145414);
+ QPointF f(16.09013040543221251255, 105.66263409332729850121);
+ QPointF g(10.62811442650854587555, 65.09154842235147953033);
+ QPointF h(5.16609844751656055450, 24.52046275138854980469);
+ QPolygonF v;
+ v << a << b << c << d << e << f << g << h;
+ QTest::newRow("failed_on_linux") << v;
+ }
+
+ {
+ QPointF a(50.014648437500000, 24.392089843750000);
+ QPointF b(92.836303710937500, 5.548706054687500);
+ QPointF c(92.145690917968750, 54.390258789062500);
+ QPointF d(65.402221679687500, 74.345092773437500);
+ QPointF e(80.789794921787347, 124.298095703129690);
+ QPointF f(34.961242675812954, 87.621459960852135);
+ QPointF g(18.305969238281250, 57.426757812500000);
+ QPointF h(1.650695800781250, 27.232055664062500);
+ QPolygonF v;
+ v << a << b << c << d << e << f << g << h;
+ QTest::newRow("failed_on_windows") << v;
+ }
+}
+
+void tst_QPathClipper::task204301()
+{
+ QFETCH(QPolygonF, points);
+
+ QPointF a = points[0];
+ QPointF b = points[1];
+ QPointF c = points[2];
+ QPointF d = points[3];
+ QPointF e = points[4];
+ QPointF f = points[5];
+ QPointF g = points[6];
+ QPointF h = points[7];
+
+ QPainterPath subA;
+ subA.addPolygon(QPolygonF() << a << b << c << d);
+ subA.closeSubpath();
+
+ QPainterPath subB;
+ subB.addPolygon(QPolygonF() << f << e << d << g);
+ subB.closeSubpath();
+
+ QPainterPath subC;
+ subC.addPolygon(QPolygonF() << h << a << d << g);
+ subC.closeSubpath();
+
+ QPainterPath path;
+ path.addPath(subA);
+ path.addPath(subB);
+ path.addPath(subC);
+
+ QPainterPath simplified = path.simplified();
+
+ QVERIFY(strictContains(simplified, subA));
+ QVERIFY(strictContains(simplified, subB));
+ QVERIFY(strictContains(simplified, subC));
+}
+
+void tst_QPathClipper::task209056()
+{
+ QPainterPath p1;
+ p1.moveTo( QPointF(188.506, 287.793) );
+ p1.lineTo( QPointF(288.506, 287.793) );
+ p1.lineTo( QPointF(288.506, 387.793) );
+ p1.lineTo( QPointF(188.506, 387.793) );
+ p1.lineTo( QPointF(188.506, 287.793) );
+
+ QPainterPath p2;
+ p2.moveTo( QPointF(419.447, 164.383) );
+ p2.cubicTo( QPointF(419.447, 69.5486), QPointF(419.447, 259.218),QPointF(419.447, 164.383) );
+
+ p2.cubicTo( QPointF(48.9378, 259.218), QPointF(131.879, 336.097),QPointF(234.192, 336.097) );
+ p2.cubicTo( QPointF(336.506, 336.097), QPointF(419.447, 259.218),QPointF(419.447, 164.383) );
+
+ QPainterPath p3 = p1.intersected(p2);
+
+ QVERIFY(p3 != QPainterPath());
+}
+
+void tst_QPathClipper::task251909()
+{
+ QPainterPath p1;
+ p1.moveTo(0, -10);
+ p1.lineTo(10, -10);
+ p1.lineTo(10, 0);
+ p1.lineTo(0, 0);
+
+ QPainterPath p2;
+ p2.moveTo(0, 8e-14);
+ p2.lineTo(10, -8e-14);
+ p2.lineTo(10, 10);
+ p2.lineTo(0, 10);
+
+ QPainterPath result = p1.united(p2);
+
+ QVERIFY(result.elementCount() <= 5);
+}
+
+void tst_QPathClipper::qtbug3778()
+{
+ if (sizeof(double) != sizeof(qreal)) {
+ QSKIP("This test only works for qreal=double, otherwise ends in rounding errors", SkipAll);
+ }
+ QPainterPath path1;
+ path1.moveTo(200, 3.22409e-5);
+ // e-5 and higher leads to a bug
+ // Using 3.22409e-4 starts to work correctly
+ path1.lineTo(0, 0);
+ path1.lineTo(1.07025e-13, 1450);
+ path1.lineTo(750, 950);
+ path1.lineTo(950, 750);
+ path1.lineTo(200, 3.22409e-13);
+
+ QPainterPath path2;
+ path2.moveTo(0, 0);
+ path2.lineTo(200, 800);
+ path2.lineTo(600, 1500);
+ path2.lineTo(1500, 1400);
+ path2.lineTo(1900, 1200);
+ path2.lineTo(2000, 1000);
+ path2.lineTo(1400, 0);
+ path2.lineTo(0, 0);
+
+ QPainterPath p12 = path1.intersected(path2);
+
+ QVERIFY(p12.contains(QPointF(100, 100)));
+}
+
+QTEST_APPLESS_MAIN(tst_QPathClipper)
+
+
+#include "tst_qpathclipper.moc"
diff --git a/tests/auto/gui/painting/qpen/.gitignore b/tests/auto/gui/painting/qpen/.gitignore
new file mode 100644
index 0000000000..a9187367dc
--- /dev/null
+++ b/tests/auto/gui/painting/qpen/.gitignore
@@ -0,0 +1 @@
+tst_qpen
diff --git a/tests/auto/gui/painting/qpen/qpen.pro b/tests/auto/gui/painting/qpen/qpen.pro
new file mode 100644
index 0000000000..53bd5e2b6e
--- /dev/null
+++ b/tests/auto/gui/painting/qpen/qpen.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+SOURCES += tst_qpen.cpp
+
+
+
diff --git a/tests/auto/gui/painting/qpen/tst_qpen.cpp b/tests/auto/gui/painting/qpen/tst_qpen.cpp
new file mode 100644
index 0000000000..64d725bc50
--- /dev/null
+++ b/tests/auto/gui/painting/qpen/tst_qpen.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include "qpen.h"
+#include "qbrush.h"
+
+#include <qdebug.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QPen : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QPen();
+
+private slots:
+ void getSetCheck();
+ void swap();
+ void operator_eq_eq();
+ void operator_eq_eq_data();
+
+ void stream();
+ void stream_data();
+
+ void constructor();
+ void constructor_data();
+};
+
+// Testing get/set functions
+void tst_QPen::getSetCheck()
+{
+ QPen obj1;
+ // qreal QPen::miterLimit()
+ // void QPen::setMiterLimit(qreal)
+ obj1.setMiterLimit(0.0);
+ QCOMPARE(0.0, obj1.miterLimit());
+ obj1.setMiterLimit(qreal(1.1));
+ QCOMPARE(qreal(1.1), obj1.miterLimit());
+
+ // qreal QPen::widthF()
+ // void QPen::setWidthF(qreal)
+ obj1.setWidthF(0.0);
+ QCOMPARE(0.0, obj1.widthF());
+ obj1.setWidthF(qreal(1.1));
+ QCOMPARE(qreal(1.1), obj1.widthF());
+
+ // int QPen::width()
+ // void QPen::setWidth(int)
+ for (int i = 0; i < 100; ++i) {
+ obj1.setWidth(i);
+ QCOMPARE(i, obj1.width());
+ }
+}
+
+void tst_QPen::swap()
+{
+ QPen p1(Qt::black), p2(Qt::white);
+ p1.swap(p2);
+ QCOMPARE(p1.color(), QColor(Qt::white));
+ QCOMPARE(p2.color(), QColor(Qt::black));
+}
+
+Q_DECLARE_METATYPE(QPen)
+Q_DECLARE_METATYPE(QBrush)
+
+tst_QPen::tst_QPen()
+
+{
+}
+
+void tst_QPen::operator_eq_eq_data()
+{
+ QTest::addColumn<QPen>("pen1");
+ QTest::addColumn<QPen>("pen2");
+ QTest::addColumn<bool>("isEqual");
+
+ QTest::newRow("differentColor") << QPen(Qt::red)
+ << QPen(Qt::blue)
+ << bool(FALSE);
+ QTest::newRow("differentWidth") << QPen(Qt::red, 2)
+ << QPen(Qt::red, 3)
+ << bool(FALSE);
+ QTest::newRow("differentPenStyle") << QPen(Qt::red, 2, Qt::DashLine)
+ << QPen(Qt::red, 2, Qt::DotLine)
+ << bool(FALSE);
+ QTest::newRow("differentCapStyle") << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
+ << QPen(Qt::red, 2, Qt::DashLine, Qt::SquareCap, Qt::BevelJoin)
+ << bool(FALSE);
+ QTest::newRow("differentJoinStyle") << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
+ << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::MiterJoin)
+ << bool(FALSE);
+ QTest::newRow("same") << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
+ << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
+ << bool(TRUE);
+
+}
+
+void tst_QPen::operator_eq_eq()
+{
+ QFETCH(QPen, pen1);
+ QFETCH(QPen, pen2);
+ QFETCH(bool, isEqual);
+ QCOMPARE(pen1 == pen2, isEqual);
+}
+
+
+void tst_QPen::constructor_data()
+{
+ QTest::addColumn<QPen>("pen");
+ QTest::addColumn<QBrush>("brush");
+ QTest::addColumn<double>("width");
+ QTest::addColumn<int>("style");
+ QTest::addColumn<int>("capStyle");
+ QTest::addColumn<int>("joinStyle");
+
+ QTest::newRow("solid_black") << QPen() << QBrush(Qt::black) << 0. << (int)Qt::SolidLine
+ << (int) Qt::SquareCap << (int)Qt::BevelJoin;
+ QTest::newRow("solid_red") << QPen(Qt::red) << QBrush(Qt::red) << 0. << (int)Qt::SolidLine
+ << (int)Qt::SquareCap << (int)Qt::BevelJoin;
+ QTest::newRow("full") << QPen(QBrush(QLinearGradient(0, 0, 100, 100)), 10,
+ Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin)
+ << QBrush(QLinearGradient(0, 0, 100, 100)) << 10. << (int)Qt::SolidLine
+ << (int)Qt::RoundCap << (int)Qt::MiterJoin;
+
+}
+
+
+void tst_QPen::constructor()
+{
+ QFETCH(QPen, pen);
+ QFETCH(QBrush, brush);
+ QFETCH(double, width);
+ QFETCH(int, style);
+ QFETCH(int, capStyle);
+ QFETCH(int, joinStyle);
+
+ QCOMPARE(pen.style(), Qt::PenStyle(style));
+ QCOMPARE(pen.capStyle(), Qt::PenCapStyle(capStyle));
+ QCOMPARE(pen.joinStyle(), Qt::PenJoinStyle(joinStyle));
+ QCOMPARE(pen.widthF(), width);
+ QCOMPARE(pen.brush(), brush);
+}
+
+
+void tst_QPen::stream_data()
+{
+ QTest::addColumn<QPen>("pen");
+
+ QTest::newRow("solid_black") << QPen();
+ QTest::newRow("solid_red") << QPen(Qt::red);
+ QTest::newRow("full") << QPen(QBrush(QLinearGradient(0, 0, 100, 100)), 10, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin);
+}
+
+
+void tst_QPen::stream()
+{
+ QFETCH(QPen, pen);
+
+ QByteArray bytes;
+
+ {
+ QDataStream stream(&bytes, QIODevice::WriteOnly);
+ stream << pen;
+ }
+
+ QPen cmp;
+ {
+ QDataStream stream(&bytes, QIODevice::ReadOnly);
+ stream >> cmp;
+ }
+
+ QCOMPARE(pen.widthF(), cmp.widthF());
+ QCOMPARE(pen.style(), cmp.style());
+ QCOMPARE(pen.capStyle(), cmp.capStyle());
+ QCOMPARE(pen.joinStyle(), cmp.joinStyle());
+ QCOMPARE(pen.brush(), cmp.brush());
+
+ QCOMPARE(pen, cmp);
+}
+
+QTEST_APPLESS_MAIN(tst_QPen)
+#include "tst_qpen.moc"
diff --git a/tests/auto/gui/painting/qpolygon/.gitignore b/tests/auto/gui/painting/qpolygon/.gitignore
new file mode 100644
index 0000000000..7c9d48c848
--- /dev/null
+++ b/tests/auto/gui/painting/qpolygon/.gitignore
@@ -0,0 +1 @@
+tst_qpointarray
diff --git a/tests/auto/gui/painting/qpolygon/qpolygon.pro b/tests/auto/gui/painting/qpolygon/qpolygon.pro
new file mode 100644
index 0000000000..186b704d17
--- /dev/null
+++ b/tests/auto/gui/painting/qpolygon/qpolygon.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qpolygon.cpp
+
+unix:!mac:!symbian:LIBS+=-lm
+
+
diff --git a/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp b/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp
new file mode 100644
index 0000000000..f47073a048
--- /dev/null
+++ b/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qpolygon.h>
+#include <qpainterpath.h>
+#include <math.h>
+
+#include <qpainter.h>
+#include <qdialog.h>
+
+
+
+//TESTED_CLASS=
+//TESTED_FILES=gui/painting/qpolygon.h gui/painting/qpolygon.cpp
+
+class tst_QPolygon : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QPolygon();
+
+private slots:
+ void makeEllipse();
+ void swap();
+};
+
+tst_QPolygon::tst_QPolygon()
+{
+}
+
+void tst_QPolygon::makeEllipse()
+{
+ // create an ellipse with R1 = R2 = R, i.e. a circle
+ QPolygon pa;
+ const int R = 50; // radius
+ QPainterPath path;
+ path.addEllipse(0, 0, 2*R, 2*R);
+ pa = path.toSubpathPolygons().at(0).toPolygon();
+
+ int i;
+ // make sure that all points are R+-1 away from the center
+ bool err = FALSE;
+ for (i = 1; i < pa.size(); i++) {
+ QPoint p = pa.at( i );
+ double r = sqrt( pow( double(p.x() - R), 2.0 ) + pow( double(p.y() - R), 2.0 ) );
+ // ### too strict ? at least from visual inspection it looks
+ // quite odd around the main axes. 2.0 passes easily.
+ err |= ( qAbs( r - double(R) ) > 2.0 );
+ }
+ QVERIFY( !err );
+}
+
+void tst_QPolygon::swap()
+{
+ QPolygon p1(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10));
+ QPolygon p2(QVector<QPoint>() << QPoint(0,0) << QPoint( 0,10) << QPoint( 10,10) << QPoint(10,0));
+ p1.swap(p2);
+ QCOMPARE(p1.count(),4);
+ QCOMPARE(p2.count(),3);
+}
+
+QTEST_APPLESS_MAIN(tst_QPolygon)
+#include "tst_qpolygon.moc"
diff --git a/tests/auto/gui/painting/qprinter/.gitignore b/tests/auto/gui/painting/qprinter/.gitignore
new file mode 100644
index 0000000000..85de0e9675
--- /dev/null
+++ b/tests/auto/gui/painting/qprinter/.gitignore
@@ -0,0 +1,4 @@
+tqpluginloader/st_qprinter
+silly
+test.pdf
+
diff --git a/tests/auto/gui/painting/qprinter/qprinter.pro b/tests/auto/gui/painting/qprinter/qprinter.pro
new file mode 100644
index 0000000000..cbe4ad7986
--- /dev/null
+++ b/tests/auto/gui/painting/qprinter/qprinter.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+QT += printsupport widgets
+SOURCES += tst_qprinter.cpp
+
+mac*:CONFIG+=insignificant_test
diff --git a/tests/auto/gui/painting/qprinter/tst_qprinter.cpp b/tests/auto/gui/painting/qprinter/tst_qprinter.cpp
new file mode 100644
index 0000000000..a6b6895981
--- /dev/null
+++ b/tests/auto/gui/painting/qprinter/tst_qprinter.cpp
@@ -0,0 +1,1044 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <qprinter.h>
+#include <qpagesetupdialog.h>
+#include <qpainter.h>
+#include <qprintdialog.h>
+#include <qprinterinfo.h>
+#include <qvariant.h>
+#include <qpainter.h>
+#include <qprintengine.h>
+
+#include <math.h>
+
+#ifdef Q_WS_WIN
+#include <windows.h>
+#endif
+
+Q_DECLARE_METATYPE(QRect)
+
+QT_FORWARD_DECLARE_CLASS(QPrinter)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#ifndef QT_NO_PRINTER
+
+class tst_QPrinter : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QPrinter();
+ virtual ~tst_QPrinter();
+
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+private slots:
+ void getSetCheck();
+// Add your testfunctions and testdata create functions here
+ void testPageSize();
+ void testPageRectAndPaperRect();
+ void testPageRectAndPaperRect_data();
+ void testSetOptions();
+ void testMargins_data();
+ void testMargins();
+ void testNonExistentPrinter();
+ void testPageSetupDialog();
+ void testMulitpleSets_data();
+ void testMulitpleSets();
+ void testPageMargins_data();
+ void testPageMargins();
+ void changingOutputFormat();
+ void outputFormatFromSuffix();
+ void setGetPaperSize();
+ void valuePreservation();
+ void errorReporting();
+ void testCustomPageSizes();
+ void printDialogCompleter();
+
+ void testCopyCount();
+ void testCurrentPage();
+
+ void taskQTBUG4497_reusePrinterOnDifferentFiles();
+ void testPdfTitle();
+
+private:
+};
+
+// Testing get/set functions
+void tst_QPrinter::getSetCheck()
+{
+ QPrinter obj1;
+ // OutputFormat QPrinter::outputFormat()
+ // void QPrinter::setOutputFormat(OutputFormat)
+ obj1.setOutputFormat(QPrinter::OutputFormat(QPrinter::PdfFormat));
+ QCOMPARE(QPrinter::OutputFormat(QPrinter::PdfFormat), obj1.outputFormat());
+
+ // bool QPrinter::collateCopies()
+ // void QPrinter::setCollateCopies(bool)
+ obj1.setCollateCopies(false);
+ QCOMPARE(false, obj1.collateCopies());
+ obj1.setCollateCopies(true);
+ QCOMPARE(true, obj1.collateCopies());
+
+ obj1.setColorMode(QPrinter::GrayScale);
+ QCOMPARE(obj1.colorMode(), QPrinter::GrayScale);
+ obj1.setColorMode(QPrinter::Color);
+ QCOMPARE(obj1.colorMode(), QPrinter::Color);
+
+ obj1.setCreator(QString::fromLatin1("RandomQtUser"));
+ QCOMPARE(obj1.creator(), QString::fromLatin1("RandomQtUser"));
+
+ obj1.setDocName(QString::fromLatin1("RandomQtDocument"));
+ QCOMPARE(obj1.docName(), QString::fromLatin1("RandomQtDocument"));
+
+ obj1.setDoubleSidedPrinting(true);
+ QCOMPARE(obj1.doubleSidedPrinting(), true);
+ obj1.setDoubleSidedPrinting(false);
+ QCOMPARE(obj1.doubleSidedPrinting(), false);
+
+ obj1.setFromTo(1, 4);
+ QCOMPARE(obj1.fromPage(), 1);
+ QCOMPARE(obj1.toPage(), 4);
+
+ obj1.setFullPage(true);
+ QCOMPARE(obj1.fullPage(), true);
+ obj1.setFullPage(false);
+ QCOMPARE(obj1.fullPage(), false);
+
+ obj1.setOrientation(QPrinter::Landscape);
+ QCOMPARE(obj1.orientation(), QPrinter::Landscape);
+ obj1.setOrientation(QPrinter::Portrait);
+ QCOMPARE(obj1.orientation(), QPrinter::Portrait);
+
+ obj1.setOutputFileName(QString::fromLatin1("RandomQtName"));
+ QCOMPARE(obj1.outputFileName(), QString::fromLatin1("RandomQtName"));
+
+ obj1.setPageOrder(QPrinter::FirstPageFirst);
+ QCOMPARE(obj1.pageOrder(), QPrinter::FirstPageFirst);
+ obj1.setPageOrder(QPrinter::LastPageFirst);
+ QCOMPARE(obj1.pageOrder(), QPrinter::LastPageFirst);
+
+ obj1.setPaperSource(QPrinter::Cassette);
+ QCOMPARE(obj1.paperSource(), QPrinter::Cassette);
+ obj1.setPaperSource(QPrinter::Middle);
+ QCOMPARE(obj1.paperSource(), QPrinter::Middle);
+
+#ifdef Q_OS_UNIX
+ obj1.setPrintProgram(QString::fromLatin1("/bin/true"));
+ QCOMPARE(obj1.printProgram(), QString::fromLatin1("/bin/true"));
+
+ obj1.setPrinterSelectionOption(QString::fromLatin1("--option"));
+ QCOMPARE(obj1.printerSelectionOption(), QString::fromLatin1("--option"));
+#endif
+
+ obj1.setPrinterName(QString::fromLatin1("myPrinter"));
+ QCOMPARE(obj1.printerName(), QString::fromLatin1("myPrinter"));
+
+ // bool QPrinter::fontEmbeddingEnabled()
+ // void QPrinter::setFontEmbeddingEnabled(bool)
+ obj1.setFontEmbeddingEnabled(false);
+ QCOMPARE(false, obj1.fontEmbeddingEnabled());
+ obj1.setFontEmbeddingEnabled(true);
+ QCOMPARE(true, obj1.fontEmbeddingEnabled());
+
+ // PageSize QPrinter::pageSize()
+ // void QPrinter::setPageSize(PageSize)
+ obj1.setPageSize(QPrinter::PageSize(QPrinter::A4));
+ QCOMPARE(QPrinter::PageSize(QPrinter::A4), obj1.pageSize());
+ obj1.setPageSize(QPrinter::PageSize(QPrinter::Letter));
+ QCOMPARE(QPrinter::PageSize(QPrinter::Letter), obj1.pageSize());
+ obj1.setPageSize(QPrinter::PageSize(QPrinter::Legal));
+ QCOMPARE(QPrinter::PageSize(QPrinter::Legal), obj1.pageSize());
+
+ // PrintRange QPrinter::printRange()
+ // void QPrinter::setPrintRange(PrintRange)
+ obj1.setPrintRange(QPrinter::PrintRange(QPrinter::AllPages));
+ QCOMPARE(QPrinter::PrintRange(QPrinter::AllPages), obj1.printRange());
+ obj1.setPrintRange(QPrinter::PrintRange(QPrinter::Selection));
+ QCOMPARE(QPrinter::PrintRange(QPrinter::Selection), obj1.printRange());
+ obj1.setPrintRange(QPrinter::PrintRange(QPrinter::PageRange));
+ QCOMPARE(QPrinter::PrintRange(QPrinter::PageRange), obj1.printRange());
+}
+
+tst_QPrinter::tst_QPrinter()
+{
+}
+
+tst_QPrinter::~tst_QPrinter()
+{
+}
+
+// initTestCase will be executed once before the first testfunction is executed.
+void tst_QPrinter::initTestCase()
+{
+// TODO: Add testcase generic initialization code here.
+// suggestion:
+// testWidget = new QPrinter(0,"testWidget");
+// testWidget->setFixedSize(200, 200);
+// qApp->setMainWidget(testWidget);
+// testWidget->show();
+}
+
+// cleanupTestCase will be executed once after the last testfunction is executed.
+void tst_QPrinter::cleanupTestCase()
+{
+// TODO: Add testcase generic cleanup code here.
+// suggestion:
+// testWidget->hide();
+// qApp->setMainWidget(0);
+// delete testWidget;
+}
+
+// init() will be executed immediately before each testfunction is run.
+void tst_QPrinter::init()
+{
+// TODO: Add testfunction specific initialization code here.
+}
+
+// cleanup() will be executed immediately after each testfunction is run.
+void tst_QPrinter::cleanup()
+{
+// TODO: Add testfunction specific cleanup code here.
+}
+
+#define MYCOMPARE(a, b) QCOMPARE(QVariant((int)a), QVariant((int)b))
+
+void tst_QPrinter::testPageSetupDialog()
+{
+ // Make sure this doesn't crash at least
+ {
+ QPrinter printer;
+ QPageSetupDialog dialog(&printer);
+ }
+}
+
+void tst_QPrinter::testPageSize()
+{
+#if defined (Q_WS_WIN)
+ QPrinter prn;
+
+ prn.setPageSize(QPrinter::Letter);
+ MYCOMPARE(prn.pageSize(), QPrinter::Letter);
+ MYCOMPARE(prn.winPageSize(), DMPAPER_LETTER);
+
+ prn.setPageSize(QPrinter::A4);
+ MYCOMPARE(prn.pageSize(), QPrinter::A4);
+ MYCOMPARE(prn.winPageSize(), DMPAPER_A4);
+
+ prn.setWinPageSize(DMPAPER_LETTER);
+ MYCOMPARE(prn.winPageSize(), DMPAPER_LETTER);
+ MYCOMPARE(prn.pageSize(), QPrinter::Letter);
+
+ prn.setWinPageSize(DMPAPER_A4);
+ MYCOMPARE(prn.winPageSize(), DMPAPER_A4);
+ MYCOMPARE(prn.pageSize(), QPrinter::A4);
+#else
+ QSKIP("QPrinter::winPageSize() does not exist for nonwindows platforms", SkipAll);
+#endif
+}
+
+void tst_QPrinter::testPageRectAndPaperRect_data()
+{
+ QTest::addColumn<int>("orientation");
+ QTest::addColumn<bool>("withPainter");
+ QTest::addColumn<int>("resolution");
+ QTest::addColumn<bool>("doPaperRect");
+
+ // paperrect
+ QTest::newRow("paperRect0") << int(QPrinter::Portrait) << true << 300 << true;
+ QTest::newRow("paperRect1") << int(QPrinter::Portrait) << false << 300 << true;
+ QTest::newRow("paperRect2") << int(QPrinter::Landscape) << true << 300 << true;
+ QTest::newRow("paperRect3") << int(QPrinter::Landscape) << false << 300 << true;
+ QTest::newRow("paperRect4") << int(QPrinter::Portrait) << true << 600 << true;
+ QTest::newRow("paperRect5") << int(QPrinter::Portrait) << false << 600 << true;
+ QTest::newRow("paperRect6") << int(QPrinter::Landscape) << true << 600 << true;
+ QTest::newRow("paperRect7") << int(QPrinter::Landscape) << false << 600 << true;
+ QTest::newRow("paperRect8") << int(QPrinter::Portrait) << true << 1200 << true;
+ QTest::newRow("paperRect9") << int(QPrinter::Portrait) << false << 1200 << true;
+ QTest::newRow("paperRect10") << int(QPrinter::Landscape) << true << 1200 << true;
+ QTest::newRow("paperRect11") << int(QPrinter::Landscape) << false << 1200 << true;
+
+ // page rect
+ QTest::newRow("pageRect0") << int(QPrinter::Portrait) << true << 300 << false;
+ QTest::newRow("pageRect1") << int(QPrinter::Portrait) << false << 300 << false;
+ QTest::newRow("pageRect2") << int(QPrinter::Landscape) << true << 300 << false;
+ QTest::newRow("pageRect3") << int(QPrinter::Landscape) << false << 300 << false;
+ QTest::newRow("pageRect4") << int(QPrinter::Portrait) << true << 600 << false;
+ QTest::newRow("pageRect5") << int(QPrinter::Portrait) << false << 600 << false;
+ QTest::newRow("pageRect6") << int(QPrinter::Landscape) << true << 600 << false;
+ QTest::newRow("pageRect7") << int(QPrinter::Landscape) << false << 600 << false;
+ QTest::newRow("pageRect8") << int(QPrinter::Portrait) << true << 1200 << false;
+ QTest::newRow("pageRect9") << int(QPrinter::Portrait) << false << 1200 << false;
+ QTest::newRow("pageRect10") << int(QPrinter::Landscape) << true << 1200 << false;
+ QTest::newRow("pageRect11") << int(QPrinter::Landscape) << false << 1200 << false;
+}
+
+void tst_QPrinter::testPageRectAndPaperRect()
+{
+ QFETCH(bool, withPainter);
+ QFETCH(int, orientation);
+ QFETCH(int, resolution);
+ QFETCH(bool, doPaperRect);
+
+ QPainter *painter = 0;
+ QPrinter printer(QPrinter::HighResolution);
+ printer.setOrientation(QPrinter::Orientation(orientation));
+ printer.setOutputFileName("silly");
+
+ QRect pageRect = doPaperRect ? printer.paperRect() : printer.pageRect();
+ float inchesX = float(pageRect.width()) / float(printer.resolution());
+ float inchesY = float(pageRect.height()) / float(printer.resolution());
+ printer.setResolution(resolution);
+ if (withPainter)
+ painter = new QPainter(&printer);
+
+ QRect otherRect = doPaperRect ? printer.paperRect() : printer.pageRect();
+ float otherInchesX = float(otherRect.width()) / float(printer.resolution());
+ float otherInchesY = float(otherRect.height()) / float(printer.resolution());
+ if (painter != 0)
+ delete painter;
+
+ QVERIFY(qAbs(otherInchesX - inchesX) < 0.01);
+ QVERIFY(qAbs(otherInchesY - inchesY) < 0.01);
+
+ QVERIFY(printer.orientation() == QPrinter::Portrait || pageRect.width() > pageRect.height());
+ QVERIFY(printer.orientation() != QPrinter::Portrait || pageRect.width() < pageRect.height());
+}
+
+void tst_QPrinter::testSetOptions()
+{
+ QPrinter prn;
+ QPrintDialog dlg(&prn);
+
+ // Verify default values
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintToFile), TRUE);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintSelection), FALSE);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintPageRange), TRUE);
+
+ dlg.setEnabledOptions(QAbstractPrintDialog::PrintPageRange);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintToFile), FALSE);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintSelection), FALSE);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintPageRange), TRUE);
+
+ dlg.setEnabledOptions((QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintSelection
+ | QAbstractPrintDialog::PrintPageRange)));
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintToFile), FALSE);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintSelection), TRUE);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintPageRange), TRUE);
+
+ dlg.setEnabledOptions(QAbstractPrintDialog::PrintSelection);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintToFile), FALSE);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintSelection), TRUE);
+ MYCOMPARE(dlg.isOptionEnabled(QAbstractPrintDialog::PrintPageRange), FALSE);
+}
+
+void tst_QPrinter::testMargins_data()
+{
+ QTest::addColumn<int>("orientation");
+ QTest::addColumn<bool>("fullpage");
+ QTest::addColumn<int>("pagesize");
+ QTest::addColumn<int>("width");
+ QTest::addColumn<int>("height");
+ QTest::addColumn<bool>("withPainter");
+
+ QTest::newRow("data0") << int(QPrinter::Portrait) << true << int(QPrinter::A4) << 210 << 297 << false;
+ QTest::newRow("data1") << int(QPrinter::Landscape) << true << int(QPrinter::A4) << 297 << 210 << false;
+ QTest::newRow("data2") << int(QPrinter::Landscape) << false << int(QPrinter::A4) << 297 << 210 << false;
+ QTest::newRow("data3") << int(QPrinter::Portrait) << false << int(QPrinter::A4) << 210 << 297 << false;
+ QTest::newRow("data4") << int(QPrinter::Portrait) << true << int(QPrinter::A4) << 210 << 297 << true;
+ QTest::newRow("data5") << int(QPrinter::Landscape) << true << int(QPrinter::A4) << 297 << 210 << true;
+ QTest::newRow("data6") << int(QPrinter::Landscape) << false << int(QPrinter::A4) << 297 << 210 << true;
+ QTest::newRow("data7") << int(QPrinter::Portrait) << false << int(QPrinter::A4) << 210 << 297 << true;
+}
+
+void tst_QPrinter::testMargins()
+{
+ QFETCH(bool, withPainter);
+ QFETCH(int, orientation);
+ QFETCH(int, pagesize);
+ QFETCH(int, width);
+ QFETCH(int, height);
+ QFETCH(bool, fullpage);
+ Q_UNUSED(width);
+ Q_UNUSED(height);
+ QPrinter printer;
+ QPainter *painter = 0;
+ printer.setOutputFileName("silly");
+ printer.setOrientation((QPrinter::Orientation)orientation);
+ printer.setFullPage(fullpage);
+ printer.setPageSize((QPrinter::PageSize)pagesize);
+ if (withPainter)
+ painter = new QPainter(&printer);
+
+ if (painter)
+ delete painter;
+}
+
+void tst_QPrinter::testNonExistentPrinter()
+{
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_MAC)
+ QSKIP("QPrinter::testNonExistentPrinter() is not relevant for this platform", SkipAll);
+#else
+ QPrinter printer;
+ QPainter painter;
+
+ // Make sure it doesn't crash on setting or getting properties
+ printer.setPrinterName("some non existing printer");
+ printer.setPageSize(QPrinter::A4);
+ printer.setOrientation(QPrinter::Portrait);
+ printer.setFullPage(true);
+ printer.pageSize();
+ printer.orientation();
+ printer.fullPage();
+ printer.setCopyCount(1);
+ printer.printerName();
+
+ // nor metrics
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmWidth), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmHeight), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmWidthMM), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmHeightMM), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmNumColors), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmDepth), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmDpiX), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmDpiY), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmPhysicalDpiX), 0);
+ QCOMPARE(printer.printEngine()->metric(QPaintDevice::PdmPhysicalDpiY), 0);
+
+ QVERIFY(!painter.begin(&printer));
+#endif
+}
+
+
+void tst_QPrinter::testMulitpleSets_data()
+{
+ QTest::addColumn<int>("resolution");
+ QTest::addColumn<int>("pageSize");
+ QTest::addColumn<int>("widthMMAfter");
+ QTest::addColumn<int>("heightMMAfter");
+
+
+ QTest::newRow("lowRes") << int(QPrinter::ScreenResolution) << int(QPrinter::A4) << 210 << 297;
+ QTest::newRow("lowResLetter") << int(QPrinter::ScreenResolution) << int(QPrinter::Letter) << 216 << 279;
+ QTest::newRow("lowResA5") << int(QPrinter::ScreenResolution) << int(QPrinter::A5) << 148 << 210;
+ QTest::newRow("midRes") << int(QPrinter::PrinterResolution) << int(QPrinter::A4) << 210 << 297;
+ QTest::newRow("midResLetter") << int(QPrinter::PrinterResolution) << int(QPrinter::Letter) << 216 << 279;
+ QTest::newRow("midResA5") << int(QPrinter::PrinterResolution) << int(QPrinter::A5) << 148 << 210;
+ QTest::newRow("highRes") << int(QPrinter::HighResolution) << int(QPrinter::A4) << 210 << 297;
+ QTest::newRow("highResLetter") << int(QPrinter::HighResolution) << int(QPrinter::Letter) << 216 << 279;
+ QTest::newRow("highResA5") << int(QPrinter::HighResolution) << int(QPrinter::A5) << 148 << 210;
+}
+
+static void computePageValue(const QPrinter &printer, int &retWidth, int &retHeight)
+{
+ const double Inch2MM = 25.4;
+
+ double width = double(printer.paperRect().width()) / printer.logicalDpiX() * Inch2MM;
+ double height = double(printer.paperRect().height()) / printer.logicalDpiY() * Inch2MM;
+ retWidth = qRound(width);
+ retHeight = qRound(height);
+}
+
+void tst_QPrinter::testMulitpleSets()
+{
+ // A very simple test, but Mac needs to have its format "validated" if the format is changed
+ // This takes care of that.
+ QFETCH(int, resolution);
+ QFETCH(int, pageSize);
+ QFETCH(int, widthMMAfter);
+ QFETCH(int, heightMMAfter);
+
+
+ QPrinter::PrinterMode mode = QPrinter::PrinterMode(resolution);
+ QPrinter::PageSize printerPageSize = QPrinter::PageSize(pageSize);
+ QPrinter printer(mode);
+ printer.setFullPage(true);
+
+ int paperWidth, paperHeight;
+ //const int Tolerance = 2;
+
+ computePageValue(printer, paperWidth, paperHeight);
+ printer.setPageSize(printerPageSize);
+
+ if (printer.pageSize() != printerPageSize) {
+ QSKIP("Current page size is not supported on this printer", SkipSingle);
+ return;
+ }
+
+ QCOMPARE(printer.widthMM(), widthMMAfter);
+ QCOMPARE(printer.heightMM(), heightMMAfter);
+
+ computePageValue(printer, paperWidth, paperHeight);
+
+ QVERIFY(qAbs(paperWidth - widthMMAfter) <= 2);
+ QVERIFY(qAbs(paperHeight - heightMMAfter) <= 2);
+
+ // Set it again and see if it still works.
+ printer.setPageSize(printerPageSize);
+ QCOMPARE(printer.widthMM(), widthMMAfter);
+ QCOMPARE(printer.heightMM(), heightMMAfter);
+
+ printer.setOrientation(QPrinter::Landscape);
+ computePageValue(printer, paperWidth, paperHeight);
+ QVERIFY(qAbs(paperWidth - heightMMAfter) <= 2);
+ QVERIFY(qAbs(paperHeight - widthMMAfter) <= 2);
+}
+
+void tst_QPrinter::changingOutputFormat()
+{
+#if QT_VERSION < 0x050000
+ QPrinter p;
+ p.setOutputFormat(QPrinter::PostScriptFormat);
+ p.setPageSize(QPrinter::A8);
+ p.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(p.pageSize(), QPrinter::A8);
+#endif
+}
+
+void tst_QPrinter::outputFormatFromSuffix()
+{
+ if (QPrinterInfo::availablePrinters().size() == 0)
+ QSKIP("No printers available.", SkipAll);
+ QPrinter p;
+ QVERIFY(p.outputFormat() == QPrinter::NativeFormat);
+ p.setOutputFileName("test.pdf");
+ QVERIFY(p.outputFormat() == QPrinter::PdfFormat);
+ p.setOutputFileName(QString());
+ QVERIFY(p.outputFormat() == QPrinter::NativeFormat);
+}
+
+void tst_QPrinter::setGetPaperSize()
+{
+ QPrinter p;
+ p.setOutputFormat(QPrinter::PdfFormat);
+ QSizeF size(500, 10);
+ p.setPaperSize(size, QPrinter::Millimeter);
+ QCOMPARE(p.paperSize(QPrinter::Millimeter), size);
+ QSizeF ptSize = p.paperSize(QPrinter::Point);
+ //qDebug() << ptSize;
+ QVERIFY(qAbs(ptSize.width() - size.width() * (72/25.4)) < 1E-4);
+ QVERIFY(qAbs(ptSize.height() - size.height() * (72/25.4)) < 1E-4);
+}
+
+void tst_QPrinter::testPageMargins_data()
+{
+ QTest::addColumn<qreal>("left");
+ QTest::addColumn<qreal>("top");
+ QTest::addColumn<qreal>("right");
+ QTest::addColumn<qreal>("bottom");
+ QTest::addColumn<int>("unit");
+
+ QTest::newRow("data0") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Millimeter);
+ QTest::newRow("data1") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Point);
+ QTest::newRow("data2") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Inch);
+ QTest::newRow("data3") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Pica);
+ QTest::newRow("data4") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Didot);
+ QTest::newRow("data5") << qreal(5.5) << qreal(6.5) << qreal(7.5) << qreal(8.5) << static_cast<int>(QPrinter::Cicero);
+}
+
+void tst_QPrinter::testPageMargins()
+{
+ QPrinter obj1;
+
+ qreal toMillimeters[6];
+ toMillimeters[QPrinter::Millimeter] = 1;
+ toMillimeters[QPrinter::Point] = 0.352777778;
+ toMillimeters[QPrinter::Inch] = 25.4;
+ toMillimeters[QPrinter::Pica] = 4.23333333;
+ toMillimeters[QPrinter::Didot] = 0.376;
+ toMillimeters[QPrinter::Cicero] = 4.51166667;
+
+ QFETCH(qreal, left);
+ QFETCH(qreal, top);
+ QFETCH(qreal, right);
+ QFETCH(qreal, bottom);
+ QFETCH(int, unit);
+
+ qreal nLeft, nTop, nRight, nBottom;
+
+ obj1.setPageMargins(left, top, right, bottom, static_cast<QPrinter::Unit>(unit));
+
+ qreal tolerance = 0.05;
+
+ obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Millimeter);
+ QVERIFY(fabs(left*toMillimeters[unit] - nLeft*toMillimeters[QPrinter::Millimeter]) < tolerance);
+ QVERIFY(fabs(top*toMillimeters[unit] - nTop*toMillimeters[QPrinter::Millimeter]) < tolerance);
+ QVERIFY(fabs(right*toMillimeters[unit] - nRight*toMillimeters[QPrinter::Millimeter]) < tolerance);
+ QVERIFY(fabs(bottom*toMillimeters[unit] - nBottom*toMillimeters[QPrinter::Millimeter]) < tolerance);
+
+ obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Point);
+ QVERIFY(fabs(left*toMillimeters[unit] - nLeft*toMillimeters[QPrinter::Point]) < tolerance);
+ QVERIFY(fabs(top*toMillimeters[unit] - nTop*toMillimeters[QPrinter::Point]) < tolerance);
+ QVERIFY(fabs(right*toMillimeters[unit] - nRight*toMillimeters[QPrinter::Point]) < tolerance);
+ QVERIFY(fabs(bottom*toMillimeters[unit] - nBottom*toMillimeters[QPrinter::Point]) < tolerance);
+
+ obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Inch);
+ QVERIFY(fabs(left*toMillimeters[unit] - nLeft*toMillimeters[QPrinter::Inch]) < tolerance);
+ QVERIFY(fabs(top*toMillimeters[unit] - nTop*toMillimeters[QPrinter::Inch]) < tolerance);
+ QVERIFY(fabs(right*toMillimeters[unit] - nRight*toMillimeters[QPrinter::Inch]) < tolerance);
+ QVERIFY(fabs(bottom*toMillimeters[unit] - nBottom*toMillimeters[QPrinter::Inch]) < tolerance);
+
+ obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Pica);
+ QVERIFY(fabs(left*toMillimeters[unit] - nLeft*toMillimeters[QPrinter::Pica]) < tolerance);
+ QVERIFY(fabs(top*toMillimeters[unit] - nTop*toMillimeters[QPrinter::Pica]) < tolerance);
+ QVERIFY(fabs(right*toMillimeters[unit] - nRight*toMillimeters[QPrinter::Pica]) < tolerance);
+ QVERIFY(fabs(bottom*toMillimeters[unit] - nBottom*toMillimeters[QPrinter::Pica]) < tolerance);
+
+ obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Didot);
+ QVERIFY(fabs(left*toMillimeters[unit] - nLeft*toMillimeters[QPrinter::Didot]) < tolerance);
+ QVERIFY(fabs(top*toMillimeters[unit] - nTop*toMillimeters[QPrinter::Didot]) < tolerance);
+ QVERIFY(fabs(right*toMillimeters[unit] - nRight*toMillimeters[QPrinter::Didot]) < tolerance);
+ QVERIFY(fabs(bottom*toMillimeters[unit] - nBottom*toMillimeters[QPrinter::Didot]) < tolerance);
+
+ obj1.getPageMargins(&nLeft, &nTop, &nRight, &nBottom, QPrinter::Cicero);
+ QVERIFY(fabs(left*toMillimeters[unit] - nLeft*toMillimeters[QPrinter::Cicero]) < tolerance);
+ QVERIFY(fabs(top*toMillimeters[unit] - nTop*toMillimeters[QPrinter::Cicero]) < tolerance);
+ QVERIFY(fabs(right*toMillimeters[unit] - nRight*toMillimeters[QPrinter::Cicero]) < tolerance);
+ QVERIFY(fabs(bottom*toMillimeters[unit] - nBottom*toMillimeters[QPrinter::Cicero]) < tolerance);
+}
+
+void tst_QPrinter::valuePreservation()
+{
+ QPrinter::OutputFormat oldFormat = QPrinter::PdfFormat;
+ QPrinter::OutputFormat newFormat = QPrinter::NativeFormat; // TODO: Correct?
+
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ bool status = printer.collateCopies();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.collateCopies(), status);
+
+ printer.setCollateCopies(!status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.collateCopies(), !status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.collateCopies(), !status);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QPrinter::ColorMode status = printer.colorMode();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.colorMode(), status);
+
+ printer.setColorMode(QPrinter::ColorMode(!status));
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.colorMode(), QPrinter::ColorMode(!status));
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.colorMode(), QPrinter::ColorMode(!status));
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QString status = printer.creator();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.creator(), status);
+
+ status = QString::fromLatin1("Mr. Test");
+ printer.setCreator(status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.creator(), status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.creator(), status);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QString status = printer.docName();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.docName(), status);
+
+ status = QString::fromLatin1("Test document");
+ printer.setDocName(status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.docName(), status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.docName(), status);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ bool status = printer.doubleSidedPrinting();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.doubleSidedPrinting(), status);
+
+ printer.setDoubleSidedPrinting(!status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.doubleSidedPrinting(), !status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.doubleSidedPrinting(), !status);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ bool status = printer.fontEmbeddingEnabled();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.fontEmbeddingEnabled(), status);
+
+ printer.setFontEmbeddingEnabled(!status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.fontEmbeddingEnabled(), !status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.fontEmbeddingEnabled(), !status);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ bool status = printer.fullPage();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.fullPage(), status);
+
+ printer.setFullPage(!status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.fullPage(), !status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.fullPage(), !status);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QPrinter::Orientation status = printer.orientation();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.orientation(), status);
+
+ printer.setOrientation(QPrinter::Orientation(!status));
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.orientation(), QPrinter::Orientation(!status));
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.orientation(), QPrinter::Orientation(!status));
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QString status = printer.outputFileName();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.outputFileName(), status);
+
+ status = QString::fromLatin1("Test file");
+ printer.setOutputFileName(status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.outputFileName(), status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.outputFileName(), status);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QPrinter::PageOrder status = printer.pageOrder();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.pageOrder(), status);
+
+ printer.setPageOrder(QPrinter::PageOrder(!status));
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.pageOrder(), QPrinter::PageOrder(!status));
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.pageOrder(), QPrinter::PageOrder(!status));
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QPrinter::PageSize status = printer.pageSize();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.pageSize(), status);
+
+ printer.setPageSize(QPrinter::B5);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.pageSize(), QPrinter::B5);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.pageSize(), QPrinter::B5);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QPrinter::PaperSource status = printer.paperSource();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.paperSource(), status);
+
+ printer.setPaperSource(QPrinter::Manual);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.paperSource(), QPrinter::Manual);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.paperSource(), QPrinter::Manual);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QString status = printer.printProgram();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.printProgram(), status);
+
+ status = QString::fromLatin1("/usr/local/bin/lpr");
+ printer.setPrintProgram(status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.printProgram(), status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.printProgram(), status);
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QPrinter::PrintRange status = printer.printRange();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.printRange(), status);
+
+ printer.setPrintRange(QPrinter::PrintRange(!status));
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.printRange(), QPrinter::PrintRange(!status));
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.printRange(), QPrinter::PrintRange(!status));
+ }
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QString status = printer.printerName();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.printerName(), status);
+
+ status = QString::fromLatin1("SuperDuperPrinter");
+ printer.setPrinterName(status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.printerName(), status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.printerName(), status);
+ }
+#ifndef Q_OS_WIN
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ QString status = printer.printerSelectionOption();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.printerSelectionOption(), status);
+
+ status = QString::fromLatin1("Optional option");
+ printer.setPrinterSelectionOption(status);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.printerSelectionOption(), status);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.printerSelectionOption(), status);
+ }
+#endif
+ {
+ QPrinter printer;
+ printer.setOutputFormat(oldFormat);
+ int status = printer.resolution();
+ printer.setOutputFormat(newFormat);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.resolution(), status);
+
+ printer.setResolution(status-150);
+ printer.setOutputFormat(newFormat);
+ QCOMPARE(printer.resolution(), status-150);
+ printer.setOutputFormat(oldFormat);
+ QCOMPARE(printer.resolution(), status-150);
+ }
+}
+
+void tst_QPrinter::errorReporting()
+{
+ QPrinter p;
+ p.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(p.isValid(), true);
+ QPainter painter;
+#ifndef Q_WS_WIN
+ // not sure how to choose a never-writable file on windows. But its QFile behavior anyway, so lets rely on it failing elsewhere
+ p.setOutputFileName("/foobar/nonwritable.pdf");
+ QCOMPARE(painter.begin(&p), false); // it should check the output file is writable
+#endif
+ p.setOutputFileName("test.pdf");
+ QCOMPARE(painter.begin(&p), true); // it should check the output
+ QCOMPARE(p.isValid(), true);
+ painter.end();
+}
+
+void tst_QPrinter::testCustomPageSizes()
+{
+ QPrinter p;
+
+ QSizeF customSize(8.5, 11.0);
+ p.setPaperSize(customSize, QPrinter::Inch);
+
+ QSizeF paperSize = p.paperSize(QPrinter::Inch);
+ QCOMPARE(paperSize, customSize);
+
+ QPrinter p2(QPrinter::HighResolution);
+ p2.setPaperSize(customSize, QPrinter::Inch);
+ paperSize = p.paperSize(QPrinter::Inch);
+ QCOMPARE(paperSize, customSize);
+}
+
+void tst_QPrinter::printDialogCompleter()
+{
+#if defined(QT_NO_COMPLETER) || defined(QT_NO_FILEDIALOG)
+ QSKIP("QT_NO_COMPLETER || QT_NO_FILEDIALOG: Auto-complete turned off in QPrinterDialog.", QTest::SkipAll);
+#else
+ QPrintDialog dialog;
+ dialog.printer()->setOutputFileName("file.pdf");
+ dialog.setEnabledOptions(QAbstractPrintDialog::PrintToFile);
+ dialog.show();
+
+ QTest::qWait(100);
+
+ QTest::keyClick(&dialog, Qt::Key_Tab);
+ QTest::keyClick(&dialog, 'P');
+ // The test passes if it doesn't crash.
+#endif
+}
+
+void tst_QPrinter::testCopyCount()
+{
+ QPrinter p;
+ p.setCopyCount(15);
+ QCOMPARE(p.copyCount(), 15);
+}
+
+static void printPage(QPainter *painter)
+{
+ painter->setPen(QPen(Qt::black, 4));
+ painter->drawRect(50, 60, 70, 80);
+}
+
+void tst_QPrinter::taskQTBUG4497_reusePrinterOnDifferentFiles()
+{
+ QPrinter printer;
+ {
+
+ printer.setOutputFileName("out1.ps");
+ QPainter painter(&printer);
+ printPage(&painter);
+
+ }
+ {
+
+ printer.setOutputFileName("out2.ps");
+ QPainter painter(&printer);
+ printPage(&painter);
+
+ }
+ QFile file1("out1.ps");
+ QVERIFY(file1.open(QIODevice::ReadOnly));
+
+ QFile file2("out2.ps");
+ QVERIFY(file2.open(QIODevice::ReadOnly));
+
+ QCOMPARE(file1.readAll(), file2.readAll());
+}
+
+void tst_QPrinter::testCurrentPage()
+{
+ QPrinter printer;
+ printer.setFromTo(1, 10);
+
+ // Test set print range
+ printer.setPrintRange(QPrinter::CurrentPage);
+ QCOMPARE(printer.printRange(), QPrinter::CurrentPage);
+ QCOMPARE(printer.fromPage(), 1);
+ QCOMPARE(printer.toPage(), 10);
+
+ QPrintDialog dialog(&printer);
+
+ // Test default Current Page option to off
+ QCOMPARE(dialog.isOptionEnabled(QPrintDialog::PrintCurrentPage), false);
+
+ // Test enable Current Page option
+ dialog.setOption(QPrintDialog::PrintCurrentPage);
+ QCOMPARE(dialog.isOptionEnabled(QPrintDialog::PrintCurrentPage), true);
+
+}
+
+void tst_QPrinter::testPdfTitle()
+{
+ // Check the document name is represented correctly in produced pdf
+ {
+ QPainter painter;
+ QPrinter printer;
+ // This string is just the UTF-8 encoding of the string: \()f &oslash; hiragana o
+ const char title[]={0x5c, 0x28, 0x29, 0x66, 0xc3, 0xb8, 0xe3, 0x81, 0x8a, 0x00};
+ printer.setOutputFileName("file.pdf");
+ printer.setDocName(QString::fromUtf8(title));
+ painter.begin(&printer);
+ painter.end();
+ }
+ QFile file("file.pdf");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ // The we expect the title to appear in the PDF as:
+ // ASCII('\title (') UTF16(\\\(\)f &oslash; hiragana o) ASCII(')').
+ // which has the following binary representation
+ const char expected[] = {
+ 0x2f, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x28, 0xfe,
+ 0xff, 0x00, 0x5c, 0x5c, 0x00, 0x5c, 0x28, 0x00, 0x5c,
+ 0x29, 0x00, 0x66, 0x00, 0xf8, 0x30, 0x4a, 0x29};
+ QVERIFY(file.readAll().contains(QByteArray(expected, 26)));
+}
+
+QTEST_MAIN(tst_QPrinter)
+#include "tst_qprinter.moc"
+
+#else //QT_NO_PRINTER
+
+QTEST_NOOP_MAIN
+
+#endif //QT_NO_PRINTER
diff --git a/tests/auto/gui/painting/qprinterinfo/.gitignore b/tests/auto/gui/painting/qprinterinfo/.gitignore
new file mode 100644
index 0000000000..fcef7c1997
--- /dev/null
+++ b/tests/auto/gui/painting/qprinterinfo/.gitignore
@@ -0,0 +1 @@
+tst_qprinterinfo
diff --git a/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro b/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro
new file mode 100644
index 0000000000..1bf799d6ce
--- /dev/null
+++ b/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+SOURCES += tst_qprinterinfo.cpp
+
+QT += printsupport network
+
+DEFINES += QT_USE_USING_NAMESPACE
+
diff --git a/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp b/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp
new file mode 100644
index 0000000000..7e5da4a6f8
--- /dev/null
+++ b/tests/auto/gui/painting/qprinterinfo/tst_qprinterinfo.cpp
@@ -0,0 +1,401 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtGlobal>
+#include <QtAlgorithms>
+#include <QtNetwork/QHostInfo>
+
+#ifndef QT_NO_PRINTER
+#include <qprinterinfo.h>
+
+#ifdef Q_OS_UNIX
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/wait.h>
+#endif
+
+Q_DECLARE_METATYPE(QRect)
+
+
+#if defined(Q_OS_WIN32)
+# define ACCEPTABLE_WINDOWS
+#endif
+
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QPrinterInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ //tst_QPrinterInfo();
+ //virtual ~tst_QPrinterInfo();
+
+
+public slots:
+ //void initTestCase();
+ //void cleanupTestCase();
+ //void init();
+ //void cleanup();
+private slots:
+ void testForDefaultPrinter();
+ void testForPrinters();
+ void testForPaperSizes();
+ void testConstructors();
+ void testAssignment();
+
+private:
+ void macFixNameFormat(QString *printerName);
+ QString getDefaultPrinterFromSystem();
+ QStringList getPrintersFromSystem();
+
+ QString getOutputFromCommand(const QStringList& command);
+};
+
+void tst_QPrinterInfo::macFixNameFormat(QString *printerName)
+{
+// Modify the format of the printer name to match Qt, lpstat returns
+// foo___domain_no, Qt returns foo @ domain.no
+#ifdef Q_WS_MAC
+ printerName->replace(QLatin1String("___"), QLatin1String(" @ "));
+ printerName->replace(QLatin1String("_"), QLatin1String("."));
+#else
+ Q_UNUSED(printerName);
+#endif
+}
+
+QString tst_QPrinterInfo::getDefaultPrinterFromSystem()
+{
+ QStringList command;
+ command << "lpstat" << "-d";
+ QString output = getOutputFromCommand(command);
+
+ QRegExp noDefaultReg("[^:]*no .*default");
+ int pos = noDefaultReg.indexIn(output);
+ if (pos >= 0) {
+ return QString();
+ }
+
+ QRegExp defaultReg("default.*: *([a-zA-Z0-9_]+)");
+ defaultReg.indexIn(output);
+ QString printer = defaultReg.cap(1);
+ macFixNameFormat(&printer);
+ return printer;
+}
+
+QStringList tst_QPrinterInfo::getPrintersFromSystem()
+{
+ QStringList ans;
+
+ QStringList command;
+ command << "lpstat" << "-p";
+ QString output = getOutputFromCommand(command);
+ QStringList list = output.split(QChar::fromLatin1('\n'));
+
+ QRegExp reg("^[Pp]rinter ([.a-zA-Z0-9-_@]+)");
+ for (int c = 0; c < list.size(); ++c) {
+ if (reg.indexIn(list[c]) >= 0) {
+ QString printer = reg.cap(1);
+ macFixNameFormat(&printer);
+ ans << printer;
+ }
+ }
+
+ return ans;
+}
+
+// This function does roughly the same as the `command substitution` in
+// the shell.
+QString tst_QPrinterInfo::getOutputFromCommand(const QStringList& command)
+{
+// The command execution does nothing on non-unix systems.
+#ifdef Q_OS_UNIX
+ int pid;
+ int status = 0;
+ int pipePtr[2];
+
+ // Create a pipe that is shared between parent and child process.
+ if (pipe(pipePtr) < 0) {
+ return QString();
+ }
+ pid = fork();
+ if (pid < 0) {
+ close(pipePtr[0]);
+ close(pipePtr[1]);
+ return QString();
+ } else if (pid == 0) {
+ // In child.
+ // Close the reading end.
+ close(pipePtr[0]);
+ // Redirect stdout to the pipe.
+ if (dup2(pipePtr[1], 1) < 0) {
+ exit(1);
+ }
+
+ char** argv = new char*[command.size()+1];
+ for (int c = 0; c < command.size(); ++c) {
+ argv[c] = new char[command[c].size()+1];
+ strcpy(argv[c], command[c].toLatin1().data());
+ }
+ argv[command.size()] = NULL;
+ execvp(argv[0], argv);
+ // Shouldn't get here, but it's possible if command is not found.
+ close(pipePtr[1]);
+ close(1);
+ for (int c = 0; c < command.size(); ++c) {
+ delete [] argv[c];
+ }
+ delete [] argv;
+ exit(1);
+ } else {
+ // In parent.
+ // Close the writing end.
+ close(pipePtr[1]);
+
+ QFile pipeRead;
+ if (!pipeRead.open(pipePtr[0], QIODevice::ReadOnly)) {
+ close(pipePtr[0]);
+ return QString();
+ }
+ QByteArray array;
+ array = pipeRead.readAll();
+ pipeRead.close();
+ close(pipePtr[0]);
+ wait(&status);
+ return QString(array);
+ }
+#else
+ return QString();
+#endif // Q_OS_UNIX
+}
+
+void tst_QPrinterInfo::testForDefaultPrinter()
+{
+#if defined(Q_OS_UNIX) || defined(ACCEPTABLE_WINDOWS)
+# ifdef ACCEPTABLE_WINDOWS
+ if (QHostInfo::localHostName() == "fantomet" || QHostInfo::localHostName() == "bobo") {
+ QWARN("Test is hardcoded to \"fantomet\" and \"bobo\" on Windows and may fail");
+ } else {
+ QSKIP("Test is hardcoded to \"fantomet\" and \"bobo\" on Windows", SkipAll);
+ }
+ QString defSysPrinter;
+ if (QHostInfo::localHostName() == "fantomet") {
+ defSysPrinter = "Yacc (Lexmark Optra T610 PS3)";
+ } else if (QHostInfo::localHostName() == "bobo") {
+ defSysPrinter = "press";
+ }
+# else
+ QString defSysPrinter = getDefaultPrinterFromSystem();
+# endif
+ if (defSysPrinter == "") return;
+
+ QList<QPrinterInfo> list = QPrinterInfo::availablePrinters();
+ bool found = false;
+ for (int c = 0; c < list.size(); ++c) {
+ if (list[c].isDefault()) {
+ QVERIFY(list.at(c).printerName() == defSysPrinter);
+ QVERIFY(!list.at(c).isNull());
+ found = true;
+ } else {
+ QVERIFY(list.at(c).printerName() != defSysPrinter);
+ QVERIFY(!list.at(c).isNull());
+ }
+ }
+
+ if (!found && defSysPrinter != "") QFAIL("No default printer reported by Qt, although there is one");
+#else
+ QSKIP("Test doesn't work on non-Unix", SkipAll);
+#endif // defined(Q_OS_UNIX) || defined(ACCEPTABLE_WINDOWS)
+}
+
+void tst_QPrinterInfo::testForPrinters()
+{
+#if defined(Q_OS_UNIX) || defined(ACCEPTABLE_WINDOWS)
+# ifdef ACCEPTABLE_WINDOWS
+ if (QHostInfo::localHostName() == "fantomet" || QHostInfo::localHostName() == "bobo") {
+ QWARN("Test is hardcoded to \"fantomet\" and \"bobo\" on Windows and may fail");
+ } else {
+ QSKIP("Test is hardcoded to \"fantomet\" and \"bobo\" on Windows", SkipAll);
+ }
+ QStringList sysPrinters;
+ if (QHostInfo::localHostName() == "fantomet") {
+ sysPrinters
+ << "Press"
+ << "Canon PS-IPU Color Laser Copier v52.3"
+ << "EPSON EPL-N4000 PS3"
+ << "Kroksleiven"
+ << "Lexmark Optra Color 1200 PS"
+ << "Yacc (Lexmark Optra T610 PCL)"
+ << "Yacc (Lexmark Optra T610 PS3)"
+ ;
+ } else if (QHostInfo::localHostName() == "bobo") {
+ sysPrinters
+ << "press"
+ << "finnmarka"
+ << "nordmarka"
+ ;
+ }
+# else
+ QStringList sysPrinters = getPrintersFromSystem();
+# endif
+ QList<QPrinterInfo> printers = QPrinterInfo::availablePrinters();
+
+ QCOMPARE(printers.size(), sysPrinters.size());
+
+ QHash<QString, bool> qtPrinters;
+
+ for (int j = 0; j < printers.size(); ++j) {
+ qtPrinters.insert(printers.at(j).printerName(), !printers.at(j).isNull());
+ }
+
+ for (int i = 0; i < sysPrinters.size(); ++i) {
+ if (!qtPrinters.value(sysPrinters.at(i))) {
+ qDebug() << "Available printers: " << qtPrinters;
+ QFAIL(qPrintable(QString("Printer '%1' reported by system, but not reported by Qt").arg(sysPrinters.at(i))));
+ }
+ }
+#else
+ QSKIP("Test doesn't work on non-Unix", SkipAll);
+#endif // defined(Q_OS_UNIX) || defined(ACCEPTABLE_WINDOWS)
+}
+
+void tst_QPrinterInfo::testForPaperSizes()
+{
+QSKIP("PaperSize feature doesn't work on Windows, fails on Mac, and is unstable on Linux", SkipAll);
+ // This test is based on common printers found at the Oslo
+ // office. It is likely to be skipped or fail for other locations.
+ QStringList hardPrinters;
+ hardPrinters << "Finnmarka" << "Huldra";
+
+ QList<QList<QPrinter::PaperSize> > hardSizes;
+ hardSizes
+ << QList<QPrinter::PaperSize>()
+ << QList<QPrinter::PaperSize>()
+ ;
+ hardSizes[0] // Finnmarka
+ << QPrinter::Letter
+ << QPrinter::A4
+ << QPrinter::A3
+ << QPrinter::A5
+ << QPrinter::B4
+ << QPrinter::B5
+ << QPrinter::Custom // COM10
+ << QPrinter::Custom // C5
+ << QPrinter::Custom // DL
+ << QPrinter::Custom // Monarch
+ << QPrinter::Executive
+ << QPrinter::Custom // Foolscap
+ << QPrinter::Custom // ISO B5
+ << QPrinter::Ledger
+ << QPrinter::Legal
+ << QPrinter::Custom // Japanese Post Card
+ << QPrinter::Custom // Invoice
+ ;
+ hardSizes[1] // Huldra
+ << QPrinter::Custom // Not listed at http://localhost:631/, name "Custom"
+ << QPrinter::Letter
+ << QPrinter::A4
+ << QPrinter::A5
+ << QPrinter::A6
+ << QPrinter::B5
+ << QPrinter::Custom // #5 1/2 Envelope
+ << QPrinter::Custom // 6x9 Envelope
+ << QPrinter::Custom // #10 Envelope
+ << QPrinter::Custom // A7 Envelope
+ << QPrinter::Custom // C5 Envelope
+ << QPrinter::Custom // DL Envelope
+ << QPrinter::Custom // Monarch Envelope
+ << QPrinter::Custom // #6 3/4 Envelope
+ << QPrinter::Executive
+ << QPrinter::Custom // US Folio
+ << QPrinter::Custom // Index Card
+ << QPrinter::Custom // ISO B5
+ << QPrinter::Legal
+ << QPrinter::Custom // Statement
+ ;
+
+ QList<QPrinterInfo> printers = QPrinterInfo::availablePrinters();
+ for (int i = 0; i < printers.size(); ++i) {
+ for (int j = 0; j < hardPrinters.size(); ++j) {
+ if (printers[i].printerName() == hardPrinters[j]) {
+ QList<QPrinter::PaperSize> sizes = printers[i].supportedPaperSizes();
+ qSort(sizes);
+ qSort(hardSizes[j]);
+ QCOMPARE(sizes, hardSizes[j]);
+ }
+ }
+ }
+}
+
+void tst_QPrinterInfo::testConstructors()
+{
+ QList<QPrinterInfo> prns(QPrinterInfo::availablePrinters());
+
+ for (int c = 0; c < prns.size(); ++c) {
+ QList<QPrinter::PaperSize> list1, list2;
+ list1 = prns[c].supportedPaperSizes();
+ QPrinter pr(prns[c]);
+ list2 = QPrinterInfo(pr).supportedPaperSizes();
+ QCOMPARE(list2, list1);
+ }
+}
+
+void tst_QPrinterInfo::testAssignment()
+{
+ QList<QPrinterInfo> prns(QPrinterInfo::availablePrinters());
+
+ for (int c = 0; c < prns.size(); ++c) {
+ QPrinterInfo pi = QPrinterInfo::defaultPrinter();
+ pi = prns[c];
+ QCOMPARE(pi.printerName(), prns[c].printerName());
+ QCOMPARE(pi.supportedPaperSizes(), prns[c].supportedPaperSizes());
+ }
+}
+
+QTEST_MAIN(tst_QPrinterInfo)
+#include "tst_qprinterinfo.moc"
+#else
+QTEST_NOOP_MAIN
+#endif
diff --git a/tests/auto/gui/painting/qregion/.gitignore b/tests/auto/gui/painting/qregion/.gitignore
new file mode 100644
index 0000000000..8be21c3736
--- /dev/null
+++ b/tests/auto/gui/painting/qregion/.gitignore
@@ -0,0 +1 @@
+tst_qregion
diff --git a/tests/auto/gui/painting/qregion/qregion.pro b/tests/auto/gui/painting/qregion/qregion.pro
new file mode 100644
index 0000000000..8dbb4844a0
--- /dev/null
+++ b/tests/auto/gui/painting/qregion/qregion.pro
@@ -0,0 +1,8 @@
+load(qttest_p4)
+
+QT += gui-private
+
+SOURCES += tst_qregion.cpp
+
+
+
diff --git a/tests/auto/gui/painting/qregion/tst_qregion.cpp b/tests/auto/gui/painting/qregion/tst_qregion.cpp
new file mode 100644
index 0000000000..58d2034e41
--- /dev/null
+++ b/tests/auto/gui/painting/qregion/tst_qregion.cpp
@@ -0,0 +1,1012 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <qregion.h>
+
+#include <qbitmap.h>
+#include <qpainter.h>
+#include <qpolygon.h>
+#ifdef Q_WS_X11
+#include <private/qt_x11_p.h>
+#endif
+
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QRegion : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QRegion();
+
+private slots:
+ void boundingRect();
+ void rects();
+ void swap();
+ void setRects();
+ void ellipseRegion();
+ void polygonRegion();
+ void bitmapRegion();
+ void intersected_data();
+ void intersected();
+ void emptyPolygonRegion_data();
+ void emptyPolygonRegion();
+
+ void intersects_region_data();
+ void intersects_region();
+ void intersects_rect_data();
+ void intersects_rect();
+ void contains_point();
+
+ void operator_plus_data();
+ void operator_plus();
+ void operator_minus_data();
+ void operator_minus();
+ void operator_intersect_data();
+ void operator_intersect();
+ void operator_xor_data();
+ void operator_xor();
+
+ void rectCount_data();
+ void rectCount();
+
+ void isEmpty_data();
+ void isEmpty();
+#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL)
+ void clipRectangles();
+#endif
+
+ void regionFromPath();
+
+ void regionToPath_data();
+ void regionToPath();
+};
+
+Q_DECLARE_METATYPE(QPolygon)
+Q_DECLARE_METATYPE(QVector<QRect>)
+Q_DECLARE_METATYPE(QRegion)
+
+tst_QRegion::tst_QRegion()
+{
+}
+
+void tst_QRegion::boundingRect()
+{
+ {
+ QRect rect;
+ QRegion region( rect );
+ QCOMPARE( region.boundingRect(), rect );
+ }
+ {
+ QRect rect( 10, -20, 30, 40 );
+ QRegion region( rect );
+ QCOMPARE( region.boundingRect(), rect );
+ }
+ {
+ QRect rect(15,25,10,10);
+ QRegion region( rect );
+ QCOMPARE( region.boundingRect(), rect );
+ }
+
+}
+
+void tst_QRegion::rects()
+{
+ {
+ QRect rect;
+ QRegion region( rect );
+ QVERIFY( region.isEmpty() );
+ QVERIFY( region.rects().isEmpty() );
+ }
+ {
+ QRect rect( 10, -20, 30, 40 );
+ QRegion region( rect );
+ QCOMPARE( region.rects().count(), 1 );
+ QCOMPARE( region.rects()[0], rect );
+ }
+ {
+ QRect r( QPoint(10, 10), QPoint(40, 40) );
+ QRegion region( r );
+ QVERIFY( region.contains( QPoint(10,10) ) );
+ QVERIFY( region.contains( QPoint(20,40) ) );
+ QVERIFY( region.contains( QPoint(40,20) ) );
+ QVERIFY( !region.contains( QPoint(20,41) ) );
+ QVERIFY( !region.contains( QPoint(41,20) ) );
+ }
+ {
+ QRect r( 10, 10, 30, 30 );
+ QRegion region( r );
+ QVERIFY( region.contains( QPoint(10,10) ) );
+ QVERIFY( region.contains( QPoint(20,39) ) );
+ QVERIFY( region.contains( QPoint(39,20) ) );
+ QVERIFY( !region.contains( QPoint(20,40) ) );
+ QVERIFY( !region.contains( QPoint(40,20) ) );
+ }
+}
+
+void tst_QRegion::swap()
+{
+ QRegion r1(QRect( 0, 0,10,10));
+ QRegion r2(QRect(10,10,10,10));
+ r1.swap(r2);
+ QCOMPARE(r1.rects().front(), QRect(10,10,10,10));
+ QCOMPARE(r2.rects().front(), QRect( 0, 0,10,10));
+}
+
+void tst_QRegion::setRects()
+{
+ {
+ QRegion region;
+ region.setRects( 0, 0 );
+ QVERIFY( region.rects().isEmpty() );
+ }
+ {
+ QRegion region;
+ QRect rect;
+ region.setRects( &rect, 0 );
+ QVERIFY(region.isEmpty());
+ QVERIFY(region == QRegion());
+ QVERIFY(!region.boundingRect().isValid());
+ QVERIFY(region.rects().isEmpty());
+ }
+ {
+ QRegion region;
+ QRect rect;
+ region.setRects( &rect, 1 );
+ QVERIFY( !region.boundingRect().isValid() );
+ QVERIFY( region.rects().isEmpty() );
+ }
+ {
+ QRegion region;
+ QRect rect( 10, -20, 30, 40 );
+ region.setRects( &rect, 1 );
+ QCOMPARE( region.rects().count(), 1 );
+ QCOMPARE( region.rects()[0], rect );
+ }
+}
+
+void tst_QRegion::ellipseRegion()
+{
+ QRegion region(0, 0, 100, 100, QRegion::Ellipse);
+
+ // These should not be inside the circe
+ QVERIFY(!region.contains(QPoint(13, 13)));
+ QVERIFY(!region.contains(QPoint(13, 86)));
+ QVERIFY(!region.contains(QPoint(86, 13)));
+ QVERIFY(!region.contains(QPoint(86, 86)));
+
+ // These should be inside
+ QVERIFY(region.contains(QPoint(16, 16)));
+ QVERIFY(region.contains(QPoint(16, 83)));
+ QVERIFY(region.contains(QPoint(83, 16)));
+ QVERIFY(region.contains(QPoint(83, 83)));
+
+ // ..a..
+ // .. ..
+ // . .
+ // . .
+ // b c
+ // . .
+ // . .
+ // .. ..
+ // ..d..
+ QVERIFY(region.contains(QPoint(50, 0))); // Mid-top (a)
+ QVERIFY(region.contains(QPoint(0, 50))); // Mid-left (b)
+ QVERIFY(region.contains(QPoint(99, 50))); // Mid-right (c)
+ QVERIFY(region.contains(QPoint(50, 99))); // Mid-bottom (d)
+
+ QRect bounds = region.boundingRect();
+ QCOMPARE(bounds.x(), 0);
+ QCOMPARE(bounds.y(), 0);
+ QCOMPARE(bounds.width(), 100);
+ QCOMPARE(bounds.height(), 100);
+}
+
+void tst_QRegion::polygonRegion()
+{
+ QPolygon pa;
+ {
+ QRegion region ( pa );
+ QVERIFY( region.isEmpty() );
+ }
+ {
+ pa.setPoints( 8, 10, 10, // a____________b
+ 40, 10, // | |
+ 40, 20, // |___ ___|
+ 30, 20, // | |
+ 30, 40, // | |
+ 20, 40, // | |
+ 20, 20, // |____c
+ 10, 20 );
+
+ QRegion region ( pa );
+ QVERIFY( !region.isEmpty() );
+
+ // These should not be inside the circle
+ QVERIFY( !region.contains( QPoint( 9, 9 ) ) );
+ QVERIFY( !region.contains( QPoint( 30, 41 ) ) );
+ QVERIFY( !region.contains( QPoint( 41, 10 ) ) );
+ QVERIFY( !region.contains( QPoint( 31, 21 ) ) );
+
+ // These should be inside
+ QVERIFY( region.contains( QPoint( 10, 10 ) ) ); // Upper-left (a)
+
+ }
+}
+
+void tst_QRegion::emptyPolygonRegion_data()
+{
+ QTest::addColumn<QPolygon>("pa");
+ QTest::addColumn<bool>("isEmpty");
+ QTest::addColumn<int>("numRects");
+ QTest::addColumn<QVector<QRect> >("rects");
+
+ QPolygon pa;
+
+
+ QTest::newRow("no points") << pa << true << 0 << QVector<QRect>();
+ pa = QPolygon() << QPoint(10,10);
+ QTest::newRow("one point") << pa << true << 0 << QVector<QRect>();
+ pa = QPolygon() << QPoint(10,10) << QPoint(10,20);
+ QTest::newRow("two points, horizontal") << pa << true << 0 << QVector<QRect>();
+
+ pa = QPolygon() << QPoint(10,10) << QPoint(20,10);
+ QTest::newRow("two points, vertical") << pa << true << 0 << QVector<QRect>();
+
+ pa = QPolygon() << QPoint(10,10) << QPoint(20,20);
+ QTest::newRow("two points, diagonal") << pa << true << 0 << QVector<QRect>();
+
+ pa = QPolygon() << QPoint(10,10) << QPoint(15,15) << QPoint(10,15) << QPoint(10, 10) ;
+ QVector<QRect> v;
+ v << QRect(10,11,1, 1) << QRect(10,12,2,1) << QRect(10,13,3,1) << QRect(10,14,4,1);
+ QTest::newRow("triangle") << pa << false << 4 << v;
+
+ v.clear();
+ v << QRect(10,10,10,10);
+
+ QTest::newRow("rectangle") << QPolygon(QRect(10,10,10,10)) << false << 1 << v;
+
+}
+
+void tst_QRegion::emptyPolygonRegion()
+{
+ QFETCH(QPolygon, pa);
+
+ QRegion r(pa);
+ QTEST(r.isEmpty(), "isEmpty");
+ QTEST(r.rects().count(), "numRects");
+ QTEST(r.rects(), "rects");
+}
+
+
+static const char *circle_xpm[] = {
+ "20 20 2 1",
+ " c #FFFFFF",
+ ". c #000000",
+ " ...... ",
+ " .......... ",
+ " .............. ",
+ " ................ ",
+ " ................ ",
+ " .................. ",
+ " .................. ",
+ "....................",
+ "....................",
+ "....................",
+ "....................",
+ "....................",
+ "....................",
+ " .................. ",
+ " .................. ",
+ " ................ ",
+ " ................ ",
+ " .............. ",
+ " .......... ",
+ " ...... "
+};
+
+void tst_QRegion::bitmapRegion()
+{
+ QBitmap circle;
+ {
+ QRegion region( circle );
+ QVERIFY( region.isEmpty() );
+ }
+ {
+ circle = QPixmap( circle_xpm );
+ QRegion region( circle );
+
+ //// These should not be inside the circe
+ QVERIFY( !region.contains( QPoint( 2, 2 ) ) );
+ QVERIFY( !region.contains( QPoint( 2, 17 ) ) );
+ QVERIFY( !region.contains( QPoint( 17, 2 ) ) );
+ QVERIFY( !region.contains( QPoint( 17, 17 ) ) );
+
+ //// These should be inside
+ QVERIFY( region.contains( QPoint( 3, 3 ) ) );
+ QVERIFY( region.contains( QPoint( 3, 16 ) ) );
+ QVERIFY( region.contains( QPoint( 16, 3 ) ) );
+ QVERIFY( region.contains( QPoint( 16, 16 ) ) );
+
+ QVERIFY( region.contains( QPoint( 0, 10 ) ) ); // Mid-left
+ QVERIFY( region.contains( QPoint( 10, 0 ) ) ); // Mid-top
+ QVERIFY( region.contains( QPoint( 19, 10 ) ) ); // Mid-right
+ QVERIFY( region.contains( QPoint( 10, 19 ) ) ); // Mid-bottom
+ }
+}
+
+void tst_QRegion::intersected_data()
+{
+ QTest::addColumn<QRegion>("r1");
+ QTest::addColumn<QRegion>("r2");
+ QTest::addColumn<bool>("intersects");
+ // QTest::addColumn<QRegion>("intersected");
+
+ QPolygon ps1(8);
+ QPolygon ps2(8);
+ ps1.putPoints(0,8, 20,20, 50,20, 50,100, 70,100, 70,20, 120,20, 120,200, 20, 200);
+ ps2.putPoints(0,8, 100,150, 140,150, 140,160, 160,160, 160,150, 200,150, 200,180, 100,180);
+ QTest::newRow("task30716") << QRegion(ps1) << QRegion(ps2) << true;
+}
+
+void tst_QRegion::intersected()
+{
+ QFETCH(QRegion, r1);
+ QFETCH(QRegion, r2);
+ QFETCH(bool, intersects);
+
+ QRegion interReg = r1.intersected(r2);
+ QVERIFY(interReg.isEmpty() != intersects);
+ // Need a way to test the intersected QRegion is right
+}
+
+void tst_QRegion::intersects_region_data()
+{
+ QTest::addColumn<QRegion>("r1");
+ QTest::addColumn<QRegion>("r2");
+ QTest::addColumn<bool>("intersects");
+
+ QTest::newRow("rect overlap rect") << QRegion(100, 100, 200, 200)
+ << QRegion(200, 200, 200, 200)
+ << true;
+
+ QTest::newRow("rect not overlap rect") << QRegion(100, 100, 200, 200)
+ << QRegion(400, 400, 200, 200)
+ << false;
+
+ QTest::newRow("ellipse overlap ellipse") << QRegion(100, 100, 200, 200, QRegion::Ellipse)
+ << QRegion(200, 200, 200, 200, QRegion::Ellipse)
+ << true;
+
+ QTest::newRow("ellipse not overlap ellipse") << QRegion(100, 100, 200, 200, QRegion::Ellipse)
+ << QRegion(400, 400, 200, 200, QRegion::Ellipse)
+ << false;
+}
+
+void tst_QRegion::intersects_region()
+{
+ QFETCH(QRegion, r1);
+ QFETCH(QRegion, r2);
+ QFETCH(bool, intersects);
+ QCOMPARE(r1.intersects(r2), intersects);
+}
+
+
+void tst_QRegion::intersects_rect_data()
+{
+ QTest::addColumn<QRegion>("region");
+ QTest::addColumn<QRect>("rect");
+ QTest::addColumn<bool>("intersects");
+
+ QTest::newRow("rect overlap rect") << QRegion(100, 100, 200, 200)
+ << QRect(200, 200, 200, 200)
+ << true;
+
+ QTest::newRow("rect not overlap rect") << QRegion(100, 100, 200, 200)
+ << QRect(400, 400, 200, 200)
+ << false;
+
+ QTest::newRow("ellipse overlap rect") << QRegion(100, 100, 200, 200, QRegion::Ellipse)
+ << QRect(200, 200, 200, 200)
+ << true;
+
+ QTest::newRow("ellipse not overlap rect") << QRegion(100, 100, 200, 200, QRegion::Ellipse)
+ << QRect(400, 400, 200, 200)
+ << false;
+}
+
+void tst_QRegion::intersects_rect()
+{
+ QFETCH(QRegion, region);
+ QFETCH(QRect, rect);
+ QFETCH(bool, intersects);
+ QCOMPARE(region.intersects(rect), intersects);
+}
+
+void tst_QRegion::contains_point()
+{
+ QCOMPARE(QRegion().contains(QPoint(1,1)),false);
+ QCOMPARE(QRegion(0,0,2,2).contains(QPoint(1,1)),true);
+}
+
+void tst_QRegion::operator_plus_data()
+{
+ QTest::addColumn<QRegion>("r1");
+ QTest::addColumn<QRegion>("r2");
+ QTest::addColumn<QRegion>("expected");
+
+ QTest::newRow("empty 0") << QRegion() << QRegion() << QRegion();
+ QTest::newRow("empty 1") << QRegion() << QRegion(QRect(10, 10, 10, 10))
+ << QRegion(QRect(10, 10, 10, 10));
+ QTest::newRow("empty 2") << QRegion(QRect(10, 10, 10, 10)) << QRegion()
+ << QRegion(QRect(10, 10, 10, 10));
+
+ QRegion expected;
+ QVector<QRect> rects;
+ rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
+ expected.setRects(rects.constData(), rects.size());
+ QTest::newRow("non overlapping") << QRegion(10, 10, 10, 10)
+ << QRegion(22, 10, 10, 10)
+ << expected;
+
+ rects.clear();
+ rects << QRect(50, 0, 50, 2);
+ expected.setRects(rects.constData(), rects.size());
+ QTest::newRow("adjacent y-rects") << QRegion(50, 0, 50, 1)
+ << QRegion(50, 1, 50, 1)
+ << expected;
+
+ rects.clear();
+ rects << QRect(50, 0, 2, 1);
+ expected.setRects(rects.constData(), rects.size());
+ QTest::newRow("adjacent x-rects") << QRegion(50, 0, 1, 1)
+ << QRegion(51, 0, 1, 1)
+ << expected;
+
+ rects.clear();
+ rects << QRect(10, 10, 10, 10) << QRect(10, 20, 5, 10);
+ QRegion r1;
+ r1.setRects(rects.constData(), rects.size());
+ QTest::newRow("double merge") << r1 << QRegion(15, 20, 5, 10)
+ << QRegion(10, 10, 10, 20);
+ rects.clear();
+ rects << QRect(15, 10, 5, 10) << QRect(10, 20, 10, 10);
+ r1.setRects(rects.constData(), rects.size());
+ QTest::newRow("double merge 2") << r1 << QRegion(10, 10, 5, 10)
+ << QRegion(10, 10, 10, 20);
+ QTest::newRow("overlapping x") << QRegion(10, 10, 10, 10)
+ << QRegion(15, 10, 10, 10)
+ << QRegion(10, 10, 15, 10);
+ QTest::newRow("overlapping y") << QRegion(10, 10, 10, 10)
+ << QRegion(10, 15, 10, 10)
+ << QRegion(10, 10, 10, 15);
+ rects.clear();
+ rects << QRect(10, 10, 10, 10) << QRect(10, 20, 5, 10);
+ r1.setRects(rects.constData(), rects.size());
+ rects.clear();
+ rects << QRect(15, 20, 5, 10) << QRect(10, 30, 10, 10);
+ QRegion r2;
+ r2.setRects(rects.constData(), rects.size());
+ QTest::newRow("triple merge") << r1 << r2
+ << QRegion(10, 10, 10, 30);
+
+ rects.clear();
+ rects << QRect(10, 10, 4, 10) << QRect(15, 10, 10, 10);
+ r1.setRects(rects.constData(), rects.size());
+ rects.clear();
+ rects << QRect(15, 20, 10, 10);
+ r2.setRects(rects.constData(), rects.size());
+ rects.clear();
+ rects << QRect(10, 10, 4, 10) << QRect(15, 10, 10, 10)
+ << QRect(15, 20, 10, 10);
+ expected.setRects(rects.constData(), rects.size());
+ QTest::newRow("don't merge y") << r1 << r2 << expected;
+
+ QTest::newRow("equal 1") << QRegion(10, 10, 10, 10)
+ << QRegion(10, 10, 10, 10)
+ << QRegion(10, 10, 10, 10);
+ QTest::newRow("equal 2") << expected << expected << expected;
+}
+
+void tst_QRegion::operator_plus()
+{
+ QFETCH(QRegion, r1);
+ QFETCH(QRegion, r2);
+ QFETCH(QRegion, expected);
+
+ if (r1 + r2 != expected) {
+ qDebug() << "r1 + r2" << (r1 + r2);
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(r1 + r2, expected);
+ if (r2.rectCount() == 1) {
+ if (r1 + r2.boundingRect() != expected) {
+ qDebug() << "r1 + QRect(r2)" << (r1 + r2.boundingRect());
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(r1 + r2.boundingRect(), expected);
+ }
+
+ if (r2 + r1 != expected) {
+ qDebug() << "r2 + r1" << (r2 + r1);
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(r2 + r1, expected);
+ if (r1.rectCount() == 1) {
+ if (r1 + r2.boundingRect() != expected) {
+ qDebug() << "r2 + QRect(r1)" << (r2 + r1.boundingRect());
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(r2 + r1.boundingRect(), expected);
+ }
+
+ QRegion result1 = r1;
+ result1 += r2;
+ if (result1 != expected) {
+ qDebug() << "r1 += r2" << result1;
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(result1, expected);
+ if (r2.rectCount() == 1) {
+ result1 = r1;
+ result1 += r2.boundingRect();
+ if (result1 != expected) {
+ qDebug() << "r1 += QRect(r2)" << result1;
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(result1, expected);
+ }
+
+ QRegion result2 = r2;
+ result2 += r1;
+ if (result2 != expected) {
+ qDebug() << "r2 += r1" << result2;
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(result2, expected);
+ if (r1.rectCount() == 1) {
+ result2 = r2;
+ result2 += r1.boundingRect();
+ if (result2 != expected) {
+ qDebug() << "r2 += QRect(r1)" << result2;
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(result2, expected);
+ }
+}
+
+void tst_QRegion::operator_minus_data()
+{
+ QTest::addColumn<QRegion>("dest");
+ QTest::addColumn<QRegion>("subtract");
+ QTest::addColumn<QRegion>("expected");
+
+ QTest::newRow("empty 0") << QRegion() << QRegion() << QRegion();
+ QTest::newRow("empty 1") << QRegion() << QRegion(QRect(10, 10, 10, 10))
+ << QRegion();
+ QTest::newRow("empty 2") << QRegion(QRect(10, 10, 10, 10)) << QRegion()
+ << QRegion(QRect(10, 10, 10, 10));
+
+ QRegion dest;
+ QVector<QRect> rects;
+ rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
+ dest.setRects(rects.constData(), rects.size());
+ QTest::newRow("simple 1") << dest
+ << QRegion(22, 10, 10, 10)
+ << QRegion(10, 10, 10, 10);
+ QTest::newRow("simple 2") << dest
+ << QRegion(10, 10, 10, 10)
+ << QRegion(22, 10, 10, 10);
+
+ rects.clear();
+ rects << QRect(0, 0, 10, 10) << QRect(15, 0, 10, 10);
+ dest.setRects(rects.constData(), rects.size());
+
+ QRegion minus;
+ rects.clear();
+ rects << QRect(0, 0, 12, 12) << QRect(15, 0, 12, 12);
+ minus.setRects(rects.constData(), rects.size());
+ QTest::newRow("empty 3") << dest << minus << QRegion();
+}
+
+void tst_QRegion::operator_minus()
+{
+ QFETCH(QRegion, dest);
+ QFETCH(QRegion, subtract);
+ QFETCH(QRegion, expected);
+
+ if (dest - subtract != expected) {
+ qDebug() << "dest - subtract" << (dest - subtract);
+ qDebug() << "expected" << expected;
+ };
+ QCOMPARE(dest - subtract, expected);
+
+ dest -= subtract;
+
+ if (dest != expected) {
+ qDebug() << "dest" << dest;
+ qDebug() << "expected" << expected;
+ };
+ QCOMPARE(dest, expected);
+}
+
+void tst_QRegion::operator_intersect_data()
+{
+ QTest::addColumn<QRegion>("r1");
+ QTest::addColumn<QRegion>("r2");
+ QTest::addColumn<QRegion>("expected");
+
+ QTest::newRow("empty 0") << QRegion() << QRegion() << QRegion();
+ QTest::newRow("empty 1") << QRegion() << QRegion(QRect(10, 10, 10, 10))
+ << QRegion();
+ QTest::newRow("empty 2") << QRegion(QRect(10, 10, 10, 10)) << QRegion()
+ << QRegion();
+
+ QRegion dest;
+ QVector<QRect> rects;
+ rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
+ dest.setRects(rects.constData(), rects.size());
+ QTest::newRow("simple 1") << dest
+ << QRegion(22, 10, 10, 10)
+ << QRegion(22, 10, 10, 10);
+ QTest::newRow("simple 2") << dest
+ << QRegion(10, 10, 10, 10)
+ << QRegion(10, 10, 10, 10);
+
+ rects.clear();
+ rects << QRect(10, 10, 10, 10) << QRect(10, 20, 15, 10);
+ dest.setRects(rects.constData(), rects.size());
+ QTest::newRow("merge 1") << dest
+ << QRegion(10, 10, 10, 20)
+ << QRegion(10, 10, 10, 20);
+
+ rects.clear();
+ rects << QRect(11, 11, 218, 117) << QRect(11, 128, 218, 27)
+ << QRect(264, 128, 122, 27) << QRect(11, 155, 218, 43)
+ << QRect(11, 198, 218, 27) << QRect(264, 198, 122, 27)
+ << QRect(11, 225, 218, 221);
+ dest.setRects(rects.constData(), rects.size());
+ QTest::newRow("merge 2") << dest << QRegion(11, 11, 218, 458)
+ << QRegion(11, 11, 218, 435);
+
+ rects.clear();
+ rects << QRect(0, 0, 10, 10) << QRect(20, 0, 10, 10);
+ dest.setRects(rects.constData(), rects.size());
+ QTest::newRow("empty 3") << dest << QRegion(11, 0, 5, 5) << QRegion();
+
+ QTest::newRow("extents check") << dest << QRegion(0, 0, 15, 15)
+ << QRegion(0, 0, 10, 10);
+
+ rects.clear();
+ rects << QRect(10, 10, 10, 10) << QRect(10, 20, 10, 10)
+ << QRect(30, 20, 10, 10) << QRect(10, 30, 10, 10);
+ dest.setRects(rects.constData(), rects.size());
+ rects.clear();
+ rects << QRect(10, 10, 10, 10) << QRect(10, 20, 10, 10)
+ << QRect(30, 20, 10, 10);
+ QRegion expected;
+ expected.setRects(rects.constData(), rects.size());
+ QTest::newRow("dont merge") << dest << QRegion(0, 0, 100, 30)
+ << expected;
+}
+
+void tst_QRegion::operator_intersect()
+{
+ QFETCH(QRegion, r1);
+ QFETCH(QRegion, r2);
+ QFETCH(QRegion, expected);
+
+ if ((r1 & r2) != expected) {
+ qDebug() << "r1 & r2" << (r1 & r2);
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(r1 & r2, expected);
+
+ if ((r2 & r1) != expected) {
+ qDebug() << "r2 & r1" << (r2 & r1);
+ qDebug() << "expected" << expected;
+ }
+ QCOMPARE(r2 & r1, expected);
+
+ r1 &= r2;
+ QCOMPARE(r1, expected);
+}
+
+void tst_QRegion::operator_xor_data()
+{
+ QTest::addColumn<QRegion>("dest");
+ QTest::addColumn<QRegion>("arg");
+ QTest::addColumn<QRegion>("expected");
+
+ QTest::newRow("empty 0") << QRegion() << QRegion() << QRegion();
+ QTest::newRow("empty 1") << QRegion() << QRegion(QRect(10, 10, 10, 10))
+ << QRegion(QRect(10, 10, 10, 10));
+ QTest::newRow("empty 2") << QRegion(QRect(10, 10, 10, 10)) << QRegion()
+ << QRegion(QRect(10, 10, 10, 10));
+
+ QRegion dest;
+ QVector<QRect> rects;
+ rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
+ dest.setRects(rects.constData(), rects.size());
+ QTest::newRow("simple 1") << dest
+ << QRegion(22, 10, 10, 10)
+ << QRegion(10, 10, 10, 10);
+ QTest::newRow("simple 2") << dest
+ << QRegion(10, 10, 10, 10)
+ << QRegion(22, 10, 10, 10);
+ QTest::newRow("simple 3") << dest << dest << QRegion();
+ QTest::newRow("simple 4") << QRegion(10, 10, 10, 10)
+ << QRegion(10, 10, 5, 10)
+ << QRegion(15, 10, 5, 10);
+ QTest::newRow("simple 5") << QRegion(10, 10, 10, 10)
+ << QRegion(10, 10, 10, 5)
+ << QRegion(10, 15, 10, 5);
+
+ const QRegion rgnA(0, 0, 100, 100);
+ const QRegion rgnB(0, 0, 10, 10);
+
+ QTest::newRow("simple 6") << rgnA
+ << rgnA - rgnB
+ << rgnB;
+
+ QTest::newRow("simple 7") << rgnB
+ << rgnA
+ << rgnA - rgnB;
+}
+
+void tst_QRegion::operator_xor()
+{
+ QFETCH(QRegion, dest);
+ QFETCH(QRegion, arg);
+ QFETCH(QRegion, expected);
+
+ QCOMPARE(dest ^ arg, expected);
+ QCOMPARE(dest.xored(arg), expected);
+
+ dest ^= arg;
+ QCOMPARE(dest, expected);
+}
+
+void tst_QRegion::rectCount_data()
+{
+ QTest::addColumn<QRegion>("region");
+ QTest::addColumn<int>("expected");
+
+ QTest::newRow("empty") << QRegion() << 0;
+ QTest::newRow("rect") << QRegion(10, 10, 10, 10) << 1;
+
+ QRegion dest;
+ QVector<QRect> rects;
+ rects << QRect(10, 10, 10, 10) << QRect(22, 10, 10, 10);
+ dest.setRects(rects.constData(), rects.size());
+
+ QTest::newRow("2 rects") << dest << rects.size();
+}
+
+void tst_QRegion::rectCount()
+{
+ QFETCH(QRegion, region);
+ QFETCH(int, expected);
+
+ QCOMPARE(region.rectCount(), expected);
+}
+
+void tst_QRegion::isEmpty_data()
+{
+ QTest::addColumn<QRegion>("region");
+
+ QTest::newRow("QRegion") << QRegion();
+
+ QVector<QRect> rects;
+ rects << QRect(0, 0, 10, 10) << QRect(15, 0, 10, 10);
+ QRegion r1;
+ r1.setRects(rects.constData(), rects.size());
+
+ QRegion r2;
+ rects.clear();
+ rects << QRect(0, 0, 12, 12) << QRect(15, 0, 12, 12);
+ r2.setRects(rects.constData(), rects.size());
+ QTest::newRow("minus") << (r1 - r2);
+}
+
+void tst_QRegion::isEmpty()
+{
+ QFETCH(QRegion, region);
+
+ QVERIFY(region.isEmpty());
+ QCOMPARE(region, QRegion());
+ QCOMPARE(region.rectCount(), 0);
+ QCOMPARE(region.boundingRect(), QRect());
+ QVERIFY(region.rects().isEmpty());
+}
+
+#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL)
+void tst_QRegion::clipRectangles()
+{
+ QRegion region(30, 30, 30, 30);
+ int num = 0;
+ qt_getClipRects(region, num);
+ QCOMPARE(num, 1);
+
+ region += QRegion(10, 10, 10, 10);
+ XRectangle *rects2 = static_cast<XRectangle *>(qt_getClipRects(region, num));
+ QCOMPARE(num, 2);
+
+ // Here's the important part (Y-sorted):
+ QCOMPARE(int(rects2[0].y), 10);
+ QCOMPARE(int(rects2[1].y), 30);
+}
+#endif
+
+void tst_QRegion::regionFromPath()
+{
+ {
+ QPainterPath path;
+ path.addRect(0, 0, 10, 10);
+ path.addRect(0, 100, 100, 1000);
+
+ QRegion rgn(path.toFillPolygon().toPolygon());
+ QCOMPARE(rgn.rects().size(), 2);
+ QCOMPARE(rgn.rects().at(0), QRect(0, 0, 10, 10));
+ QCOMPARE(rgn.rects().at(1), QRect(0, 100, 100, 1000));
+
+ QCOMPARE(rgn.boundingRect(), QRect(0, 0, 100, 1100));
+ }
+
+ {
+ QPainterPath path;
+ path.addRect(0, 0, 100, 100);
+ path.addRect(10, 10, 80, 80);
+
+ QRegion rgn(path.toFillPolygon().toPolygon());
+ QCOMPARE(rgn.rects().size(), 4);
+
+ QCOMPARE(rgn.rects().at(0), QRect(0, 0, 100, 10));
+ QCOMPARE(rgn.rects().at(1), QRect(0, 10, 10, 80));
+ QCOMPARE(rgn.rects().at(2), QRect(90, 10, 10, 80));
+ QCOMPARE(rgn.rects().at(3), QRect(0, 90, 100, 10));
+
+ QCOMPARE(rgn.boundingRect(), QRect(0, 0, 100, 100));
+ }
+}
+
+Q_DECLARE_METATYPE(QPainterPath)
+
+void tst_QRegion::regionToPath_data()
+{
+ QTest::addColumn<QPainterPath>("path");
+ {
+ QPainterPath path;
+ path.addRect(QRect(0, 0, 10, 10));
+
+ QTest::newRow("Rectangle") << path;
+ }
+
+ {
+ QPainterPath path;
+ path.addRect(QRect(0, 0, 10, 10));
+ path.addRect(QRect(20, 0, 10, 10));
+
+ QTest::newRow("Two rects") << path;
+ }
+
+ {
+ QPainterPath path;
+ path.addEllipse(QRect(0, 0, 10, 10));
+
+ QTest::newRow("Ellipse") << path;
+ }
+
+ {
+ QPainterPath path;
+ path.addRect(QRect(0, 0, 3, 8));
+ path.addRect(QRect(6, 0, 3, 8));
+ path.addRect(QRect(3, 3, 3, 2));
+ path.addRect(QRect(12, 3, 3, 2));
+
+ QTest::newRow("H-dot") << path;
+ }
+
+ {
+ QPainterPath path;
+ for (int y = 0; y <= 10; ++y) {
+ for (int x = 0; x <= 10; ++x) {
+ if (!(y & 1) || ((x ^ y) & 1))
+ path.addRect(QRect(x, y, 1, 1));
+ }
+ }
+
+ QTest::newRow("Grid") << path;
+ }
+}
+
+#ifdef QT_BUILD_INTERNAL
+QT_BEGIN_NAMESPACE
+extern QPainterPath qt_regionToPath(const QRegion &region);
+QT_END_NAMESPACE
+#endif
+
+void tst_QRegion::regionToPath()
+{
+#ifdef QT_BUILD_INTERNAL
+
+ QFETCH(QPainterPath, path);
+
+ for (int i = 0; i < 360; i += 10) {
+
+ QTransform transform;
+ transform.scale(5, 5);
+ transform.rotate(i);
+
+ QPainterPath mapped = transform.map(path);
+ QRegion region(mapped.toFillPolygon().toPolygon());
+
+ QPainterPath a;
+ a.addRegion(region);
+
+ QPainterPath b = qt_regionToPath(region);
+
+ QRect r = a.boundingRect().toAlignedRect();
+ QImage ia(r.size(), QImage::Format_RGB32);
+ ia.fill(0xffffffff);
+ QImage ib = ia;
+
+ QPainter p(&ia);
+ p.translate(-r.x(), -r.y());
+ p.fillPath(a, Qt::red);
+ p.end();
+ p.begin(&ib);
+ p.translate(-r.x(), -r.y());
+ p.fillPath(b, Qt::red);
+ p.end();
+
+ QCOMPARE(ia, ib);
+ QCOMPARE(a.boundingRect(), b.boundingRect());
+ }
+#endif
+}
+
+QTEST_MAIN(tst_QRegion)
+#include "tst_qregion.moc"
diff --git a/tests/auto/gui/painting/qtransform/.gitignore b/tests/auto/gui/painting/qtransform/.gitignore
new file mode 100644
index 0000000000..f1da0161e7
--- /dev/null
+++ b/tests/auto/gui/painting/qtransform/.gitignore
@@ -0,0 +1 @@
+tst_qtransform
diff --git a/tests/auto/gui/painting/qtransform/qtransform.pro b/tests/auto/gui/painting/qtransform/qtransform.pro
new file mode 100644
index 0000000000..92bef8ce38
--- /dev/null
+++ b/tests/auto/gui/painting/qtransform/qtransform.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+HEADERS +=
+SOURCES += tst_qtransform.cpp
+
+unix:!mac:!symbian:LIBS+=-lm
+
+
diff --git a/tests/auto/gui/painting/qtransform/tst_qtransform.cpp b/tests/auto/gui/painting/qtransform/tst_qtransform.cpp
new file mode 100644
index 0000000000..f8319c9e13
--- /dev/null
+++ b/tests/auto/gui/painting/qtransform/tst_qtransform.cpp
@@ -0,0 +1,807 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include "qtransform.h"
+#include <math.h>
+#include <qpolygon.h>
+#include <qdebug.h>
+
+Q_DECLARE_METATYPE(QRect)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QTransform : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QTransform();
+ virtual ~tst_QTransform();
+
+
+public slots:
+ void init();
+ void cleanup();
+private slots:
+ void mapRect_data();
+ void operator_star_qrect_data();
+ void mapToPolygon_data();
+ void mapRect();
+ void operator_star_qrect();
+ void assignments();
+ void mapToPolygon();
+ void translate();
+ void scale();
+ void matrix();
+ void testOffset();
+ void types();
+ void scalarOps();
+ void transform();
+ void mapEmptyPath();
+ void boundingRect();
+ void controlPointRect();
+ void inverted_data();
+ void inverted();
+ void projectivePathMapping();
+ void mapInt();
+ void mapPathWithPoint();
+
+private:
+ void mapping_data();
+};
+
+Q_DECLARE_METATYPE(QTransform)
+Q_DECLARE_METATYPE(QPolygon)
+
+tst_QTransform::tst_QTransform()
+{
+}
+
+tst_QTransform::~tst_QTransform()
+{
+}
+
+void tst_QTransform::init()
+{
+ // No initialisation is required
+}
+
+void tst_QTransform::cleanup()
+{
+ // No cleanup is required.
+}
+
+#if defined(Q_OS_WIN) && !defined(M_PI)
+#define M_PI 3.14159265897932384626433832795f
+#endif
+
+void tst_QTransform::mapRect_data()
+{
+ mapping_data();
+
+ // rotations that are not multiples of 90 degrees. mapRect returns the bounding rect here.
+ qreal deg = -45;
+ QTest::newRow( "rot 45 a" )
+ << QTransform().rotate(deg)
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( 0, -7, 14, 14 ) );
+ QTest::newRow( "rot 45 b" )
+ << QTransform().rotate(deg)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 21, -14, 50, 49 ) );
+ QTest::newRow( "rot 45 c" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( 0, -71, 141, 142 ) );
+ QTest::newRow( "rot 45 d" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 212, -141, 495, 495 ) );
+
+ deg = 45;
+ QTest::newRow( "rot -45 a" )
+ << QTransform().rotate(deg)
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( -7, 0, 14, 14 ) );
+ QTest::newRow( "rot -45 b" )
+ << QTransform().rotate(deg)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -35, 21, 49, 50 ) );
+ QTest::newRow( "rot -45 c" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( -71, 0, 142, 141 ) );
+ QTest::newRow( "rot -45 d" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -354, 212, 495, 495 ) );
+}
+
+void tst_QTransform::operator_star_qrect_data()
+{
+ mapping_data();
+}
+
+void tst_QTransform::mapToPolygon_data()
+{
+ mapping_data();
+}
+
+void tst_QTransform::mapping_data()
+{
+ //create the testtable instance and define the elements
+ QTest::addColumn<QTransform>("matrix");
+ QTest::addColumn<QRect>("src");
+ QTest::addColumn<QPolygon>("res");
+
+ //next we fill it with data
+
+ // identity
+ QTest::newRow( "identity" )
+ << QTransform()
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 10, 20, 30, 40 ) );
+ // scaling
+ QTest::newRow( "scale 0" )
+ << QTransform().scale(2, 2)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 20, 40, 60, 80 ) );
+ QTest::newRow( "scale 1" )
+ << QTransform().scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 100, 200, 300, 400 ) );
+ // mirroring
+ QTest::newRow( "mirror 0" )
+ << QTransform().scale(-1, 1)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -40, 20, 30, 40 ) );
+ QTest::newRow( "mirror 1" )
+ << QTransform().scale(1, -1)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 10, -60, 30, 40 ) );
+ QTest::newRow( "mirror 2" )
+ << QTransform().scale(-1, -1)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -40, -60, 30, 40 ) );
+ QTest::newRow( "mirror 3" )
+ << QTransform().scale(-2, -2)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -80, -120, 60, 80 ) );
+ QTest::newRow( "mirror 4" )
+ << QTransform().scale(-10, -10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -400, -600, 300, 400 ) );
+ QTest::newRow( "mirror 5" )
+ << QTransform().scale(-1, 1)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -30, 0, 30, 40 ) );
+ QTest::newRow( "mirror 6" )
+ << QTransform().scale(1, -1)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -40, 30, 40 ) );
+ QTest::newRow( "mirror 7" )
+ << QTransform().scale(-1, -1)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -30, -40, 30, 40 ) );
+ QTest::newRow( "mirror 8" )
+ << QTransform().scale(-2, -2)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -60, -80, 60, 80 ) );
+ QTest::newRow( "mirror 9" )
+ << QTransform().scale(-10, -10) << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -300, -400, 300, 400 ) );
+
+ // rotations
+ float deg = 0.;
+ QTest::newRow( "rot 0 a" )
+ << QTransform().rotate(deg)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon ( QRect( 0, 0, 30, 40 ) );
+ deg = 0.00001f;
+ QTest::newRow( "rot 0 b" )
+ << QTransform().rotate(deg)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon ( QRect( 0, 0, 30, 40 ) );
+ deg = 0.;
+ QTest::newRow( "rot 0 c" )
+ << QTransform().rotate(deg)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon ( QRect( 10, 20, 30, 40 ) );
+ deg = 0.00001f;
+ QTest::newRow( "rot 0 d" )
+ << QTransform().rotate(deg)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon ( QRect( 10, 20, 30, 40 ) );
+
+ // rotations
+ deg = -90.f;
+ QTest::newRow( "rotscale 90 a" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -300, 400, 300 ) );
+ deg = -90.00001f;
+ QTest::newRow( "rotscale 90 b" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -300, 400, 300 ) );
+ deg = -90.f;
+ QTest::newRow( "rotscale 90 c" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 200, -400, 400, 300 ) );
+ deg = -90.00001f;
+ QTest::newRow( "rotscale 90 d" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 200, -400, 400, 300 ) );
+
+ deg = 180.f;
+ QTest::newRow( "rotscale 180 a" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -300, -400, 300, 400 ) );
+ deg = 180.000001f;
+ QTest::newRow( "rotscale 180 b" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -300, -400, 300, 400 ) );
+ deg = 180.f;
+ QTest::newRow( "rotscale 180 c" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -400, -600, 300, 400 ) );
+ deg = 180.000001f;
+ QTest::newRow( "rotscale 180 d" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -400, -600, 300, 400 ) );
+
+ deg = -270.f;
+ QTest::newRow( "rotscale 270 a" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -400, 0, 400, 300 ) );
+ deg = -270.0000001f;
+ QTest::newRow( "rotscale 270 b" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -400, 0, 400, 300 ) );
+ deg = -270.f;
+ QTest::newRow( "rotscale 270 c" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -600, 100, 400, 300 ) );
+ deg = -270.000001f;
+ QTest::newRow( "rotscale 270 d" )
+ << QTransform().rotate(deg).scale(10, 10)
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -600, 100, 400, 300 ) );
+}
+
+void tst_QTransform::mapRect()
+{
+ QFETCH( QTransform, matrix );
+ QFETCH( QRect, src );
+ QFETCH( QPolygon, res );
+ QRect mapped = matrix.mapRect(src);
+ QCOMPARE( mapped, res.boundingRect().adjusted(0, 0, -1, -1) );
+
+ QRectF r = matrix.mapRect(QRectF(src));
+ QRect ir(r.topLeft().toPoint(), r.bottomRight().toPoint() - QPoint(1, 1));
+ QCOMPARE( mapped, ir );
+}
+
+void tst_QTransform::operator_star_qrect()
+{
+#if 0
+ QFETCH( QTransform, matrix );
+ QFETCH( QRect, src );
+ QFETCH( QPolygon, res );
+
+ QCOMPARE( (matrix * src), QRegion(res) );
+#endif
+}
+
+void tst_QTransform::assignments()
+{
+ QTransform m;
+ m.scale(2, 3);
+ m.rotate(45);
+ m.shear(4, 5);
+
+ QTransform c1(m);
+
+ QCOMPARE(m.m11(), c1.m11());
+ QCOMPARE(m.m12(), c1.m12());
+ QCOMPARE(m.m21(), c1.m21());
+ QCOMPARE(m.m22(), c1.m22());
+ QCOMPARE(m.dx(), c1.dx());
+ QCOMPARE(m.dy(), c1.dy());
+
+ QTransform c2 = m;
+ QCOMPARE(m.m11(), c2.m11());
+ QCOMPARE(m.m12(), c2.m12());
+ QCOMPARE(m.m21(), c2.m21());
+ QCOMPARE(m.m22(), c2.m22());
+ QCOMPARE(m.dx(), c2.dx());
+ QCOMPARE(m.dy(), c2.dy());
+}
+
+
+void tst_QTransform::mapToPolygon()
+{
+ QFETCH( QTransform, matrix );
+ QFETCH( QRect, src );
+ QFETCH( QPolygon, res );
+
+ QPolygon poly = matrix.mapToPolygon(src);
+
+ // don't care about starting point
+ bool equal = false;
+ for (int i = 0; i < poly.size(); ++i) {
+ QPolygon rot;
+ for (int j = i; j < poly.size(); ++j)
+ rot << poly[j];
+ for (int j = 0; j < i; ++j)
+ rot << poly[j];
+ if (rot == res)
+ equal = true;
+ }
+
+ QVERIFY(equal);
+}
+
+
+void tst_QTransform::translate()
+{
+ QTransform m( 1, 2, 3, 4, 5, 6 );
+ QTransform res2( m );
+ QTransform res( 1, 2, 3, 4, 75, 106 );
+ m.translate( 10, 20 );
+ QVERIFY( m == res );
+ m.translate( -10, -20 );
+ QVERIFY( m == res2 );
+ QVERIFY( QTransform::fromTranslate( 0, 0 ).type() == QTransform::TxNone );
+ QVERIFY( QTransform::fromTranslate( 10, 0 ).type() == QTransform::TxTranslate );
+ QVERIFY( QTransform::fromTranslate( -1, 5 ) == QTransform().translate( -1, 5 ));
+ QVERIFY( QTransform::fromTranslate( 0, 0 ) == QTransform());
+}
+
+void tst_QTransform::scale()
+{
+ QTransform m( 1, 2, 3, 4, 5, 6 );
+ QTransform res2( m );
+ QTransform res( 10, 20, 60, 80, 5, 6 );
+ m.scale( 10, 20 );
+ QVERIFY( m == res );
+ m.scale( 1./10., 1./20. );
+ QVERIFY( m == res2 );
+ QVERIFY( QTransform::fromScale( 1, 1 ).type() == QTransform::TxNone );
+ QVERIFY( QTransform::fromScale( 2, 4 ).type() == QTransform::TxScale );
+ QVERIFY( QTransform::fromScale( 2, 4 ) == QTransform().scale( 2, 4 ));
+ QVERIFY( QTransform::fromScale( 1, 1 ) == QTransform());
+}
+
+void tst_QTransform::matrix()
+{
+ QMatrix mat1;
+ mat1.scale(0.3, 0.7);
+ mat1.translate(53.3, 94.4);
+ mat1.rotate(45);
+
+ QMatrix mat2;
+ mat2.rotate(33);
+ mat2.scale(0.6, 0.6);
+ mat2.translate(13.333, 7.777);
+
+ QTransform tran1(mat1);
+ QTransform tran2(mat2);
+ QTransform dummy;
+ dummy.setMatrix(mat1.m11(), mat1.m12(), 0,
+ mat1.m21(), mat1.m22(), 0,
+ mat1.dx(), mat1.dy(), 1);
+
+ QVERIFY(tran1 == dummy);
+ QVERIFY(tran1.inverted() == dummy.inverted());
+ QVERIFY(tran1.inverted() == QTransform(mat1.inverted()));
+ QVERIFY(tran2.inverted() == QTransform(mat2.inverted()));
+
+ QMatrix mat3 = mat1 * mat2;
+ QTransform tran3 = tran1 * tran2;
+ QVERIFY(QTransform(mat3) == tran3);
+
+ /* QMatrix::operator==() doesn't use qFuzzyCompare(), which
+ * on win32-g++ results in a failure. So we work around it by
+ * calling QTranform::operator==(), which performs a fuzzy compare. */
+ QCOMPARE(QTransform(mat3), QTransform(tran3.toAffine()));
+
+ QTransform tranInv = tran1.inverted();
+ QMatrix matInv = mat1.inverted();
+
+ QRect rect(43, 70, 200, 200);
+ QPoint pt(43, 66);
+ QVERIFY(tranInv.map(pt) == matInv.map(pt));
+ QVERIFY(tranInv.map(pt) == matInv.map(pt));
+
+ QPainterPath path;
+ path.moveTo(55, 60);
+ path.lineTo(110, 110);
+ path.quadTo(220, 50, 10, 20);
+ path.closeSubpath();
+ QVERIFY(tranInv.map(path) == matInv.map(path));
+}
+
+void tst_QTransform::testOffset()
+{
+ QTransform trans;
+ const QMatrix &aff = trans.toAffine();
+ QCOMPARE((void*)(&aff), (void*)(&trans));
+}
+
+void tst_QTransform::types()
+{
+ QTransform m1;
+ QCOMPARE(m1.type(), QTransform::TxNone);
+
+ m1.translate(1.0f, 0.0f);
+ QCOMPARE(m1.type(), QTransform::TxTranslate);
+ QCOMPARE(m1.inverted().type(), QTransform::TxTranslate);
+
+ m1.scale(1.0f, 2.0f);
+ QCOMPARE(m1.type(), QTransform::TxScale);
+ QCOMPARE(m1.inverted().type(), QTransform::TxScale);
+
+ m1.rotate(45.0f);
+ QCOMPARE(m1.type(), QTransform::TxRotate);
+ QCOMPARE(m1.inverted().type(), QTransform::TxRotate);
+
+ m1.shear(0.5f, 0.25f);
+ QCOMPARE(m1.type(), QTransform::TxShear);
+ QCOMPARE(m1.inverted().type(), QTransform::TxShear);
+
+ m1.rotate(45.0f, Qt::XAxis);
+ QCOMPARE(m1.type(), QTransform::TxProject);
+ m1.shear(0.5f, 0.25f);
+ QCOMPARE(m1.type(), QTransform::TxProject);
+ m1.rotate(45.0f);
+ QCOMPARE(m1.type(), QTransform::TxProject);
+ m1.scale(1.0f, 2.0f);
+ QCOMPARE(m1.type(), QTransform::TxProject);
+ m1.translate(1.0f, 0.0f);
+ QCOMPARE(m1.type(), QTransform::TxProject);
+
+ QTransform m2(1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ -1.0f, -1.0f, 1.0f);
+
+ QCOMPARE(m2.type(), QTransform::TxTranslate);
+ QCOMPARE((m1 * m2).type(), QTransform::TxProject);
+
+ m1 *= QTransform();
+ QCOMPARE(m1.type(), QTransform::TxProject);
+
+ m1 *= QTransform(1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f);
+ QCOMPARE(m1.type(), QTransform::TxProject);
+
+ m2.reset();
+ QCOMPARE(m2.type(), QTransform::TxNone);
+
+ m2.setMatrix(1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f);
+ QCOMPARE(m2.type(), QTransform::TxNone);
+
+ m2 *= QTransform();
+ QCOMPARE(m2.type(), QTransform::TxNone);
+
+ m2.setMatrix(2.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f);
+ QCOMPARE(m2.type(), QTransform::TxScale);
+ m2 *= QTransform();
+ QCOMPARE(m2.type(), QTransform::TxScale);
+
+ m2.setMatrix(0.0f, 1.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 1.0f);
+ QCOMPARE(m2.type(), QTransform::TxRotate);
+ m2 *= QTransform();
+ QCOMPARE(m2.type(), QTransform::TxRotate);
+
+ m2.setMatrix(1.0f, 0.0f, 0.5f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f);
+ QCOMPARE(m2.type(), QTransform::TxProject);
+ m2 *= QTransform();
+ QCOMPARE(m2.type(), QTransform::TxProject);
+
+ m2.setMatrix(1.0f, 1.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 1.0f);
+ QCOMPARE(m2.type(), QTransform::TxShear);
+
+ m2 *= m2.inverted();
+ QCOMPARE(m2.type(), QTransform::TxNone);
+
+ m2.translate(5.0f, 5.0f);
+ m2.rotate(45.0f);
+ m2.rotate(-45.0f);
+ QCOMPARE(m2.type(), QTransform::TxTranslate);
+
+ m2.scale(2.0f, 3.0f);
+ m2.shear(1.0f, 0.0f);
+ m2.shear(-1.0f, 0.0f);
+ QCOMPARE(m2.type(), QTransform::TxScale);
+
+ m2 *= QTransform(1.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f);
+ QCOMPARE(m2.type(), QTransform::TxShear);
+
+ m2 *= QTransform(1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f);
+ QCOMPARE(m2.type(), QTransform::TxShear);
+
+ QTransform m3(1.8f, 0.0f, 0.0f,
+ 0.0f, 1.8f, 0.0f,
+ 0.0f, 0.0f, 1.0f);
+
+ QCOMPARE(m3.type(), QTransform::TxScale);
+ m3.translate(5.0f, 5.0f);
+ QCOMPARE(m3.type(), QTransform::TxScale);
+ QCOMPARE(m3.inverted().type(), QTransform::TxScale);
+
+ m3.setMatrix(1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 2.0f);
+ QCOMPARE(m3.type(), QTransform::TxProject);
+
+ m3.setMatrix(0.0f, 2.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 2.0f);
+ QCOMPARE(m3.type(), QTransform::TxProject);
+
+ QTransform m4;
+ m4.scale(5, 5);
+ m4.translate(4, 2);
+ m4.rotate(45);
+
+ QCOMPARE(m4.type(), QTransform::TxRotate);
+
+ QTransform m5;
+ m5.scale(5, 5);
+ m5 = m5.adjoint() / m5.determinant();
+ QCOMPARE(m5.type(), QTransform::TxScale);
+}
+
+
+void tst_QTransform::scalarOps()
+{
+ QTransform t;
+ QCOMPARE(t.m11(), 1.);
+ QCOMPARE(t.m33(), 1.);
+ QCOMPARE(t.m21(), 0.);
+
+ t = QTransform() + 3;
+ QCOMPARE(t.m11(), 4.);
+ QCOMPARE(t.m33(), 4.);
+ QCOMPARE(t.m21(), 3.);
+
+ t = t - 3;
+ QCOMPARE(t.m11(), 1.);
+ QCOMPARE(t.m33(), 1.);
+ QCOMPARE(t.m21(), 0.);
+ QCOMPARE(t.isIdentity(), true);
+
+ t += 3;
+ t = t * 2;
+ QCOMPARE(t.m11(), 8.);
+ QCOMPARE(t.m33(), 8.);
+ QCOMPARE(t.m21(), 6.);
+}
+
+void tst_QTransform::transform()
+{
+ QTransform t;
+ t.rotate(30, Qt::YAxis);
+ t.translate(15, 10);
+ t.scale(2, 2);
+ t.rotate(30);
+ t.shear(0.5, 0.5);
+
+ QTransform a, b, c, d, e;
+ a.rotate(30, Qt::YAxis);
+ b.translate(15, 10);
+ c.scale(2, 2);
+ d.rotate(30);
+ e.shear(0.5, 0.5);
+
+ QVERIFY(qFuzzyCompare(t, e * d * c * b * a));
+}
+
+void tst_QTransform::mapEmptyPath()
+{
+ QPainterPath path;
+ path.moveTo(10, 10);
+ path.lineTo(10, 10);
+ QCOMPARE(QTransform().map(path), path);
+}
+
+void tst_QTransform::boundingRect()
+{
+ QPainterPath path;
+ path.moveTo(10, 10);
+ path.lineTo(10, 10);
+ QCOMPARE(path.boundingRect(), QRectF(10, 10, 0, 0));
+}
+
+void tst_QTransform::controlPointRect()
+{
+ QPainterPath path;
+ path.moveTo(10, 10);
+ path.lineTo(10, 10);
+ QCOMPARE(path.controlPointRect(), QRectF(10, 10, 0, 0));
+}
+
+void tst_QTransform::inverted_data()
+{
+ QTest::addColumn<QTransform>("matrix");
+
+ QTest::newRow("identity")
+ << QTransform();
+
+ QTest::newRow("TxTranslate")
+ << QTransform().translate(200, 10);
+
+ QTest::newRow("TxScale")
+ << QTransform().scale(5, 2);
+
+ QTest::newRow("TxTranslate TxScale")
+ << QTransform().translate(100, -10).scale(40, 2);
+
+ QTest::newRow("TxScale TxTranslate")
+ << QTransform().scale(40, 2).translate(100, -10);
+
+ QTest::newRow("TxRotate")
+ << QTransform().rotate(40, Qt::ZAxis);
+
+ QTest::newRow("TxRotate TxScale")
+ << QTransform().rotate(60, Qt::ZAxis).scale(2, 0.25);
+
+ QTest::newRow("TxScale TxRotate")
+ << QTransform().scale(2, 0.25).rotate(30, Qt::ZAxis);
+
+ QTest::newRow("TxRotate TxScale TxTranslate")
+ << QTransform().rotate(60, Qt::ZAxis).scale(2, 0.25).translate(200, -3000);
+
+ QTest::newRow("TxRotate TxTranslate TxScale")
+ << QTransform().rotate(60, Qt::ZAxis).translate(200, -3000).scale(19, 77);
+
+ QTest::newRow("TxShear")
+ << QTransform().shear(10, 10);
+
+ QTest::newRow("TxShear TxRotate")
+ << QTransform().shear(10, 10).rotate(45, Qt::ZAxis);
+
+ QTest::newRow("TxShear TxRotate TxScale")
+ << QTransform().shear(10, 10).rotate(45, Qt::ZAxis).scale(19, 81);
+
+ QTest::newRow("TxTranslate TxShear TxRotate TxScale")
+ << QTransform().translate(150, -1).shear(10, 10).rotate(45, Qt::ZAxis).scale(19, 81);
+
+ const qreal s = 500000;
+
+ QTransform big;
+ big.scale(s, s);
+
+ QTest::newRow("big") << big;
+
+ QTransform smallTransform;
+ smallTransform.scale(1/s, 1/s);
+
+ QTest::newRow("small") << smallTransform;
+}
+
+void tst_QTransform::inverted()
+{
+ if (sizeof(qreal) != sizeof(double))
+ QSKIP("precision error if qreal is not double", SkipAll);
+
+ QFETCH(QTransform, matrix);
+
+ const QTransform inverted = matrix.inverted();
+
+ QVERIFY(matrix.isIdentity() == inverted.isIdentity());
+ QVERIFY(matrix.type() == inverted.type());
+
+ QVERIFY((matrix * inverted).isIdentity());
+ QVERIFY((inverted * matrix).isIdentity());
+}
+
+void tst_QTransform::projectivePathMapping()
+{
+ QPainterPath path;
+ path.addRect(-50, -50, 100, 100);
+
+ const QRectF view(0, 0, 1024, 1024);
+
+ QVERIFY(view.intersects(path.boundingRect()));
+
+ for (int i = 0; i < 85; i += 5) {
+ QTransform transform;
+ transform.translate(512, 512);
+ transform.rotate(i, Qt::YAxis);
+
+ const QPainterPath mapped = transform.map(path);
+
+ QVERIFY(view.intersects(mapped.boundingRect()));
+ QVERIFY(transform.inverted().mapRect(view).intersects(path.boundingRect()));
+ }
+}
+
+void tst_QTransform::mapInt()
+{
+ int x = 0;
+ int y = 0;
+
+ QTransform::fromTranslate(10, 10).map(x, y, &x, &y);
+
+ QCOMPARE(x, 10);
+ QCOMPARE(y, 10);
+}
+
+void tst_QTransform::mapPathWithPoint()
+{
+ QPainterPath p(QPointF(10, 10));
+ p = QTransform::fromTranslate(10, 10).map(p);
+ QCOMPARE(p.currentPosition(), QPointF(20, 20));
+}
+
+QTEST_APPLESS_MAIN(tst_QTransform)
+
+
+#include "tst_qtransform.moc"
diff --git a/tests/auto/gui/painting/qwmatrix/.gitignore b/tests/auto/gui/painting/qwmatrix/.gitignore
new file mode 100644
index 0000000000..c983191769
--- /dev/null
+++ b/tests/auto/gui/painting/qwmatrix/.gitignore
@@ -0,0 +1 @@
+tst_qwmatrix
diff --git a/tests/auto/gui/painting/qwmatrix/qwmatrix.pro b/tests/auto/gui/painting/qwmatrix/qwmatrix.pro
new file mode 100644
index 0000000000..bab298bc93
--- /dev/null
+++ b/tests/auto/gui/painting/qwmatrix/qwmatrix.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+SOURCES += tst_qwmatrix.cpp
+
+unix:!mac:!symbian:LIBS+=-lm
+
+
diff --git a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp
new file mode 100644
index 0000000000..0e7372d9d8
--- /dev/null
+++ b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp
@@ -0,0 +1,436 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <qmatrix.h>
+#include <math.h>
+#include <qpolygon.h>
+
+Q_DECLARE_METATYPE(QRect)
+
+//TESTED_CLASS=
+//TESTED_FILES=gui/painting/qmatrix.h gui/painting/qmatrix.cpp
+
+class tst_QWMatrix : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWMatrix();
+ virtual ~tst_QWMatrix();
+
+
+public slots:
+ void init();
+ void cleanup();
+private slots:
+ void mapRect_data();
+ void operator_star_qrect_data();
+ void mapToPolygon_data();
+ void mapRect();
+ void operator_star_qrect();
+ void operator_star_qwmatrix();
+ void assignments();
+ void mapToPolygon();
+ void translate();
+ void scale();
+ void mapPolygon();
+
+private:
+ void mapping_data();
+};
+
+Q_DECLARE_METATYPE(QMatrix)
+Q_DECLARE_METATYPE(QPolygon)
+
+tst_QWMatrix::tst_QWMatrix()
+{
+}
+
+tst_QWMatrix::~tst_QWMatrix()
+{
+}
+
+void tst_QWMatrix::init()
+{
+ // No initialisation is required
+}
+
+void tst_QWMatrix::cleanup()
+{
+ // No cleanup is required.
+}
+
+void tst_QWMatrix::mapRect_data()
+{
+ mapping_data();
+}
+
+void tst_QWMatrix::operator_star_qrect_data()
+{
+ mapping_data();
+}
+
+void tst_QWMatrix::mapToPolygon_data()
+{
+ mapping_data();
+}
+
+void tst_QWMatrix::mapping_data()
+{
+ //create the testtable instance and define the elements
+ QTest::addColumn<QMatrix>("matrix");
+ QTest::addColumn<QRect>("src");
+ QTest::addColumn<QPolygon>("res");
+
+ //next we fill it with data
+
+ // identity
+ QTest::newRow( "identity" ) << QMatrix( 1, 0, 0, 1, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 10, 20, 30, 40 ) );
+ // scaling
+ QTest::newRow( "scale 0" ) << QMatrix( 2, 0, 0, 2, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 20, 40, 60, 80 ) );
+ QTest::newRow( "scale 1" ) << QMatrix( 10, 0, 0, 10, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 100, 200, 300, 400 ) );
+ // mirroring
+ QTest::newRow( "mirror 0" ) << QMatrix( -1, 0, 0, 1, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -40, 20, 30, 40 ) );
+ QTest::newRow( "mirror 1" ) << QMatrix( 1, 0, 0, -1, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 10, -60, 30, 40 ) );
+ QTest::newRow( "mirror 2" ) << QMatrix( -1, 0, 0, -1, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -40, -60, 30, 40 ) );
+ QTest::newRow( "mirror 3" ) << QMatrix( -2, 0, 0, -2, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -80, -120, 60, 80 ) );
+ QTest::newRow( "mirror 4" ) << QMatrix( -10, 0, 0, -10, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -400, -600, 300, 400 ) );
+ QTest::newRow( "mirror 5" ) << QMatrix( -1, 0, 0, 1, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -30, 0, 30, 40 ) );
+ QTest::newRow( "mirror 6" ) << QMatrix( 1, 0, 0, -1, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -40, 30, 40 ) );
+ QTest::newRow( "mirror 7" ) << QMatrix( -1, 0, 0, -1, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -30, -40, 30, 40 ) );
+ QTest::newRow( "mirror 8" ) << QMatrix( -2, 0, 0, -2, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -60, -80, 60, 80 ) );
+ QTest::newRow( "mirror 9" ) << QMatrix( -10, 0, 0, -10, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -300, -400, 300, 400 ) );
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#define M_PI 3.14159265897932384626433832795f
+#endif
+
+ // rotations
+ float deg = 0.;
+ QTest::newRow( "rot 0 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon ( QRect( 0, 0, 30, 40 ) );
+ deg = 0.00001f;
+ QTest::newRow( "rot 0 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon ( QRect( 0, 0, 30, 40 ) );
+ deg = 0.;
+ QTest::newRow( "rot 0 c" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon ( QRect( 10, 20, 30, 40 ) );
+ deg = 0.00001f;
+ QTest::newRow( "rot 0 d" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon ( QRect( 10, 20, 30, 40 ) );
+
+#if 0
+ // rotations
+ deg = 90.;
+ QTest::newRow( "rotscale 90 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -299, 400, 300 ) );
+ deg = 90.00001;
+ QTest::newRow( "rotscale 90 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -299, 400, 300 ) );
+ deg = 90.;
+ QTest::newRow( "rotscale 90 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 200, -399, 400, 300 ) );
+ deg = 90.00001;
+ QTest::newRow( "rotscale 90 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 200, -399, 400, 300 ) );
+
+ deg = 180.;
+ QTest::newRow( "rotscale 180 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -299, -399, 300, 400 ) );
+ deg = 180.000001;
+ QTest::newRow( "rotscale 180 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -299, -399, 300, 400 ) );
+ deg = 180.;
+ QTest::newRow( "rotscale 180 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -399, -599, 300, 400 ) );
+ deg = 180.000001;
+ QTest::newRow( "rotscale 180 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -399, -599, 300, 400 ) );
+
+ deg = 270.;
+ QTest::newRow( "rotscale 270 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -399, 00, 400, 300 ) );
+ deg = 270.0000001;
+ QTest::newRow( "rotscale 270 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -399, 00, 400, 300 ) );
+ deg = 270.;
+ QTest::newRow( "rotscale 270 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -599, 100, 400, 300 ) );
+ deg = 270.000001;
+ QTest::newRow( "rotscale 270 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -599, 100, 400, 300 ) );
+
+ // rotations that are not multiples of 90 degrees. mapRect returns the bounding rect here.
+ deg = 45;
+ QTest::newRow( "rot 45 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( 0, -7, 14, 14 ) );
+ QTest::newRow( "rot 45 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 21, -14, 49, 49 ) );
+ QTest::newRow( "rot 45 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( 0, -70, 141, 141 ) );
+ QTest::newRow( "rot 45 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 212, -141, 495, 495 ) );
+
+ deg = -45;
+ QTest::newRow( "rot -45 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( -7, 0, 14, 14 ) );
+ QTest::newRow( "rot -45 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -35, 21, 49, 49 ) );
+ QTest::newRow( "rot -45 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( -70, 0, 141, 141 ) );
+ QTest::newRow( "rot -45 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -353, 212, 495, 495 ) );
+#endif
+}
+
+void tst_QWMatrix::mapRect()
+{
+ QFETCH( QMatrix, matrix );
+ QFETCH( QRect, src );
+// qDebug( "got src: %d/%d (%d/%d), matrix=[ %f %f %f %f %f %f ]",
+// src.x(), src.y(), src.width(), src.height(),
+// matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), matrix.dx(), matrix.dy() );
+ QTEST( QPolygon( matrix.mapRect(src) ), "res" );
+}
+
+void tst_QWMatrix::operator_star_qrect()
+{
+#if 0 // QT_VERSION >= 0x030100
+ QFETCH( QMatrix, matrix );
+ QFETCH( QRect, src );
+ QFETCH( QPolygon, res );
+
+ QCOMPARE( (matrix * src), QRegion(res) );
+#else
+ QSKIP( "Not tested with Qt versions < 3.1", SkipAll);
+#endif
+}
+
+
+void tst_QWMatrix::operator_star_qwmatrix()
+{
+#if 0
+ // Left out until the matrix multiply operator behaves properly..
+ QMatrix m1( 2, 3, 4, 5, 6, 7 );
+ QMatrix m2( 3, 4, 5, 6, 7, 8 );
+
+ QMatrix result1x2( 21, 26, 37, 46, 44, 75 );
+ QMatrix result2x1( 22, 29, 34, 45, 53, 80);
+
+ QMatrix product12 = m1*m2;
+ QMatrix product21 = m2*m1;
+
+ QVERIFY( product12==result1x2 );
+ QVERIFY( product21==result2x1 );
+#else
+ QSKIP( "Not tested with Qt versions since the operator is broken..",
+ SkipAll );
+#endif
+}
+
+
+void tst_QWMatrix::assignments()
+{
+ QMatrix m;
+ m.scale(2, 3);
+ m.rotate(45);
+ m.shear(4, 5);
+
+ QMatrix c1(m);
+
+ QCOMPARE(m.m11(), c1.m11());
+ QCOMPARE(m.m12(), c1.m12());
+ QCOMPARE(m.m21(), c1.m21());
+ QCOMPARE(m.m22(), c1.m22());
+ QCOMPARE(m.dx(), c1.dx());
+ QCOMPARE(m.dy(), c1.dy());
+
+ QMatrix c2 = m;
+ QCOMPARE(m.m11(), c2.m11());
+ QCOMPARE(m.m12(), c2.m12());
+ QCOMPARE(m.m21(), c2.m21());
+ QCOMPARE(m.m22(), c2.m22());
+ QCOMPARE(m.dx(), c2.dx());
+ QCOMPARE(m.dy(), c2.dy());
+}
+
+
+void tst_QWMatrix::mapToPolygon()
+{
+ QFETCH( QMatrix, matrix );
+ QFETCH( QRect, src );
+ QFETCH( QPolygon, res );
+
+ QCOMPARE( matrix.mapToPolygon( src ), res );
+}
+
+
+void tst_QWMatrix::translate()
+{
+ QMatrix m( 1, 2, 3, 4, 5, 6 );
+ QMatrix res2( m );
+ QMatrix res( 1, 2, 3, 4, 75, 106 );
+ m.translate( 10, 20 );
+ QVERIFY( m == res );
+ m.translate( -10, -20 );
+ QVERIFY( m == res2 );
+}
+
+void tst_QWMatrix::scale()
+{
+ QMatrix m( 1, 2, 3, 4, 5, 6 );
+ QMatrix res2( m );
+ QMatrix res( 10, 20, 60, 80, 5, 6 );
+ m.scale( 10, 20 );
+ QVERIFY( m == res );
+ m.scale( 1./10., 1./20. );
+ QVERIFY( m == res2 );
+}
+
+void tst_QWMatrix::mapPolygon()
+{
+ QPolygon poly;
+ poly << QPoint(0, 0) << QPoint(1, 1) << QPoint(100, 1) << QPoint(1, 100) << QPoint(-1, -1) << QPoint(-1000, 1000);
+
+ {
+ QMatrix m;
+ m.rotate(90);
+
+ // rotating 90 degrees four times should result in original poly
+ QPolygon mapped = m.map(m.map(m.map(m.map(poly))));
+ QCOMPARE(mapped, poly);
+
+ QMatrix m2;
+ m2.scale(10, 10);
+ QMatrix m3;
+ m3.scale(0.1, 0.1);
+
+ mapped = m3.map(m2.map(poly));
+ QCOMPARE(mapped, poly);
+ }
+
+ {
+ QMatrix m(1, 2, 3, 4, 5, 6);
+
+ QPolygon mapped = m.map(poly);
+ for (int i = 0; i < mapped.size(); ++i)
+ QCOMPARE(mapped.at(i), m.map(poly.at(i)));
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_QWMatrix)
+#include "tst_qwmatrix.moc"