void KisSelectionTest::testSelectionActions() { KisPixelSelectionSP pixelSelection = new KisPixelSelection(); KisSelectionSP selection = new KisSelection(); QVERIFY(selection->hasPixelSelection() == false); QVERIFY(selection->hasShapeSelection() == false); selection->setPixelSelection(pixelSelection); pixelSelection->select(QRect(0, 0, 20, 20)); KisPixelSelectionSP tmpSel = KisPixelSelectionSP(new KisPixelSelection()); tmpSel->select(QRect(10, 0, 20, 20)); pixelSelection->addSelection(tmpSel); QCOMPARE(pixelSelection->selectedExactRect(), QRect(0, 0, 30, 20)); selection->updateProjection(); QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 30, 20)); pixelSelection->clear(); pixelSelection->select(QRect(0, 0, 20, 20)); pixelSelection->subtractSelection(tmpSel); selection->updateProjection(); QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 10, 20)); pixelSelection->clear(); selection->updateProjection(); pixelSelection->select(QRect(0, 0, 20, 20)); pixelSelection->intersectSelection(tmpSel); selection->updateProjection(); QCOMPARE(selection->selectedExactRect(), QRect(10, 0, 10, 20)); }
void KisSelectionToolHelper::addSelectionShape(KoShape* shape) { KisView2* view = m_canvas->view(); /** * Mark a shape that it belongs to a shape selection */ if(!shape->userData()) { shape->setUserData(new KisShapeSelectionMarker); } KisUndoAdapter *undoAdapter = view->image()->undoAdapter(); undoAdapter->beginMacro(m_name); if (!view->selection()) { undoAdapter->addCommand(new KisSetEmptyGlobalSelectionCommand(m_image)); } KisPixelSelectionSP pixelSelection = view->selection()->pixelSelection(); KisSelectionTransaction transaction(m_name, pixelSelection); pixelSelection->clear(); transaction.commit(undoAdapter); undoAdapter->addCommand(m_canvas->shapeController()->addShape(shape)); undoAdapter->endMacro(); }
QUndoCommand* KisSelectionToolHelper::selectPixelSelection(KisPixelSelectionSP selection, selectionAction action) { bool hasSelection = m_layer->selection(); QUndoCommand* selectionCmd = new QUndoCommand(m_name); if (!hasSelection) new KisSetGlobalSelectionCommand(m_image, selectionCmd); new KisSelectionTransaction(m_name, m_image, m_layer->selection(), selectionCmd); KisPixelSelectionSP getOrCreatePixelSelection = m_layer->selection()->getOrCreatePixelSelection(); if (! hasSelection || action == SELECTION_REPLACE) { getOrCreatePixelSelection->clear(); if (action == SELECTION_SUBTRACT) getOrCreatePixelSelection->invert(); } getOrCreatePixelSelection->applySelection(selection, action); if (hasSelection && action != SELECTION_REPLACE && action != SELECTION_INTERSECT) { QRect rc = selection->selectedRect(); getOrCreatePixelSelection->setDirty(rc); m_layer->selection()->updateProjection(rc); m_canvas->view()->selectionManager()->selectionChanged(); } else { getOrCreatePixelSelection->setDirty(m_image->bounds()); m_layer->selection()->updateProjection(m_image->bounds()); m_canvas->view()->selectionManager()->selectionChanged(); } return selectionCmd; }
void KisSelectionToolHelper::addSelectionShapes(QList< KoShape* > shapes) { KisViewManager* view = m_canvas->viewManager(); if (view->image()->wrapAroundModePermitted()) { view->showFloatingMessage( i18n("Shape selection does not fully " "support wraparound mode. Please " "use pixel selection instead"), KisIconUtils::loadIcon("selection-info")); } KisProcessingApplicator applicator(view->image(), 0 /* we need no automatic updates */, KisProcessingApplicator::NONE, KisImageSignalVector() << ModifiedSignal, m_name); applicator.applyCommand(new LazyInitGlobalSelection(view)); struct ClearPixelSelection : public KisTransactionBasedCommand { ClearPixelSelection(KisViewManager *view) : m_view(view) {} KisViewManager *m_view; KUndo2Command* paint() { KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection(); KIS_ASSERT_RECOVER(pixelSelection) { return 0; } KisSelectionTransaction transaction(pixelSelection); pixelSelection->clear(); return transaction.endAndTake(); } }; applicator.applyCommand(new ClearPixelSelection(view)); struct AddSelectionShape : public KisTransactionBasedCommand { AddSelectionShape(KisViewManager *view, KoShape* shape) : m_view(view), m_shape(shape) {} KisViewManager *m_view; KoShape* m_shape; KUndo2Command* paint() { /** * Mark a shape that it belongs to a shape selection */ if(!m_shape->userData()) { m_shape->setUserData(new KisShapeSelectionMarker); } return m_view->canvasBase()->shapeController()->addShape(m_shape); } }; foreach(KoShape* shape, shapes) { applicator.applyCommand( new KisGuiContextCommand(new AddSelectionShape(view, shape), view)); }
void KisLsBevelEmbossFilter::applyBevelEmboss(KisPaintDeviceSP srcDevice, KisMultipleProjection *dst, const QRect &applyRect, const psd_layer_effects_bevel_emboss *config, KisLayerStyleFilterEnvironment *env) const { if (applyRect.isEmpty()) return; BevelEmbossRectCalculator d(applyRect, config); KisSelectionSP baseSelection = KisLsUtils::selectionFromAlphaChannel(srcDevice, d.initialFetchRect); KisPixelSelectionSP selection = baseSelection->pixelSelection(); //selection->convertToQImage(0, QRect(0,0,300,300)).save("0_selection_initial.png"); const int size = config->size(); int limitingGrowSize = 0; KisPixelSelectionSP bumpmapSelection = new KisPixelSelection(new KisSelectionEmptyBounds(0)); switch (config->style()) { case psd_bevel_outer_bevel: paintBevelSelection(selection, bumpmapSelection, d.applyBevelRect, size, size, false); limitingGrowSize = size; break; case psd_bevel_inner_bevel: paintBevelSelection(selection, bumpmapSelection, d.applyBevelRect, size, 0, false); limitingGrowSize = 0; break; case psd_bevel_emboss: { const int initialSize = std::ceil(qreal(size) / 2.0); paintBevelSelection(selection, bumpmapSelection, d.applyBevelRect, size, initialSize, false); limitingGrowSize = initialSize; break; } case psd_bevel_pillow_emboss: { const int halfSizeF = std::floor(qreal(size) / 2.0); const int halfSizeC = std::ceil(qreal(size) / 2.0); // TODO: probably not correct! paintBevelSelection(selection, bumpmapSelection, d.applyBevelRect, halfSizeC, halfSizeC, false); paintBevelSelection(selection, bumpmapSelection, d.applyBevelRect, halfSizeF, 0, true); limitingGrowSize = halfSizeC; break; } case psd_bevel_stroke_emboss: warnKrita << "WARNING: Stroke Emboss style is not implemented yet!"; return; } KisPixelSelectionSP limitingSelection = new KisPixelSelection(*selection); { QRect changeRectUnused = KisLsUtils::growSelectionUniform(limitingSelection, limitingGrowSize, d.applyBevelRect); Q_UNUSED(changeRectUnused); } //bumpmapSelection->convertToQImage(0, QRect(0,0,300,300)).save("1_selection_xconv.png"); if (config->textureEnabled()) { KisPixelSelectionSP textureSelection = new KisPixelSelection(new KisSelectionEmptyBounds(0)); KisLsUtils::fillPattern(textureSelection, d.applyTextureRect, env, config->textureScale(), config->texturePattern(), config->textureHorizontalPhase(), config->textureVerticalPhase(), config->textureAlignWithLayer()); int contrastadj = 0; { using namespace std; int tex_depth = config->textureDepth(); if (tex_depth >= 0.0) { if (tex_depth <= 100.0) { contrastadj = int(qRound((1-(tex_depth/100.0)) * -127)); } else { contrastadj = int(qRound(((tex_depth-100.0)/900.0) * 127)); } } else { textureSelection->invert(); if (tex_depth >= -100.0) { contrastadj = int(qRound((1-(abs(tex_depth)/100.0)) * -127)); } else { contrastadj = int(qRound(((abs(tex_depth)-100.0)/900.0) * 127)); } } } qreal contrast = qBound(-1.0, qreal(contrastadj) / 127.0, 1.0); mapPixelValues(textureSelection, ContrastOp(contrast), d.applyTextureRect); { KisPainter gc(bumpmapSelection); gc.setCompositeOp(COMPOSITE_MULT); gc.bitBlt(d.applyTextureRect.topLeft(), textureSelection, d.applyTextureRect); gc.end(); } } //bumpmapSelection->convertToQImage(0, QRect(0,0,300,300)).save("15_selection_texture.png"); if (config->contourEnabled()) { if (config->range() != KisLsUtils::FULL_PERCENT_RANGE) { KisLsUtils::adjustRange(bumpmapSelection, d.applyContourRect, config->range()); } KisLsUtils::applyContourCorrection(bumpmapSelection, d.applyContourRect, config->contourLookupTable(), config->antiAliased(), true); } bumpmap_vals_t bmvals; bmvals.azimuth = config->angle(); bmvals.elevation = config->altitude(); bmvals.depth = config->depth(); bmvals.ambient = 0; bmvals.compensate = true; bmvals.invert = config->direction() == psd_direction_down; bmvals.type = LINEAR; bumpmap(bumpmapSelection, d.applyBumpmapRect, bmvals); //bumpmapSelection->convertToQImage(0, QRect(0,0,300,300)).save("3_selection_bumpmap.png"); { // TODO: optimize! KisLsUtils::applyContourCorrection(bumpmapSelection, d.applyGlossContourRect, config->glossContourLookupTable(), config->glossAntiAliased(), true); } if (config->soften()) { KisLsUtils::applyGaussian(bumpmapSelection, d.applyGaussianRect, config->soften()); } if (config->textureEnabled() && config->textureInvert()) { bumpmapSelection->invert(); } selection->clear(); mapPixelValues(bumpmapSelection, selection, ShadowsFetchOp(), d.shadowHighlightsFinalRect); selection->applySelection(limitingSelection, SELECTION_INTERSECT); //dstDevice->convertToQImage(0, QRect(0,0,300,300)).save("4_dst_before_apply.png"); //selection->convertToQImage(0, QRect(0,0,300,300)).save("4_shadows_sel.png"); { KisPaintDeviceSP dstDevice = dst->getProjection("00_bevel_shadow", config->shadowBlendMode(), srcDevice); const KoColor fillColor(config->shadowColor(), dstDevice->colorSpace()); const QRect &fillRect = d.shadowHighlightsFinalRect; KisPaintDeviceSP fillDevice = new KisPaintDevice(dstDevice->colorSpace()); fillDevice->setDefaultPixel(fillColor); KisPainter gc(dstDevice); gc.setSelection(baseSelection); gc.setCompositeOp(COMPOSITE_OVER); env->setupFinalPainter(&gc, config->shadowOpacity(), QBitArray()); gc.bitBlt(fillRect.topLeft(), fillDevice, fillRect); gc.end(); } selection->clear(); mapPixelValues(bumpmapSelection, selection, HighlightsFetchOp(), d.shadowHighlightsFinalRect); selection->applySelection(limitingSelection, SELECTION_INTERSECT); //selection->convertToQImage(0, QRect(0,0,300,300)).save("5_highlights_sel.png"); { KisPaintDeviceSP dstDevice = dst->getProjection("01_bevel_highlight", config->highlightBlendMode(), srcDevice); const KoColor fillColor(config->highlightColor(), dstDevice->colorSpace()); const QRect &fillRect = d.shadowHighlightsFinalRect; KisPaintDeviceSP fillDevice = new KisPaintDevice(dstDevice->colorSpace()); fillDevice->setDefaultPixel(fillColor); KisPainter gc(dstDevice); gc.setSelection(baseSelection); gc.setCompositeOp(COMPOSITE_OVER); env->setupFinalPainter(&gc, config->highlightOpacity(), QBitArray()); gc.bitBlt(fillRect.topLeft(), fillDevice, fillRect); gc.end(); } }