File indexing completed on 2024-06-09 04:22:03
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_base_node_test.h" 0008 #include "KoColor.h" 0009 #include "kis_base_node.h" 0010 #include "kis_global.h" 0011 #include "kis_image_animation_interface.h" 0012 #include "kis_paint_device.h" 0013 #include "kis_scalar_keyframe_channel.h" 0014 #include "kis_types.h" 0015 #include <limits.h> 0016 #include <simpletest.h> 0017 #include <testing_nodes.h> 0018 #include <testutil.h> 0019 0020 0021 #include <KoProperties.h> 0022 0023 class TestNode : public TestUtil::DefaultNode 0024 { 0025 using KisBaseNode::accept; 0026 0027 KisNodeSP clone() const override { 0028 return new TestNode(*this); 0029 } 0030 }; 0031 0032 void KisBaseNodeTest::testCreation() 0033 { 0034 KisBaseNodeSP node = new TestNode(); 0035 QVERIFY(node->name().isEmpty()); 0036 QVERIFY(node->name() == node->objectName()); 0037 QVERIFY(node->icon().isNull()); 0038 QVERIFY(node->visible() == true); 0039 QVERIFY(node->userLocked() == false); 0040 QVERIFY(node->x() == 0); 0041 QVERIFY(node->y() == 0); 0042 } 0043 0044 void KisBaseNodeTest::testContract() 0045 { 0046 KisBaseNodeSP node = new TestNode(); 0047 0048 node->setName("bla"); 0049 QVERIFY(node->name() == "bla"); 0050 QVERIFY(node->objectName() == "bla"); 0051 0052 node->setObjectName("zxc"); 0053 QVERIFY(node->name() == "zxc"); 0054 QVERIFY(node->objectName() == "zxc"); 0055 0056 node->setVisible(!node->visible()); 0057 QVERIFY(node->visible() == false); 0058 0059 node->setUserLocked(!node->userLocked()); 0060 QVERIFY(node->userLocked() == true); 0061 0062 KisBaseNode::PropertyList list = node->sectionModelProperties(); 0063 QVERIFY(list.count() == 2); 0064 QVERIFY(list.at(0).state == node->visible()); 0065 QVERIFY(list.at(1).state == node->userLocked()); 0066 0067 QImage image = node->createThumbnail(10, 10); 0068 QCOMPARE(image.size(), QSize(10, 10)); 0069 QVERIFY(image.pixel(5, 5) == QColor(0, 0, 0, 0).rgba()); 0070 0071 } 0072 0073 void KisBaseNodeTest::testProperties() 0074 { 0075 KisBaseNodeSP node = new TestNode(); 0076 0077 { 0078 KoProperties props; 0079 0080 props.setProperty("bladiebla", false); 0081 QVERIFY(node->check(props)); 0082 0083 props.setProperty("visible", true); 0084 props.setProperty("locked", false); 0085 QVERIFY(node->check(props)); 0086 0087 props.setProperty("locked", true); 0088 QVERIFY(!node->check(props)); 0089 0090 node->setNodeProperty("locked", false); 0091 QVERIFY(node->userLocked() == false); 0092 } 0093 { 0094 KoProperties props; 0095 props.setProperty("blablabla", 10); 0096 node->mergeNodeProperties(props); 0097 0098 QVERIFY(node->nodeProperties().intProperty("blablabla") == 10); 0099 QVERIFY(node->check(props)); 0100 props.setProperty("blablabla", 12); 0101 QVERIFY(!node->check(props)); 0102 } 0103 } 0104 0105 void KisBaseNodeTest::testOpacityKeyframing() 0106 { 0107 TestUtil::MaskParent context; 0108 0109 // Get/create channel.. 0110 KisScalarKeyframeChannel *opacityChannel = dynamic_cast<KisScalarKeyframeChannel*>( 0111 context.layer->getKeyframeChannel(KisKeyframeChannel::Opacity.id(), true)); 0112 QVERIFY(opacityChannel); 0113 QVERIFY(opacityChannel->limits()); 0114 0115 const int timeA = 7; 0116 const int timeB = 15; 0117 const int halfTimeOffset = (timeB - timeA) / 2; 0118 0119 // Keyframe values are stored in percent, 0120 // but opacity values are stored as bytes 0121 // Therefore, we should convert all percentage 0122 // values to bytes for comparison testing. 0123 const qreal valueA = 50; 0124 const quint8 valueAU8 = (valueA / 100) * 255; 0125 const qreal valueB = 25; 0126 const quint8 valueBU8 = (valueB / 100) * 255; 0127 0128 // Interpolated value lands on frame edge, so value isn't quite in the middle.. 0129 const qreal valueDeltaPerFrame = (valueA - valueB) / qreal(timeB - timeA); 0130 const qreal interpolatedValueAB = valueB + valueDeltaPerFrame * halfTimeOffset; 0131 const quint8 interpValueABU8 = (interpolatedValueAB / 100) * 255; 0132 0133 // Add frames.. 0134 opacityChannel->addScalarKeyframe(timeA, valueA); 0135 opacityChannel->addScalarKeyframe(timeB, valueB); 0136 0137 QVERIFY(opacityChannel->keyframeCount() == 2); 0138 0139 // Paint starting color.. 0140 const KoColorSpace *colorSpace = context.layer->paintDevice()->colorSpace(); 0141 const KoColor originalColor = KoColor(Qt::red, colorSpace); 0142 context.layer->paintDevice()->fill(context.imageRect, originalColor); 0143 0144 // Regenerate projection.. 0145 context.image->refreshGraph(); 0146 0147 { // Before A (Opacity should be the same as A!) 0148 context.image->animationInterface()->switchCurrentTimeAsync(0); 0149 context.image->waitForDone(); 0150 0151 KoColor sample(colorSpace); 0152 context.image->projection()->pixel(16, 16, &sample); 0153 QCOMPARE(opacityChannel->valueAt(0), valueA); 0154 QCOMPARE(sample.opacityU8(), valueAU8); 0155 } 0156 0157 { // A 0158 context.image->animationInterface()->switchCurrentTimeAsync(timeA); 0159 context.image->waitForDone(); 0160 0161 KoColor sample; 0162 context.image->projection()->pixel(16, 16, &sample); 0163 QCOMPARE(opacityChannel->valueAt(timeA), valueA); 0164 QCOMPARE(sample.opacityU8(), valueAU8); 0165 } 0166 0167 { // Between A-B (Opacity interpolated) 0168 context.image->animationInterface()->switchCurrentTimeAsync(timeA + halfTimeOffset); 0169 context.image->waitForDone(); 0170 0171 QCOMPARE(opacityChannel->valueAt(timeA + halfTimeOffset), interpolatedValueAB); 0172 0173 KoColor sample; 0174 context.image->projection()->pixel(16, 16, &sample); 0175 QCOMPARE(sample.opacityU8(), interpValueABU8); 0176 0177 // Restore opacity and double check color continuity.. 0178 sample.setOpacity(originalColor.opacityU8()); 0179 QCOMPARE(sample, originalColor); 0180 } 0181 0182 { // B 0183 context.image->animationInterface()->switchCurrentTimeAsync(timeB); 0184 context.image->waitForDone(); 0185 0186 QCOMPARE(opacityChannel->valueAt(timeB), valueB); 0187 0188 KoColor sample; 0189 context.image->projection()->pixel(16, 16, &sample); 0190 QCOMPARE(sample.opacityU8(), valueBU8); 0191 } 0192 0193 { // After B (Opacity should be the same as B!) 0194 context.image->animationInterface()->switchCurrentTimeAsync(timeB + halfTimeOffset); 0195 context.image->waitForDone(); 0196 0197 QCOMPARE(opacityChannel->valueAt(timeB + halfTimeOffset), valueB); 0198 0199 KoColor sample; 0200 context.image->projection()->pixel(16, 16, &sample); 0201 QCOMPARE(sample.opacityU8(), valueBU8); 0202 } 0203 } 0204 0205 SIMPLE_TEST_MAIN(KisBaseNodeTest) 0206 0207