diff --git a/libs/image/layerstyles/KisLayerStyleKnockoutBlower.h b/libs/image/layerstyles/KisLayerStyleKnockoutBlower.h index 3d6a1c8d6f..50188eff42 100644 --- a/libs/image/layerstyles/KisLayerStyleKnockoutBlower.h +++ b/libs/image/layerstyles/KisLayerStyleKnockoutBlower.h @@ -1,44 +1,44 @@ /* * Copyright (c) 2019 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KISLAYERSTYLEKNOCKOUTBLOWER_H #define KISLAYERSTYLEKNOCKOUTBLOWER_H #include "kis_selection.h" #include class KisPainter; -class KisLayerStyleKnockoutBlower +class KRITAIMAGE_EXPORT KisLayerStyleKnockoutBlower { public: KisSelectionSP knockoutSelectionLazy(); void setKnockoutSelection(KisSelectionSP selection); void resetKnockoutSelection(); void apply(KisPainter *painter, KisPaintDeviceSP mergedStyle, const QRect &rect) const; bool isEmpty() const; private: mutable QReadWriteLock m_lock; KisSelectionSP m_knockoutSelection; }; #endif // KISLAYERSTYLEKNOCKOUTBLOWER_H diff --git a/libs/image/tests/kis_layer_styles_test.cpp b/libs/image/tests/kis_layer_styles_test.cpp index 318984e647..c875ceaac8 100644 --- a/libs/image/tests/kis_layer_styles_test.cpp +++ b/libs/image/tests/kis_layer_styles_test.cpp @@ -1,279 +1,284 @@ /* * Copyright (c) 2014 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_layer_styles_test.h" #include #include "kis_transaction.h" #include "testutil.h" #include #include "layerstyles/kis_layer_style_filter.h" #include "layerstyles/kis_layer_style_filter_environment.h" #include "layerstyles/kis_ls_drop_shadow_filter.h" #include "kis_psd_layer_style.h" #include "layerstyles/kis_multiple_projection.h" +#include "layerstyles/KisLayerStyleKnockoutBlower.h" struct TestConfig { TestConfig() : distance(0), angle(0), spread(0), size(0), noise(0), knocks_out(false), keep_original(false) { } int distance; int angle; int spread; int size; int noise; int knocks_out; int opacity; bool keep_original; void writeProperties(KisPSDLayerStyleSP style) const { style->context()->keep_original = keep_original; style->dropShadow()->setEffectEnabled(true); style->dropShadow()->setDistance(distance); style->dropShadow()->setSpread(spread); style->dropShadow()->setSize(size); style->dropShadow()->setNoise(noise); style->dropShadow()->setKnocksOut(knocks_out); style->dropShadow()->setOpacity(opacity); } QString genTestname(const QString &prefix) const { return QString("%1_d_%2_an_%3_sz_%4_spr_%5_nz_%6_ko_%7_keep_%8") .arg(prefix) .arg(distance) .arg(angle) .arg(size) .arg(spread) .arg(noise) .arg(knocks_out) .arg(keep_original); } }; void testDropShadowImpl(const TestConfig &config, const QVector &applyRects, const QString &testName, bool useSeparateDevices) { Q_UNUSED(useSeparateDevices); const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); QRect srcRect(50, 50, 100, 100); QRect dstRect(0, 0, 200, 200); KisPaintDeviceSP dev = new KisPaintDevice(cs); dev->fill(srcRect, KoColor(Qt::red, cs)); KisMultipleProjection projection; KisLsDropShadowFilter lsFilter; KisPSDLayerStyleSP style(new KisPSDLayerStyle()); config.writeProperties(style); TestUtil::MaskParent parent; KisLayerStyleFilterEnvironment env(parent.layer.data()); + KisLayerStyleKnockoutBlower blower; Q_FOREACH (const QRect &rc, applyRects) { - lsFilter.processDirectly(dev, &projection, rc, style, &env); + lsFilter.processDirectly(dev, &projection, &blower, rc, style, &env); } + // drop shadow doesn't use global knockout + QVERIFY(blower.isEmpty()); + KisPaintDeviceSP dst = new KisPaintDevice(cs); projection.apply(dst, dstRect, &env); QImage resultImage = dst->convertToQImage(0, dstRect); TestUtil::checkQImage(resultImage, "layer_styles_test", "common", config.genTestname(testName)); } void KisLayerStylesTest::testLayerStylesFull() { TestConfig c; c.distance = 20; c.angle = 135; c.spread = 50; c.size = 10; c.noise = 30; c.knocks_out = false; c.opacity = 50; c.keep_original = false; testDropShadowImpl(c, QVector() << QRect(0,0,200,200), "full", false); } void KisLayerStylesTest::testLayerStylesPartial() { QVector rects; for (int y = 0; y < 200; y += 50) { for (int x = 0; x < 200; x += 50) { rects << QRect(x, y, 50, 50); } } TestConfig c; c.distance = 20; c.angle = 135; c.spread = 50; c.size = 10; c.noise = 30; c.knocks_out = false; c.opacity = 50; c.keep_original = false; testDropShadowImpl(c, rects, "partial", true); } void KisLayerStylesTest::testLayerStylesPartialVary() { QVector rects; for (int y = 0; y < 200; y += 50) { for (int x = 0; x < 200; x += 50) { rects << QRect(x, y, 50, 50); } } TestConfig c; c.distance = 20; c.angle = 135; c.spread = 50; c.size = 10; c.noise = 30; c.knocks_out = false; c.opacity = 50; c.keep_original = true; testDropShadowImpl(c, rects, "partial", true); c.noise = 90; testDropShadowImpl(c, rects, "partial", true); c.noise = 0; testDropShadowImpl(c, rects, "partial", true); c.noise = 10; testDropShadowImpl(c, rects, "partial", true); c.angle = 90; testDropShadowImpl(c, rects, "partial", true); c.angle = 45; testDropShadowImpl(c, rects, "partial", true); c.knocks_out = true; testDropShadowImpl(c, rects, "partial", true); c.spread = 90; testDropShadowImpl(c, rects, "partial", true); } void testDropShadowNeedChangeRects(int distance, int noise, int size, int spread, const QRect &applyRect, const QRect &needRect, const QRect &changeRect) { TestConfig c; c.distance = distance; c.spread = spread; c.size = size; c.noise = noise; c.angle = 90; c.knocks_out = false; c.opacity = 50; KisLsDropShadowFilter lsFilter; KisPSDLayerStyleSP style(new KisPSDLayerStyle()); c.writeProperties(style); TestUtil::MaskParent parent; KisLayerStyleFilterEnvironment env(parent.layer.data()); QCOMPARE(lsFilter.neededRect(applyRect, style, &env), needRect); QCOMPARE(lsFilter.changedRect(applyRect, style, &env), changeRect); } void KisLayerStylesTest::testLayerStylesRects() { QRect applyRect; QRect needRect; QRect changeRect; applyRect = QRect(10,10,10,10); needRect = applyRect; changeRect = applyRect; testDropShadowNeedChangeRects(0, 0, 0, 0, applyRect, needRect, changeRect); applyRect = QRect(10,10,10,10); needRect = QRect(10,0,10,20); changeRect = QRect(10,10,10,20); testDropShadowNeedChangeRects(10, 0, 0, 0, applyRect, needRect, changeRect); applyRect = QRect(10,10,10,10); needRect = QRect(2,2,26,26); changeRect = QRect(2,2,26,26); testDropShadowNeedChangeRects(0, 30, 0, 0, applyRect, needRect, changeRect); applyRect = QRect(10,10,10,10); needRect = QRect(-2,-2,34,34); changeRect = QRect(-2,-2,34,34); testDropShadowNeedChangeRects(0, 0, 10, 0, applyRect, needRect, changeRect); applyRect = QRect(10,10,10,10); needRect = QRect(-2,-2,34,34); changeRect = QRect(-2,-2,34,34); testDropShadowNeedChangeRects(0, 0, 10, 50, applyRect, needRect, changeRect); applyRect = QRect(10,10,10,10); needRect = QRect(-2,-2,34,34); changeRect = QRect(-2,-2,34,34); testDropShadowNeedChangeRects(0, 0, 10, 75, applyRect, needRect, changeRect); } QTEST_MAIN(KisLayerStylesTest)