File indexing completed on 2024-06-09 04:22:13
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Sven Langkamp <sven.langkamp@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_painter_test.h" 0008 #include <simpletest.h> 0009 0010 #include <kis_debug.h> 0011 #include <QRect> 0012 #include <QElapsedTimer> 0013 #include <QtXml> 0014 0015 #include <KoChannelInfo.h> 0016 #include <KoColorSpace.h> 0017 #include <KoColorSpaceRegistry.h> 0018 #include <KoCompositeOpRegistry.h> 0019 0020 #include "kis_datamanager.h" 0021 #include "kis_types.h" 0022 #include "kis_paint_device.h" 0023 #include "kis_painter.h" 0024 #include "kis_pixel_selection.h" 0025 #include "kis_fill_painter.h" 0026 #include <kis_fixed_paint_device.h> 0027 #include <testutil.h> 0028 #include <kis_iterator_ng.h> 0029 #include <testimage.h> 0030 0031 void KisPainterTest::allCsApplicator(void (KisPainterTest::* funcPtr)(const KoColorSpace*cs)) 0032 { 0033 qDebug() << qAppName(); 0034 0035 QList<const KoColorSpace*> colorspaces = KoColorSpaceRegistry::instance()->allColorSpaces(KoColorSpaceRegistry::AllColorSpaces, KoColorSpaceRegistry::OnlyDefaultProfile); 0036 0037 Q_FOREACH (const KoColorSpace* cs, colorspaces) { 0038 0039 QString csId = cs->id(); 0040 // ALL THESE COLORSPACES ARE BROKEN: WE NEED UNITTESTS FOR COLORSPACES! 0041 if (csId.startsWith("KS")) continue; 0042 if (csId.startsWith("Xyz")) continue; 0043 if (csId.startsWith('Y')) continue; 0044 if (csId.contains("AF")) continue; 0045 if (csId == "GRAYU16") continue; // No point in testing bounds with a cs without alpha 0046 if (csId == "GRAYU8") continue; // No point in testing bounds with a cs without alpha 0047 0048 dbgKrita << "Testing with cs" << csId; 0049 0050 if (cs && cs->compositeOp(COMPOSITE_OVER) != 0) { 0051 (this->*funcPtr)(cs); 0052 } else { 0053 dbgKrita << "Cannot bitBlt for cs" << csId; 0054 } 0055 } 0056 } 0057 0058 void KisPainterTest::testSimpleBlt(const KoColorSpace * cs) 0059 { 0060 0061 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0062 KisPaintDeviceSP src = new KisPaintDevice(cs); 0063 KoColor c(Qt::red, cs); 0064 c.setOpacity(quint8(128)); 0065 src->fill(20, 20, 20, 20, c.data()); 0066 0067 QCOMPARE(src->exactBounds(), QRect(20, 20, 20, 20)); 0068 0069 const KoCompositeOp* op; 0070 0071 { 0072 op = cs->compositeOp(COMPOSITE_OVER); 0073 KisPainter painter(dst); 0074 painter.setCompositeOpId(op); 0075 painter.bitBlt(50, 50, src, 20, 20, 20, 20); 0076 painter.end(); 0077 QCOMPARE(dst->exactBounds(), QRect(50,50,20,20)); 0078 } 0079 0080 dst->clear(); 0081 0082 { 0083 op = cs->compositeOp(COMPOSITE_COPY); 0084 KisPainter painter(dst); 0085 painter.setCompositeOpId(op); 0086 painter.bitBlt(50, 50, src, 20, 20, 20, 20); 0087 painter.end(); 0088 QCOMPARE(dst->exactBounds(), QRect(50,50,20,20)); 0089 } 0090 } 0091 0092 void KisPainterTest::testSimpleBlt() 0093 { 0094 allCsApplicator(&KisPainterTest::testSimpleBlt); 0095 } 0096 0097 /* 0098 0099 Note: the bltSelection tests assume the following geometry: 0100 0101 0,0 0,30 0102 +---------+------+ 0103 | 10,10 | | 0104 | +----+ | 0105 | |####| | 0106 | |####| | 0107 +----+----+ | 0108 | 20,20 | 0109 | | 0110 | | 0111 +----------------+ 0112 30,30 0113 */ 0114 void KisPainterTest::testPaintDeviceBltSelection(const KoColorSpace * cs) 0115 { 0116 0117 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0118 0119 KisPaintDeviceSP src = new KisPaintDevice(cs); 0120 KoColor c(Qt::red, cs); 0121 c.setOpacity(quint8(128)); 0122 src->fill(0, 0, 20, 20, c.data()); 0123 0124 QCOMPARE(src->exactBounds(), QRect(0, 0, 20, 20)); 0125 0126 KisSelectionSP selection = new KisSelection(); 0127 selection->pixelSelection()->select(QRect(10, 10, 20, 20)); 0128 selection->updateProjection(); 0129 QCOMPARE(selection->selectedExactRect(), QRect(10, 10, 20, 20)); 0130 0131 KisPainter painter(dst); 0132 painter.setSelection(selection); 0133 0134 painter.bitBlt(0, 0, src, 0, 0, 30, 30); 0135 painter.end(); 0136 0137 QImage image = dst->convertToQImage(0); 0138 image.save("blt_Selection_" + cs->name() + ".png"); 0139 0140 QCOMPARE(dst->exactBounds(), QRect(10, 10, 10, 10)); 0141 0142 const KoCompositeOp* op = cs->compositeOp(COMPOSITE_SUBTRACT); 0143 if (op->id() == COMPOSITE_SUBTRACT) { 0144 0145 KisPaintDeviceSP dst2 = new KisPaintDevice(cs); 0146 KisPainter painter2(dst2); 0147 painter2.setSelection(selection); 0148 painter2.setCompositeOpId(op); 0149 painter2.bitBlt(0, 0, src, 0, 0, 30, 30); 0150 painter2.end(); 0151 0152 QCOMPARE(dst2->exactBounds(), QRect(10, 10, 10, 10)); 0153 } 0154 } 0155 0156 void KisPainterTest::testPaintDeviceBltSelection() 0157 { 0158 allCsApplicator(&KisPainterTest::testPaintDeviceBltSelection); 0159 } 0160 0161 void KisPainterTest::testPaintDeviceBltSelectionIrregular(const KoColorSpace * cs) 0162 { 0163 0164 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0165 KisPaintDeviceSP src = new KisPaintDevice(cs); 0166 KisFillPainter gc(src); 0167 gc.fillRect(0, 0, 20, 20, KoColor(Qt::red, cs)); 0168 gc.end(); 0169 0170 QCOMPARE(src->exactBounds(), QRect(0, 0, 20, 20)); 0171 0172 KisSelectionSP sel = new KisSelection(); 0173 0174 KisPixelSelectionSP psel = sel->pixelSelection(); 0175 psel->select(QRect(10, 15, 20, 15)); 0176 psel->select(QRect(15, 10, 15, 5)); 0177 0178 QCOMPARE(psel->selectedExactRect(), QRect(10, 10, 20, 20)); 0179 QCOMPARE(TestUtil::alphaDevicePixel(psel, 13, 13), MIN_SELECTED); 0180 0181 KisPainter painter(dst); 0182 painter.setSelection(sel); 0183 painter.bitBlt(0, 0, src, 0, 0, 30, 30); 0184 painter.end(); 0185 0186 QImage image = dst->convertToQImage(0); 0187 image.save("blt_Selection_irregular" + cs->name() + ".png"); 0188 0189 QCOMPARE(dst->exactBounds(), QRect(10, 10, 10, 10)); 0190 Q_FOREACH (KoChannelInfo * channel, cs->channels()) { 0191 // Only compare alpha if there actually is an alpha channel in 0192 // this colorspace 0193 if (channel->channelType() == KoChannelInfo::ALPHA) { 0194 QColor c; 0195 0196 dst->pixel(13, 13, &c); 0197 0198 QCOMPARE((int) c.alpha(), (int) OPACITY_TRANSPARENT_U8); 0199 } 0200 } 0201 } 0202 0203 0204 void KisPainterTest::testPaintDeviceBltSelectionIrregular() 0205 { 0206 allCsApplicator(&KisPainterTest::testPaintDeviceBltSelectionIrregular); 0207 } 0208 0209 void KisPainterTest::testPaintDeviceBltSelectionInverted(const KoColorSpace * cs) 0210 { 0211 0212 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0213 KisPaintDeviceSP src = new KisPaintDevice(cs); 0214 KisFillPainter gc(src); 0215 gc.fillRect(0, 0, 30, 30, KoColor(Qt::red, cs)); 0216 gc.end(); 0217 QCOMPARE(src->exactBounds(), QRect(0, 0, 30, 30)); 0218 0219 KisSelectionSP sel = new KisSelection(); 0220 KisPixelSelectionSP psel = sel->pixelSelection(); 0221 psel->select(QRect(10, 10, 20, 20)); 0222 psel->invert(); 0223 sel->updateProjection(); 0224 0225 KisPainter painter(dst); 0226 painter.setSelection(sel); 0227 painter.bitBlt(0, 0, src, 0, 0, 30, 30); 0228 painter.end(); 0229 QCOMPARE(dst->exactBounds(), QRect(0, 0, 30, 30)); 0230 } 0231 0232 void KisPainterTest::testPaintDeviceBltSelectionInverted() 0233 { 0234 allCsApplicator(&KisPainterTest::testPaintDeviceBltSelectionInverted); 0235 } 0236 0237 0238 void KisPainterTest::testSelectionBltSelection() 0239 { 0240 KisPixelSelectionSP src = new KisPixelSelection(); 0241 src->select(QRect(0, 0, 20, 20)); 0242 QCOMPARE(src->selectedExactRect(), QRect(0, 0, 20, 20)); 0243 0244 KisSelectionSP sel = new KisSelection(); 0245 0246 KisPixelSelectionSP Selection = sel->pixelSelection(); 0247 Selection->select(QRect(10, 10, 20, 20)); 0248 QCOMPARE(Selection->selectedExactRect(), QRect(10, 10, 20, 20)); 0249 0250 sel->updateProjection(); 0251 KisPixelSelectionSP dst = new KisPixelSelection(); 0252 KisPainter painter(dst); 0253 painter.setSelection(sel); 0254 painter.bitBlt(0, 0, src, 0, 0, 30, 30); 0255 painter.end(); 0256 0257 QCOMPARE(dst->selectedExactRect(), QRect(10, 10, 10, 10)); 0258 0259 KisSequentialConstIterator it(dst, QRect(10, 10, 10, 10)); 0260 while (it.nextPixel()) { 0261 // These are selections, so only one channel and it should 0262 // be totally selected 0263 QCOMPARE(it.oldRawData()[0], MAX_SELECTED); 0264 } 0265 } 0266 0267 /* 0268 0269 Test with non-square selection 0270 0271 0,0 0,30 0272 +-----------+------+ 0273 | 13,13 | | 0274 | x +--+ | 0275 | +--+##| | 0276 | |#####| | 0277 +-----+-----+ | 0278 | 20,20 | 0279 | | 0280 | | 0281 +------------------+ 0282 30,30 0283 */ 0284 void KisPainterTest::testSelectionBltSelectionIrregular() 0285 { 0286 0287 KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8()); 0288 0289 KisPixelSelectionSP src = new KisPixelSelection(); 0290 src->select(QRect(0, 0, 20, 20)); 0291 QCOMPARE(src->selectedExactRect(), QRect(0, 0, 20, 20)); 0292 0293 KisSelectionSP sel = new KisSelection(); 0294 0295 KisPixelSelectionSP Selection = sel->pixelSelection(); 0296 Selection->select(QRect(10, 15, 20, 15)); 0297 Selection->select(QRect(15, 10, 15, 5)); 0298 QCOMPARE(Selection->selectedExactRect(), QRect(10, 10, 20, 20)); 0299 QCOMPARE(TestUtil::alphaDevicePixel(Selection, 13, 13), MIN_SELECTED); 0300 0301 sel->updateProjection(); 0302 0303 KisPixelSelectionSP dst = new KisPixelSelection(); 0304 KisPainter painter(dst); 0305 painter.setSelection(sel); 0306 painter.bitBlt(0, 0, src, 0, 0, 30, 30); 0307 painter.end(); 0308 0309 QCOMPARE(dst->selectedExactRect(), QRect(10, 10, 10, 10)); 0310 QCOMPARE(TestUtil::alphaDevicePixel(dst, 13, 13), MIN_SELECTED); 0311 } 0312 0313 void KisPainterTest::testSelectionBitBltFixedSelection() 0314 { 0315 const KoColorSpace* cs = KoColorSpaceRegistry::instance()->rgb8(); 0316 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0317 0318 KisPaintDeviceSP src = new KisPaintDevice(cs); 0319 KoColor c(Qt::red, cs); 0320 c.setOpacity(quint8(128)); 0321 src->fill(0, 0, 20, 20, c.data()); 0322 0323 QCOMPARE(src->exactBounds(), QRect(0, 0, 20, 20)); 0324 0325 KisFixedPaintDeviceSP fixedSelection = new KisFixedPaintDevice(cs); 0326 fixedSelection->setRect(QRect(0, 0, 20, 20)); 0327 fixedSelection->initialize(); 0328 KoColor fill(Qt::white, cs); 0329 fixedSelection->fill(5, 5, 10, 10, fill.data()); 0330 fixedSelection->convertTo(KoColorSpaceRegistry::instance()->alpha8()); 0331 0332 KisPainter painter(dst); 0333 0334 painter.bitBltWithFixedSelection(0, 0, src, fixedSelection, 20, 20); 0335 painter.end(); 0336 0337 QCOMPARE(dst->exactBounds(), QRect(5, 5, 10, 10)); 0338 /* 0339 dbgKrita << "canary1.5"; 0340 dst->clear(); 0341 painter.begin(dst); 0342 0343 painter.bitBltWithFixedSelection(0, 0, src, fixedSelection, 10, 20); 0344 painter.end(); 0345 dbgKrita << "canary2"; 0346 QCOMPARE(dst->exactBounds(), QRect(5, 5, 5, 10)); 0347 0348 dst->clear(); 0349 painter.begin(dst); 0350 0351 painter.bitBltWithFixedSelection(0, 0, src, fixedSelection, 5, 5, 5, 5, 10, 20); 0352 painter.end(); 0353 dbgKrita << "canary3"; 0354 QCOMPARE(dst->exactBounds(), QRect(5, 5, 5, 10)); 0355 0356 dst->clear(); 0357 painter.begin(dst); 0358 0359 painter.bitBltWithFixedSelection(5, 5, src, fixedSelection, 10, 20); 0360 painter.end(); 0361 dbgKrita << "canary4"; 0362 QCOMPARE(dst->exactBounds(), QRect(10, 10, 5, 10)); 0363 */ 0364 } 0365 0366 void KisPainterTest::testSelectionBitBltEraseCompositeOp() 0367 { 0368 const KoColorSpace* cs = KoColorSpaceRegistry::instance()->rgb8(); 0369 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0370 KoColor c(Qt::red, cs); 0371 dst->fill(0, 0, 150, 150, c.data()); 0372 0373 KisPaintDeviceSP src = new KisPaintDevice(cs); 0374 KoColor c2(Qt::black, cs); 0375 src->fill(50, 50, 50, 50, c2.data()); 0376 0377 KisSelectionSP sel = new KisSelection(); 0378 KisPixelSelectionSP selection = sel->pixelSelection(); 0379 selection->select(QRect(25, 25, 100, 100)); 0380 sel->updateProjection(); 0381 0382 const KoCompositeOp* op = cs->compositeOp(COMPOSITE_ERASE); 0383 KisPainter painter(dst); 0384 painter.setSelection(sel); 0385 painter.setCompositeOpId(op); 0386 painter.bitBlt(0, 0, src, 0, 0, 150, 150); 0387 painter.end(); 0388 0389 //dst->convertToQImage(0).save("result.png"); 0390 0391 QRect erasedRect(50, 50, 50, 50); 0392 KisSequentialConstIterator it(dst, QRect(0, 0, 150, 150)); 0393 while (it.nextPixel()) { 0394 if(!erasedRect.contains(it.x(), it.y())) { 0395 QVERIFY(memcmp(it.oldRawData(), c.data(), cs->pixelSize()) == 0); 0396 } 0397 } 0398 0399 } 0400 0401 void KisPainterTest::testSimpleAlphaCopy() 0402 { 0403 KisPaintDeviceSP src = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8()); 0404 KisPaintDeviceSP dst = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8()); 0405 quint8 p = 128; 0406 src->fill(0, 0, 100, 100, &p); 0407 QVERIFY(src->exactBounds() == QRect(0, 0, 100, 100)); 0408 KisPainter gc(dst); 0409 gc.setCompositeOpId(KoColorSpaceRegistry::instance()->alpha8()->compositeOp(COMPOSITE_COPY)); 0410 gc.bitBlt(QPoint(0, 0), src, src->exactBounds()); 0411 gc.end(); 0412 QCOMPARE(dst->exactBounds(), QRect(0, 0, 100, 100)); 0413 0414 } 0415 0416 void KisPainterTest::checkPerformance() 0417 { 0418 KisPaintDeviceSP src = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8()); 0419 KisPaintDeviceSP dst = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8()); 0420 quint8 p = 128; 0421 src->fill(0, 0, 10000, 5000, &p); 0422 KisSelectionSP sel = new KisSelection(); 0423 sel->pixelSelection()->select(QRect(0, 0, 10000, 5000), 128); 0424 sel->updateProjection(); 0425 0426 QElapsedTimer t; 0427 t.start(); 0428 for (int i = 0; i < 10; ++i) { 0429 KisPainter gc(dst); 0430 gc.bitBlt(0, 0, src, 0, 0, 10000, 5000); 0431 } 0432 0433 t.restart(); 0434 for (int i = 0; i < 10; ++i) { 0435 KisPainter gc(dst, sel); 0436 gc.bitBlt(0, 0, src, 0, 0, 10000, 5000); 0437 } 0438 } 0439 0440 void KisPainterTest::testBitBltOldData() 0441 { 0442 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->alpha8(); 0443 0444 KisPaintDeviceSP src = new KisPaintDevice(cs); 0445 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0446 0447 quint8 defaultPixel = 0; 0448 quint8 p1 = 128; 0449 quint8 p2 = 129; 0450 quint8 p3 = 130; 0451 KoColor defaultColor(&defaultPixel, cs); 0452 KoColor color1(&p1, cs); 0453 KoColor color2(&p2, cs); 0454 KoColor color3(&p3, cs); 0455 QRect fillRect(0,0,5000,5000); 0456 0457 src->fill(fillRect, color1); 0458 0459 KisPainter srcGc(src); 0460 srcGc.beginTransaction(); 0461 src->fill(fillRect, color2); 0462 0463 KisPainter dstGc(dst); 0464 dstGc.bitBltOldData(QPoint(), src, fillRect); 0465 0466 QVERIFY(TestUtil::checkAlphaDeviceFilledWithPixel(dst, fillRect, p1)); 0467 0468 dstGc.end(); 0469 srcGc.deleteTransaction(); 0470 } 0471 0472 #include "kis_paint_device_debug_utils.h" 0473 #include "KisRenderedDab.h" 0474 0475 void testMassiveBltFixedImpl(int numRects, bool varyOpacity = false, bool useSelection = false) 0476 { 0477 const KoColorSpace* cs = KoColorSpaceRegistry::instance()->rgb8(); 0478 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0479 0480 QList<QColor> colors; 0481 colors << Qt::red; 0482 colors << Qt::green; 0483 colors << Qt::blue; 0484 0485 QRect devicesRect; 0486 QList<KisRenderedDab> devices; 0487 0488 for (int i = 0; i < numRects; i++) { 0489 const QRect rc(10 + i * 10, 10 + i * 10, 30, 30); 0490 KisFixedPaintDeviceSP dev = new KisFixedPaintDevice(cs); 0491 dev->setRect(rc); 0492 dev->initialize(); 0493 dev->fill(rc, KoColor(colors[i % 3], cs)); 0494 dev->fill(kisGrowRect(rc, -5), KoColor(Qt::white, cs)); 0495 0496 KisRenderedDab dab; 0497 dab.device = dev; 0498 dab.offset = dev->bounds().topLeft(); 0499 dab.opacity = varyOpacity ? qreal(1 + i) / numRects : 1.0; 0500 dab.flow = 1.0; 0501 0502 devices << dab; 0503 devicesRect |= rc; 0504 } 0505 0506 KisSelectionSP selection; 0507 0508 if (useSelection) { 0509 selection = new KisSelection(); 0510 selection->pixelSelection()->select(kisGrowRect(devicesRect, -7)); 0511 } 0512 0513 const QString opacityPostfix = varyOpacity ? "_varyop" : ""; 0514 const QString selectionPostfix = useSelection ? "_sel" : ""; 0515 0516 const QRect fullRect = kisGrowRect(devicesRect, 10); 0517 0518 { 0519 KisPainter painter(dst); 0520 painter.setSelection(selection); 0521 painter.bltFixed(fullRect, devices); 0522 painter.end(); 0523 QVERIFY(TestUtil::checkQImage(dst->convertToQImage(0, fullRect), 0524 "kispainter_test", 0525 "massive_bitblt", 0526 QString("full_update_%1%2%3") 0527 .arg(numRects) 0528 .arg(opacityPostfix) 0529 .arg(selectionPostfix), 2, 2)); 0530 } 0531 0532 dst->clear(); 0533 0534 { 0535 KisPainter painter(dst); 0536 painter.setSelection(selection); 0537 0538 for (int i = fullRect.x(); i <= fullRect.center().x(); i += 10) { 0539 const QRect rc(i, fullRect.y(), 10, fullRect.height()); 0540 painter.bltFixed(rc, devices); 0541 } 0542 0543 painter.end(); 0544 0545 QVERIFY(TestUtil::checkQImage(dst->convertToQImage(0, fullRect), 0546 "kispainter_test", 0547 "massive_bitblt", 0548 QString("partial_update_%1%2%3") 0549 .arg(numRects) 0550 .arg(opacityPostfix) 0551 .arg(selectionPostfix), 2, 2)); 0552 0553 } 0554 } 0555 0556 void KisPainterTest::testMassiveBltFixedSingleTile() 0557 { 0558 testMassiveBltFixedImpl(3); 0559 } 0560 0561 void KisPainterTest::testMassiveBltFixedMultiTile() 0562 { 0563 testMassiveBltFixedImpl(6); 0564 } 0565 0566 void KisPainterTest::testMassiveBltFixedMultiTileWithOpacity() 0567 { 0568 testMassiveBltFixedImpl(6, true); 0569 } 0570 0571 void KisPainterTest::testMassiveBltFixedMultiTileWithSelection() 0572 { 0573 testMassiveBltFixedImpl(6, false, true); 0574 } 0575 0576 void KisPainterTest::testMassiveBltFixedCornerCases() 0577 { 0578 const KoColorSpace* cs = KoColorSpaceRegistry::instance()->rgb8(); 0579 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0580 0581 QList<KisRenderedDab> devices; 0582 0583 QVERIFY(dst->extent().isEmpty()); 0584 0585 { 0586 // empty devices, shouldn't crash 0587 KisPainter painter(dst); 0588 painter.bltFixed(QRect(60,60,20,20), devices); 0589 painter.end(); 0590 } 0591 0592 QVERIFY(dst->extent().isEmpty()); 0593 0594 const QRect rc(10,10,20,20); 0595 KisFixedPaintDeviceSP dev = new KisFixedPaintDevice(cs); 0596 dev->setRect(rc); 0597 dev->initialize(); 0598 dev->fill(rc, KoColor(Qt::white, cs)); 0599 0600 devices.append(KisRenderedDab(dev)); 0601 0602 { 0603 // rect outside the devices bounds, shouldn't crash 0604 KisPainter painter(dst); 0605 painter.bltFixed(QRect(60,60,20,20), devices); 0606 painter.end(); 0607 } 0608 0609 QVERIFY(dst->extent().isEmpty()); 0610 } 0611 0612 0613 #include "kis_lod_transform.h" 0614 0615 inline QRect extentifyRect(const QRect &rc) 0616 { 0617 return KisLodTransform::alignedRect(rc, 6); 0618 } 0619 0620 void testOptimizedCopyingImpl(const QRect &srcRect, 0621 const QRect &dstRect, 0622 const QRect &srcCopyRect, 0623 const QPoint &dstPt, 0624 const QRect &expectedDstBounds) 0625 { 0626 const QRect expectedDstExtent = extentifyRect(expectedDstBounds); 0627 0628 const KoColorSpace* cs = KoColorSpaceRegistry::instance()->rgb8(); 0629 KisPaintDeviceSP src = new KisPaintDevice(cs); 0630 KisPaintDeviceSP dst = new KisPaintDevice(cs); 0631 0632 const KoColor color1(Qt::red, cs); 0633 const KoColor color2(Qt::blue, cs); 0634 0635 src->fill(srcRect, color1); 0636 dst->fill(dstRect, color2); 0637 0638 KisPainter::copyAreaOptimized(dstPt, src, dst, srcCopyRect); 0639 0640 //KIS_DUMP_DEVICE_2(dst, QRect(0,0,5000,5000), "dst", "dd"); 0641 0642 QCOMPARE(dst->exactBounds(), expectedDstBounds); 0643 QCOMPARE(dst->extent(), expectedDstExtent); 0644 } 0645 0646 void KisPainterTest::testOptimizedCopying() 0647 { 0648 const QRect srcRect(1000, 1000, 1000, 1000); 0649 const QRect srcCopyRect(0, 0, 5000, 5000); 0650 0651 0652 testOptimizedCopyingImpl(srcRect, QRect(6000, 500, 1000,1000), 0653 srcCopyRect, srcCopyRect.topLeft(), 0654 QRect(1000, 500, 6000, 1500)); 0655 0656 testOptimizedCopyingImpl(srcRect, QRect(4500, 1500, 1000, 1000), 0657 srcCopyRect, srcCopyRect.topLeft(), 0658 QRect(1000, 1000, 4500, 1500)); 0659 0660 testOptimizedCopyingImpl(srcRect, QRect(2500, 2500, 1000, 1000), 0661 srcCopyRect, srcCopyRect.topLeft(), 0662 srcRect); 0663 0664 testOptimizedCopyingImpl(srcRect, QRect(1200, 1200, 600, 1600), 0665 srcCopyRect, srcCopyRect.topLeft(), 0666 srcRect); 0667 0668 testOptimizedCopyingImpl(srcRect, QRect(1200, 1200, 600, 600), 0669 srcCopyRect, srcCopyRect.topLeft(), 0670 srcRect); 0671 0672 } 0673 0674 KISTEST_MAIN(KisPainterTest) 0675 0676