File indexing completed on 2024-12-22 04:10:19

0001 /*
0002  *  SPDX-FileCopyrightText: 2007 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_layer_test.h"
0008 #include <simpletest.h>
0009 
0010 #include <QRect>
0011 #include <QIcon>
0012 #include <QBitArray>
0013 
0014 #include <KoColorSpace.h>
0015 #include <KoColorSpaceRegistry.h>
0016 
0017 #include "kis_paint_device.h"
0018 #include "kis_selection.h"
0019 #include "kis_filter_mask.h"
0020 #include "kis_transparency_mask.h"
0021 
0022 #include "kis_group_layer.h"
0023 #include "kis_paint_layer.h"
0024 
0025 #include "filter/kis_filter.h"
0026 #include "filter/kis_filter_configuration.h"
0027 #include "filter/kis_filter_registry.h"
0028 #include <KisGlobalResourcesInterface.h>
0029 
0030 
0031 void KisLayerTest::testCreation()
0032 {
0033 
0034     const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8();
0035     KisImageSP image = new KisImage(0, 512, 512, colorSpace, "layer test");
0036     image->waitForDone();
0037 
0038     KisLayerSP layer = new TestLayer(image, "test", OPACITY_OPAQUE_U8);
0039     QCOMPARE(layer->name(), QString("test"));
0040     QCOMPARE(layer->opacity(), OPACITY_OPAQUE_U8);
0041     QCOMPARE(layer->image().data(), image.data());
0042     QCOMPARE(layer->colorSpace(), image->colorSpace());
0043     QCOMPARE(layer->visible(), true);
0044     QCOMPARE(layer->userLocked(), false);
0045     QCOMPARE(layer->temporary(), false);
0046 
0047     image->addNode(layer, image->rootLayer());
0048 
0049     QBitArray channels(4);
0050     channels.fill(true);
0051     channels.setBit(1, false);
0052     layer->setChannelFlags(channels);
0053     QVERIFY(layer->channelFlags().count() == 4);
0054     QCOMPARE(layer->channelFlags().at(0), true);
0055     QCOMPARE(layer->channelFlags().at(1), false);
0056     QCOMPARE(layer->channelFlags().at(2), true);
0057     QCOMPARE(layer->channelFlags().at(3), true);
0058 
0059 
0060     layer->setOpacity(OPACITY_TRANSPARENT_U8);
0061     QCOMPARE(layer->opacity(), OPACITY_TRANSPARENT_U8);
0062     layer->setPercentOpacity(100);
0063     QCOMPARE(layer->opacity(), OPACITY_OPAQUE_U8);
0064     layer->setPercentOpacity(0);
0065     QCOMPARE(layer->opacity(), OPACITY_TRANSPARENT_U8);
0066 
0067 
0068 }
0069 
0070 void KisLayerTest::testOrdering()
0071 {
0072     const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8();
0073     KisImageSP image = new KisImage(0, 512, 512, colorSpace, "layer test");
0074     image->waitForDone();
0075 
0076     KisLayerSP layer1 = new TestLayer(image, "layer1", OPACITY_OPAQUE_U8);
0077     KisLayerSP layer2 = new TestLayer(image, "layer2", OPACITY_OPAQUE_U8);
0078     KisLayerSP layer3 = new TestLayer(image, "layer3", OPACITY_OPAQUE_U8);
0079 
0080     QVERIFY(layer1->name() == "layer1");
0081     QVERIFY(layer2->name() == "layer2");
0082     QVERIFY(layer3->name() == "layer3");
0083 
0084     /*
0085       +---------+
0086       | layer 2 |
0087       | layer 3 |
0088       | layer 1 |
0089       |root     |
0090       +---------+
0091      */
0092 
0093     QVERIFY(image->addNode(layer1, image->rootLayer()));
0094     QVERIFY(image->addNode(layer2, image->rootLayer()));
0095     QVERIFY(image->addNode(layer3, image->rootLayer(), layer1));
0096 
0097     QCOMPARE((int) image->nlayers(), 4);
0098 
0099     QVERIFY(layer1->parent() == image->root());
0100     QVERIFY(layer2->parent() == image->root());
0101     QVERIFY(layer3->parent() == image->root());
0102 
0103     QVERIFY(image->rootLayer()->firstChild() == layer1.data());
0104     QVERIFY(image->rootLayer()->lastChild() == layer2.data());
0105 
0106     QVERIFY(image->rootLayer()->at(0) == layer1.data());
0107     QVERIFY(image->rootLayer()->at(1) == layer3.data());
0108     QVERIFY(image->rootLayer()->at(2) == layer2.data());
0109 
0110     QVERIFY(image->rootLayer()->index(layer1) == 0);
0111     QVERIFY(image->rootLayer()->index(layer3) == 1);
0112     QVERIFY(image->rootLayer()->index(layer2) == 2);
0113 
0114     QVERIFY(layer3->prevSibling() == layer1.data());
0115     QVERIFY(layer2->prevSibling() == layer3.data());
0116     QVERIFY(layer1->prevSibling() == 0);
0117 
0118     QVERIFY(layer3->nextSibling() == layer2.data());
0119     QVERIFY(layer2->nextSibling() == 0);
0120     QVERIFY(layer1->nextSibling() == layer3.data());
0121 
0122 
0123     /*
0124       +---------+
0125       | layer 3 |
0126       | layer 2 |
0127       | layer 1 |
0128       |root     |
0129       +---------+
0130      */
0131     QVERIFY(image->moveNode(layer2, image->rootLayer(), layer1));
0132 
0133     QVERIFY(image->rootLayer()->at(0) == layer1.data());
0134     QVERIFY(image->rootLayer()->at(1) == layer2.data());
0135     QVERIFY(image->rootLayer()->at(2) == layer3.data());
0136 
0137     QVERIFY(image->rootLayer()->firstChild() == layer1.data());
0138     QVERIFY(image->rootLayer()->lastChild() == layer3.data());
0139 
0140     QVERIFY(image->rootLayer()->index(layer1) == 0);
0141     QVERIFY(image->rootLayer()->index(layer2) == 1);
0142     QVERIFY(image->rootLayer()->index(layer3) == 2);
0143 
0144     QVERIFY(layer3->prevSibling() == layer2.data());
0145     QVERIFY(layer2->prevSibling() == layer1.data());
0146     QVERIFY(layer1->prevSibling() == 0);
0147 
0148     QVERIFY(layer3->nextSibling() == 0);
0149     QVERIFY(layer2->nextSibling() == layer3.data());
0150     QVERIFY(layer1->nextSibling() == layer2.data());
0151 
0152 }
0153 
0154 
0155 void KisLayerTest::testMoveNode()
0156 {
0157     const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8();
0158     KisImageSP image = new KisImage(0, 512, 512, colorSpace, "layer test");
0159     image->waitForDone();
0160 
0161     KisLayerSP node1 = new TestLayer(image, "layer1", OPACITY_OPAQUE_U8);
0162     KisLayerSP node2 = new TestLayer(image, "layer2", OPACITY_OPAQUE_U8);
0163     KisLayerSP node3 = new TestLayer(image, "layer3", OPACITY_OPAQUE_U8);
0164 
0165     node1->setName("node1");
0166     node2->setName("node2");
0167     node3->setName("node3");
0168 
0169     QVERIFY(image->addNode(node1));
0170     QVERIFY(image->addNode(node2));
0171     QVERIFY(image->addNode(node3));
0172 
0173     QVERIFY(image->root()->at(0) == node1.data());
0174     QVERIFY(image->root()->at(1) == node2.data());
0175     QVERIFY(image->root()->at(2) == node3.data());
0176 
0177     QVERIFY(image->moveNode(node3, image->root(), node1));
0178 
0179     QVERIFY(image->root()->at(0) == node1.data());
0180     QVERIFY(image->root()->at(1) == node3.data());
0181     QVERIFY(image->root()->at(2) == node2.data());
0182 
0183 }
0184 
0185 
0186 void KisLayerTest::testMoveLayer()
0187 {
0188     const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8();
0189     KisImageSP image = new KisImage(0, 512, 512, colorSpace, "layer test");
0190     image->waitForDone();
0191 
0192     KisLayerSP node1 = new TestLayer(image, "layer1", OPACITY_OPAQUE_U8);
0193     KisLayerSP node2 = new TestLayer(image, "layer2", OPACITY_OPAQUE_U8);
0194     KisLayerSP node3 = new TestLayer(image, "layer3", OPACITY_OPAQUE_U8);
0195     node1->setName("node1");
0196     node2->setName("node2");
0197     node3->setName("node3");
0198 
0199     QVERIFY(image->addNode(node1));
0200     QVERIFY(image->addNode(node2));
0201     QVERIFY(image->addNode(node3));
0202 
0203     QVERIFY(image->root()->at(0) == node1.data());
0204     QVERIFY(image->root()->at(1) == node2.data());
0205     QVERIFY(image->root()->at(2) == node3.data());
0206 
0207     QVERIFY(image->moveNode(node3, image->rootLayer(), node1));
0208 
0209     QVERIFY(image->root()->at(0) == node1.data());
0210     QVERIFY(image->root()->at(1) == node3.data());
0211     QVERIFY(image->root()->at(2) == node2.data());
0212 
0213 }
0214 
0215     /*
0216       +----------+
0217       |root      |
0218       | paint 1  |
0219       |  fmask2  |
0220       |  fmask1  |
0221       +----------+
0222      */
0223 
0224 void KisLayerTest::testMasksChangeRect()
0225 {
0226     const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8();
0227     KisImageSP image = new KisImage(0, 512, 512, colorSpace, "walker test");
0228 
0229     KisLayerSP paintLayer1 = new KisPaintLayer(image, "paint1", OPACITY_OPAQUE_U8);
0230 
0231     image->addNode(paintLayer1, image->rootLayer());
0232 
0233     KisFilterMaskSP filterMask1 = new KisFilterMask(image, "fmask1");
0234     KisFilterMaskSP filterMask2 = new KisFilterMask(image, "fmask2");
0235 
0236     KisFilterSP filter = KisFilterRegistry::instance()->value("blur");
0237     Q_ASSERT(filter);
0238     KisFilterConfigurationSP configuration1 = filter->defaultConfiguration(KisGlobalResourcesInterface::instance());
0239     KisFilterConfigurationSP configuration2 = filter->defaultConfiguration(KisGlobalResourcesInterface::instance());
0240 
0241     filterMask1->setFilter(configuration1->cloneWithResourcesSnapshot());
0242     filterMask2->setFilter(configuration2->cloneWithResourcesSnapshot());
0243 
0244     image->addNode(filterMask1, paintLayer1);
0245     image->addNode(filterMask2, paintLayer1);
0246 
0247     QVERIFY(paintLayer1->hasEffectMasks());
0248 
0249     QRect testRect(10, 10, 100, 100);
0250     QRect resultRect;
0251 
0252     resultRect = paintLayer1->changeRect(testRect, KisNode::N_FILTHY);
0253     QVERIFY2(resultRect == QRect(0, 0, 120, 120),
0254               "KisNode::N_FILTHY node should take masks into account");
0255 
0256     resultRect = paintLayer1->changeRect(testRect, KisNode::N_ABOVE_FILTHY);
0257     QVERIFY2(resultRect == testRect,
0258               "KisNode::N_ABOVE_FILTHY node should NOT take "
0259               "masks into account");
0260 
0261     /**
0262      * KisNode::N_BELOW_FILTHY, KisNode::N_FILTHY_PROJECTION
0263      * should not be use by the caller, because the walker
0264      * should not visit these node on a forward way.
0265      * So the behavior here is undefined.
0266      *
0267      * resultRect = paintLayer1->changeRect(testRect, KisNode::N_BELOW_FILTHY);
0268      * resultRect = paintLayer1->changeRect(testRect, KisNode::N_FILTHY_PROJECTION);
0269      */
0270 
0271 }
0272 
0273 void KisLayerTest::testMoveLayerWithMaskThreaded()
0274 {
0275     /**
0276      * This test ensures that the layer's original() can be moved
0277      * while its projection is still being updated
0278      */
0279 
0280     const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8();
0281     KisImageSP image = new KisImage(0, 2000, 2000, colorSpace, "walker test");
0282 
0283     KisLayerSP paintLayer = new KisPaintLayer(image, "paint1", OPACITY_OPAQUE_U8);
0284     image->addNode(paintLayer, image->rootLayer());
0285 
0286     paintLayer->paintDevice()->fill(image->bounds(), KoColor(Qt::black, colorSpace));
0287 
0288     KisTransparencyMaskSP transpMask = new KisTransparencyMask(image, "tmask");
0289     transpMask->initSelection(paintLayer);
0290     image->addNode(transpMask, paintLayer);
0291 
0292     for(int i = 0; i < 100; i++) {
0293         paintLayer->setDirty();
0294 
0295         QTest::qSleep(1 + (qrand() & 63));
0296 
0297         paintLayer->setX((i*67) % 1873);
0298         paintLayer->setY((i*23) % 1873);
0299     }
0300 }
0301 
0302 
0303 SIMPLE_TEST_MAIN(KisLayerTest)
0304