File indexing completed on 2024-06-09 04:22:15
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_scanline_fill_test.h" 0008 0009 #include <testutil.h> 0010 0011 #include <simpletest.h> 0012 #include <floodfill/kis_scanline_fill.h> 0013 #include <floodfill/kis_fill_interval.h> 0014 #include <floodfill/kis_fill_interval_map.h> 0015 0016 #include <KoColor.h> 0017 #include <KoColorSpace.h> 0018 #include <KoColorSpaceRegistry.h> 0019 #include "kis_types.h" 0020 #include "kis_paint_device.h" 0021 0022 0023 void KisScanlineFillTest::testFillGeneral(const QVector<KisFillInterval> &initialBackwardIntervals, 0024 const QVector<QColor> &expectedResult, 0025 const QVector<KisFillInterval> &expectedForwardIntervals, 0026 const QVector<KisFillInterval> &expectedBackwardIntervals) 0027 { 0028 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); 0029 KisPaintDeviceSP dev = new KisPaintDevice(cs); 0030 0031 dev->setPixel(1, 0, Qt::white); 0032 dev->setPixel(2, 0, Qt::white); 0033 dev->setPixel(5, 0, Qt::white); 0034 dev->setPixel(8, 0, Qt::white); 0035 dev->setPixel(17, 0, Qt::white); 0036 0037 QRect boundingRect(-10, -10, 30, 30); 0038 0039 KisScanlineFill gc(dev, QPoint(), boundingRect); 0040 0041 KisFillIntervalMap *backwardMap = gc.testingGetBackwardIntervals(); 0042 Q_FOREACH (const KisFillInterval &i, initialBackwardIntervals) { 0043 backwardMap->insertInterval(i); 0044 } 0045 0046 KisFillInterval processInterval(0,10,0); 0047 gc.testingProcessLine(processInterval); 0048 0049 Q_ASSERT(expectedResult.size() == processInterval.width()); 0050 0051 for (int i = 0; i < 11; i++) { 0052 QColor c; 0053 dev->pixel(i, 0, &c); 0054 dbgKrita << i << ":" << c.red(); 0055 0056 QCOMPARE(c, expectedResult[i]); 0057 } 0058 0059 QVector<KisFillInterval> forwardIntervals = 0060 gc.testingGetForwardIntervals(); 0061 0062 for (int i = 0; i < forwardIntervals.size(); i++) { 0063 dbgKrita << "FW:" << forwardIntervals[i]; 0064 QCOMPARE(forwardIntervals[i], expectedForwardIntervals[i]); 0065 } 0066 QCOMPARE(forwardIntervals.size(), expectedForwardIntervals.size()); 0067 0068 0069 QStack<KisFillInterval> backwardIntervals = 0070 gc.testingGetBackwardIntervals()->fetchAllIntervals(); 0071 0072 for (int i = 0; i < backwardIntervals.size(); i++) { 0073 dbgKrita << "BW:" << backwardIntervals[i]; 0074 QCOMPARE(backwardIntervals[i], expectedBackwardIntervals[i]); 0075 } 0076 QCOMPARE(backwardIntervals.size(), expectedBackwardIntervals.size()); 0077 } 0078 0079 inline QColor testingColor(quint8 c) { 0080 return QColor(c, c, c, c); 0081 } 0082 0083 void KisScanlineFillTest::testSimpleFill() 0084 { 0085 QVector<KisFillInterval> initialBackwardIntervals; 0086 QVector<QColor> expectedResult; 0087 expectedResult << testingColor(200); // 0 0088 expectedResult << testingColor(255); // 1 0089 expectedResult << testingColor(255); // 2 0090 expectedResult << testingColor(200); // 3 0091 expectedResult << testingColor(200); // 4 0092 expectedResult << testingColor(255); // 5 0093 expectedResult << testingColor(200); // 6 0094 expectedResult << testingColor(200); // 7 0095 expectedResult << testingColor(255); // 8 0096 expectedResult << testingColor(200); // 9 0097 expectedResult << testingColor(200); // 10 0098 0099 QVector<KisFillInterval> expectedForwardIntervals; 0100 expectedForwardIntervals << KisFillInterval(-10, 0, 1); 0101 expectedForwardIntervals << KisFillInterval(3, 4, 1); 0102 expectedForwardIntervals << KisFillInterval(6, 7, 1); 0103 expectedForwardIntervals << KisFillInterval(9, 16, 1); 0104 0105 QVector<KisFillInterval> expectedBackwardIntervals; 0106 expectedBackwardIntervals << KisFillInterval(-10, -1, 0); 0107 expectedBackwardIntervals << KisFillInterval(11, 16, 0); 0108 0109 testFillGeneral(initialBackwardIntervals, 0110 expectedResult, 0111 expectedForwardIntervals, 0112 expectedBackwardIntervals); 0113 } 0114 0115 void KisScanlineFillTest::testFillBackwardCollisionOnTheLeft() 0116 { 0117 QVector<KisFillInterval> initialBackwardIntervals; 0118 initialBackwardIntervals << KisFillInterval(-10, 0, 0); 0119 0120 QVector<QColor> expectedResult; 0121 expectedResult << testingColor( 0); // 0 0122 expectedResult << testingColor(255); // 1 0123 expectedResult << testingColor(255); // 2 0124 expectedResult << testingColor(200); // 3 0125 expectedResult << testingColor(200); // 4 0126 expectedResult << testingColor(255); // 5 0127 expectedResult << testingColor(200); // 6 0128 expectedResult << testingColor(200); // 7 0129 expectedResult << testingColor(255); // 8 0130 expectedResult << testingColor(200); // 9 0131 expectedResult << testingColor(200); // 10 0132 0133 QVector<KisFillInterval> expectedForwardIntervals; 0134 expectedForwardIntervals << KisFillInterval(3, 4, 1); 0135 expectedForwardIntervals << KisFillInterval(6, 7, 1); 0136 expectedForwardIntervals << KisFillInterval(9, 16, 1); 0137 0138 QVector<KisFillInterval> expectedBackwardIntervals; 0139 expectedBackwardIntervals << KisFillInterval(-10, -1, 0); 0140 expectedBackwardIntervals << KisFillInterval(11, 16, 0); 0141 0142 0143 testFillGeneral(initialBackwardIntervals, 0144 expectedResult, 0145 expectedForwardIntervals, 0146 expectedBackwardIntervals); 0147 } 0148 0149 void KisScanlineFillTest::testFillBackwardCollisionOnTheRight() 0150 { 0151 QVector<KisFillInterval> initialBackwardIntervals; 0152 initialBackwardIntervals << KisFillInterval(9, 20, 0); 0153 0154 QVector<QColor> expectedResult; 0155 expectedResult << testingColor(200); // 0 0156 expectedResult << testingColor(255); // 1 0157 expectedResult << testingColor(255); // 2 0158 expectedResult << testingColor(200); // 3 0159 expectedResult << testingColor(200); // 4 0160 expectedResult << testingColor(255); // 5 0161 expectedResult << testingColor(200); // 6 0162 expectedResult << testingColor(200); // 7 0163 expectedResult << testingColor(255); // 8 0164 expectedResult << testingColor( 0); // 9 0165 expectedResult << testingColor( 0); // 10 0166 0167 QVector<KisFillInterval> expectedForwardIntervals; 0168 expectedForwardIntervals << KisFillInterval(-10, 0, 1); 0169 expectedForwardIntervals << KisFillInterval(3, 4, 1); 0170 expectedForwardIntervals << KisFillInterval(6, 7, 1); 0171 0172 QVector<KisFillInterval> expectedBackwardIntervals; 0173 expectedBackwardIntervals << KisFillInterval(-10, -1, 0); 0174 expectedBackwardIntervals << KisFillInterval(11, 20, 0); 0175 0176 testFillGeneral(initialBackwardIntervals, 0177 expectedResult, 0178 expectedForwardIntervals, 0179 expectedBackwardIntervals); 0180 } 0181 0182 void KisScanlineFillTest::testFillBackwardCollisionFull() 0183 { 0184 QVector<KisFillInterval> initialBackwardIntervals; 0185 initialBackwardIntervals << KisFillInterval(-10, 20, 0); 0186 0187 QVector<QColor> expectedResult; 0188 expectedResult << testingColor( 0); // 0 0189 expectedResult << testingColor(255); // 1 0190 expectedResult << testingColor(255); // 2 0191 expectedResult << testingColor( 0); // 3 0192 expectedResult << testingColor( 0); // 4 0193 expectedResult << testingColor(255); // 5 0194 expectedResult << testingColor( 0); // 6 0195 expectedResult << testingColor( 0); // 7 0196 expectedResult << testingColor(255); // 8 0197 expectedResult << testingColor( 0); // 9 0198 expectedResult << testingColor( 0); // 10 0199 0200 QVector<KisFillInterval> expectedForwardIntervals; 0201 0202 QVector<KisFillInterval> expectedBackwardIntervals; 0203 expectedBackwardIntervals << KisFillInterval(-10, -1, 0); 0204 expectedBackwardIntervals << KisFillInterval(11, 20, 0); 0205 0206 testFillGeneral(initialBackwardIntervals, 0207 expectedResult, 0208 expectedForwardIntervals, 0209 expectedBackwardIntervals); 0210 } 0211 0212 void KisScanlineFillTest::testFillBackwardCollisionSanityCheck() 0213 { 0214 #if defined ENABLE_FILL_SANITY_CHECKS && defined ENABLE_CHECKS_FOR_TESTING 0215 QVector<KisFillInterval> initialBackwardIntervals; 0216 initialBackwardIntervals << KisFillInterval(0, 10, 0); 0217 0218 QVector<QColor> expectedResult; 0219 QVector<KisFillInterval> expectedForwardIntervals; 0220 QVector<KisFillInterval> expectedBackwardIntervals; 0221 expectedBackwardIntervals << KisFillInterval(0, 10, 0); 0222 0223 bool gotException = false; 0224 0225 try { 0226 testFillGeneral(initialBackwardIntervals, 0227 expectedResult, 0228 expectedForwardIntervals, 0229 expectedBackwardIntervals); 0230 } catch (...) { 0231 gotException = true; 0232 } 0233 0234 QVERIFY(gotException); 0235 #endif /* ENABLE_FILL_SANITY_CHECKS */ 0236 } 0237 0238 void KisScanlineFillTest::testClearNonZeroComponent() 0239 { 0240 const QRect rc1(10, 10, 10, 10); 0241 const QRect rc2(30, 10, 10, 10); 0242 const QRect boundingRect(0,0,100,100); 0243 0244 KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8()); 0245 0246 dev->fill(rc1, KoColor(Qt::red, dev->colorSpace())); 0247 dev->fill(rc2, KoColor(Qt::green, dev->colorSpace())); 0248 0249 QCOMPARE(dev->exactBounds(), rc1 | rc2); 0250 0251 KisScanlineFill fill(dev, QPoint(10,10), boundingRect); 0252 fill.clearNonZeroComponent(); 0253 0254 QCOMPARE(dev->exactBounds(), rc2); 0255 } 0256 0257 void KisScanlineFillTest::testExternalFill() 0258 { 0259 const QRect rc1(10, 10, 10, 10); 0260 const QRect rc2(30, 10, 10, 10); 0261 const QRect boundingRect(0,0,100,100); 0262 0263 KisPaintDeviceSP dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8()); 0264 KisPaintDeviceSP other = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8()); 0265 0266 dev->fill(rc1, KoColor(Qt::red, dev->colorSpace())); 0267 dev->fill(rc2, KoColor(Qt::green, dev->colorSpace())); 0268 0269 QCOMPARE(dev->exactBounds(), rc1 | rc2); 0270 0271 KisScanlineFill fill(dev, QPoint(10,10), boundingRect); 0272 fill.fill(KoColor(Qt::blue, dev->colorSpace()), other); 0273 0274 QCOMPARE(dev->exactBounds(), rc1 | rc2); 0275 QCOMPARE(other->exactBounds(), rc1); 0276 0277 QColor c; 0278 0279 dev->pixel(10, 10, &c); 0280 QCOMPARE(c, QColor(Qt::red)); 0281 0282 other->pixel(10, 10, &c); 0283 QCOMPARE(c, QColor(Qt::blue)); 0284 } 0285 0286 SIMPLE_TEST_MAIN(KisScanlineFillTest)