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) {