void KisTransformMaskTest::testMaskOnCloneLayer() { QImage refImage(TestUtil::fetchDataFileLazy("test_transform_quality.png")); QRect refRect = refImage.rect(); TestUtil::MaskParent p(refRect); p.layer->paintDevice()->convertFromQImage(refImage, 0); KisPaintLayerSP player = new KisPaintLayer(p.image, "bg", OPACITY_OPAQUE_U8, p.image->colorSpace()); p.image->addNode(player, p.image->root(), KisNodeSP()); KisCloneLayerSP clone = new KisCloneLayer(p.layer, p.image, "clone", OPACITY_OPAQUE_U8); p.image->addNode(clone, p.image->root()); KisTransformMaskSP mask = new KisTransformMask(); p.image->addNode(mask, clone); QTransform transform(-0.177454, -0.805953, -0.00213713, -1.9295, -0.371835, -0.00290463, 3075.05, 2252.32, 7.62371); mask->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform))); QVERIFY(doPartialTests("cl", p.image, p.layer, clone, mask)); }
void KisTransformMaskTest::testMaskWithOffset() { TestUtil::ExternalImageChecker chk("mask_with_offset", "transform_mask_updates"); QRect refRect(0,0,512,512); QRect fillRect(400,400,100,100); TestUtil::MaskParent p(refRect); p.layer->paintDevice()->fill(fillRect, KoColor(Qt::red, p.layer->colorSpace())); KisPaintLayerSP player = new KisPaintLayer(p.image, "bg", OPACITY_OPAQUE_U8, p.image->colorSpace()); p.image->addNode(player, p.image->root(), KisNodeSP()); KisTransformMaskSP mask1 = new KisTransformMask(); p.image->addNode(mask1, p.layer); mask1->setName("mask1"); p.layer->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "00_initial_layer_update"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "00X_initial_layer_update"); QTransform transform; transform = QTransform::fromTranslate(-150, 0); mask1->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform))); p.layer->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "01_mask1_moved_layer_update"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "01X_mask1_moved_layer_update"); mask1->setY(-150); mask1->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "02_mask1_y_offset"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "02X_mask1_y_offset"); QVERIFY(chk.testPassed()); }
void KisTransformMaskTest::testTransformHiddenPartsOfTheGroup() { //TestUtil::ExternalImageChecker chk("mask_with_offset", "transform_mask_updates"); QRect imageRect(0,0,512,512); QRect fillRect(10, 10, 236, 236); QRect outsideFillRect = fillRect.translated(0, -1.5 * 256); TestUtil::MaskParent p(imageRect); //p.layer->paintDevice()->fill(fillRect, KoColor(Qt::green, p.layer->colorSpace())); p.image->initialRefreshGraph(); KisGroupLayerSP glayer = new KisGroupLayer(p.image, "gl", OPACITY_OPAQUE_U8); p.image->addNode(glayer, p.image->root()); KisPaintLayerSP player1 = new KisPaintLayer(p.image, "pl1", OPACITY_OPAQUE_U8, p.image->colorSpace()); player1->paintDevice()->fill(fillRect, KoColor(Qt::red, p.layer->colorSpace())); player1->paintDevice()->fill(outsideFillRect, KoColor(Qt::blue, p.layer->colorSpace())); p.image->addNode(player1, glayer); player1->setDirty(); p.image->waitForDone(); QCOMPARE(p.image->projection()->exactBounds(), fillRect); //KIS_DUMP_DEVICE_2(p.image->projection(), imageRect, "image_proj_initial", "dd"); KisTransformMaskSP mask1 = new KisTransformMask(); mask1->setName("mask1"); QTransform transform1 = QTransform::fromTranslate(0, 1.5 * 256); mask1->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform1))); p.image->addNode(mask1, player1); mask1->setDirty(); p.image->waitForDone(); /** * Transform mask i sexpected to crop the externals of the layer by 50% * far behind the layer border! Take care! */ QCOMPARE(p.image->projection()->exactBounds(), QRect(10, 128, 236, 384)); //KIS_DUMP_DEVICE_2(p.image->projection(), imageRect, "image_proj_mask", "dd"); }
void KisTransformMaskTest::testMaskOnCloneLayerWithOffset() { TestUtil::ExternalImageChecker chk("clone_offset_simple", "transform_mask_updates"); QRect refRect(0,0,512,512); QRect fillRect(400,400,100,100); TestUtil::MaskParent p(refRect); p.layer->paintDevice()->fill(fillRect, KoColor(Qt::red, p.layer->colorSpace())); KisPaintLayerSP player = new KisPaintLayer(p.image, "bg", OPACITY_OPAQUE_U8, p.image->colorSpace()); p.image->addNode(player, p.image->root(), KisNodeSP()); KisCloneLayerSP clone = new KisCloneLayer(p.layer, p.image, "clone", OPACITY_OPAQUE_U8); p.image->addNode(clone, p.image->root()); KisTransformMaskSP mask = new KisTransformMask(); p.image->addNode(mask, clone); QTransform transform(1, 0, 0, 0, 1, 0, 0, -150, 1); mask->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform))); p.layer->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "0_initial"); clone->setX(-300); clone->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "1_after_offset"); mask->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "2_after_offset_dirty_mask"); QTest::qWait(4000); chk.checkImage(p.image, "3_delayed_regeneration"); KisPaintDeviceSP previewDevice = mask->buildPreviewDevice(); chk.checkDevice(previewDevice, p.image, "4_preview_device"); QVERIFY(chk.testPassed()); QVERIFY(doPartialTests("clone_offset_complex", p.image, p.layer, clone, mask)); }
void KisTransformMaskTest::testWeirdFullUpdates() { //TestUtil::ExternalImageChecker chk("mask_with_offset", "transform_mask_updates"); QRect imageRect(0,0,512,512); QRect fillRect(10, 10, 236, 236); TestUtil::MaskParent p(imageRect); p.layer->paintDevice()->fill(fillRect, KoColor(Qt::red, p.layer->colorSpace())); KisPaintLayerSP player1 = new KisPaintLayer(p.image, "pl1", OPACITY_OPAQUE_U8, p.image->colorSpace()); player1->paintDevice()->fill(fillRect, KoColor(Qt::red, p.layer->colorSpace())); p.image->addNode(player1, p.image->root()); KisTransformMaskSP mask1 = new KisTransformMask(); mask1->setName("mask1"); QTransform transform1 = QTransform::fromTranslate(256, 0); mask1->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform1))); p.image->addNode(mask1, player1); KisPaintLayerSP player2 = new KisPaintLayer(p.image, "pl2", OPACITY_OPAQUE_U8, p.image->colorSpace()); player2->paintDevice()->fill(fillRect, KoColor(Qt::red, p.layer->colorSpace())); p.image->addNode(player2, p.image->root()); KisTransformMaskSP mask2 = new KisTransformMask(); mask2->setName("mask2"); QTransform transform2 = QTransform::fromTranslate(0, 256); mask2->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform2))); p.image->addNode(mask2, player2); KisPaintLayerSP player3 = new KisPaintLayer(p.image, "pl3", OPACITY_OPAQUE_U8, p.image->colorSpace()); player3->paintDevice()->fill(fillRect, KoColor(Qt::red, p.layer->colorSpace())); p.image->addNode(player3, p.image->root()); KisTransformMaskSP mask3 = new KisTransformMask(); mask3->setName("mask3"); QTransform transform3 = QTransform::fromTranslate(256, 256); mask3->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform3))); p.image->addNode(mask3, player3); //p.image->initialRefreshGraph(); p.image->refreshGraphAsync(0, QRect(0,0,256,256), QRect()); p.image->waitForDone(); QVERIFY(player1->projection()->extent().isEmpty()); QVERIFY(player1->projection()->exactBounds().isEmpty()); QVERIFY(player2->projection()->extent().isEmpty()); QVERIFY(player2->projection()->exactBounds().isEmpty()); QVERIFY(player3->projection()->extent().isEmpty()); QVERIFY(player3->projection()->exactBounds().isEmpty()); QCOMPARE(p.image->projection()->exactBounds(), QRect(QRect(10,10,236,236))); p.image->refreshGraphAsync(0, QRect(0,256,256,256), QRect()); p.image->waitForDone(); QVERIFY(player1->projection()->extent().isEmpty()); QVERIFY(player1->projection()->exactBounds().isEmpty()); QVERIFY(!player2->projection()->extent().isEmpty()); QVERIFY(!player2->projection()->exactBounds().isEmpty()); QVERIFY(player3->projection()->extent().isEmpty()); QVERIFY(player3->projection()->exactBounds().isEmpty()); QCOMPARE(p.image->projection()->exactBounds(), QRect(QRect(10,10,236,492))); p.image->refreshGraphAsync(0, QRect(256,0,256,256), QRect()); p.image->waitForDone(); QVERIFY(!player1->projection()->extent().isEmpty()); QVERIFY(!player1->projection()->exactBounds().isEmpty()); QVERIFY(!player2->projection()->extent().isEmpty()); QVERIFY(!player2->projection()->exactBounds().isEmpty()); QVERIFY(player3->projection()->extent().isEmpty()); QVERIFY(player3->projection()->exactBounds().isEmpty()); QCOMPARE(p.image->projection()->exactBounds(), QRect(QRect(10,10,492,492))); QVERIFY((p.image->projection()->region() & QRect(256,256,256,256)).isEmpty()); p.image->refreshGraphAsync(0, QRect(256,256,256,256), QRect()); p.image->waitForDone(); QVERIFY(!player1->projection()->extent().isEmpty()); QVERIFY(!player1->projection()->exactBounds().isEmpty()); QVERIFY(!player2->projection()->extent().isEmpty()); QVERIFY(!player2->projection()->exactBounds().isEmpty()); QVERIFY(!player3->projection()->extent().isEmpty()); QVERIFY(!player3->projection()->exactBounds().isEmpty()); QCOMPARE(p.image->projection()->exactBounds(), QRect(QRect(10,10,492,492))); QVERIFY(!(p.image->projection()->region() & QRect(256,256,256,256)).isEmpty()); p.image->waitForDone(); KIS_DUMP_DEVICE_2(p.image->projection(), imageRect, "image_proj", "dd"); }
void KisTransformMaskTest::testMultipleMasks() { TestUtil::ExternalImageChecker chk("multiple_masks", "transform_mask_updates"); QRect refRect(0,0,512,512); QRect fillRect(400,400,100,100); TestUtil::MaskParent p(refRect); p.layer->paintDevice()->fill(fillRect, KoColor(Qt::red, p.layer->colorSpace())); KisPaintLayerSP player = new KisPaintLayer(p.image, "bg", OPACITY_OPAQUE_U8, p.image->colorSpace()); p.image->addNode(player, p.image->root(), KisNodeSP()); //KisCloneLayerSP clone = new KisCloneLayer(p.layer, p.image, "clone", OPACITY_OPAQUE_U8); //p.image->addNode(clone, p.image->root()); KisTransformMaskSP mask1 = new KisTransformMask(); p.image->addNode(mask1, p.layer); KisTransformMaskSP mask2 = new KisTransformMask(); p.image->addNode(mask2, p.layer); mask1->setName("mask1"); mask2->setName("mask2"); p.layer->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "00_initial_layer_update"); QTransform transform; transform = QTransform::fromTranslate(-150, 0); mask1->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform))); p.layer->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "01_mask1_moved_layer_update"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "01X_mask1_moved_layer_update"); transform = QTransform::fromTranslate(0, -150); mask2->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform))); p.layer->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "02_mask2_moved_layer_update"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "02X_mask2_moved_layer_update"); #ifdef CHECK_MASK1_TOGGLE { mask1->setVisible(false); mask1->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "03_mask1_tg_off_refRect"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "03X_mask1_tg_off_refRect"); mask1->setVisible(true); mask1->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "04_mask1_tg_on_refRect"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "04X_mask1_tg_on_refRect"); mask1->setVisible(false); mask1->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "05_mask1_tg_off_default_rect"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "05X_mask1_tg_off_default_rect"); mask1->setVisible(true); mask1->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "06_mask1_tg_on_default_rect"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "06X_mask1_tg_on_default_rect"); } #endif /* CHECK_MASK1_TOGGLE */ #ifdef CHECK_MASK2_TOGGLE { mask2->setVisible(false); mask2->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "07_mask2_tg_off_refRect"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "07X_mask2_tg_off_refRect"); mask2->setVisible(true); mask2->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "08_mask2_tg_on_refRect"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "08X_mask2_tg_on_refRect"); mask2->setVisible(false); mask2->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "09_mask2_tg_off_default_rect"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "09X_mask2_tg_off_default_rect"); mask2->setVisible(true); mask2->setDirty(refRect); p.image->waitForDone(); chk.checkImage(p.image, "10_mask2_tg_on_default_rect"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "10X_mask2_tg_on_default_rect"); } #endif /* CHECK_MASK2_TOGGLE */ #ifdef CHECK_HIDE_ALL { mask1->setVisible(false); mask1->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "11.1_hide_both_update_default_mask1"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "11.1X_hide_both_update_default_mask1"); mask2->setVisible(false); mask2->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "11.2_hide_both_update_default_mask2"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "11.2X_hide_both_update_default_mask2"); mask1->setVisible(true); mask1->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "12_sh_mask1_on"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "12X_sh_mask1_on"); mask1->setVisible(false); mask1->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "13_sh_mask1_off"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "13X_sh_mask1_off"); mask2->setVisible(true); mask2->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "14_sh_mask2_on"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "14X_sh_mask2_on"); mask2->setVisible(false); mask2->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "15_sh_mask2_off"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "15X_sh_mask2_off"); } #endif /* CHECK_HIDE_ALL */ #ifdef CHECK_HIDE_ALL_AFTER_MOVE { transform = QTransform::fromTranslate(50, -150); mask2->setTransformParams(KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(transform))); mask2->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "20_moved_mask2"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "20X_moved_mask2"); } { mask1->setVisible(false); mask1->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "21.1_hide_both_update_default_mask1"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "21.1X_hide_both_update_default_mask1"); mask2->setVisible(false); mask2->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "21.2_hide_both_update_default_mask2"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "21.2X_hide_both_update_default_mask2"); mask1->setVisible(true); mask1->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "22_sh_mask1_on"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "22X_sh_mask1_on"); mask1->setVisible(false); mask1->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "23_sh_mask1_off"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "23X_sh_mask1_off"); mask2->setVisible(true); mask2->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "24_sh_mask2_on"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "24X_sh_mask2_on"); mask2->setVisible(false); mask2->setDirty(); p.image->waitForDone(); chk.checkImage(p.image, "25_sh_mask2_off"); QTest::qWait(4000); p.image->waitForDone(); chk.checkImage(p.image, "25X_sh_mask2_off"); } #endif /* CHECK_HIDE_ALL_AFTER_MOVE */ QVERIFY(chk.testPassed()); }
KisTransformMaskParamsInterfaceSP KisTransformMaskParamsFactoryRegistry::animateParams(KisTransformMaskParamsInterfaceSP params) { if (!m_animatedParamsFactory) return KisTransformMaskParamsInterfaceSP(); return m_animatedParamsFactory(params); }
KisTransformMaskParamsInterfaceSP KisTransformMaskParamsFactoryRegistry::createParams(const QString &id, const QDomElement &e) { KisTransformMaskParamsFactoryMap::iterator it = m_map.find(id); return it != m_map.end() ? (*it)(e) : KisTransformMaskParamsInterfaceSP(0); }
void TransformStrokeStrategy::doStrokeCallback(KisStrokeJobData *data) { TransformData *td = dynamic_cast<TransformData*>(data); ClearSelectionData *csd = dynamic_cast<ClearSelectionData*>(data); if(td) { m_savedTransformArgs = td->config; if (td->destination == TransformData::PAINT_DEVICE) { QRect oldExtent = td->node->extent(); KisPaintDeviceSP device = td->node->paintDevice(); if (device && !checkBelongsToSelection(device)) { KisPaintDeviceSP cachedPortion = getDeviceCache(device); Q_ASSERT(cachedPortion); KisTransaction transaction(device); KisProcessingVisitor::ProgressHelper helper(td->node); transformAndMergeDevice(td->config, cachedPortion, device, &helper); runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()), KisStrokeJobData::CONCURRENT, KisStrokeJobData::NORMAL); td->node->setDirty(oldExtent | td->node->extent()); } if (KisExternalLayer *extLayer = dynamic_cast<KisExternalLayer*>(td->node.data())) { if (td->config.mode() == ToolTransformArgs::FREE_TRANSFORM || td->config.mode() == ToolTransformArgs::PERSPECTIVE_4POINT) { if (td->config.aX() || td->config.aY()) { warnKrita << "Perspective transform of an external layer is not supported:" << extLayer->name(); } QVector3D transformedCenter; KisTransformWorker w = KisTransformUtils::createTransformWorker(td->config, 0, 0, &transformedCenter); QTransform t = w.transform(); runAndSaveCommand(KUndo2CommandSP(extLayer->transform(t)), KisStrokeJobData::CONCURRENT, KisStrokeJobData::NORMAL); } } else if (KisTransformMask *transformMask = dynamic_cast<KisTransformMask*>(td->node.data())) { runAndSaveCommand(KUndo2CommandSP( new ModifyTransformMaskCommand(transformMask, KisTransformMaskParamsInterfaceSP( new KisTransformMaskAdapter(td->config)))), KisStrokeJobData::CONCURRENT, KisStrokeJobData::NORMAL); } } else if (m_selection) { /** * We use usual transaction here, because we cannot calsulate * transformation for perspective and warp workers. */ KisTransaction transaction(m_selection->pixelSelection()); KisProcessingVisitor::ProgressHelper helper(td->node); KisTransformUtils::transformDevice(td->config, m_selection->pixelSelection(), &helper); runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()), KisStrokeJobData::CONCURRENT, KisStrokeJobData::NORMAL); } } else if (csd) { KisPaintDeviceSP device = csd->node->paintDevice(); if (device && !checkBelongsToSelection(device)) { if (!haveDeviceInCache(device)) { putDeviceCache(device, createDeviceCache(device)); } clearSelection(device); } else if (KisTransformMask *transformMask = dynamic_cast<KisTransformMask*>(csd->node.data())) { runAndSaveCommand(KUndo2CommandSP( new ModifyTransformMaskCommand(transformMask, KisTransformMaskParamsInterfaceSP( new KisDumbTransformMaskParams(true)))), KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::NORMAL); } } else { KisStrokeStrategyUndoCommandBased::doStrokeCallback(data); } }