diff --git a/libs/image/kis_pixel_selection.h b/libs/image/kis_pixel_selection.h --- a/libs/image/kis_pixel_selection.h +++ b/libs/image/kis_pixel_selection.h @@ -152,6 +152,11 @@ * Intersects a selection using min-T-norm for this. */ void intersectSelection(KisPixelSelectionSP selection); + + /** + * Exclude a selection + */ + void excludeSelection(KisPixelSelectionSP selection); private: // We don't want these methods to be used on selections: diff --git a/libs/image/kis_pixel_selection.cpp b/libs/image/kis_pixel_selection.cpp --- a/libs/image/kis_pixel_selection.cpp +++ b/libs/image/kis_pixel_selection.cpp @@ -150,6 +150,9 @@ case SELECTION_INTERSECT: intersectSelection(selection); break; + case SELECTION_EXCLUDE: + excludeSelection(selection); + break; default: break; } @@ -255,6 +258,31 @@ m_d->invalidateThumbnailImage(); } +void KisPixelSelection::excludeSelection(KisPixelSelectionSP selection) +{ + QRect r = selection->selectedRect(); + if (r.isEmpty()) return; + + + KisHLineIteratorSP dst = createHLineIteratorNG(r.x(), r.y(), r.width()); + KisHLineConstIteratorSP src = selection->createHLineConstIteratorNG(r.x(), r.y(), r.width()); + for (int i = 0; i < r.height(); ++i) { + do {*dst->rawData() = abs(*dst->rawData() - *src->oldRawData()); + + } while (src->nextPixel() && dst->nextPixel()); + dst->nextRow(); + src->nextRow(); + } + + m_d->outlineCacheValid &= selection->outlineCacheValid(); + + if (m_d->outlineCacheValid) { + m_d->outlineCache |= selection->outlineCache(); + } + + m_d->invalidateThumbnailImage(); +} + void KisPixelSelection::clear(const QRect & r) { if (*defaultPixel().data() != MIN_SELECTED) { diff --git a/libs/image/kis_selection.h b/libs/image/kis_selection.h --- a/libs/image/kis_selection.h +++ b/libs/image/kis_selection.h @@ -35,6 +35,7 @@ SELECTION_ADD, SELECTION_SUBTRACT, SELECTION_INTERSECT, + SELECTION_EXCLUDE, SELECTION_DEFAULT }; diff --git a/libs/libkis/Selection.h b/libs/libkis/Selection.h --- a/libs/libkis/Selection.h +++ b/libs/libkis/Selection.h @@ -195,6 +195,11 @@ * Intersect the given selection with this selection. */ void intersect(Selection *selection); + + /** + * Exclude the given selection with this selection. + */ + void exclude(Selection *selection); /** * @brief pixelData reads the given rectangle from the Selection's mask and returns it as a diff --git a/libs/libkis/Selection.cpp b/libs/libkis/Selection.cpp --- a/libs/libkis/Selection.cpp +++ b/libs/libkis/Selection.cpp @@ -294,6 +294,12 @@ d->selection->pixelSelection()->applySelection(selection->selection()->pixelSelection(), SELECTION_INTERSECT); } +void Selection::exclude(Selection *selection) +{ + if (!d->selection) return; + d->selection->pixelSelection()->applySelection(selection->selection()->pixelSelection(), SELECTION_EXCLUDE); +} + QByteArray Selection::pixelData(int x, int y, int w, int h) const { diff --git a/libs/ui/forms/wdgselectionoptions.ui b/libs/ui/forms/wdgselectionoptions.ui --- a/libs/ui/forms/wdgselectionoptions.ui +++ b/libs/ui/forms/wdgselectionoptions.ui @@ -6,35 +6,33 @@ 0 0 - 271 - 106 + 652 + 257 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - + 0 - - + + + + CrossCursor + + + Mode: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + - Intersect + Subtract (Shortcut S) ... @@ -63,10 +61,10 @@ - - + + - Replace (Shortcut R) + Add (Shortcut A) ... @@ -74,18 +72,15 @@ true - - true - false - - + + - Add (Shortcut A) + Pixel Selection ... @@ -93,38 +88,34 @@ true + + true + false - - - - CrossCursor + + + + Intersect - Mode: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + ... - - - - - - Action: + + true - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + false - - + + - Pixel Selection + Replace (Shortcut R) ... @@ -140,8 +131,18 @@ - - + + + + Action: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Subtract (Shortcut S) @@ -158,7 +159,7 @@ - + Qt::Horizontal diff --git a/libs/ui/tool/kis_selection_tool_config_widget_helper.cpp b/libs/ui/tool/kis_selection_tool_config_widget_helper.cpp --- a/libs/ui/tool/kis_selection_tool_config_widget_helper.cpp +++ b/libs/ui/tool/kis_selection_tool_config_widget_helper.cpp @@ -124,6 +124,9 @@ case Qt::Key_T: slotWidgetActionChanged(SELECTION_INTERSECT); break; + case Qt::Key_E: + slotWidgetActionChanged(SELECTION_EXCLUDE); + break; default: event->ignore(); } diff --git a/libs/ui/widgets/kis_selection_options.cc b/libs/ui/widgets/kis_selection_options.cc --- a/libs/ui/widgets/kis_selection_options.cc +++ b/libs/ui/widgets/kis_selection_options.cc @@ -53,6 +53,7 @@ m_action->addButton(m_page->subtract, SELECTION_SUBTRACT); m_action->addButton(m_page->replace, SELECTION_REPLACE); m_action->addButton(m_page->intersect, SELECTION_INTERSECT); + m_action->addButton(m_page->exclude, SELECTION_EXCLUDE); m_page->pixel->setGroupPosition(KoGroupButton::GroupLeft); m_page->shape->setGroupPosition(KoGroupButton::GroupRight); @@ -63,10 +64,12 @@ m_page->subtract->setGroupPosition(KoGroupButton::GroupRight); m_page->replace->setGroupPosition(KoGroupButton::GroupLeft); m_page->intersect->setGroupPosition(KoGroupButton::GroupCenter); + m_page->exclude->setGroupPosition(KoGroupButton::GroupRight); m_page->add->setIcon(KisIconUtils::loadIcon("selection_add")); m_page->subtract->setIcon(KisIconUtils::loadIcon("selection_subtract")); m_page->replace->setIcon(KisIconUtils::loadIcon("selection_replace")); m_page->intersect->setIcon(KisIconUtils::loadIcon("selection_intersect")); + m_page->exclude->setIcon(KisIconUtils::loadIcon("selection_exclude")); connect(m_mode, SIGNAL(buttonClicked(int)), this, SIGNAL(modeChanged(int))); connect(m_action, SIGNAL(buttonClicked(int)), this, SIGNAL(actionChanged(int))); @@ -105,6 +108,7 @@ m_page->subtract->setVisible(isPixelSelection); m_page->replace->setVisible(isPixelSelection); m_page->intersect->setVisible(isPixelSelection); + m_page->exclude->setVisible(isPixelSelection); m_page->chkAntiAliasing->setVisible(isPixelSelection); } diff --git a/plugins/tools/selectiontools/kis_selection_modifier_mapper.cc b/plugins/tools/selectiontools/kis_selection_modifier_mapper.cc --- a/plugins/tools/selectiontools/kis_selection_modifier_mapper.cc +++ b/plugins/tools/selectiontools/kis_selection_modifier_mapper.cc @@ -59,6 +59,7 @@ Qt::KeyboardModifiers intersectModifiers; Qt::KeyboardModifiers addModifiers; Qt::KeyboardModifiers subtractModifiers; + Qt::KeyboardModifiers excludeModifiers; }; @@ -115,6 +116,8 @@ newAction = SELECTION_REPLACE; } else if (m == intersectModifiers) { newAction = SELECTION_INTERSECT; + } else if (m == excludeModifiers) { + newAction = SELECTION_EXCLUDE; } else if (m == addModifiers) { newAction = SELECTION_ADD; } else if (m == subtractModifiers) {