File indexing completed on 2024-06-09 04:23:12
0001 /* SPDX-FileCopyrightText: 2017 Boudewijn Rempt <boud@valdyas.org> 0002 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 #include "TestDocument.h" 0006 #include <simpletest.h> 0007 0008 #include <KritaVersionWrapper.h> 0009 #include <QColor> 0010 #include <QDataStream> 0011 #include <QDir> 0012 #include <QBuffer> 0013 #include <QTextStream> 0014 0015 #include <Node.h> 0016 #include <Krita.h> 0017 #include <Document.h> 0018 0019 #include <KoColorSpaceRegistry.h> 0020 #include <KoColorProfile.h> 0021 #include <KoColor.h> 0022 0023 #include <KisDocument.h> 0024 #include <kis_image.h> 0025 #include <kis_fill_painter.h> 0026 #include <kis_paint_layer.h> 0027 #include <KisPart.h> 0028 0029 #include <kis_transform_mask_params_factory_registry.h> 0030 #include <kis_undo_stores.h> 0031 #include <testui.h> 0032 0033 void TestDocument::testSetColorSpace() 0034 { 0035 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0036 KisImageSP image = new KisImage(0, 100, 100, KoColorSpaceRegistry::instance()->rgb8(), "test"); 0037 KisNodeSP layer = new KisPaintLayer(image, "test1", 255); 0038 image->addNode(layer); 0039 kisdoc->setCurrentImage(image); 0040 0041 Document d(kisdoc.data(), false); 0042 QStringList profiles = Krita().profiles("GRAYA", "U16"); 0043 d.setColorSpace("GRAYA", "U16", profiles.first()); 0044 0045 QVERIFY(layer->colorSpace()->colorModelId().id() == "GRAYA"); 0046 QVERIFY(layer->colorSpace()->colorDepthId().id() == "U16"); 0047 QVERIFY(layer->colorSpace()->profile()->name() == profiles.first()); 0048 0049 KisPart::instance()->removeDocument(kisdoc.data(), false); 0050 } 0051 0052 void TestDocument::testSetColorProfile() 0053 { 0054 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0055 KisImageSP image = new KisImage(0, 100, 100, KoColorSpaceRegistry::instance()->rgb8(), "test"); 0056 KisNodeSP layer = new KisPaintLayer(image, "test1", 255); 0057 image->addNode(layer); 0058 kisdoc->setCurrentImage(image); 0059 0060 Document d(kisdoc.data(), false); 0061 0062 QStringList profiles = Krita().profiles("RGBA", "U8"); 0063 Q_FOREACH(const QString &profileName, profiles) { 0064 const KoColorProfile *profile = KoColorSpaceRegistry::instance()->profileByName(profileName); 0065 0066 // skip input-only profiles (e.g. for scanners) 0067 if (!profile->isSuitableForOutput()) continue; 0068 0069 d.setColorProfile(profileName); 0070 QVERIFY(image->colorSpace()->profile()->name() == profileName); 0071 } 0072 KisPart::instance()->removeDocument(kisdoc.data(), false); 0073 } 0074 0075 void TestDocument::testPixelData() 0076 { 0077 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0078 KisImageSP image = new KisImage(0, 100, 100, KoColorSpaceRegistry::instance()->rgb8(), "test"); 0079 KisNodeSP layer = new KisPaintLayer(image, "test1", 255); 0080 KisFillPainter gc(layer->paintDevice()); 0081 gc.fillRect(0, 0, 100, 100, KoColor(Qt::red, layer->colorSpace())); 0082 image->addNode(layer); 0083 kisdoc->setCurrentImage(image); 0084 0085 Document d(kisdoc.data(), false); 0086 d.refreshProjection(); 0087 0088 QByteArray ba = d.pixelData(0, 0, 100, 100); 0089 QDataStream ds(ba); 0090 do { 0091 quint8 channelvalue; 0092 ds >> channelvalue; 0093 QVERIFY(channelvalue == 0); 0094 ds >> channelvalue; 0095 QVERIFY(channelvalue == 0); 0096 ds >> channelvalue; 0097 QVERIFY(channelvalue == 255); 0098 ds >> channelvalue; 0099 QVERIFY(channelvalue == 255); 0100 } while (!ds.atEnd()); 0101 0102 KisPart::instance()->removeDocument(kisdoc.data(), false); 0103 } 0104 0105 void TestDocument::testThumbnail() 0106 { 0107 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0108 KisImageSP image = new KisImage(0, 100, 100, KoColorSpaceRegistry::instance()->rgb8(), "test"); 0109 KisNodeSP layer = new KisPaintLayer(image, "test1", 255); 0110 KisFillPainter gc(layer->paintDevice()); 0111 gc.fillRect(0, 0, 100, 100, KoColor(Qt::red, layer->colorSpace())); 0112 image->addNode(layer); 0113 kisdoc->setCurrentImage(image); 0114 0115 Document d(kisdoc.data(), false); 0116 d.refreshProjection(); 0117 0118 QImage thumb = d.thumbnail(10, 10); 0119 thumb.save("thumb.png"); 0120 QVERIFY(thumb.width() == 10); 0121 QVERIFY(thumb.height() == 10); 0122 // Our thumbnail calculator in KisPaintDevice cannot make a filled 10x10 thumbnail from a 100x100 device, 0123 // it makes it 10x10 empty, then puts 8x8 pixels in there... Not a bug in the Node class 0124 for (int i = 0; i < 8; ++i) { 0125 for (int j = 0; j < 8; ++j) { 0126 QVERIFY(thumb.pixelColor(i, j) == QColor(Qt::red)); 0127 } 0128 } 0129 KisPart::instance()->removeDocument(kisdoc.data(), false); 0130 } 0131 0132 void TestDocument::testCreateFillLayer() 0133 { 0134 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0135 KisImageSP image = new KisImage(0, 50, 50, KoColorSpaceRegistry::instance()->rgb16(), "test"); 0136 kisdoc->setCurrentImage(image); 0137 Document d(kisdoc.data(), false); 0138 0139 const QString pattern("pattern"); 0140 const QString color("color"); 0141 const QString filllayer = "filllayer"; 0142 InfoObject info; 0143 Selection sel(image->globalSelection()); 0144 0145 FillLayer *f = d.createFillLayer("test1", pattern, info, sel); 0146 QVERIFY(f->generatorName() == pattern); 0147 QVERIFY(f->type() == filllayer); 0148 delete f; 0149 f = d.createFillLayer("test1", color, info, sel); 0150 QVERIFY(f->generatorName() == color); 0151 QVERIFY(f->type() == filllayer); 0152 0153 info.setProperty(pattern, "Cross01.pat"); 0154 QVERIFY(f->setGenerator(pattern, &info)); 0155 QVERIFY(f->filterConfig()->property(pattern).toString() == "Cross01.pat"); 0156 QVERIFY(f->generatorName() == pattern); 0157 QVERIFY(f->type() == filllayer); 0158 0159 info.setProperty(color, QColor(Qt::red)); 0160 QVERIFY(f->setGenerator(color, &info)); 0161 QVariant v = f->filterConfig()->property(color); 0162 QColor c = v.value<QColor>(); 0163 QVERIFY(c == QColor(Qt::red)); 0164 QVERIFY(f->generatorName() == color); 0165 QVERIFY(f->type() == filllayer); 0166 0167 bool r = f->setGenerator(QString("xxx"), &info); 0168 QVERIFY(!r); 0169 0170 delete f; 0171 0172 QVERIFY(d.createFillLayer("test1", "xxx", info, sel) == 0); 0173 0174 KisPart::instance()->removeDocument(kisdoc.data(), false); 0175 } 0176 0177 void TestDocument::testCreateCloneLayer() 0178 { 0179 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0180 KisImageSP image = new KisImage(0, 50, 50, KoColorSpaceRegistry::instance()->rgb16(), "test"); 0181 kisdoc->setCurrentImage(image); 0182 Document d(kisdoc.data(), false); 0183 0184 const QString layerType = "clonelayer"; 0185 const QString node1Name = "node1"; 0186 const QString node2Name = "node2"; 0187 0188 Node *node1 = d.createNode(node1Name,"paintlayer"); 0189 Node *node2 = d.createNode(node2Name,"paintlayer"); 0190 CloneLayer *layer = d.createCloneLayer("test1", node1); 0191 Node* rootNode = d.rootNode(); 0192 0193 rootNode->addChildNode(node1,0); 0194 rootNode->addChildNode(node2,0); 0195 rootNode->addChildNode(layer,0); 0196 0197 QVERIFY(layer->type() == layerType); 0198 0199 Node *sourceNode1 = layer->sourceNode(); 0200 0201 QVERIFY(sourceNode1->name() == node1Name); 0202 0203 layer->setSourceNode(node2); 0204 0205 Node *sourceNode2 = layer->sourceNode(); 0206 0207 QVERIFY(sourceNode2->name() == node2Name); 0208 0209 delete layer; 0210 delete node1; 0211 delete node2; 0212 delete sourceNode1; 0213 delete sourceNode2; 0214 delete rootNode; 0215 0216 KisPart::instance()->removeDocument(kisdoc.data(), false); 0217 } 0218 0219 void TestDocument::testCreateTransparencyMask() 0220 { 0221 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0222 KisImageSP image = new KisImage(0, 50, 50, KoColorSpaceRegistry::instance()->rgb16(), "test"); 0223 kisdoc->setCurrentImage(image); 0224 Document d(kisdoc.data(), false); 0225 0226 const QString layerType = "transparencymask"; 0227 0228 Selection sel(image->globalSelection()); 0229 0230 sel.select(10,10,10,10,255); 0231 0232 Node *node = d.createNode("node1","paintlayer"); 0233 TransparencyMask *mask = d.createTransparencyMask("test1"); 0234 Node* rootNode = d.rootNode(); 0235 0236 rootNode->addChildNode(node,0); 0237 node->addChildNode(mask,0); 0238 0239 Selection* selResult = mask->selection(); 0240 0241 QVERIFY(mask->type() == layerType); 0242 QVERIFY(selResult->width() == sel.width() && selResult->height() == sel.height()); 0243 0244 delete selResult; 0245 delete mask; 0246 delete node; 0247 delete rootNode; 0248 0249 KisPart::instance()->removeDocument(kisdoc.data(), false); 0250 } 0251 0252 void TestDocument::testCreateColorizeMask() 0253 { 0254 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0255 KisImageSP image = new KisImage(new KisSurrogateUndoStore(), 10, 3, KoColorSpaceRegistry::instance()->rgb8(), "test"); 0256 0257 kisdoc->setCurrentImage(image); 0258 0259 Document d(kisdoc.data(), false); 0260 const QString layerType = "colorizemask"; 0261 0262 Node *node = d.createNode("node1","paintlayer"); 0263 0264 ColorizeMask *mask = d.createColorizeMask("test1"); 0265 Node* rootNode = d.rootNode(); 0266 0267 QByteArray nodeData = QByteArray::fromBase64("AAAAAAAAAAAAAAAAEQYMBhEGDP8RBgz/EQYMAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARBgz5EQYM/xEGDAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQYMAhEGDAkRBgwCAAAAAAAAAAAAAAAA"); 0268 0269 node->setPixelData(nodeData,0,0,10,3); 0270 rootNode->addChildNode(node,0); 0271 0272 d.waitForDone(); 0273 d.refreshProjection(); 0274 0275 node->addChildNode(mask,0); 0276 0277 qApp->processEvents(); 0278 d.waitForDone(); 0279 0280 ManagedColor col1("RGBA","U8",""); 0281 ManagedColor col2("RGBA","U8",""); 0282 0283 col1.setComponents({1.0, 0.0, 0.0, 1.0}); 0284 col2.setComponents({0.0, 0.0, 1.0, 1.0}); 0285 0286 QVERIFY(mask->type() == layerType); 0287 0288 mask->setEditKeyStrokes(true); 0289 QVERIFY(mask->editKeyStrokes() == true); 0290 0291 mask->setUseEdgeDetection(true); 0292 QVERIFY(mask->useEdgeDetection() == true); 0293 0294 mask->setEdgeDetectionSize(4.0); 0295 QVERIFY(mask->edgeDetectionSize() == 4.0); 0296 0297 mask->setCleanUpAmount(70.0); 0298 QVERIFY(mask->cleanUpAmount() == 70.0); 0299 0300 mask->setLimitToDeviceBounds(true); 0301 QVERIFY(mask->limitToDeviceBounds() == true); 0302 0303 mask->initializeKeyStrokeColors({&col1, &col2}); 0304 0305 QByteArray pdata1 = QByteArray::fromBase64("//8AAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA"); 0306 QByteArray pdata2 = QByteArray::fromBase64("AAAAAAAAAAD//wAAAAAAAAAAAP8AAAAAAAAAAAAA"); 0307 0308 mask->setKeyStrokePixelData(pdata1,&col1,0,0,10,3); 0309 mask->setKeyStrokePixelData(pdata2,&col2,0,0,10,3); 0310 0311 QList<ManagedColor *> checkColors(mask->keyStrokesColors()); 0312 0313 QVERIFY(checkColors.size() == 2); 0314 QVERIFY(col1.toQString() == checkColors[0]->toQString()); 0315 QVERIFY(col2.toQString() == checkColors[1]->toQString()); 0316 0317 QVERIFY(mask->keyStrokePixelData(&col1,0,0,10,3) == pdata1); 0318 QVERIFY(mask->keyStrokePixelData(&col2,0,0,10,3) == pdata2); 0319 0320 delete checkColors[0]; 0321 delete checkColors[1]; 0322 0323 mask->updateMask(true); 0324 mask->setEditKeyStrokes(false); 0325 mask->setShowOutput(true); 0326 0327 d.waitForDone(); 0328 d.refreshProjection(); 0329 0330 QByteArray pdata = d.pixelData(0,0,10,3); 0331 0332 QVERIFY(d.pixelData(3,2,1,1).toBase64() == "/wAA/w=="); 0333 QVERIFY(d.pixelData(6,2,1,1).toBase64() == "AAD9/w=="); 0334 0335 mask->removeKeyStroke(&col2); 0336 qApp->processEvents(); 0337 d.waitForDone(); 0338 0339 checkColors = mask->keyStrokesColors(); 0340 0341 QVERIFY(checkColors.size() == 1); 0342 QVERIFY(col1.toQString() == checkColors[0]->toQString()); 0343 0344 delete checkColors[0]; 0345 delete mask; 0346 delete node; 0347 delete rootNode; 0348 0349 KisPart::instance()->removeDocument(kisdoc.data(), false); 0350 } 0351 0352 0353 0354 void TestDocument::testAnnotations() 0355 { 0356 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0357 KisImageSP image = new KisImage(0, 100, 100, KoColorSpaceRegistry::instance()->rgb8(), "test"); 0358 KisNodeSP layer = new KisPaintLayer(image, "test1", 255); 0359 image->addNode(layer); 0360 kisdoc->setCurrentImage(image); 0361 0362 Document d(kisdoc.data(), false); 0363 0364 QVERIFY(d.annotationTypes().isEmpty()); 0365 0366 QBuffer buf; 0367 buf.open(QBuffer::WriteOnly); 0368 QTextStream in(&buf); 0369 in.setCodec("UTF-8"); 0370 in << "AnnotationTest"; 0371 buf.close(); 0372 0373 d.setAnnotation("test", "description", buf.data()); 0374 0375 QVERIFY(d.annotationTypes().size() == 1); 0376 QVERIFY(d.annotationTypes().contains("test")); 0377 QVERIFY(d.annotation("test").toHex() == buf.data().toHex()); 0378 QVERIFY(d.annotationDescription("test") == "description"); 0379 0380 d.saveAs("roundtriptest.kra"); 0381 0382 d.removeAnnotation("test"); 0383 QVERIFY(d.annotationTypes().isEmpty()); 0384 0385 d.close(); 0386 0387 Krita *krita = Krita::instance(); 0388 Document *d2 = krita->openDocument("roundtriptest.kra"); 0389 0390 QVERIFY(d2->annotationTypes().size() == 1); 0391 QVERIFY(d2->annotationTypes().contains("test")); 0392 QVERIFY(d2->annotation("test").toHex() == buf.data().toHex()); 0393 QVERIFY(d2->annotationDescription("test") == "description"); 0394 0395 d2->close(); 0396 } 0397 0398 void TestDocument::testNodeByName() 0399 { 0400 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0401 KisImageSP image = new KisImage(0, 100, 100, KoColorSpaceRegistry::instance()->rgb8(), "test"); 0402 KisNodeSP layer = new KisPaintLayer(image, "test1", 255); 0403 image->addNode(layer); 0404 kisdoc->setCurrentImage(image); 0405 0406 Document d(kisdoc.data(), false); 0407 0408 QVERIFY(d.nodeByName("test1")->name() == layer->name()); 0409 QVERIFY(d.nodeByName("test2") == 0); 0410 } 0411 0412 void TestDocument::testNodeByUniqueId() 0413 { 0414 QScopedPointer<KisDocument> kisdoc(KisPart::instance()->createDocument()); 0415 KisImageSP image = new KisImage(0, 100, 100, KoColorSpaceRegistry::instance()->rgb8(), "test"); 0416 KisNodeSP layer = new KisPaintLayer(image, "test1", 255); 0417 image->addNode(layer); 0418 kisdoc->setCurrentImage(image); 0419 0420 Document d(kisdoc.data(), false); 0421 0422 QVERIFY(d.nodeByUniqueID(layer->uuid())->name() == layer->name()); 0423 0424 QUuid test(QUuid::createUuid()); 0425 0426 while (test == layer->uuid()) { 0427 test = QUuid::createUuid(); 0428 } 0429 QVERIFY(d.nodeByUniqueID(test) == 0); 0430 } 0431 0432 class KisTransformMaskAdapter; 0433 0434 KISTEST_MAIN(TestDocument) 0435