[calligra/calligra/2.9] krita/image: Fixed Flatten Layer and Merge Down actions for layer with layer styles

Dmitry Kazakov dimula73 at gmail.com
Mon Jul 13 17:46:23 UTC 2015


Git commit 515c472b4416d42334db09de84f051d0bdf8ddbe by Dmitry Kazakov.
Committed on 13/07/2015 at 17:45.
Pushed by dkazakov into branch 'calligra/2.9'.

Fixed Flatten Layer and Merge Down actions for layer with layer styles

Also fixed a few of other bus. Now merging strategy is the following:

For Flatten Layer:
1) If a layer doesn't have layer styles, its blending mode and channel flags
   are kept untouched while the flattening process.
2) If a layer has a style applied, then all the composition options
   are reset and the layer is converted into Normal-mode layer.

For Merge Down:
1) If the two layers has the same opacity, blend mode, channel flags and
   have no layer styles, then the resulting layer inherits all their blend
   options.
2) If the condition above isn't true, then the two layers are blended
   into a new layer with default blending options (Normal, 100% opacity).

Still TODO:
Implement "Merge Selected Layers" correctly.

CC:kimageshop at kde.org
BUG:349479
Ref T456

M  +1    -1    krita/image/kis_group_layer.cc
M  +22   -7    krita/image/kis_image.cc
M  +23   -21   krita/image/kis_layer.cc
M  +2    -0    krita/image/kis_layer.h
M  +327  -0    krita/image/tests/kis_image_test.cpp
M  +7    -0    krita/image/tests/kis_image_test.h

http://commits.kde.org/calligra/515c472b4416d42334db09de84f051d0bdf8ddbe

diff --git a/krita/image/kis_group_layer.cc b/krita/image/kis_group_layer.cc
index 393d4d2..95a7fc5 100644
--- a/krita/image/kis_group_layer.cc
+++ b/krita/image/kis_group_layer.cc
@@ -144,7 +144,7 @@ KisLayerSP KisGroupLayer::createMergedLayer(KisLayerSP prevLayer)
 {
     KisGroupLayer *prevGroup = dynamic_cast<KisGroupLayer*>(prevLayer.data());
 
-    if (prevGroup) {
+    if (prevGroup && canMergeAndKeepBlendOptions(prevLayer)) {
         KisSharedPtr<KisGroupLayer> merged(new KisGroupLayer(*prevGroup));
 
         KisNodeSP child, cloned;
diff --git a/krita/image/kis_image.cc b/krita/image/kis_image.cc
index 1cebdec..c99f2f9 100644
--- a/krita/image/kis_image.cc
+++ b/krita/image/kis_image.cc
@@ -959,7 +959,6 @@ KisLayerSP KisImage::mergeDown(KisLayerSP layer, const KisMetaData::MergeStrateg
     refreshHiddenArea(layer, bounds());
     refreshHiddenArea(prevLayer, bounds());
 
-    bool prevAlphaDisabled = prevLayer->alphaChannelDisabled();
     QRect layerProjectionExtent = this->projection()->extent();
     QRect prevLayerProjectionExtent = prevLayer->projection()->extent();
 
@@ -967,10 +966,6 @@ KisLayerSP KisImage::mergeDown(KisLayerSP layer, const KisMetaData::MergeStrateg
     KisLayerSP mergedLayer = layer->createMergedLayer(prevLayer);
     Q_CHECK_PTR(mergedLayer);
 
-    mergedLayer->setCompositeOp(COMPOSITE_OVER);
-    mergedLayer->setChannelFlags(layer->channelFlags());
-    mergedLayer->disableAlphaChannel(prevAlphaDisabled);
-
     // Merge meta data
     QList<const KisMetaData::Store*> srcs;
     srcs.append(prevLayer->metaData());
@@ -1025,13 +1020,33 @@ KisLayerSP KisImage::flattenLayer(KisLayerSP layer)
 
     refreshHiddenArea(layer, bounds());
 
+    bool resetComposition = false;
+
+    KisPaintDeviceSP mergedDevice;
+
     lock();
-    KisPaintDeviceSP mergedDevice = new KisPaintDevice(*layer->projection());
+    if (layer->layerStyle()) {
+        mergedDevice = new KisPaintDevice(layer->colorSpace());
+        mergedDevice->prepareClone(layer->projection());
+
+        QRect updateRect = layer->projection()->extent() | bounds();
+
+        KisPainter gc(mergedDevice);
+        layer->projectionPlane()->apply(&gc, updateRect);
+
+        resetComposition = true;
+
+    } else {
+        mergedDevice = new KisPaintDevice(*layer->projection());
+    }
     unlock();
 
     KisPaintLayerSP newLayer = new KisPaintLayer(this, layer->name(), layer->opacity(), mergedDevice);
-    newLayer->setCompositeOp(layer->compositeOp()->id());
 
+    if (!resetComposition) {
+        newLayer->setCompositeOp(layer->compositeOp()->id());
+        newLayer->setChannelFlags(layer->channelFlags());
+    }
 
     undoAdapter()->beginMacro(kundo2_i18n("Flatten Layer"));
     undoAdapter()->addCommand(new KisImageLayerAddCommand(this, newLayer, layer->parent(), layer));
diff --git a/krita/image/kis_layer.cc b/krita/image/kis_layer.cc
index 2987600..d9ff8be 100644
--- a/krita/image/kis_layer.cc
+++ b/krita/image/kis_layer.cc
@@ -305,9 +305,18 @@ void KisLayer::setImage(KisImageWSP image)
     }
 }
 
+bool KisLayer::canMergeAndKeepBlendOptions(KisLayerSP otherLayer)
+{
+    return
+        this->compositeOpId() == otherLayer->compositeOpId() &&
+        this->opacity() == otherLayer->opacity() &&
+        this->channelFlags() == otherLayer->channelFlags() &&
+        !this->layerStyle() && !otherLayer->layerStyle();
+}
+
 KisLayerSP KisLayer::createMergedLayer(KisLayerSP prevLayer)
 {
-    KisImageWSP my_image = image();
+    KisImageSP my_image = image();
 
     QRect layerProjectionExtent = this->projection()->extent();
     QRect prevLayerProjectionExtent = prevLayer->projection()->extent();
@@ -316,7 +325,9 @@ KisLayerSP KisLayer::createMergedLayer(KisLayerSP prevLayer)
 
     KisPaintDeviceSP mergedDevice;
 
-    if (this->compositeOpId() != prevLayer->compositeOpId() || prevLayer->opacity() != OPACITY_OPAQUE_U8) {
+    bool keepBlendingOptions = canMergeAndKeepBlendOptions(prevLayer);
+
+    if (!keepBlendingOptions) {
 
         mergedDevice = new KisPaintDevice(this->colorSpace(), "merged");
         KisPainter gc(mergedDevice);
@@ -324,11 +335,7 @@ KisLayerSP KisLayer::createMergedLayer(KisLayerSP prevLayer)
         //Copy the pixels of previous layer with their actual alpha value
         prevLayer->disableAlphaChannel(false);
 
-        gc.setChannelFlags(prevLayer->channelFlags());
-        gc.setCompositeOp(mergedDevice->colorSpace()->compositeOp(prevLayer->compositeOpId()));
-        gc.setOpacity(prevLayer->opacity());
-
-        gc.bitBlt(prevLayerProjectionExtent.topLeft(), prevLayer->projection(), prevLayerProjectionExtent);
+        prevLayer->projectionPlane()->apply(&gc, prevLayerProjectionExtent | my_image->bounds());
 
         //Restore the previous prevLayer disableAlpha status for correct undo/redo
         prevLayer->disableAlphaChannel(prevAlphaDisabled);
@@ -337,11 +344,8 @@ KisLayerSP KisLayer::createMergedLayer(KisLayerSP prevLayer)
         if (alphaDisabled == prevAlphaDisabled) {
             this->disableAlphaChannel(false);
         }
-        gc.setChannelFlags(this->channelFlags());
-        gc.setCompositeOp(mergedDevice->colorSpace()->compositeOp(this->compositeOpId()));
-        gc.setOpacity(this->opacity());
 
-        gc.bitBlt(layerProjectionExtent.topLeft(), this->projection(), layerProjectionExtent);
+        this->projectionPlane()->apply(&gc, layerProjectionExtent | my_image->bounds());
 
         //Restore the layer disableAlpha status for correct undo/redo
         this->disableAlphaChannel(alphaDisabled);
@@ -354,20 +358,18 @@ KisLayerSP KisLayer::createMergedLayer(KisLayerSP prevLayer)
 
         //Paint layer on the copy
         KisPainter gc(mergedDevice);
-        if (alphaDisabled == prevAlphaDisabled) {
-            this->disableAlphaChannel(false);
-        }
-        gc.setChannelFlags(this->channelFlags());
-        gc.setCompositeOp(mergedDevice->colorSpace()->compositeOp(this->compositeOpId()));
-        gc.setOpacity(this->opacity());
-
         gc.bitBlt(layerProjectionExtent.topLeft(), this->projection(), layerProjectionExtent);
+    }
 
-        //Restore the layer disableAlpha status for correct undo/redo
-        this->disableAlphaChannel(alphaDisabled);
+    KisLayerSP newLayer = new KisPaintLayer(my_image, prevLayer->name(), OPACITY_OPAQUE_U8, mergedDevice);
+
+    if (keepBlendingOptions) {
+        newLayer->setCompositeOp(compositeOpId());
+        newLayer->setOpacity(opacity());
+        newLayer->setChannelFlags(channelFlags());
     }
 
-    return new KisPaintLayer(my_image, prevLayer->name(), OPACITY_OPAQUE_U8, mergedDevice);
+    return newLayer;
 }
 
 void KisLayer::registerClone(KisCloneLayerWSP clone)
diff --git a/krita/image/kis_layer.h b/krita/image/kis_layer.h
index 0803075..52bc357 100644
--- a/krita/image/kis_layer.h
+++ b/krita/image/kis_layer.h
@@ -365,6 +365,8 @@ protected:
                      KisPaintDeviceSP destination,
                      const QRect &requestedRect,
                      KisNodeSP filthyNode, KisNodeSP lastNode) const;
+
+    bool canMergeAndKeepBlendOptions(KisLayerSP otherLayer);
 private:
     friend class KisLayerProjectionPlane;
     friend class KisTransformMask;
diff --git a/krita/image/tests/kis_image_test.cpp b/krita/image/tests/kis_image_test.cpp
index c2f1b5b..7ea3d40 100644
--- a/krita/image/tests/kis_image_test.cpp
+++ b/krita/image/tests/kis_image_test.cpp
@@ -171,6 +171,333 @@ void KisImageTest::testLayerComposition()
     QVERIFY(!layer2->visible());
 }
 
+#include "testutil.h"
+#include "kis_group_layer.h"
+#include "kis_transparency_mask.h"
+#include "kis_psd_layer_style.h"
+
+struct FlattenTestImage
+{
+    FlattenTestImage()
+        : refRect(0,0,512,512)
+        , p(refRect)
+    {
+
+        image = p.image;
+
+        layer1 = p.layer;
+
+        layer5 = new KisPaintLayer(p.image, "paint5", 0.4 * OPACITY_OPAQUE_U8);
+        layer5->disableAlphaChannel(true);
+
+        layer2 = new KisPaintLayer(p.image, "paint2", OPACITY_OPAQUE_U8);
+        tmask = new KisTransparencyMask();
+
+        // check channel flags
+        // make addition composite op
+        group1 = new KisGroupLayer(p.image, "group1", OPACITY_OPAQUE_U8);
+        layer3 = new KisPaintLayer(p.image, "paint3", OPACITY_OPAQUE_U8);
+        layer4 = new KisPaintLayer(p.image, "paint4", OPACITY_OPAQUE_U8);
+
+        layer6 = new KisPaintLayer(p.image, "paint6", OPACITY_OPAQUE_U8);
+
+        layer7 = new KisPaintLayer(p.image, "paint7", OPACITY_OPAQUE_U8);
+        layer8 = new KisPaintLayer(p.image, "paint8", OPACITY_OPAQUE_U8);
+        layer7->setCompositeOp(COMPOSITE_ADD);
+        layer8->setCompositeOp(COMPOSITE_ADD);
+
+        QRect rect1(100, 100, 100, 100);
+        QRect rect2(150, 150, 150, 150);
+        QRect tmaskRect(200,200,100,100);
+
+        QRect rect3(400, 100, 100, 100);
+        QRect rect4(500, 100, 100, 100);
+
+        QRect rect5(50, 50, 100, 100);
+
+        QRect rect6(50, 250, 100, 100);
+
+        QRect rect7(50, 350, 50, 50);
+        QRect rect8(50, 400, 50, 50);
+
+        layer1->paintDevice()->fill(rect1, KoColor(Qt::red, p.image->colorSpace()));
+
+        layer2->paintDevice()->fill(rect2, KoColor(Qt::green, p.image->colorSpace()));
+        tmask->testingInitSelection(tmaskRect);
+
+        layer3->paintDevice()->fill(rect3, KoColor(Qt::blue, p.image->colorSpace()));
+        layer4->paintDevice()->fill(rect4, KoColor(Qt::yellow, p.image->colorSpace()));
+        layer5->paintDevice()->fill(rect5, KoColor(Qt::green, p.image->colorSpace()));
+
+        layer6->paintDevice()->fill(rect6, KoColor(Qt::cyan, p.image->colorSpace()));
+
+        layer7->paintDevice()->fill(rect7, KoColor(Qt::red, p.image->colorSpace()));
+        layer8->paintDevice()->fill(rect8, KoColor(Qt::green, p.image->colorSpace()));
+
+        KisPSDLayerStyleSP style(new KisPSDLayerStyle());
+        style->dropShadow()->setEffectEnabled(true);
+        style->dropShadow()->setDistance(10.0);
+        style->dropShadow()->setSpread(80.0);
+        style->dropShadow()->setSize(10);
+        style->dropShadow()->setNoise(0);
+        style->dropShadow()->setKnocksOut(false);
+        style->dropShadow()->setOpacity(80.0);
+        layer2->setLayerStyle(style);
+
+        layer2->setCompositeOp(COMPOSITE_ADD);
+        group1->setCompositeOp(COMPOSITE_ADD);
+
+        p.image->addNode(layer5);
+
+        p.image->addNode(layer2);
+        p.image->addNode(tmask, layer2);
+
+        p.image->addNode(group1);
+        p.image->addNode(layer3, group1);
+        p.image->addNode(layer4, group1);
+
+        p.image->addNode(layer6);
+
+        p.image->addNode(layer7);
+        p.image->addNode(layer8);
+
+        p.image->initialRefreshGraph();
+
+        // qDebug() << ppVar(layer1->exactBounds());
+        // qDebug() << ppVar(layer5->exactBounds());
+        // qDebug() << ppVar(layer2->exactBounds());
+        // qDebug() << ppVar(group1->exactBounds());
+        // qDebug() << ppVar(layer3->exactBounds());
+        // qDebug() << ppVar(layer4->exactBounds());
+
+        TestUtil::ExternalImageChecker chk("flatten", "imagetest");
+        QVERIFY(chk.checkDevice(p.image->projection(), p.image, "00_initial"));
+    }
+
+    QRect refRect;
+    TestUtil::MaskParent p;
+
+    KisImageSP image;
+    KisPaintLayerSP layer1;
+
+    KisPaintLayerSP layer2;
+    KisTransparencyMaskSP tmask;
+
+    KisGroupLayerSP group1;
+    KisPaintLayerSP layer3;
+    KisPaintLayerSP layer4;
+
+    KisPaintLayerSP layer5;
+
+    KisPaintLayerSP layer6;
+
+    KisPaintLayerSP layer7;
+    KisPaintLayerSP layer8;
+};
+
+void KisImageTest::testFlattenLayer()
+{
+    FlattenTestImage p;
+
+    TestUtil::ExternalImageChecker chk("flatten", "imagetest");
+
+    {
+        QCOMPARE(p.layer2->compositeOpId(), COMPOSITE_ADD);
+
+        KisLayerSP newLayer = p.image->flattenLayer(p.layer2);
+        p.image->waitForDone();
+
+        QVERIFY(chk.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "01_layer2_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_OVER);
+    }
+
+    {
+        QCOMPARE(p.group1->compositeOpId(), COMPOSITE_ADD);
+
+        KisLayerSP newLayer = p.image->flattenLayer(p.group1);
+        p.image->waitForDone();
+
+        QVERIFY(chk.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "02_group1_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(newLayer->exactBounds(), QRect(400, 100, 200, 100));
+    }
+
+    {
+        QCOMPARE(p.layer5->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(p.layer5->alphaChannelDisabled(), true);
+
+        KisLayerSP newLayer = p.image->flattenLayer(p.layer5);
+        p.image->waitForDone();
+
+        QVERIFY(chk.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "03_layer5_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(newLayer->exactBounds(), QRect(50, 50, 100, 100));
+
+        QCOMPARE(newLayer->alphaChannelDisabled(), true);
+    }
+}
+
+#include <metadata/kis_meta_data_merge_strategy_registry.h>
+
+void KisImageTest::testMergeDown()
+{
+    FlattenTestImage p;
+
+    TestUtil::ExternalImageChecker img("flatten", "imagetest");
+    TestUtil::ExternalImageChecker chk("mergedown_simple", "imagetest");
+
+
+    {
+        QCOMPARE(p.layer5->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(p.layer5->alphaChannelDisabled(), true);
+
+        KisLayerSP newLayer = p.image->mergeDown(p.layer5, KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
+        p.image->waitForDone();
+
+        QVERIFY(img.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "01_layer5_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(newLayer->alphaChannelDisabled(), false);
+    }
+
+    {
+        QCOMPARE(p.layer2->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(p.layer2->alphaChannelDisabled(), false);
+
+        KisLayerSP newLayer = p.image->mergeDown(p.layer2, KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
+        p.image->waitForDone();
+
+        QVERIFY(img.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "02_layer2_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(newLayer->exactBounds(), QRect(100, 100, 213, 217));
+        QCOMPARE(newLayer->alphaChannelDisabled(), false);
+    }
+
+    {
+        QCOMPARE(p.group1->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(p.group1->alphaChannelDisabled(), false);
+
+        KisLayerSP newLayer = p.image->mergeDown(p.group1, KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
+        p.image->waitForDone();
+
+        QVERIFY(img.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "03_group1_mergedown_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(newLayer->exactBounds(), QRect(100, 100, 500, 217));
+        QCOMPARE(newLayer->alphaChannelDisabled(), false);
+    }
+}
+
+void KisImageTest::testMergeDownDestinationInheritsAlpha()
+{
+    FlattenTestImage p;
+
+    TestUtil::ExternalImageChecker img("flatten", "imagetest");
+    TestUtil::ExternalImageChecker chk("mergedown_dst_inheritsalpha", "imagetest");
+
+    {
+        QCOMPARE(p.layer2->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(p.layer2->alphaChannelDisabled(), false);
+
+        KisLayerSP newLayer = p.image->mergeDown(p.layer2, KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
+        p.image->waitForDone();
+
+        QVERIFY(img.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "01_layer2_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(newLayer->exactBounds(), QRect(50,50, 263, 267));
+        QCOMPARE(newLayer->alphaChannelDisabled(), false);
+    }
+}
+
+void KisImageTest::testMergeDownDestinationCustomCompositeOp()
+{
+    FlattenTestImage p;
+
+    TestUtil::ExternalImageChecker img("flatten", "imagetest");
+    TestUtil::ExternalImageChecker chk("mergedown_dst_customop", "imagetest");
+
+    {
+        QCOMPARE(p.layer6->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(p.layer6->alphaChannelDisabled(), false);
+
+        QCOMPARE(p.group1->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(p.group1->alphaChannelDisabled(), false);
+
+        KisLayerSP newLayer = p.image->mergeDown(p.layer6, KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
+        p.image->waitForDone();
+
+        QVERIFY(img.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "01_layer6_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(newLayer->exactBounds(), QRect(50, 100, 550, 250));
+        QCOMPARE(newLayer->alphaChannelDisabled(), false);
+    }
+}
+
+void KisImageTest::testMergeDownDestinationSameCompositeOpLayerStyle()
+{
+    FlattenTestImage p;
+
+    TestUtil::ExternalImageChecker img("flatten", "imagetest");
+    TestUtil::ExternalImageChecker chk("mergedown_sameop_ls", "imagetest");
+
+    {
+        QCOMPARE(p.group1->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(p.group1->alphaChannelDisabled(), false);
+
+        QCOMPARE(p.layer2->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(p.layer2->alphaChannelDisabled(), false);
+
+        KisLayerSP newLayer = p.image->mergeDown(p.group1, KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
+        p.image->waitForDone();
+
+        QVERIFY(img.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "01_group1_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_OVER);
+        QCOMPARE(newLayer->exactBounds(), QRect(197, 100, 403, 217));
+        QCOMPARE(newLayer->alphaChannelDisabled(), false);
+    }
+}
+
+void KisImageTest::testMergeDownDestinationSameCompositeOp()
+{
+    FlattenTestImage p;
+
+    TestUtil::ExternalImageChecker img("flatten", "imagetest");
+    TestUtil::ExternalImageChecker chk("mergedown_sameop_fastpath", "imagetest");
+
+    {
+        QCOMPARE(p.layer8->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(p.layer8->alphaChannelDisabled(), false);
+
+        QCOMPARE(p.layer7->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(p.layer7->alphaChannelDisabled(), false);
+
+        KisLayerSP newLayer = p.image->mergeDown(p.layer8, KisMetaData::MergeStrategyRegistry::instance()->get("Drop"));
+        p.image->waitForDone();
+
+        QVERIFY(img.checkDevice(p.image->projection(), p.image, "00_initial"));
+        QVERIFY(chk.checkDevice(newLayer->projection(), p.image, "01_layer8_layerproj"));
+
+        QCOMPARE(newLayer->compositeOpId(), COMPOSITE_ADD);
+        QCOMPARE(newLayer->exactBounds(), QRect(50, 350, 50, 100));
+        QCOMPARE(newLayer->alphaChannelDisabled(), false);
+    }
+}
 
 QTEST_KDEMAIN(KisImageTest, NoGUI)
 #include "kis_image_test.moc"
diff --git a/krita/image/tests/kis_image_test.h b/krita/image/tests/kis_image_test.h
index bd6c677..9238b02 100644
--- a/krita/image/tests/kis_image_test.h
+++ b/krita/image/tests/kis_image_test.h
@@ -32,6 +32,13 @@ private Q_SLOTS:
     void testConvertImageColorSpace();
     void testGlobalSelection();
     void testLayerComposition();
+
+    void testFlattenLayer();
+    void testMergeDown();
+    void testMergeDownDestinationInheritsAlpha();
+    void testMergeDownDestinationCustomCompositeOp();
+    void testMergeDownDestinationSameCompositeOpLayerStyle();
+    void testMergeDownDestinationSameCompositeOp();
 };
 
 #endif


More information about the kimageshop mailing list