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

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_layer_styles_test.h"
0008 
0009 #include <simpletest.h>
0010 
0011 #include "kis_transaction.h"
0012 
0013 #include <KoColor.h>
0014 
0015 
0016 #include "layerstyles/kis_layer_style_filter.h"
0017 #include "layerstyles/kis_layer_style_filter_environment.h"
0018 #include "layerstyles/kis_ls_drop_shadow_filter.h"
0019 #include "kis_psd_layer_style.h"
0020 #include "layerstyles/kis_multiple_projection.h"
0021 #include "layerstyles/KisLayerStyleKnockoutBlower.h"
0022 
0023 #include <testutil.h>
0024 #include "testimage.h"
0025 
0026 
0027 struct TestConfig {
0028     TestConfig()
0029         : distance(0),
0030           angle(0),
0031           spread(0),
0032           size(0),
0033           noise(0),
0034           knocks_out(false),
0035           keep_original(false)
0036     {
0037     }
0038 
0039     int distance;
0040     int angle;
0041     int spread;
0042     int size;
0043     int noise;
0044     int knocks_out;
0045     int opacity;
0046     bool keep_original;
0047 
0048     void writeProperties(KisPSDLayerStyleSP style) const {
0049         style->context()->keep_original = keep_original;
0050 
0051         style->dropShadow()->setEffectEnabled(true);
0052         style->dropShadow()->setDistance(distance);
0053         style->dropShadow()->setSpread(spread);
0054         style->dropShadow()->setSize(size);
0055         style->dropShadow()->setNoise(noise);
0056         style->dropShadow()->setKnocksOut(knocks_out);
0057         style->dropShadow()->setOpacity(opacity);
0058         style->dropShadow()->setAngle(angle);
0059     }
0060 
0061     QString genTestname(const QString &prefix) const {
0062         return QString("%1_d_%2_an_%3_sz_%4_spr_%5_nz_%6_ko_%7_keep_%8")
0063             .arg(prefix)
0064             .arg(distance)
0065             .arg(angle)
0066             .arg(size)
0067             .arg(spread)
0068             .arg(noise)
0069             .arg(knocks_out)
0070             .arg(keep_original);
0071     }
0072 };
0073 
0074 
0075 void testDropShadowImpl(const TestConfig &config,
0076                         const QVector<QRect> &applyRects,
0077                         const QString &testName,
0078                         bool useSeparateDevices)
0079 {
0080     Q_UNUSED(useSeparateDevices);
0081 
0082     const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
0083 
0084     QRect srcRect(50, 50, 100, 100);
0085     QRect dstRect(0, 0, 200, 200);
0086 
0087     KisPaintDeviceSP dev = new KisPaintDevice(cs);
0088     dev->fill(srcRect, KoColor(Qt::red, cs));
0089 
0090     KisMultipleProjection projection;
0091 
0092     KisLsDropShadowFilter lsFilter;
0093     KisPSDLayerStyleSP style(new KisPSDLayerStyle());
0094     config.writeProperties(style);
0095 
0096 
0097 
0098     TestUtil::MaskParent parent;
0099     KisLayerStyleFilterEnvironment env(parent.layer.data());
0100     KisLayerStyleKnockoutBlower blower;
0101 
0102     Q_FOREACH (const QRect &rc, applyRects) {
0103         lsFilter.processDirectly(dev, &projection, &blower, rc, style, &env);
0104     }
0105 
0106     // drop shadow doesn't use global knockout
0107     QVERIFY(blower.isEmpty());
0108 
0109 
0110     KisPaintDeviceSP dst = new KisPaintDevice(cs);
0111 
0112     projection.apply(dst, dstRect, &env);
0113 
0114     QImage resultImage =
0115         dst->convertToQImage(0, dstRect);
0116 
0117     TestUtil::checkQImage(resultImage,
0118                           "layer_styles_test",
0119                           "common",
0120                           config.genTestname(testName));
0121 }
0122 
0123 void KisLayerStylesTest::testLayerStylesFull()
0124 {
0125     TestConfig c;
0126     c.distance = 20;
0127     c.angle = 135;
0128     c.spread = 50;
0129     c.size = 10;
0130     c.noise = 30;
0131     c.knocks_out = false;
0132     c.opacity = 50;
0133     c.keep_original = false;
0134 
0135     testDropShadowImpl(c, QVector<QRect>() << QRect(0,0,200,200), "full", false);
0136 }
0137 
0138 void KisLayerStylesTest::testLayerStylesPartial()
0139 {
0140     QVector<QRect> rects;
0141 
0142     for (int y = 0; y < 200; y += 50) {
0143         for (int x = 0; x < 200; x += 50) {
0144             rects << QRect(x, y, 50, 50);
0145         }
0146     }
0147 
0148     TestConfig c;
0149     c.distance = 20;
0150     c.angle = 135;
0151     c.spread = 50;
0152     c.size = 10;
0153     c.noise = 30;
0154     c.knocks_out = false;
0155     c.opacity = 50;
0156     c.keep_original = false;
0157 
0158     testDropShadowImpl(c, rects, "partial", true);
0159 }
0160 
0161 void KisLayerStylesTest::testLayerStylesPartialVary()
0162 {
0163     QVector<QRect> rects;
0164 
0165     for (int y = 0; y < 200; y += 50) {
0166         for (int x = 0; x < 200; x += 50) {
0167             rects << QRect(x, y, 50, 50);
0168         }
0169     }
0170 
0171     TestConfig c;
0172     c.distance = 20;
0173     c.angle = 135;
0174     c.spread = 50;
0175     c.size = 10;
0176     c.noise = 30;
0177     c.knocks_out = false;
0178     c.opacity = 50;
0179     c.keep_original = true;
0180 
0181     testDropShadowImpl(c, rects, "partial", true);
0182 
0183     c.noise = 90;
0184     testDropShadowImpl(c, rects, "partial", true);
0185 
0186     c.noise = 0;
0187     testDropShadowImpl(c, rects, "partial", true);
0188 
0189     c.noise = 10;
0190     testDropShadowImpl(c, rects, "partial", true);
0191 
0192     c.angle = 90;
0193     testDropShadowImpl(c, rects, "partial", true);
0194 
0195     c.angle = 45;
0196     testDropShadowImpl(c, rects, "partial", true);
0197 
0198     c.knocks_out = true;
0199     testDropShadowImpl(c, rects, "partial", true);
0200 
0201     c.spread = 90;
0202     testDropShadowImpl(c, rects, "partial", true);
0203 
0204 
0205 }
0206 
0207 void testDropShadowNeedChangeRects(int distance,
0208                                    int noise,
0209                                    int size,
0210                                    int spread,
0211                                    const QRect &applyRect,
0212                                    const QRect &needRect,
0213                                    const QRect &changeRect)
0214 {
0215     TestConfig c;
0216     c.distance = distance;
0217     c.spread = spread;
0218     c.size = size;
0219     c.noise = noise;
0220     c.angle = 90;
0221     c.knocks_out = false;
0222     c.opacity = 50;
0223 
0224 
0225     KisLsDropShadowFilter lsFilter;
0226     KisPSDLayerStyleSP style(new KisPSDLayerStyle());
0227     c.writeProperties(style);
0228 
0229 
0230     TestUtil::MaskParent parent;
0231     KisLayerStyleFilterEnvironment env(parent.layer.data());
0232 
0233     QCOMPARE(lsFilter.neededRect(applyRect, style, &env), needRect);
0234     QCOMPARE(lsFilter.changedRect(applyRect, style, &env), changeRect);
0235 }
0236 
0237 void KisLayerStylesTest::testLayerStylesRects()
0238 {
0239     QRect applyRect;
0240     QRect needRect;
0241     QRect changeRect;
0242 
0243     applyRect = QRect(10,10,10,10);
0244     needRect = applyRect;
0245     changeRect = applyRect;
0246     testDropShadowNeedChangeRects(0, 0, 0, 0, applyRect, needRect, changeRect);
0247 
0248     applyRect = QRect(10,10,10,10);
0249     needRect = QRect(10,0,10,20);
0250     changeRect = QRect(10,10,10,20);
0251     testDropShadowNeedChangeRects(10, 0, 0, 0, applyRect, needRect, changeRect);
0252 
0253     applyRect = QRect(10,10,10,10);
0254     needRect = QRect(2,2,26,26);
0255     changeRect = QRect(2,2,26,26);
0256     testDropShadowNeedChangeRects(0, 30, 0, 0, applyRect, needRect, changeRect);
0257 
0258     applyRect = QRect(10,10,10,10);
0259     needRect = QRect(-2,-2,34,34);
0260     changeRect = QRect(-2,-2,34,34);
0261     testDropShadowNeedChangeRects(0, 0, 10, 0, applyRect, needRect, changeRect);
0262 
0263 
0264     applyRect = QRect(10,10,10,10);
0265     needRect = QRect(-2,-2,34,34);
0266     changeRect = QRect(-2,-2,34,34);
0267     testDropShadowNeedChangeRects(0, 0, 10, 50, applyRect, needRect, changeRect);
0268 
0269     applyRect = QRect(10,10,10,10);
0270     needRect = QRect(-2,-2,34,34);
0271     changeRect = QRect(-2,-2,34,34);
0272     testDropShadowNeedChangeRects(0, 0, 10, 75, applyRect, needRect, changeRect);
0273 }
0274 
0275 KISTEST_MAIN(KisLayerStylesTest)