void KisSelectionBasedLayer::copyOriginalToProjection(const KisPaintDeviceSP original, KisPaintDeviceSP projection, const QRect& rect) const { lockTemporaryTarget(); m_d->selection->updateProjection(); KisSelectionSP tempSelection = m_d->selection; KisPainter gc(projection); if (m_d->selection) { if (hasTemporaryTarget()) { /** * Cloning a selection with COW * FIXME: check whether it's faster than usual bitBlt'ing */ tempSelection = new KisSelection(*tempSelection); KisPainter gc2(tempSelection->pixelSelection()); gc2.setOpacity(temporaryOpacity()); gc2.setCompositeOp(temporaryCompositeOp()); gc2.bitBlt(rect.topLeft(), temporaryTarget(), rect); } projection->clear(rect); gc.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_OVER)); gc.setSelection(tempSelection); } else gc.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_COPY)); gc.bitBlt(rect.topLeft(), original, rect); unlockTemporaryTarget(); }
void KisSelectionToVectorActionFactory::run(KisView2 *view) { KisSelectionSP selection = view->selection(); if (selection->hasShapeSelection() || !selection->outlineCacheValid()) { return; } QPainterPath selectionOutline = selection->outlineCache(); QTransform transform = view->canvasBase()->coordinatesConverter()->imageToDocumentTransform(); KoShape *shape = KoPathShape::createShapeFromPainterPath(transform.map(selectionOutline)); shape->setShapeId(KoPathShapeId); /** * Mark a shape that it belongs to a shape selection */ if(!shape->userData()) { shape->setUserData(new KisShapeSelectionMarker); } KisProcessingApplicator *ap = beginAction(view, i18n("Convert to Vector Selection")); ap->applyCommand(view->canvasBase()->shapeController()->addShape(shape), KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::EXCLUSIVE); endAction(ap, KisOperationConfiguration(id()).toXML()); }
void KisFilterTest::testDifferentSrcAndDst() { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); QImage qimage(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa.png"); QImage inverted(QString(FILES_DATA_DIR) + QDir::separator() + "inverted_hakonepa.png"); KisPaintDeviceSP src = new KisPaintDevice(cs); KisPaintDeviceSP dst = new KisPaintDevice(cs); KisSelectionSP sel = new KisSelection(new KisSelectionDefaultBounds(src)); sel->getOrCreatePixelSelection()->invert(); // select everything sel->updateProjection(); src->convertFromQImage(qimage, 0, 0, 0); KisFilterSP f = KisFilterRegistry::instance()->value("invert"); Q_ASSERT(f); KisFilterConfiguration * kfc = f->defaultConfiguration(0); Q_ASSERT(kfc); f->process(src, dst, sel, QRect(QPoint(0,0), qimage.size()), kfc); QPoint errpoint; if (!TestUtil::compareQImages(errpoint, inverted, dst->convertToQImage(0, 0, 0, qimage.width(), qimage.height()))) { dst->convertToQImage(0, 0, 0, qimage.width(), qimage.height()).save("filtertest.png"); QFAIL(QString("Failed to create inverted image, first different pixel: %1,%2 ").arg(errpoint.x()).arg(errpoint.y()).toLatin1()); } }
void paintBevelSelection(KisPixelSelectionSP srcSelection, KisPixelSelectionSP dstSelection, const QRect &applyRect, int size, int initialSize, bool invert) { KisSelectionSP tmpBaseSelection = new KisSelection(new KisSelectionEmptyBounds(0)); KisPixelSelectionSP tmpSelection = tmpBaseSelection->pixelSelection(); // NOTE: we are not using createCompositionSourceDevice() intentionally, // because the source device doesn't have alpha channel KisPixelSelectionSP fillDevice = new KisPixelSelection(); KisPainter gc(dstSelection); gc.setCompositeOp(COMPOSITE_COPY); for (int i = 0; i < size; i++) { const int growSize = initialSize - i - 1; quint8 selectedness = invert ? qRound(qreal(size - i - 1) / size * 255.0) : qRound(qreal(i + 1) / size * 255.0); fillDevice->setDefaultPixel(KoColor(&selectedness, fillDevice->colorSpace())); tmpSelection->makeCloneFromRough(srcSelection, srcSelection->selectedRect()); QRect changeRect = KisLsUtils::growSelectionUniform(tmpSelection, growSize, applyRect); gc.setSelection(tmpBaseSelection); gc.bitBlt(changeRect.topLeft(), fillDevice, changeRect); } }
void KisMaskTest::testCropUpdateBySelection() { TestUtil::MaskParent p; /** * We do not use exact selection bounds for cropping, * so the rects should be covered by different tiles */ QRect selectionRect(10, 10, 20, 20); QRect updateRect(64, 64, 20, 20); TestMaskSP mask = new TestMask; KisSelectionSP sel = new KisSelection(); sel->pixelSelection()->select(selectionRect, MAX_SELECTED); mask->initSelection(sel, p.layer); mask->apply(p.layer->projection(), updateRect); // Here we crash! :) /** * If you see a crash, it means KisMask tried to update * the area that is outside its selection. * Please consider fixing KisMask::apply() first */ }
bool KisKraLoadVisitor::visit(KisAdjustmentLayer* layer) { loadNodeKeyframes(layer); // Adjustmentlayers are tricky: there's the 1.x style and the 2.x // style, which has selections with selection components bool result = true; if (m_syntaxVersion == 1) { KisSelectionSP selection = new KisSelection(); KisPixelSelectionSP pixelSelection = selection->pixelSelection(); result = loadPaintDevice(pixelSelection, getLocation(layer, ".selection")); layer->setInternalSelection(selection); } else if (m_syntaxVersion == 2) { result = loadSelection(getLocation(layer), layer->internalSelection()); } else { // We use the default, empty selection } if (!loadMetaData(layer)) { return false; } loadFilterConfiguration(layer->filter().data(), getLocation(layer, DOT_FILTERCONFIG)); result = visitAll(layer); return result; }
void KisMaskTest::testDeferredOffsetInitialization() { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisImageSP image = new KisImage(0, 100, 100, cs, "stest"); KisMaskSP mask = new TestMask; QCOMPARE(mask->x(), 0); QCOMPARE(mask->y(), 0); mask->setX(10); QCOMPARE(mask->x(), 10); QCOMPARE(mask->y(), 0); mask->setY(11); QCOMPARE(mask->x(), 10); QCOMPARE(mask->y(), 11); mask->initSelection(image->rootLayer()); // IMPORTANT: a bit weird behavior, but it is needed for // KisKraLoadVisitor to work properly QCOMPARE(mask->x(), 10); QCOMPARE(mask->y(), 11); // Now there is no deferred initialization, so the offest // should simply be reset mask->initSelection(image->rootLayer()); QCOMPARE(mask->x(), 0); QCOMPARE(mask->y(), 0); KisSelectionSP selection = mask->selection(); QCOMPARE(selection->parentNode(), KisNodeSP(mask)); }
void KisSelectionToolHelper::addSelectionShape(KoShape* shape) { bool hasSelection = m_layer->selection(); m_canvas->startMacro(m_name); if (!hasSelection) m_canvas->addCommand(new KisSetGlobalSelectionCommand(m_image, 0)); KisSelectionSP selection = m_layer->selection(); if (selection->isDeselected()) new KisSelectionTransaction(m_name, m_image, m_layer->selection()); KisShapeSelection* shapeSelection; if (!selection->hasShapeSelection()) { shapeSelection = new KisShapeSelection(m_image, selection); selection->setShapeSelection(shapeSelection); } else { shapeSelection = static_cast<KisShapeSelection*>(selection->shapeSelection()); } QUndoCommand * cmd = m_canvas->shapeController()->addShape(shape); m_canvas->addCommand(cmd); m_canvas->stopMacro(); }
bool KisKraLoadVisitor::loadSelection(const QString& location, KisSelectionSP dstSelection) { // Pixel selection bool result = true; QString pixelSelectionLocation = location + DOT_PIXEL_SELECTION; if (m_store->hasFile(pixelSelectionLocation)) { KisPixelSelectionSP pixelSelection = dstSelection->pixelSelection(); result = loadPaintDevice(pixelSelection, pixelSelectionLocation); if (!result) { m_errorMessages << i18n("Could not load raster selection %1.", location); } pixelSelection->invalidateOutlineCache(); } // Shape selection QString shapeSelectionLocation = location + DOT_SHAPE_SELECTION; if (m_store->hasFile(shapeSelectionLocation + "/content.xml")) { m_store->pushDirectory(); m_store->enterDirectory(shapeSelectionLocation) ; KisShapeSelection* shapeSelection = new KisShapeSelection(m_image, dstSelection); dstSelection->setShapeSelection(shapeSelection); result = shapeSelection->loadSelection(m_store); m_store->popDirectory(); if (!result) { m_errorMessages << i18n("Could not load vector selection %1.", location); } } return result; }
void KisSelectionTest::testInvertSelection() { KisSelectionSP selection = new KisSelection(); KisPixelSelectionSP pixelSelection = selection->getOrCreatePixelSelection(); pixelSelection->select(QRect(20, 20, 20, 20)); QCOMPARE(pixelSelection->selected(30, 30), MAX_SELECTED); QCOMPARE(pixelSelection->selected(0, 0), MIN_SELECTED); QCOMPARE(pixelSelection->selected(512, 512), MIN_SELECTED); pixelSelection->invert(); QCOMPARE(pixelSelection->selected(100, 100), MAX_SELECTED); QCOMPARE(pixelSelection->selected(22, 22), MIN_SELECTED); QCOMPARE(pixelSelection->selected(0, 0), MAX_SELECTED); QCOMPARE(pixelSelection->selected(512, 512), MAX_SELECTED); pixelSelection->convertToQImage(0, 0, 0, 100, 100).save("yyy.png"); // XXX: This should happen automatically selection->updateProjection(); selection->convertToQImage(0, 0, 0, 100, 100).save("zzz.png"); QCOMPARE(selection->selectedExactRect(), QRect(qint32_MIN/2, qint32_MIN/2, qint32_MAX, qint32_MAX)); QCOMPARE(selection->selectedRect(), QRect(qint32_MIN/2, qint32_MIN/2, qint32_MAX, qint32_MAX)); QCOMPARE(selection->selected(100, 100), MAX_SELECTED); QCOMPARE(selection->selected(22, 22), MIN_SELECTED); QCOMPARE(selection->selected(10, 10), MAX_SELECTED); QCOMPARE(selection->selected(0, 0), MAX_SELECTED); QCOMPARE(selection->selected(512, 512), MAX_SELECTED); }
void copyFromDevice(KisViewManager *view, KisPaintDeviceSP device, bool makeSharpClip = false) { KisImageWSP image = view->image(); if (!image) return; KisSelectionSP selection = view->selection(); QRect rc = (selection) ? selection->selectedExactRect() : image->bounds(); KisPaintDeviceSP clip = new KisPaintDevice(device->colorSpace()); Q_CHECK_PTR(clip); const KoColorSpace *cs = clip->colorSpace(); // TODO if the source is linked... copy from all linked layers?!? // Copy image data KisPainter::copyAreaOptimized(QPoint(), device, clip, rc); if (selection) { // Apply selection mask. KisPaintDeviceSP selectionProjection = selection->projection(); KisHLineIteratorSP layerIt = clip->createHLineIteratorNG(0, 0, rc.width()); KisHLineConstIteratorSP selectionIt = selectionProjection->createHLineIteratorNG(rc.x(), rc.y(), rc.width()); const KoColorSpace *selCs = selection->projection()->colorSpace(); for (qint32 y = 0; y < rc.height(); y++) { for (qint32 x = 0; x < rc.width(); x++) { /** * Sharp method is an exact reverse of COMPOSITE_OVER * so if you cover the cut/copied piece over its source * you get an exactly the same image without any seams */ if (makeSharpClip) { qreal dstAlpha = cs->opacityF(layerIt->rawData()); qreal sel = selCs->opacityF(selectionIt->oldRawData()); qreal newAlpha = sel * dstAlpha / (1.0 - dstAlpha + sel * dstAlpha); float mask = newAlpha / dstAlpha; cs->applyAlphaNormedFloatMask(layerIt->rawData(), &mask, 1); } else { cs->applyAlphaU8Mask(layerIt->rawData(), selectionIt->oldRawData(), 1); } layerIt->nextPixel(); selectionIt->nextPixel(); } layerIt->nextRow(); selectionIt->nextRow(); } } KisClipboard::instance()->setClip(clip, rc.topLeft()); }
void KisImageResizeToSelectionActionFactory::run(KisViewManager *view) { // XXX: "Add saving of XML data for Image Resize To Selection action" KisSelectionSP selection = view->selection(); if (!selection) return; view->image()->cropImage(selection->selectedExactRect()); }
void testShapedGradientPainterImpl(const QPolygonF &selectionPolygon, const QString &testName, const QPolygonF &selectionErasePolygon = QPolygonF()) { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP dev = new KisPaintDevice(cs); QRect imageRect(0,0,300,300); KisSelectionSP selection = new KisSelection(); KisPixelSelectionSP pixelSelection = selection->pixelSelection(); KisPainter selPainter(pixelSelection); selPainter.setFillStyle(KisPainter::FillStyleForegroundColor); selPainter.setPaintColor(KoColor(Qt::white, pixelSelection->colorSpace())); selPainter.paintPolygon(selectionPolygon); if (!selectionErasePolygon.isEmpty()) { selPainter.setCompositeOp(COMPOSITE_ERASE); selPainter.setPaintColor(KoColor(Qt::white, pixelSelection->colorSpace())); selPainter.paintPolygon(selectionErasePolygon); } selPainter.end(); pixelSelection->invalidateOutlineCache(); pixelSelection->convertToQImage(0, imageRect).save("sgt_selection.png"); QLinearGradient testGradient; testGradient.setColorAt(0.0, Qt::white); testGradient.setColorAt(0.5, Qt::green); testGradient.setColorAt(1.0, Qt::black); testGradient.setSpread(QGradient::ReflectSpread); QScopedPointer<KoStopGradient> gradient( KoStopGradient::fromQGradient(&testGradient)); KisGradientPainter gc(dev, selection); gc.setGradient(gradient.data()); gc.setGradientShape(KisGradientPainter::GradientShapePolygonal); gc.paintGradient(selectionPolygon.boundingRect().topLeft(), selectionPolygon.boundingRect().bottomRight(), KisGradientPainter::GradientRepeatNone, 0, false, imageRect.x(), imageRect.y(), imageRect.width(), imageRect.height()); QVERIFY(TestUtil::checkQImageExternal(dev->convertToQImage(0, imageRect), "shaped_gradient", "fill", testName, 1, 1, 0)); }
void KisImageResizeToSelectionActionFactory::run(KisView2 *view) { #ifdef __GNUC__ #warning "Add saving of XML data for Image Resize To Selection action" #endif KisSelectionSP selection = view->selection(); if (!selection) return; view->image()->cropImage(selection->selectedExactRect()); }
void KisSelectionTest::testUpdatePixelSelection() { KisSelectionSP selection = new KisSelection(); KisPixelSelectionSP pSel = selection->getOrCreatePixelSelection(); pSel->select(QRect(0, 0, 348, 212)); QVERIFY(selection->pixelSelection()->selectedExactRect() == QRect(0, 0, 348, 212)); selection->updateProjection(QRect(0, 0, 348, 212)); for (int i = 0; i < 212; ++i) { for (int j = 0; j < 348; ++j) { QVERIFY(selection->selected(j, i) == MAX_SELECTED); } } }
void KisFillActionFactory::run(const QString &fillSource, KisViewManager *view) { KisNodeSP node = view->activeNode(); if (!node || !node->hasEditablePaintDevice()) return; KisSelectionSP selection = view->selection(); QRect selectedRect = selection ? selection->selectedRect() : view->image()->bounds(); Q_UNUSED(selectedRect); KisPaintDeviceSP filled = node->paintDevice()->createCompositionSourceDevice(); Q_UNUSED(filled); bool usePattern = false; bool useBgColor = false; if (fillSource.contains("pattern")) { usePattern = true; } else if (fillSource.contains("bg")) { useBgColor = true; } KisProcessingApplicator applicator(view->image(), node, KisProcessingApplicator::NONE, KisImageSignalVector() << ModifiedSignal, kundo2_i18n("Flood Fill Layer")); KisResourcesSnapshotSP resources = new KisResourcesSnapshot(view->image(), node, 0, view->resourceProvider()->resourceManager()); if (!fillSource.contains("opacity")) { resources->setOpacity(1.0); } KisProcessingVisitorSP visitor = new FillProcessingVisitor(QPoint(0, 0), // start position selection, resources, false, // fast mode usePattern, true, // fill only selection, 0, // feathering radius 0, // sizemod 80, // threshold, false, // unmerged useBgColor); applicator.applyVisitor(visitor, KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::EXCLUSIVE); applicator.end(); }
void KisSelectionTest::testCopy() { KisSelectionSP sel = new KisSelection(); sel->getOrCreatePixelSelection()->select(QRect(10, 10, 200, 200), 128); KisSelectionSP sel2 = new KisSelection(*sel.data()); QCOMPARE(sel2->selectedExactRect(), sel->selectedExactRect()); QPoint errpoint; if (!TestUtil::comparePaintDevices(errpoint, sel, sel2)) { sel2->convertToQImage(0, 0, 0, 200, 200).save("merge_visitor6.png"); QFAIL(QString("Failed to copy selection, first different pixel: %1,%2 ") .arg(errpoint.x()) .arg(errpoint.y()) .toAscii()); } }
void KisMaskTest::testSelection() { TestUtil::MaskParent p; TestMaskSP mask = new TestMask; KisSelectionSP sel = new KisSelection(); sel->pixelSelection()->select(QRect(0,0,100,100), MAX_SELECTED); mask->initSelection(sel, p.layer); QCOMPARE(mask->extent(), QRect(0,0,128,128)); QCOMPARE(mask->exactBounds(), QRect(0,0,100,100)); mask->select(QRect(0,0,500,500), MAX_SELECTED);; QCOMPARE(mask->extent(), QRect(0,0,512,512)); QCOMPARE(mask->exactBounds(), QRect(0,0,500,500)); }
void KisSelectionBasedLayer::setInternalSelection(KisSelectionSP selection) { if (selection) { m_d->selection = new KisSelection(*selection.data()); m_d->selection->setParentNode(this); m_d->selection->updateProjection(); } else m_d->selection = 0; }
KisSelectionSP selectionFromAlphaChannel(KisPaintDeviceSP device, const QRect &srcRect) { const KoColorSpace *cs = device->colorSpace(); KisSelectionSP baseSelection = new KisSelection(new KisSelectionEmptyBounds(0)); KisPixelSelectionSP selection = baseSelection->pixelSelection(); KisSequentialConstIterator srcIt(device, srcRect); KisSequentialIterator dstIt(selection, srcRect); do { quint8 *dstPtr = dstIt.rawData(); const quint8* srcPtr = srcIt.rawDataConst(); *dstPtr = cs->opacityU8(srcPtr); } while(srcIt.nextPixel() && dstIt.nextPixel()); return baseSelection; }
void KisMaskTest::testSelectionParent() { { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisImageSP image = new KisImage(0, 100, 100, cs, "stest"); KisMaskSP mask = new TestMask; mask->initSelection(image->rootLayer()); KisSelectionSP selection = mask->selection(); QCOMPARE(selection->parentNode(), KisNodeSP(mask)); } { KisMaskSP mask = new TestMask; mask->setSelection(new KisSelection()); KisSelectionSP selection = mask->selection(); QCOMPARE(selection->parentNode(), KisNodeSP(mask)); } }
void copyFromDevice(KisView2 *view, KisPaintDeviceSP device) { KisImageWSP image = view->image(); KisSelectionSP selection = view->selection(); QRect rc = (selection) ? selection->selectedExactRect() : image->bounds(); KisPaintDeviceSP clip = new KisPaintDevice(device->colorSpace()); Q_CHECK_PTR(clip); const KoColorSpace *cs = clip->colorSpace(); // TODO if the source is linked... copy from all linked layers?!? // Copy image data KisPainter gc; gc.begin(clip); gc.setCompositeOp(COMPOSITE_COPY); gc.bitBlt(0, 0, device, rc.x(), rc.y(), rc.width(), rc.height()); gc.end(); if (selection) { // Apply selection mask. KisPaintDeviceSP selectionProjection = selection->projection(); KisHLineIteratorSP layerIt = clip->createHLineIteratorNG(0, 0, rc.width()); KisHLineConstIteratorSP selectionIt = selectionProjection->createHLineIteratorNG(rc.x(), rc.y(), rc.width()); for (qint32 y = 0; y < rc.height(); y++) { for (qint32 x = 0; x < rc.width(); x++) { cs->applyAlphaU8Mask(layerIt->rawData(), selectionIt->oldRawData(), 1); layerIt->nextPixel(); selectionIt->nextPixel(); } layerIt->nextRow(); selectionIt->nextRow(); } } KisClipboard::instance()->setClip(clip, rc.topLeft()); }
bool KisMirrorVisitor::mirrorMask(KisMask* mask) { KoProperties properties; KisSelectionSP selection = mask->selection(); if (selection->hasPixelSelection()) { KisPaintDeviceSP dev = selection->pixelSelection(); QString name; if (m_orientation == Qt::Horizontal) { name = i18n("Mirror Mask X"); } else { name = i18n("Mirror Mask Y"); } // TODO: use a selection transaction to cache the outline KisTransaction transaction(name, dev); QRect dirty; if (m_orientation == Qt::Horizontal) { dirty = KisTransformWorker::mirrorX(dev, m_image->width()/2.0f); } else { dirty = KisTransformWorker::mirrorY(dev, m_image->height()/2.0f); } mask->setDirty(dirty); transaction.commit(m_image->undoAdapter()); dev->setDirty(dirty); } /* TODO: Doesn't work correctly even thoush it's the same code as the shape layer if (selection->hasShapeSelection()) { if (m_orientation == Qt::Horizontal) { KisTransformVisitor visitor(m_image, -1.0, 1.0, 0.0, 0.0, 0.0, m_image->width(), 0, 0, 0, true); mask->accept(visitor); } else { KisTransformVisitor visitor(m_image, 1.0, -1.0, 0.0, 0.0, 0.0, 0, m_image->height(), 0, 0, true); mask->accept(visitor); } } */ selection->updateProjection(); return true; }
bool KisKraSaveVisitor::saveSelection(KisNode* node) { KisSelectionSP selection; if (node->inherits("KisMask")) { selection = static_cast<KisMask*>(node)->selection(); } else if (node->inherits("KisAdjustmentLayer")) { selection = static_cast<KisAdjustmentLayer*>(node)->internalSelection(); } else if (node->inherits("KisGeneratorLayer")) { selection = static_cast<KisGeneratorLayer*>(node)->internalSelection(); } else { return false; } bool retval = true; if (selection->hasPixelSelection()) { KisPaintDeviceSP dev = selection->pixelSelection(); if (!savePaintDevice(dev, getLocation(node, DOT_PIXEL_SELECTION))) { m_errorMessages << i18n("Failed to save the pixel selection data for layer %1.", node->name()); retval = false; } } if (selection->hasShapeSelection()) { m_store->pushDirectory(); retval = m_store->enterDirectory(getLocation(node, DOT_SHAPE_SELECTION)); if (retval) { KisShapeSelection* shapeSelection = dynamic_cast<KisShapeSelection*>(selection->shapeSelection()); if (!shapeSelection) { retval = false; } if (retval && !shapeSelection->saveSelection(m_store)) { m_errorMessages << i18n("Failed to save the vector selection data for layer %1.", node->name()); retval = false; } } m_store->popDirectory(); } return retval; }
bool KisKraLoadVisitor::visit(KisPaintLayer *layer) { loadNodeKeyframes(layer); dbgFile << "Visit: " << layer->name() << " colorSpace: " << layer->colorSpace()->id(); if (!loadPaintDevice(layer->paintDevice(), getLocation(layer))) { return false; } if (!loadProfile(layer->paintDevice(), getLocation(layer, DOT_ICC))) { return false; } if (!loadMetaData(layer)) { return false; } if (m_syntaxVersion == 1) { // Check whether there is a file with a .mask extension in the // layer directory, if so, it's an old-style transparency mask // that should be converted. QString location = getLocation(layer, ".mask"); if (m_store->open(location)) { KisSelectionSP selection = KisSelectionSP(new KisSelection()); KisPixelSelectionSP pixelSelection = selection->pixelSelection(); if (!pixelSelection->read(m_store->device())) { pixelSelection->disconnect(); } else { KisTransparencyMask* mask = new KisTransparencyMask(); mask->setSelection(selection); m_image->addNode(mask, layer, layer->firstChild()); } m_store->close(); } } bool result = visitAll(layer); return result; }
void KisSelectionTest::testSelectionExactBounds() { QRect referenceImageRect(0,0,1000,1000); QRect referenceDeviceRect(10,10,1000,1000); const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisImageSP image = new KisImage(0, referenceImageRect.width(), referenceImageRect.height(), cs, "stest"); KisPaintDeviceSP device = new KisPaintDevice(cs); device->fill(referenceDeviceRect, KoColor(Qt::white, cs)); QCOMPARE(device->exactBounds(), referenceDeviceRect); KisSelectionSP selection = new KisSelection(device, new KisSelectionDefaultBounds(device, image)); quint8 defaultPixel = MAX_SELECTED; selection->setDefaultPixel(&defaultPixel); QCOMPARE(selection->selectedExactRect(), referenceImageRect | referenceDeviceRect); }
KUndo2Command* paint() { KisSelectionSP cutSelection = m_sel; // Shrinking the cutting area was previously used // for getting seamless cut-paste. Now we use makeSharpClip // instead. // QRect originalRect = cutSelection->selectedExactRect(); // static const int preciseSelectionThreshold = 16; // // if (originalRect.width() > preciseSelectionThreshold || // originalRect.height() > preciseSelectionThreshold) { // cutSelection = new KisSelection(*m_sel); // delete cutSelection->flatten(); // // KisSelectionFilter* filter = new KisShrinkSelectionFilter(1, 1, false); // // QRect processingRect = filter->changeRect(originalRect); // filter->process(cutSelection->pixelSelection(), processingRect); // } KisTransaction transaction(m_node->paintDevice()); m_node->paintDevice()->clearSelection(cutSelection); m_node->setDirty(cutSelection->selectedRect()); return transaction.endAndTake(); }
void KisSelectionTest::testUpdateSelectionProjection() { KisSelectionSP selection = new KisSelection(); QVERIFY(selection->selectedExactRect().isNull()); // Now fill the layer with some opaque pixels KisFillPainter gc(selection->getOrCreatePixelSelection()); gc.fillRect(QRect(0, 0, 100, 100), KoColor(QColor(0, 0, 0, 0), KoColorSpaceRegistry::instance()->rgb8()), MAX_SELECTED); gc.end(); QVERIFY(selection->pixelSelection()->selectedExactRect() == QRect(0, 0, 100, 100)); selection->updateProjection(); QCOMPARE(selection->pixelSelection()->selectedExactRect(), QRect(0, 0, 100, 100)); QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 100, 100)); }
void KisShapeSelectionTest::testAddChild() { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisImageSP image = new KisImage(new KisUndoAdapter(0), 300, 300, cs, "test"); KisSelectionSP selection = new KisSelection(); QVERIFY(selection->hasPixelSelection() == false); QVERIFY(selection->hasShapeSelection() == false); KisPixelSelectionSP pixelSelection = selection->getOrCreatePixelSelection(); pixelSelection->select(QRect(0, 0, 100, 100)); // Selection is using the pixel selection as datamanager so no projection update // needed QCOMPARE(pixelSelection->selected(25, 25), MAX_SELECTED); QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 100, 100)); QRect rect(50, 50, 100, 100); QTransform matrix; matrix.scale(1 / image->xRes(), 1 / image->yRes()); rect = matrix.mapRect(rect); KoPathShape* shape = new KoPathShape(); shape->setShapeId(KoPathShapeId); shape->moveTo(rect.topLeft()); shape->lineTo(rect.topLeft() + QPointF(rect.width(), 0)); shape->lineTo(rect.bottomRight()); shape->lineTo(rect.topLeft() + QPointF(0, rect.height())); shape->close(); shape->normalize(); KisShapeSelection * shapeSelection = new KisShapeSelection(image, selection); selection->setShapeSelection(shapeSelection); shapeSelection->addShape(shape); QCOMPARE(pixelSelection->selected(25, 25), MAX_SELECTED); QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 150, 150)); selection->updateProjection(); }
void KisTransformProcessingVisitor::transformSelection(KisSelectionSP selection, KisUndoAdapter *adapter, const ProgressHelper &helper) { if(selection->hasPixelSelection()) { transformPaintDevice(selection->pixelSelection(), adapter, helper); } if (selection->hasShapeSelection()) { KisTransformWorker tw(selection->projection(), m_sx, m_sy, m_shearx, m_sheary, m_shearOrigin.x(), m_shearOrigin.y(), m_angle, m_tx, m_ty, 0, m_filter); KUndo2Command* command = selection->shapeSelection()->transform(tw.transform() * m_shapesCorrection); if (command) { adapter->addCommand(command); } } selection->updateProjection(); }