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::selectPixelSelection(KisPixelSelectionSP selection, SelectionAction action) { KisViewManager* view = m_canvas->viewManager(); if (selection->selectedExactRect().isEmpty()) { m_canvas->viewManager()->selectionManager()->deselect(); return; } KisProcessingApplicator applicator(view->image(), 0 /* we need no automatic updates */, KisProcessingApplicator::SUPPORTS_WRAPAROUND_MODE, KisImageSignalVector() << ModifiedSignal, m_name); applicator.applyCommand(new LazyInitGlobalSelection(view)); struct ApplyToPixelSelection : public KisTransactionBasedCommand { ApplyToPixelSelection(KisViewManager *view, KisPixelSelectionSP selection, SelectionAction action) : m_view(view), m_selection(selection), m_action(action) {} KisViewManager *m_view; KisPixelSelectionSP m_selection; SelectionAction m_action; KUndo2Command* paint() { KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection(); KIS_ASSERT_RECOVER(pixelSelection) { return 0; } bool hasSelection = !pixelSelection->isEmpty(); KisSelectionTransaction transaction(pixelSelection); if (!hasSelection && m_action == SELECTION_SUBTRACT) { pixelSelection->invert(); } pixelSelection->applySelection(m_selection, m_action); QRect dirtyRect = m_view->image()->bounds(); if (hasSelection && m_action != SELECTION_REPLACE && m_action != SELECTION_INTERSECT) { dirtyRect = m_selection->selectedRect(); } m_view->selection()->updateProjection(dirtyRect); KUndo2Command *savedCommand = transaction.endAndTake(); pixelSelection->setDirty(dirtyRect); return savedCommand; } }; applicator.applyCommand(new ApplyToPixelSelection(view, selection, action)); applicator.end(); }
void KisSelectionToolHelper::selectPixelSelection(KisPixelSelectionSP selection, SelectionAction action) { KisView2* view = m_canvas->view(); if (selection->selectedRect().isEmpty()) { m_canvas->view()->selectionManager()->deselect(); return; } KisUndoAdapter *undoAdapter = view->image()->undoAdapter(); undoAdapter->beginMacro(m_name); bool hasSelection = view->selection(); if (!hasSelection) { undoAdapter->addCommand(new KisSetEmptyGlobalSelectionCommand(m_image)); } KisSelectionTransaction transaction(m_name, m_image->undoAdapter(), view->selection()); KisPixelSelectionSP pixelSelection = view->selection()->getOrCreatePixelSelection(); if (!hasSelection && action == SELECTION_SUBTRACT) { pixelSelection->invert(); } pixelSelection->applySelection(selection, action); QRect dirtyRect = m_image->bounds(); if (hasSelection && action != SELECTION_REPLACE && action != SELECTION_INTERSECT) { dirtyRect = selection->selectedRect(); } view->selection()->updateProjection(dirtyRect); transaction.commit(undoAdapter); undoAdapter->endMacro(); pixelSelection->setDirty(dirtyRect); m_canvas->view()->selectionManager()->selectionChanged(); }
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(); } }
void KisSelectionToolHelper::selectPixelSelection(KisPixelSelectionSP selection, SelectionAction action) { KisViewManager* view = m_canvas->viewManager(); if (selection->selectedExactRect().isEmpty()) { m_canvas->viewManager()->selectionManager()->deselect(); return; } KisProcessingApplicator applicator(view->image(), 0 /* we need no automatic updates */, KisProcessingApplicator::SUPPORTS_WRAPAROUND_MODE, KisImageSignalVector() << ModifiedSignal, m_name); applicator.applyCommand(new LazyInitGlobalSelection(view)); struct ApplyToPixelSelection : public KisTransactionBasedCommand { ApplyToPixelSelection(KisViewManager *view, KisPixelSelectionSP selection, SelectionAction action) : m_view(view), m_selection(selection), m_action(action) {} KisViewManager *m_view; KisPixelSelectionSP m_selection; SelectionAction m_action; KUndo2Command* paint() override { KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection(); KIS_ASSERT_RECOVER(pixelSelection) { return 0; } bool hasSelection = !pixelSelection->isEmpty(); KisSelectionTransaction transaction(pixelSelection); if (!hasSelection && m_action == SELECTION_SUBTRACT) { pixelSelection->invert(); } pixelSelection->applySelection(m_selection, m_action); const QRect imageBounds = m_view->image()->bounds(); QRect selectionExactRect = m_view->selection()->selectedExactRect(); if (!imageBounds.contains(selectionExactRect)) { pixelSelection->crop(imageBounds); if (pixelSelection->outlineCacheValid()) { QPainterPath cache = pixelSelection->outlineCache(); QPainterPath imagePath; imagePath.addRect(imageBounds); cache &= imagePath; pixelSelection->setOutlineCache(cache); } selectionExactRect &= imageBounds; } QRect dirtyRect = imageBounds; if (hasSelection && m_action != SELECTION_REPLACE && m_action != SELECTION_INTERSECT) { dirtyRect = m_selection->selectedRect(); } m_view->selection()->updateProjection(dirtyRect); KUndo2Command *savedCommand = transaction.endAndTake(); pixelSelection->setDirty(dirtyRect); if (selectionExactRect.isEmpty()) { KisCommandUtils::CompositeCommand *cmd = new KisCommandUtils::CompositeCommand(); cmd->addCommand(savedCommand); cmd->addCommand(new KisDeselectGlobalSelectionCommand(m_view->image())); savedCommand = cmd; } return savedCommand; } }; applicator.applyCommand(new ApplyToPixelSelection(view, selection, action)); applicator.end(); }