1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 */ 10 11 #include <test/bootstrapfixture.hxx> 12 13 #include <vcl/bitmap.hxx> 14 #include <tools/stream.hxx> 15 #include <vcl/graphicfilter.hxx> 16 #include <basegfx/matrix/b2dhommatrix.hxx> 17 #include <bitmap/BitmapWriteAccess.hxx> 18 19 #include <test/outputdevice.hxx> 20 21 // Run tests from visualbackendtest ('bin/run visualbackendtest'). 22 class BackendTest : public test::BootstrapFixture 23 { 24 // if enabled - check the result images with: 25 // "xdg-open ./workdir/CppunitTest/vcl_backend_test.test.core/" 26 static constexpr const bool mbExportBitmap = false; 27 exportImage(OUString const & rsFilename,BitmapEx const & rBitmapEx)28 void exportImage(OUString const& rsFilename, BitmapEx const& rBitmapEx) 29 { 30 if (mbExportBitmap) 31 { 32 BitmapEx aBitmapEx(rBitmapEx); 33 aBitmapEx.Scale(Size(128, 128), BmpScaleFlag::Fast); 34 SvFileStream aStream(rsFilename, StreamMode::WRITE | StreamMode::TRUNC); 35 GraphicFilter::GetGraphicFilter().compressAsPNG(aBitmapEx, aStream); 36 } 37 } 38 exportImage(OUString const & rsFilename,Bitmap const & rBitmap)39 void exportImage(OUString const& rsFilename, Bitmap const& rBitmap) 40 { 41 if (mbExportBitmap) 42 { 43 Bitmap aBitmap(rBitmap); 44 aBitmap.Scale(Size(128, 128), BmpScaleFlag::Fast); 45 SvFileStream aStream(rsFilename, StreamMode::WRITE | StreamMode::TRUNC); 46 GraphicFilter::GetGraphicFilter().compressAsPNG(BitmapEx(aBitmap), aStream); 47 } 48 } 49 exportDevice(const OUString & filename,const VclPtr<VirtualDevice> & device)50 void exportDevice(const OUString& filename, const VclPtr<VirtualDevice>& device) 51 { 52 if (mbExportBitmap) 53 { 54 BitmapEx aBitmapEx(device->GetBitmapEx(Point(0, 0), device->GetOutputSizePixel())); 55 SvFileStream aStream(filename, StreamMode::WRITE | StreamMode::TRUNC); 56 GraphicFilter::GetGraphicFilter().compressAsPNG(aBitmapEx, aStream); 57 } 58 } 59 60 public: BackendTest()61 BackendTest() 62 : BootstrapFixture(true, false) 63 { 64 } 65 66 // We need to enable tests ONE BY ONE as they fail because of backend bugs 67 // it is still important to have the test defined so we know the issues 68 // exist and we need to fix them. Consistent behaviour of our backends 69 // is of highest priority. 70 assertBackendNameNotEmpty(const OUString & name)71 static bool assertBackendNameNotEmpty(const OUString& name) 72 { 73 // This ensures that all backends return a valid name. 74 assert(!name.isEmpty()); 75 (void)name; 76 return true; 77 } 78 79 // Check whether tests should fail depending on which backend is used 80 // (not all work). If you want to disable just a specific test 81 // for a specific backend, use something like 82 // 'if(SHOULD_ASSERT && aOutDevTest.getRenderBackendName() != "skia")'. 83 // The macro uses opt-out rather than opt-in so that this doesn't "pass" 84 // silently in case a new backend is added. 85 #define SHOULD_ASSERT \ 86 (assertBackendNameNotEmpty(aOutDevTest.getRenderBackendName()) \ 87 && aOutDevTest.getRenderBackendName() != "qt5" \ 88 && aOutDevTest.getRenderBackendName() != "qt5svp" \ 89 && aOutDevTest.getRenderBackendName() != "gtk3svp" \ 90 && aOutDevTest.getRenderBackendName() != "aqua" \ 91 && aOutDevTest.getRenderBackendName() != "gen" \ 92 && aOutDevTest.getRenderBackendName() != "genpsp" \ 93 && aOutDevTest.getRenderBackendName() != "win") 94 testDrawRectWithRectangle()95 void testDrawRectWithRectangle() 96 { 97 if (getDefaultDeviceBitCount() < 24) 98 return; 99 vcl::test::OutputDeviceTestRect aOutDevTest; 100 Bitmap aBitmap = aOutDevTest.setupRectangle(false); 101 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangle(aBitmap); 102 exportImage("01-01_rectangle_test-rectangle.png", aBitmap); 103 104 if (SHOULD_ASSERT) 105 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 106 } 107 testDrawRectWithPixel()108 void testDrawRectWithPixel() 109 { 110 if (getDefaultDeviceBitCount() < 24) 111 return; 112 vcl::test::OutputDeviceTestPixel aOutDevTest; 113 Bitmap aBitmap = aOutDevTest.setupRectangle(false); 114 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangle(aBitmap); 115 exportImage("01-02_rectangle_test-pixel.png", aBitmap); 116 117 if (SHOULD_ASSERT) 118 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 119 } 120 testDrawRectWithLine()121 void testDrawRectWithLine() 122 { 123 if (getDefaultDeviceBitCount() < 24) 124 return; 125 vcl::test::OutputDeviceTestLine aOutDevTest; 126 Bitmap aBitmap = aOutDevTest.setupRectangle(false); 127 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangle(aBitmap); 128 exportImage("01-03_rectangle_test-line.png", aBitmap); 129 130 if (SHOULD_ASSERT) 131 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 132 } 133 testDrawRectWithPolygon()134 void testDrawRectWithPolygon() 135 { 136 if (getDefaultDeviceBitCount() < 24) 137 return; 138 vcl::test::OutputDeviceTestPolygon aOutDevTest; 139 Bitmap aBitmap = aOutDevTest.setupRectangle(false); 140 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangle(aBitmap); 141 exportImage("01-04_rectangle_test-polygon.png", aBitmap); 142 if (SHOULD_ASSERT) 143 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 144 } 145 testDrawRectWithPolyLine()146 void testDrawRectWithPolyLine() 147 { 148 if (getDefaultDeviceBitCount() < 24) 149 return; 150 vcl::test::OutputDeviceTestPolyLine aOutDevTest; 151 Bitmap aBitmap = aOutDevTest.setupRectangle(false); 152 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangle(aBitmap); 153 exportImage("01-05_rectangle_test-polyline.png", aBitmap); 154 if (SHOULD_ASSERT) 155 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 156 } 157 testDrawRectWithPolyLineB2D()158 void testDrawRectWithPolyLineB2D() 159 { 160 if (getDefaultDeviceBitCount() < 24) 161 return; 162 vcl::test::OutputDeviceTestPolyLineB2D aOutDevTest; 163 Bitmap aBitmap = aOutDevTest.setupRectangle(false); 164 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangle(aBitmap); 165 exportImage("01-06_rectangle_test-polyline_b2d.png", aBitmap); 166 if (SHOULD_ASSERT) 167 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 168 } 169 testDrawRectWithPolyPolygon()170 void testDrawRectWithPolyPolygon() 171 { 172 if (getDefaultDeviceBitCount() < 24) 173 return; 174 vcl::test::OutputDeviceTestPolyPolygon aOutDevTest; 175 Bitmap aBitmap = aOutDevTest.setupRectangle(false); 176 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangle(aBitmap); 177 exportImage("01-07_rectangle_test-polypolygon.png", aBitmap); 178 if (SHOULD_ASSERT) 179 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 180 } 181 testDrawRectWithPolyPolygonB2D()182 void testDrawRectWithPolyPolygonB2D() 183 { 184 if (getDefaultDeviceBitCount() < 24) 185 return; 186 vcl::test::OutputDeviceTestPolyPolygonB2D aOutDevTest; 187 Bitmap aBitmap = aOutDevTest.setupRectangle(false); 188 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangle(aBitmap); 189 exportImage("01-08_rectangle_test-polypolygon_b2d.png", aBitmap); 190 if (SHOULD_ASSERT) 191 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 192 } 193 testDrawRectAAWithRectangle()194 void testDrawRectAAWithRectangle() 195 { 196 if (getDefaultDeviceBitCount() < 24) 197 return; 198 vcl::test::OutputDeviceTestRect aOutDevTest; 199 Bitmap aBitmap = aOutDevTest.setupRectangle(true); 200 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangleAA(aBitmap); 201 exportImage("02-01_rectangle_AA_test-rectangle.png", aBitmap); 202 if (SHOULD_ASSERT) 203 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 204 } 205 testDrawRectAAWithPixel()206 void testDrawRectAAWithPixel() 207 { 208 if (getDefaultDeviceBitCount() < 24) 209 return; 210 vcl::test::OutputDeviceTestPixel aOutDevTest; 211 Bitmap aBitmap = aOutDevTest.setupRectangle(true); 212 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangleAA(aBitmap); 213 exportImage("02-02_rectangle_AA_test-pixel.png", aBitmap); 214 if (SHOULD_ASSERT) 215 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 216 } 217 testDrawRectAAWithLine()218 void testDrawRectAAWithLine() 219 { 220 if (getDefaultDeviceBitCount() < 24) 221 return; 222 vcl::test::OutputDeviceTestLine aOutDevTest; 223 Bitmap aBitmap = aOutDevTest.setupRectangle(true); 224 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangleAA(aBitmap); 225 exportImage("02-03_rectangle_AA_test-line.png", aBitmap); 226 if (SHOULD_ASSERT) 227 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 228 } 229 testDrawRectAAWithPolygon()230 void testDrawRectAAWithPolygon() 231 { 232 if (getDefaultDeviceBitCount() < 24) 233 return; 234 vcl::test::OutputDeviceTestPolygon aOutDevTest; 235 Bitmap aBitmap = aOutDevTest.setupRectangle(true); 236 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangleAA(aBitmap); 237 exportImage("02-04_rectangle_AA_test-polygon.png", aBitmap); 238 if (SHOULD_ASSERT) 239 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 240 } 241 testDrawRectAAWithPolyLine()242 void testDrawRectAAWithPolyLine() 243 { 244 if (getDefaultDeviceBitCount() < 24) 245 return; 246 vcl::test::OutputDeviceTestPolyLine aOutDevTest; 247 Bitmap aBitmap = aOutDevTest.setupRectangle(true); 248 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangleAA(aBitmap); 249 exportImage("02-05_rectangle_AA_test-polyline.png", aBitmap); 250 if (SHOULD_ASSERT) 251 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 252 } 253 testDrawRectAAWithPolyLineB2D()254 void testDrawRectAAWithPolyLineB2D() 255 { 256 if (getDefaultDeviceBitCount() < 24) 257 return; 258 vcl::test::OutputDeviceTestPolyLineB2D aOutDevTest; 259 Bitmap aBitmap = aOutDevTest.setupRectangle(true); 260 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangleAA(aBitmap); 261 exportImage("02-06_rectangle_AA_test-polyline_b2d.png", aBitmap); 262 if (SHOULD_ASSERT) 263 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 264 } 265 testDrawRectAAWithPolyPolygon()266 void testDrawRectAAWithPolyPolygon() 267 { 268 if (getDefaultDeviceBitCount() < 24) 269 return; 270 vcl::test::OutputDeviceTestPolyPolygon aOutDevTest; 271 Bitmap aBitmap = aOutDevTest.setupRectangle(true); 272 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangleAA(aBitmap); 273 exportImage("02-07_rectangle_AA_test-polypolygon.png", aBitmap); 274 if (SHOULD_ASSERT) 275 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 276 } 277 testDrawRectAAWithPolyPolygonB2D()278 void testDrawRectAAWithPolyPolygonB2D() 279 { 280 if (getDefaultDeviceBitCount() < 24) 281 return; 282 vcl::test::OutputDeviceTestPolyPolygonB2D aOutDevTest; 283 Bitmap aBitmap = aOutDevTest.setupRectangle(true); 284 auto eResult = vcl::test::OutputDeviceTestCommon::checkRectangleAA(aBitmap); 285 exportImage("02-08_rectangle_AA_test-polypolygon_b2d.png", aBitmap); 286 if (SHOULD_ASSERT) 287 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 288 } 289 testDrawFilledRectWithRectangle()290 void testDrawFilledRectWithRectangle() 291 { 292 if (getDefaultDeviceBitCount() < 24) 293 return; 294 vcl::test::OutputDeviceTestRect aOutDevTest; 295 Bitmap aBitmap = aOutDevTest.setupFilledRectangle(false); 296 auto eResult = vcl::test::OutputDeviceTestCommon::checkFilledRectangle(aBitmap, false); 297 exportImage("03-01_filled_rectangle_test-rectangle_noline.png", aBitmap); 298 if (SHOULD_ASSERT) 299 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 300 aBitmap = aOutDevTest.setupFilledRectangle(true); 301 eResult = vcl::test::OutputDeviceTestCommon::checkFilledRectangle(aBitmap, true); 302 exportImage("03-01_filled_rectangle_test-rectangle_line.png", aBitmap); 303 if (SHOULD_ASSERT) 304 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 305 } 306 testDrawFilledRectWithPolygon()307 void testDrawFilledRectWithPolygon() 308 { 309 if (getDefaultDeviceBitCount() < 24) 310 return; 311 vcl::test::OutputDeviceTestPolygon aOutDevTest; 312 Bitmap aBitmap = aOutDevTest.setupFilledRectangle(false); 313 auto eResult = vcl::test::OutputDeviceTestCommon::checkFilledRectangle(aBitmap, false); 314 exportImage("03-02_filled_rectangle_test-polygon_noline.png", aBitmap); 315 if (SHOULD_ASSERT) 316 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 317 aBitmap = aOutDevTest.setupFilledRectangle(true); 318 eResult = vcl::test::OutputDeviceTestCommon::checkFilledRectangle(aBitmap, true); 319 exportImage("03-02_filled_rectangle_test-polygon_line.png", aBitmap); 320 if (SHOULD_ASSERT) 321 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 322 } 323 testDrawFilledRectWithPolyPolygon()324 void testDrawFilledRectWithPolyPolygon() 325 { 326 if (getDefaultDeviceBitCount() < 24) 327 return; 328 vcl::test::OutputDeviceTestPolyPolygon aOutDevTest; 329 Bitmap aBitmap = aOutDevTest.setupFilledRectangle(false); 330 auto eResult = vcl::test::OutputDeviceTestCommon::checkFilledRectangle(aBitmap, false); 331 exportImage("03-03_filled_rectangle_test-polypolygon_noline.png", aBitmap); 332 if (SHOULD_ASSERT) 333 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 334 aBitmap = aOutDevTest.setupFilledRectangle(true); 335 eResult = vcl::test::OutputDeviceTestCommon::checkFilledRectangle(aBitmap, true); 336 exportImage("03-03_filled_rectangle_test-polypolygon_line.png", aBitmap); 337 if (SHOULD_ASSERT) 338 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 339 } 340 testDrawFilledRectWithPolyPolygon2D()341 void testDrawFilledRectWithPolyPolygon2D() 342 { 343 if (getDefaultDeviceBitCount() < 24) 344 return; 345 vcl::test::OutputDeviceTestPolyPolygonB2D aOutDevTest; 346 Bitmap aBitmap = aOutDevTest.setupFilledRectangle(false); 347 auto eResult = vcl::test::OutputDeviceTestCommon::checkFilledRectangle(aBitmap, false); 348 exportImage("03-04_filled_rectangle_test-polypolygon_b2d_noline.png", aBitmap); 349 if (SHOULD_ASSERT) 350 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 351 aBitmap = aOutDevTest.setupFilledRectangle(true); 352 eResult = vcl::test::OutputDeviceTestCommon::checkFilledRectangle(aBitmap, true); 353 exportImage("03-04_filled_rectangle_test-polypolygon_b2d_line.png", aBitmap); 354 if (SHOULD_ASSERT) 355 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 356 } 357 testDrawDiamondWithPolygon()358 void testDrawDiamondWithPolygon() 359 { 360 vcl::test::OutputDeviceTestPolygon aOutDevTest; 361 Bitmap aBitmap = aOutDevTest.setupDiamond(); 362 auto eResult = vcl::test::OutputDeviceTestCommon::checkDiamond(aBitmap); 363 exportImage("04-01_diamond_test-polygon.png", aBitmap); 364 if (SHOULD_ASSERT) 365 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 366 } 367 testDrawDiamondWithLine()368 void testDrawDiamondWithLine() 369 { 370 vcl::test::OutputDeviceTestLine aOutDevTest; 371 Bitmap aBitmap = aOutDevTest.setupDiamond(); 372 auto eResult = vcl::test::OutputDeviceTestCommon::checkDiamond(aBitmap); 373 exportImage("04-02_diamond_test-line.png", aBitmap); 374 if (SHOULD_ASSERT) 375 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 376 } 377 testDrawDiamondWithPolyline()378 void testDrawDiamondWithPolyline() 379 { 380 vcl::test::OutputDeviceTestPolyLine aOutDevTest; 381 Bitmap aBitmap = aOutDevTest.setupDiamond(); 382 auto eResult = vcl::test::OutputDeviceTestCommon::checkDiamond(aBitmap); 383 exportImage("04-03_diamond_test-polyline.png", aBitmap); 384 if (SHOULD_ASSERT) 385 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 386 } 387 testDrawDiamondWithPolylineB2D()388 void testDrawDiamondWithPolylineB2D() 389 { 390 vcl::test::OutputDeviceTestPolyLineB2D aOutDevTest; 391 Bitmap aBitmap = aOutDevTest.setupDiamond(); 392 auto eResult = vcl::test::OutputDeviceTestCommon::checkDiamond(aBitmap); 393 exportImage("04-04_diamond_test-polyline_b2d.png", aBitmap); 394 if (SHOULD_ASSERT) 395 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 396 } 397 testDrawInvertWithRectangle()398 void testDrawInvertWithRectangle() 399 { 400 vcl::test::OutputDeviceTestRect aOutDevTest; 401 Bitmap aBitmap = aOutDevTest.setupInvert_NONE(); 402 auto eResult = vcl::test::OutputDeviceTestCommon::checkInvertRectangle(aBitmap); 403 exportImage("05-01_invert_test-rectangle.png", aBitmap); 404 if (SHOULD_ASSERT) 405 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 406 } 407 testDrawInvertN50WithRectangle()408 void testDrawInvertN50WithRectangle() 409 { 410 vcl::test::OutputDeviceTestRect aOutDevTest; 411 Bitmap aBitmap = aOutDevTest.setupInvert_N50(); 412 auto eResult = vcl::test::OutputDeviceTestCommon::checkInvertN50Rectangle(aBitmap); 413 exportImage("05-02_invert_N50_test-rectangle.png", aBitmap); 414 if (SHOULD_ASSERT && aOutDevTest.getRenderBackendName() != "svp") 415 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 416 } 417 testDrawInvertTrackFrameWithRectangle()418 void testDrawInvertTrackFrameWithRectangle() 419 { 420 vcl::test::OutputDeviceTestRect aOutDevTest; 421 Bitmap aBitmap = aOutDevTest.setupInvert_TrackFrame(); 422 auto eResult = vcl::test::OutputDeviceTestCommon::checkInvertTrackFrameRectangle(aBitmap); 423 exportImage("05-03_invert_TrackFrame_test-rectangle.png", aBitmap); 424 if (SHOULD_ASSERT && aOutDevTest.getRenderBackendName() != "svp") 425 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 426 } 427 testDrawBezierWithPolylineB2D()428 void testDrawBezierWithPolylineB2D() 429 { 430 if (getDefaultDeviceBitCount() < 24) 431 return; 432 vcl::test::OutputDeviceTestPolyLineB2D aOutDevTest; 433 Bitmap aBitmap = aOutDevTest.setupBezier(); 434 auto eResult = vcl::test::OutputDeviceTestCommon::checkBezier(aBitmap); 435 exportImage("06-01_bezier_test-polyline_b2d.png", aBitmap); 436 if (SHOULD_ASSERT) 437 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 438 } 439 testDrawBezierAAWithPolylineB2D()440 void testDrawBezierAAWithPolylineB2D() 441 { 442 if (getDefaultDeviceBitCount() < 24) 443 return; 444 vcl::test::OutputDeviceTestPolyLineB2D aOutDevTest; 445 Bitmap aBitmap = aOutDevTest.setupAABezier(); 446 auto eResult = vcl::test::OutputDeviceTestCommon::checkBezier(aBitmap); 447 exportImage("07-01_bezier_AA_test-polyline_b2d.png", aBitmap); 448 if (SHOULD_ASSERT) 449 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 450 } 451 testDrawBitmap()452 void testDrawBitmap() 453 { 454 if (getDefaultDeviceBitCount() < 24) 455 return; 456 vcl::test::OutputDeviceTestBitmap aOutDevTest; 457 Bitmap aBitmap = aOutDevTest.setupDrawBitmap(); 458 exportImage("08-01_bitmap_test.png", aBitmap); 459 auto eResult = vcl::test::OutputDeviceTestBitmap::checkTransformedBitmap(aBitmap); 460 if (SHOULD_ASSERT) 461 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 462 } 463 testDrawTransformedBitmap()464 void testDrawTransformedBitmap() 465 { 466 if (getDefaultDeviceBitCount() < 24) 467 return; 468 vcl::test::OutputDeviceTestBitmap aOutDevTest; 469 Bitmap aBitmap = aOutDevTest.setupDrawTransformedBitmap(); 470 auto eResult = vcl::test::OutputDeviceTestBitmap::checkTransformedBitmap(aBitmap); 471 exportImage("08-02_transformed_bitmap_test.png", aBitmap); 472 if (SHOULD_ASSERT) 473 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 474 } 475 testDrawBitmapExWithAlpha()476 void testDrawBitmapExWithAlpha() 477 { 478 if (getDefaultDeviceBitCount() < 24) 479 return; 480 vcl::test::OutputDeviceTestBitmap aOutDevTest; 481 Bitmap aBitmap = aOutDevTest.setupDrawBitmapExWithAlpha(); 482 auto eResult = vcl::test::OutputDeviceTestBitmap::checkBitmapExWithAlpha(aBitmap); 483 exportImage("08-03_bitmapex_with_alpha_test.png", aBitmap); 484 if (SHOULD_ASSERT) 485 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 486 } 487 testDrawMask()488 void testDrawMask() 489 { 490 if (getDefaultDeviceBitCount() < 24) 491 return; 492 vcl::test::OutputDeviceTestBitmap aOutDevTest; 493 Bitmap aBitmap = aOutDevTest.setupDrawMask(); 494 auto eResult = vcl::test::OutputDeviceTestBitmap::checkMask(aBitmap); 495 exportImage("08-04_mask_test.png", aBitmap); 496 if (SHOULD_ASSERT) 497 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 498 } 499 testDrawBlend()500 void testDrawBlend() 501 { 502 if (getDefaultDeviceBitCount() < 24) 503 return; 504 vcl::test::OutputDeviceTestBitmap aOutDevTest; 505 BitmapEx aBitmapEx = aOutDevTest.setupDrawBlend(); 506 auto eResult = vcl::test::OutputDeviceTestBitmap::checkBlend(aBitmapEx); 507 exportImage("08-05_blend_test.png", aBitmapEx); 508 if (SHOULD_ASSERT) 509 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 510 } 511 testDrawXor()512 void testDrawXor() 513 { 514 if (getDefaultDeviceBitCount() < 24) 515 return; 516 vcl::test::OutputDeviceTestAnotherOutDev aOutDevTest; 517 Bitmap aBitmap = aOutDevTest.setupXOR(); 518 auto eResult = vcl::test::OutputDeviceTestAnotherOutDev::checkXOR(aBitmap); 519 exportImage("08-06_xor_test.png", aBitmap); 520 if (SHOULD_ASSERT) 521 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 522 } 523 testDrawTransformedBitmapExAlpha()524 void testDrawTransformedBitmapExAlpha() 525 { 526 // TODO: This unit test is not executed for macOS unless bitmap scaling is implemented 527 #ifndef MACOSX 528 if (getDefaultDeviceBitCount() < 24) 529 return; 530 ScopedVclPtrInstance<VirtualDevice> device; 531 device->SetOutputSizePixel(Size(16, 16)); 532 device->SetBackground(Wallpaper(COL_WHITE)); 533 device->Erase(); 534 Bitmap aBitmap(Size(16, 16), vcl::PixelFormat::N24_BPP); 535 { 536 // Fill the top left quarter with black. 537 BitmapScopedWriteAccess pWriteAccess(aBitmap); 538 pWriteAccess->Erase(COL_WHITE); 539 for (int i = 0; i < 8; ++i) 540 for (int j = 0; j < 8; ++j) 541 pWriteAccess->SetPixel(j, i, COL_BLACK); 542 } 543 BitmapEx aBitmapEx(aBitmap); 544 basegfx::B2DHomMatrix aMatrix; 545 // Draw with no transformation, only alpha change. 546 aMatrix.scale(16, 16); 547 device->DrawTransformedBitmapEx(aMatrix, aBitmapEx, 0.5); 548 BitmapEx result = device->GetBitmapEx(Point(0, 0), Size(16, 16)); 549 CPPUNIT_ASSERT_EQUAL(Color(0x80, 0x80, 0x80), result.GetPixelColor(0, 0)); 550 CPPUNIT_ASSERT_EQUAL(COL_WHITE, result.GetPixelColor(15, 15)); 551 // Draw rotated and move to the bottom-left corner. 552 device->Erase(); 553 aMatrix.identity(); 554 aMatrix.scale(16, 16); 555 aMatrix.rotate(M_PI / 2); 556 aMatrix.translate(8, 8); 557 device->DrawTransformedBitmapEx(aMatrix, aBitmapEx, 0.5); 558 result = device->GetBitmap(Point(0, 0), Size(16, 16)); 559 CPPUNIT_ASSERT_EQUAL(COL_WHITE, result.GetPixelColor(0, 0)); 560 CPPUNIT_ASSERT_EQUAL(Color(0x80, 0x80, 0x80), result.GetPixelColor(0, 15)); 561 #endif 562 } 563 testClipRectangle()564 void testClipRectangle() 565 { 566 if (getDefaultDeviceBitCount() < 24) 567 return; 568 vcl::test::OutputDeviceTestClip aOutDevTest; 569 Bitmap aBitmap = aOutDevTest.setupClipRectangle(); 570 auto eResult = vcl::test::OutputDeviceTestClip::checkClip(aBitmap); 571 exportImage("09-01_clip_rectangle_test.png", aBitmap); 572 if (SHOULD_ASSERT) 573 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 574 } 575 testClipPolygon()576 void testClipPolygon() 577 { 578 if (getDefaultDeviceBitCount() < 24) 579 return; 580 vcl::test::OutputDeviceTestClip aOutDevTest; 581 Bitmap aBitmap = aOutDevTest.setupClipPolygon(); 582 auto eResult = vcl::test::OutputDeviceTestClip::checkClip(aBitmap); 583 exportImage("09-02_clip_polygon_test.png", aBitmap); 584 if (SHOULD_ASSERT) 585 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 586 } 587 testClipPolyPolygon()588 void testClipPolyPolygon() 589 { 590 if (getDefaultDeviceBitCount() < 24) 591 return; 592 vcl::test::OutputDeviceTestClip aOutDevTest; 593 Bitmap aBitmap = aOutDevTest.setupClipPolyPolygon(); 594 auto eResult = vcl::test::OutputDeviceTestClip::checkClip(aBitmap); 595 exportImage("09-03_clip_polypolygon_test.png", aBitmap); 596 if (SHOULD_ASSERT) 597 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 598 } 599 testClipB2DPolyPolygon()600 void testClipB2DPolyPolygon() 601 { 602 if (getDefaultDeviceBitCount() < 24) 603 return; 604 vcl::test::OutputDeviceTestClip aOutDevTest; 605 Bitmap aBitmap = aOutDevTest.setupClipB2DPolyPolygon(); 606 auto eResult = vcl::test::OutputDeviceTestClip::checkClip(aBitmap); 607 exportImage("09-04_clip_b2dpolypolygon_test.png", aBitmap); 608 if (SHOULD_ASSERT) 609 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 610 } 611 testDrawOutDev()612 void testDrawOutDev() 613 { 614 if (getDefaultDeviceBitCount() < 24) 615 return; 616 vcl::test::OutputDeviceTestAnotherOutDev aOutDevTest; 617 Bitmap aBitmap = aOutDevTest.setupDrawOutDev(); 618 auto eResult = vcl::test::OutputDeviceTestAnotherOutDev::checkDrawOutDev(aBitmap); 619 exportImage("10-01_draw_out_dev_test.png", aBitmap); 620 if (SHOULD_ASSERT) 621 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 622 } 623 testDashedLine()624 void testDashedLine() 625 { 626 if (getDefaultDeviceBitCount() < 24) 627 return; 628 vcl::test::OutputDeviceTestLine aOutDevTest; 629 Bitmap aBitmap = aOutDevTest.setupDashedLine(); 630 auto eResult = vcl::test::OutputDeviceTestLine::checkDashedLine(aBitmap); 631 exportImage("11-01_dashed_line_test.png", aBitmap); 632 if (SHOULD_ASSERT) 633 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 634 } 635 testErase()636 void testErase() 637 { 638 if (getDefaultDeviceBitCount() < 24) 639 return; 640 { 641 // Create normal virtual device (no alpha). 642 ScopedVclPtr<VirtualDevice> device 643 = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT); 644 device->SetOutputSizePixel(Size(10, 10)); 645 // Erase with white, check it's white. 646 device->SetBackground(Wallpaper(COL_WHITE)); 647 device->Erase(); 648 exportDevice("/tmp/12-01_erase.png", device); 649 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(0, 0))); 650 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(9, 9))); 651 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(5, 5))); 652 // Erase with black, check it's black. 653 device->SetBackground(Wallpaper(COL_BLACK)); 654 device->Erase(); 655 exportDevice("/tmp/12-02_erase.png", device); 656 CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(0, 0))); 657 CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(9, 9))); 658 CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(5, 5))); 659 // Erase with cyan, check it's cyan. 660 device->SetBackground(Wallpaper(COL_CYAN)); 661 device->Erase(); 662 exportDevice("/tmp/12-03_erase.png", device); 663 CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(0, 0))); 664 CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(9, 9))); 665 CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(5, 5))); 666 } 667 { 668 // Create virtual device with alpha. 669 ScopedVclPtr<VirtualDevice> device 670 = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT); 671 device->SetOutputSizePixel(Size(10, 10)); 672 // Erase with white, check it's white. 673 device->SetBackground(Wallpaper(COL_WHITE)); 674 device->Erase(); 675 exportDevice("/tmp/12-04_erase.png", device); 676 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(0, 0))); 677 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(9, 9))); 678 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(5, 5))); 679 // Erase with black, check it's black. 680 device->SetBackground(Wallpaper(COL_BLACK)); 681 device->Erase(); 682 exportDevice("/tmp/12-05_erase.png", device); 683 CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(0, 0))); 684 CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(9, 9))); 685 CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(5, 5))); 686 // Erase with cyan, check it's cyan. 687 device->SetBackground(Wallpaper(COL_CYAN)); 688 device->Erase(); 689 exportDevice("/tmp/12-06_erase.png", device); 690 CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(0, 0))); 691 CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(9, 9))); 692 CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(5, 5))); 693 // Erase with transparent, check it's transparent. 694 device->SetBackground(Wallpaper(COL_TRANSPARENT)); 695 device->Erase(); 696 exportDevice("/tmp/12-07_erase.png", device); 697 CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), device->GetPixel(Point(0, 0)).GetAlpha()); 698 CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), device->GetPixel(Point(9, 9)).GetAlpha()); 699 CPPUNIT_ASSERT_EQUAL(sal_uInt8(0), device->GetPixel(Point(5, 5)).GetAlpha()); 700 } 701 } 702 testLinearGradient()703 void testLinearGradient() 704 { 705 if (getDefaultDeviceBitCount() < 24) 706 return; 707 vcl::test::OutputDeviceTestGradient aOutDevTest; 708 Bitmap aBitmap = aOutDevTest.setupLinearGradient(); 709 auto eResult = vcl::test::OutputDeviceTestGradient::checkLinearGradient(aBitmap); 710 exportImage("13-01_linear_gradient_test.png", aBitmap); 711 if (SHOULD_ASSERT) 712 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 713 } 714 testLinearGradientAngled()715 void testLinearGradientAngled() 716 { 717 if (getDefaultDeviceBitCount() < 24) 718 return; 719 vcl::test::OutputDeviceTestGradient aOutDevTest; 720 Bitmap aBitmap = aOutDevTest.setupLinearGradientAngled(); 721 auto eResult = vcl::test::OutputDeviceTestGradient::checkLinearGradientAngled(aBitmap); 722 exportImage("13-02_linear_gradient_angled_test.png", aBitmap); 723 if (SHOULD_ASSERT) 724 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 725 } 726 testLinearGradientBorder()727 void testLinearGradientBorder() 728 { 729 vcl::test::OutputDeviceTestGradient aOutDevTest; 730 Bitmap aBitmap = aOutDevTest.setupLinearGradientBorder(); 731 auto eResult = vcl::test::OutputDeviceTestGradient::checkLinearGradientBorder(aBitmap); 732 exportImage("13-03_linear_gradient_border_test.png", aBitmap); 733 if (SHOULD_ASSERT) 734 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 735 } 736 testLinearGradientIntensity()737 void testLinearGradientIntensity() 738 { 739 if (getDefaultDeviceBitCount() < 24) 740 return; 741 vcl::test::OutputDeviceTestGradient aOutDevTest; 742 Bitmap aBitmap = aOutDevTest.setupLinearGradientIntensity(); 743 auto eResult = vcl::test::OutputDeviceTestGradient::checkLinearGradientIntensity(aBitmap); 744 exportImage("13-04_linear_gradient_intensity_test.png", aBitmap); 745 if (SHOULD_ASSERT) 746 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 747 } 748 testLinearGradientSteps()749 void testLinearGradientSteps() 750 { 751 if (getDefaultDeviceBitCount() < 24) 752 return; 753 vcl::test::OutputDeviceTestGradient aOutDevTest; 754 Bitmap aBitmap = aOutDevTest.setupLinearGradientSteps(); 755 auto eResult = vcl::test::OutputDeviceTestGradient::checkLinearGradientSteps(aBitmap); 756 exportImage("13-05_linear_gradient_steps_test.png", aBitmap); 757 if (SHOULD_ASSERT) 758 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 759 } 760 testAxialGradient()761 void testAxialGradient() 762 { 763 if (getDefaultDeviceBitCount() < 24) 764 return; 765 vcl::test::OutputDeviceTestGradient aOutDevTest; 766 Bitmap aBitmap = aOutDevTest.setupAxialGradient(); 767 auto eResult = vcl::test::OutputDeviceTestGradient::checkAxialGradient(aBitmap); 768 exportImage("13-06_axial_gradient_test.png", aBitmap); 769 if (SHOULD_ASSERT) 770 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 771 } 772 testRadialGradient()773 void testRadialGradient() 774 { 775 if (getDefaultDeviceBitCount() < 24) 776 return; 777 vcl::test::OutputDeviceTestGradient aOutDevTest; 778 Bitmap aBitmap = aOutDevTest.setupRadialGradient(); 779 auto eResult = vcl::test::OutputDeviceTestGradient::checkRadialGradient(aBitmap); 780 exportImage("13-07_radial_gradient_test.png", aBitmap); 781 if (SHOULD_ASSERT) 782 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 783 } 784 testRadialGradientOfs()785 void testRadialGradientOfs() 786 { 787 vcl::test::OutputDeviceTestGradient aOutDevTest; 788 Bitmap aBitmap = aOutDevTest.setupRadialGradientOfs(); 789 auto eResult = vcl::test::OutputDeviceTestGradient::checkRadialGradientOfs(aBitmap); 790 exportImage("13-08_radial_gradient_ofs_test.png", aBitmap); 791 if (SHOULD_ASSERT) 792 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 793 } 794 testLineJoinBevel()795 void testLineJoinBevel() 796 { 797 vcl::test::OutputDeviceTestLine aOutDevTest; 798 Bitmap aBitmap = aOutDevTest.setupLineJoinBevel(); 799 auto eResult = vcl::test::OutputDeviceTestLine::checkLineJoinBevel(aBitmap); 800 exportImage("14-01_line_join_bevel_test.png", aBitmap); 801 if (SHOULD_ASSERT) 802 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 803 } 804 testLineJoinRound()805 void testLineJoinRound() 806 { 807 vcl::test::OutputDeviceTestLine aOutDevTest; 808 Bitmap aBitmap = aOutDevTest.setupLineJoinRound(); 809 auto eResult = vcl::test::OutputDeviceTestLine::checkLineJoinRound(aBitmap); 810 exportImage("14-02_line_join_round_test.png", aBitmap); 811 if (SHOULD_ASSERT) 812 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 813 } 814 testLineJoinMiter()815 void testLineJoinMiter() 816 { 817 vcl::test::OutputDeviceTestLine aOutDevTest; 818 Bitmap aBitmap = aOutDevTest.setupLineJoinMiter(); 819 auto eResult = vcl::test::OutputDeviceTestLine::checkLineJoinMiter(aBitmap); 820 exportImage("14-03_line_join_miter_test.png", aBitmap); 821 if (SHOULD_ASSERT) 822 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 823 } 824 testLineJoinNone()825 void testLineJoinNone() 826 { 827 vcl::test::OutputDeviceTestLine aOutDevTest; 828 Bitmap aBitmap = aOutDevTest.setupLineJoinNone(); 829 auto eResult = vcl::test::OutputDeviceTestLine::checkLineJoinNone(aBitmap); 830 exportImage("14-04_line_join_none_test.png", aBitmap); 831 if (SHOULD_ASSERT) 832 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 833 } 834 testLineCapRound()835 void testLineCapRound() 836 { 837 vcl::test::OutputDeviceTestLine aOutDevTest; 838 Bitmap aBitmap = aOutDevTest.setupLineCapRound(); 839 auto eResult = vcl::test::OutputDeviceTestLine::checkLineCapRound(aBitmap); 840 exportImage("14-05_line_cap_round_test.png", aBitmap); 841 if (SHOULD_ASSERT) 842 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 843 } 844 testLineCapSquare()845 void testLineCapSquare() 846 { 847 vcl::test::OutputDeviceTestLine aOutDevTest; 848 Bitmap aBitmap = aOutDevTest.setupLineCapSquare(); 849 auto eResult = vcl::test::OutputDeviceTestLine::checkLineCapSquare(aBitmap); 850 exportImage("14-06_line_cap_square_test.png", aBitmap); 851 if (SHOULD_ASSERT) 852 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 853 } 854 testLineCapButt()855 void testLineCapButt() 856 { 857 vcl::test::OutputDeviceTestLine aOutDevTest; 858 Bitmap aBitmap = aOutDevTest.setupLineCapButt(); 859 auto eResult = vcl::test::OutputDeviceTestLine::checkLineCapButt(aBitmap); 860 exportImage("14-07_line_cap_butt_test.png", aBitmap); 861 if (SHOULD_ASSERT) 862 CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed); 863 } 864 865 // Test SalGraphics::blendBitmap() and blendAlphaBitmap() calls. testDrawBlendExtended()866 void testDrawBlendExtended() 867 { 868 // TODO: This unit test is not executed for macOS unless bitmap scaling is implemented 869 #ifndef MACOSX 870 if (getDefaultDeviceBitCount() < 24) 871 return; 872 // Create virtual device with alpha. 873 ScopedVclPtr<VirtualDevice> device 874 = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT); 875 device->SetOutputSizePixel(Size(10, 10)); 876 device->SetBackground(Wallpaper(COL_WHITE)); 877 device->Erase(); 878 Bitmap bitmap(Size(5, 5), vcl::PixelFormat::N24_BPP); 879 bitmap.Erase(COL_BLUE); 880 // No alpha, this will actually call SalGraphics::DrawBitmap(), but still check 881 // the alpha of the device is handled correctly. 882 device->DrawBitmapEx(Point(2, 2), BitmapEx(bitmap)); 883 exportDevice("/tmp/blend_extended_01.png", device); 884 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(2, 2))); 885 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(6, 6))); 886 // Check pixels outside of the bitmap aren't affected. 887 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(1, 1))); 888 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(7, 7))); 889 890 device->Erase(); 891 AlphaMask alpha(Size(5, 5)); 892 alpha.Erase(0); // opaque 893 device->DrawBitmapEx(Point(2, 2), BitmapEx(bitmap, alpha)); 894 exportDevice("/tmp/blend_extended_02.png", device); 895 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(2, 2))); 896 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(6, 6))); 897 898 device->Erase(); 899 alpha.Erase(255); // transparent 900 device->DrawBitmapEx(Point(2, 2), BitmapEx(bitmap, alpha)); 901 exportDevice("/tmp/blend_extended_03.png", device); 902 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(2, 2))); 903 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(6, 6))); 904 905 // Skia optimizes bitmaps that have just been Erase()-ed, so explicitly 906 // set some pixels in the alpha to avoid this and have an actual bitmap 907 // as the alpha mask. 908 device->Erase(); 909 alpha.Erase(255); // transparent 910 BitmapWriteAccess* alphaWrite = alpha.AcquireAlphaWriteAccess(); 911 alphaWrite->SetPixelIndex(0, 0, 0); // opaque 912 alpha.ReleaseAccess(alphaWrite); 913 device->DrawBitmapEx(Point(2, 2), BitmapEx(bitmap, alpha)); 914 exportDevice("/tmp/blend_extended_04.png", device); 915 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(2, 2))); 916 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(6, 6))); 917 #endif 918 } 919 testDrawAlphaBitmapMirrored()920 void testDrawAlphaBitmapMirrored() 921 { 922 // TODO: This unit test is not executed for macOS unless bitmap scaling is implemented 923 #ifndef MACOSX 924 if (getDefaultDeviceBitCount() < 24) 925 return; 926 // Normal virtual device. 927 ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT); 928 // Virtual device with alpha. 929 ScopedVclPtr<VirtualDevice> alphaDevice 930 = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT); 931 device->SetOutputSizePixel(Size(20, 20)); 932 device->SetBackground(Wallpaper(COL_BLACK)); 933 device->Erase(); 934 alphaDevice->SetOutputSizePixel(Size(20, 20)); 935 alphaDevice->SetBackground(Wallpaper(COL_BLACK)); 936 alphaDevice->Erase(); 937 Bitmap bitmap(Size(4, 4), vcl::PixelFormat::N24_BPP); 938 AlphaMask alpha(Size(4, 4)); 939 bitmap.Erase(COL_LIGHTBLUE); 940 { 941 BitmapScopedWriteAccess writeAccess(bitmap); 942 writeAccess->SetPixel(3, 3, COL_LIGHTRED); 943 } 944 // alpha 127 will make COL_LIGHTRED -> COL_RED and the same for blue 945 alpha.Erase(127); 946 // Normal device. 947 device->DrawBitmapEx(Point(5, 5), Size(-4, -4), BitmapEx(bitmap)); 948 device->DrawBitmapEx(Point(15, 15), Size(4, 4), BitmapEx(bitmap)); 949 exportDevice("/tmp/draw_alpha_bitmap_mirrored_01.png", device); 950 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, device->GetPixel(Point(18, 18))); 951 CPPUNIT_ASSERT_EQUAL(COL_LIGHTBLUE, device->GetPixel(Point(17, 18))); 952 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, device->GetPixel(Point(2, 2))); 953 CPPUNIT_ASSERT_EQUAL(COL_LIGHTBLUE, device->GetPixel(Point(3, 2))); 954 device->Erase(); 955 device->DrawBitmapEx(Point(5, 5), Size(-4, -4), BitmapEx(bitmap, alpha)); 956 device->DrawBitmapEx(Point(15, 15), Size(4, 4), BitmapEx(bitmap, alpha)); 957 exportDevice("/tmp/draw_alpha_bitmap_mirrored_02.png", device); 958 CPPUNIT_ASSERT_EQUAL(COL_RED, device->GetPixel(Point(18, 18))); 959 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(17, 18))); 960 CPPUNIT_ASSERT_EQUAL(COL_RED, device->GetPixel(Point(2, 2))); 961 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(3, 2))); 962 device->Erase(); 963 // Now with alpha device. 964 alphaDevice->DrawBitmapEx(Point(5, 5), Size(-4, -4), BitmapEx(bitmap)); 965 alphaDevice->DrawBitmapEx(Point(15, 15), Size(4, 4), BitmapEx(bitmap)); 966 exportDevice("/tmp/draw_alpha_bitmap_mirrored_03.png", alphaDevice); 967 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, alphaDevice->GetPixel(Point(18, 18))); 968 CPPUNIT_ASSERT_EQUAL(COL_LIGHTBLUE, alphaDevice->GetPixel(Point(17, 18))); 969 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, alphaDevice->GetPixel(Point(2, 2))); 970 CPPUNIT_ASSERT_EQUAL(COL_LIGHTBLUE, alphaDevice->GetPixel(Point(3, 2))); 971 alphaDevice->Erase(); 972 alphaDevice->DrawBitmapEx(Point(5, 5), Size(-4, -4), BitmapEx(bitmap, alpha)); 973 alphaDevice->DrawBitmapEx(Point(15, 15), Size(4, 4), BitmapEx(bitmap, alpha)); 974 exportDevice("/tmp/draw_alpha_bitmap_mirrored_04.png", alphaDevice); 975 CPPUNIT_ASSERT_EQUAL(COL_RED, alphaDevice->GetPixel(Point(18, 18))); 976 CPPUNIT_ASSERT_EQUAL(COL_BLUE, alphaDevice->GetPixel(Point(17, 18))); 977 CPPUNIT_ASSERT_EQUAL(COL_RED, alphaDevice->GetPixel(Point(2, 2))); 978 CPPUNIT_ASSERT_EQUAL(COL_BLUE, alphaDevice->GetPixel(Point(3, 2))); 979 alphaDevice->Erase(); 980 #endif 981 } 982 testTdf124848()983 void testTdf124848() 984 { 985 // TODO: This unit test is not executed for macOS unless bitmap scaling is implemented 986 #ifndef MACOSX 987 ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT); 988 device->SetOutputSizePixel(Size(100, 100)); 989 device->SetBackground(Wallpaper(COL_WHITE)); 990 device->Erase(); 991 device->SetAntialiasing(AntialiasingFlags::Enable); 992 device->SetLineColor(COL_BLACK); 993 basegfx::B2DHomMatrix matrix; 994 // DrawPolyLine() would apply the whole matrix to the line width, making it negative 995 // in case of a larger rotation. 996 matrix.rotate(M_PI); //180 degrees 997 matrix.translate(100, 100); 998 CPPUNIT_ASSERT(device->DrawPolyLineDirect(matrix, 999 basegfx::B2DPolygon{ { 50, 50 }, { 50, 100 } }, 1000 100, 0, nullptr, basegfx::B2DLineJoin::Miter)); 1001 exportDevice("/tmp/tdf124848-1.png", device); 1002 // 100px wide line should fill the entire width of the upper half 1003 CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(2, 2))); 1004 1005 // Also check hairline. 1006 device->Erase(); 1007 CPPUNIT_ASSERT(device->DrawPolyLineDirect(matrix, 1008 basegfx::B2DPolygon{ { 50, 50 }, { 50, 100 } }, 0, 1009 0, nullptr, basegfx::B2DLineJoin::Miter)); 1010 exportDevice("/tmp/tdf124848-2.png", device); 1011 // 1px wide 1012 CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(50, 20))); 1013 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(49, 20))); 1014 CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(51, 20))); 1015 #endif 1016 } 1017 testTdf136171()1018 void testTdf136171() 1019 { 1020 // TODO: Following unit tests are not executed for macOS unless bitmap scaling is implemented 1021 #ifndef MACOSX 1022 if (getDefaultDeviceBitCount() < 24) 1023 return; 1024 // Create virtual device with alpha. 1025 ScopedVclPtr<VirtualDevice> device 1026 = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT); 1027 device->SetOutputSizePixel(Size(10, 10)); 1028 device->SetBackground(Wallpaper(COL_WHITE)); 1029 device->Erase(); 1030 Bitmap bitmap(Size(10, 10), vcl::PixelFormat::N24_BPP); 1031 bitmap.Erase(COL_BLUE); 1032 basegfx::B2DHomMatrix matrix; 1033 matrix.scale(bitmap.GetSizePixel().Width(), 1034 bitmap.GetSizePixel().Height()); // draw as 10x10 1035 // Draw a blue bitmap to the device. The bug was that there was no alpha, but OutputDevice::DrawTransformBitmapExDirect() 1036 // supplied a fully opaque alpha done with Erase() on the alpha bitmap, and Skia backend didn't handle such alpha correctly. 1037 device->DrawTransformedBitmapEx(matrix, BitmapEx(bitmap)); 1038 exportDevice("/tmp/tdf136171.png", device); 1039 // The whole virtual device content now should be blue. 1040 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(0, 0))); 1041 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(9, 0))); 1042 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(0, 9))); 1043 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(9, 9))); 1044 CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(4, 4))); 1045 #endif 1046 } 1047 1048 CPPUNIT_TEST_SUITE(BackendTest); 1049 CPPUNIT_TEST(testDrawRectWithRectangle); 1050 CPPUNIT_TEST(testDrawRectWithPixel); 1051 CPPUNIT_TEST(testDrawRectWithLine); 1052 CPPUNIT_TEST(testDrawRectWithPolygon); 1053 CPPUNIT_TEST(testDrawRectWithPolyLine); 1054 CPPUNIT_TEST(testDrawRectWithPolyLineB2D); 1055 CPPUNIT_TEST(testDrawRectWithPolyPolygon); 1056 CPPUNIT_TEST(testDrawRectWithPolyPolygonB2D); 1057 1058 CPPUNIT_TEST(testDrawRectAAWithRectangle); 1059 CPPUNIT_TEST(testDrawRectAAWithPixel); 1060 CPPUNIT_TEST(testDrawRectAAWithLine); 1061 CPPUNIT_TEST(testDrawRectAAWithPolygon); 1062 CPPUNIT_TEST(testDrawRectAAWithPolyLine); 1063 CPPUNIT_TEST(testDrawRectAAWithPolyLineB2D); 1064 CPPUNIT_TEST(testDrawRectAAWithPolyPolygon); 1065 CPPUNIT_TEST(testDrawRectAAWithPolyPolygonB2D); 1066 1067 CPPUNIT_TEST(testDrawFilledRectWithRectangle); 1068 CPPUNIT_TEST(testDrawFilledRectWithPolygon); 1069 CPPUNIT_TEST(testDrawFilledRectWithPolyPolygon); 1070 CPPUNIT_TEST(testDrawFilledRectWithPolyPolygon2D); 1071 1072 CPPUNIT_TEST(testDrawDiamondWithPolygon); 1073 CPPUNIT_TEST(testDrawDiamondWithLine); 1074 CPPUNIT_TEST(testDrawDiamondWithPolyline); 1075 CPPUNIT_TEST(testDrawDiamondWithPolylineB2D); 1076 1077 CPPUNIT_TEST(testDrawInvertWithRectangle); 1078 CPPUNIT_TEST(testDrawInvertN50WithRectangle); 1079 CPPUNIT_TEST(testDrawInvertTrackFrameWithRectangle); 1080 1081 CPPUNIT_TEST(testDrawBezierWithPolylineB2D); 1082 CPPUNIT_TEST(testDrawBezierAAWithPolylineB2D); 1083 1084 CPPUNIT_TEST(testDrawBitmap); 1085 CPPUNIT_TEST(testDrawTransformedBitmap); 1086 CPPUNIT_TEST(testDrawBitmapExWithAlpha); 1087 CPPUNIT_TEST(testDrawMask); 1088 CPPUNIT_TEST(testDrawBlend); 1089 CPPUNIT_TEST(testDrawXor); 1090 1091 CPPUNIT_TEST(testDrawTransformedBitmapExAlpha); 1092 1093 CPPUNIT_TEST(testClipRectangle); 1094 CPPUNIT_TEST(testClipPolygon); 1095 CPPUNIT_TEST(testClipPolyPolygon); 1096 CPPUNIT_TEST(testClipB2DPolyPolygon); 1097 1098 CPPUNIT_TEST(testDrawOutDev); 1099 1100 CPPUNIT_TEST(testDashedLine); 1101 1102 CPPUNIT_TEST(testErase); 1103 1104 CPPUNIT_TEST(testLinearGradient); 1105 CPPUNIT_TEST(testLinearGradientAngled); 1106 CPPUNIT_TEST(testLinearGradientBorder); 1107 CPPUNIT_TEST(testLinearGradientIntensity); 1108 CPPUNIT_TEST(testLinearGradientSteps); 1109 CPPUNIT_TEST(testAxialGradient); 1110 CPPUNIT_TEST(testRadialGradient); 1111 CPPUNIT_TEST(testRadialGradientOfs); 1112 1113 CPPUNIT_TEST(testLineCapRound); 1114 CPPUNIT_TEST(testLineCapSquare); 1115 CPPUNIT_TEST(testLineCapButt); 1116 CPPUNIT_TEST(testLineJoinBevel); 1117 CPPUNIT_TEST(testLineJoinRound); 1118 CPPUNIT_TEST(testLineJoinMiter); 1119 CPPUNIT_TEST(testLineJoinNone); 1120 1121 CPPUNIT_TEST(testDrawBlendExtended); 1122 CPPUNIT_TEST(testDrawAlphaBitmapMirrored); 1123 1124 CPPUNIT_TEST(testTdf124848); 1125 CPPUNIT_TEST(testTdf136171); 1126 1127 CPPUNIT_TEST_SUITE_END(); 1128 }; 1129 1130 CPPUNIT_TEST_SUITE_REGISTRATION(BackendTest); 1131 1132 CPPUNIT_PLUGIN_IMPLEMENT(); 1133 1134 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1135