[krita/kazakov/lazy-brush-remastered] /: Implement "Limit to layer bounds" feature of the Colorize Mask
Dmitry Kazakov
null at kde.org
Mon Dec 11 21:14:09 UTC 2017
Git commit dfae2014343f90cf0ad00adf37506dc945d92a5b by Dmitry Kazakov.
Committed on 11/12/2017 at 21:14.
Pushed by dkazakov into branch 'kazakov/lazy-brush-remastered'.
Implement "Limit to layer bounds" feature of the Colorize Mask
If the outer color of the mask is transparent (e.g. when coloring
a character), the user might select "Limit to layer bounds" option,
which will limit the coloring area by the non-zero area of the parent
layer. It might speedup the coloring significantly.
CC:kimageshop at kde.org
M +37 -6 libs/image/lazybrush/kis_colorize_mask.cpp
M +2 -0 libs/image/lazybrush/kis_colorize_mask.h
M +2 -1 libs/image/lazybrush/kis_colorize_stroke_strategy.h
M +2 -0 plugins/impex/libkra/kis_kra_loader.cpp
M +1 -0 plugins/impex/libkra/kis_kra_savexml_visitor.cpp
M +1 -0 plugins/impex/libkra/kis_kra_tags.h
M +12 -1 plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp
M +1 -0 plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.h
M +7 -0 plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.ui
https://commits.kde.org/krita/dfae2014343f90cf0ad00adf37506dc945d92a5b
diff --git a/libs/image/lazybrush/kis_colorize_mask.cpp b/libs/image/lazybrush/kis_colorize_mask.cpp
index ad2d46f63a9..118f55b1cbf 100644
--- a/libs/image/lazybrush/kis_colorize_mask.cpp
+++ b/libs/image/lazybrush/kis_colorize_mask.cpp
@@ -65,7 +65,8 @@ struct KisColorizeMask::Private
dirtyParentUpdateCompressor(200, KisSignalCompressor::FIRST_ACTIVE_POSTPONE_NEXT, _q),
prefilterRecalculationCompressor(1000, KisSignalCompressor::POSTPONE, _q),
updateIsRunning(false),
- filteringOptions(false, 4.0, 15, 0.7)
+ filteringOptions(false, 4.0, 15, 0.7),
+ limitToDeviceBounds(false)
{
}
@@ -74,6 +75,7 @@ struct KisColorizeMask::Private
coloringProjection(new KisPaintDevice(*rhs.coloringProjection)),
fakePaintDevice(new KisPaintDevice(*rhs.fakePaintDevice)),
filteredSource(new KisPaintDevice(*rhs.filteredSource)),
+ filteredDeviceBounds(rhs.filteredDeviceBounds),
needAddCurrentKeyStroke(rhs.needAddCurrentKeyStroke),
showKeyStrokes(rhs.showKeyStrokes),
showColoring(rhs.showColoring),
@@ -84,7 +86,8 @@ struct KisColorizeMask::Private
prefilterRecalculationCompressor(1000, KisSignalCompressor::POSTPONE, _q),
offset(rhs.offset),
updateIsRunning(false),
- filteringOptions(rhs.filteringOptions)
+ filteringOptions(rhs.filteringOptions),
+ limitToDeviceBounds(rhs.limitToDeviceBounds)
{
Q_FOREACH (const KeyStroke &stroke, rhs.keyStrokes) {
keyStrokes << KeyStroke(KisPaintDeviceSP(new KisPaintDevice(*stroke.dev)), stroke.color, stroke.isTransparent);
@@ -97,6 +100,7 @@ struct KisColorizeMask::Private
KisPaintDeviceSP coloringProjection;
KisPaintDeviceSP fakePaintDevice;
KisPaintDeviceSP filteredSource;
+ QRect filteredDeviceBounds;
KoColor currentColor;
KisPaintDeviceSP currentKeyStrokeDevice;
@@ -122,6 +126,8 @@ struct KisColorizeMask::Private
FilteringOptions filteringOptions;
bool filteringDirty = true;
+ bool limitToDeviceBounds = false;
+
bool filteredSourceValid(KisPaintDeviceSP parentDevice) {
return !filteringDirty && originalSequenceNumber == parentDevice->sequenceNumber();
}
@@ -130,7 +136,6 @@ struct KisColorizeMask::Private
bool shouldShowFilteredSource() const;
bool shouldShowColoring() const;
-
};
KisColorizeMask::KisColorizeMask()
@@ -327,12 +332,26 @@ void KisColorizeMask::slotUpdateRegenerateFilling(bool prefilterOnly)
if (image) {
m_d->updateIsRunning = true;
+ QRect fillBounds;
+
+ if (m_d->limitToDeviceBounds) {
+ fillBounds |= src->exactBounds();
+ Q_FOREACH (const KeyStroke &stroke, m_d->keyStrokes) {
+ fillBounds |= stroke.dev->exactBounds();
+ }
+ fillBounds &= image->bounds();
+ } else {
+ fillBounds = image->bounds();
+ }
+
+ m_d->filteredDeviceBounds = fillBounds;
+
KisColorizeStrokeStrategy *strategy =
new KisColorizeStrokeStrategy(src,
m_d->coloringProjection,
m_d->filteredSource,
filteredSourceValid,
- image->bounds(),
+ fillBounds,
this,
prefilterOnly);
@@ -475,7 +494,6 @@ bool KisColorizeMask::Private::shouldShowColoring() const
coloringProjection;
}
-
QRect KisColorizeMask::decorateRect(KisPaintDeviceSP &src,
KisPaintDeviceSP &dst,
const QRect &rect,
@@ -498,8 +516,10 @@ QRect KisColorizeMask::decorateRect(KisPaintDeviceSP &src,
KisPainter gc(dst);
if (m_d->shouldShowFilteredSource()) {
+ const QRect drawRect = rect & m_d->filteredDeviceBounds;
+
gc.setOpacity(128);
- gc.bitBlt(rect.topLeft(), m_d->filteredSource, rect);
+ gc.bitBlt(drawRect.topLeft(), m_d->filteredSource, drawRect);
} else {
gc.setOpacity(255);
gc.bitBlt(rect.topLeft(), src, rect);
@@ -1011,6 +1031,17 @@ qreal KisColorizeMask::cleanUpAmount() const
return m_d->filteringOptions.cleanUpAmount;
}
+void KisColorizeMask::setLimitToDeviceBounds(bool value)
+{
+ m_d->limitToDeviceBounds = value;
+ m_d->filteringDirty = true;
+ setNeedsUpdate(true);
+}
+
+bool KisColorizeMask::limitToDeviceBounds() const
+{
+ return m_d->limitToDeviceBounds;
+}
void KisColorizeMask::rerenderFakePaintDevice()
{
diff --git a/libs/image/lazybrush/kis_colorize_mask.h b/libs/image/lazybrush/kis_colorize_mask.h
index 50fd0ca2ff8..c6382e2145c 100644
--- a/libs/image/lazybrush/kis_colorize_mask.h
+++ b/libs/image/lazybrush/kis_colorize_mask.h
@@ -114,6 +114,8 @@ public:
void setCleanUpAmount(qreal value);
qreal cleanUpAmount() const;
+ void setLimitToDeviceBounds(bool value);
+ bool limitToDeviceBounds() const;
void testingAddKeyStroke(KisPaintDeviceSP dev, const KoColor &color, bool isTransparent = false);
void testingRegenerateMask();
diff --git a/libs/image/lazybrush/kis_colorize_stroke_strategy.h b/libs/image/lazybrush/kis_colorize_stroke_strategy.h
index dbec3b8f322..b5176f3947a 100644
--- a/libs/image/lazybrush/kis_colorize_stroke_strategy.h
+++ b/libs/image/lazybrush/kis_colorize_stroke_strategy.h
@@ -41,7 +41,8 @@ public:
KisPaintDeviceSP dst,
KisPaintDeviceSP filteredSource,
bool filteredSourceValid,
- const QRect &boundingRect, KisNodeSP progressNode,
+ const QRect &boundingRect,
+ KisNodeSP progressNode,
bool prefilterOnly = false);
KisColorizeStrokeStrategy(const KisColorizeStrokeStrategy &rhs, int levelOfDetail);
~KisColorizeStrokeStrategy() override;
diff --git a/plugins/impex/libkra/kis_kra_loader.cpp b/plugins/impex/libkra/kis_kra_loader.cpp
index ae38512c0f1..ac8c5f61768 100644
--- a/plugins/impex/libkra/kis_kra_loader.cpp
+++ b/plugins/impex/libkra/kis_kra_loader.cpp
@@ -1039,11 +1039,13 @@ KisNodeSP KisKraLoader::loadColorizeMask(KisImageSP image, const KoXmlElement& e
const qreal edgeDetectionSize = KisDomUtils::toDouble(element.attribute(COLORIZE_EDGE_DETECTION_SIZE, "4"));
const qreal radius = KisDomUtils::toDouble(element.attribute(COLORIZE_FUZZY_RADIUS, "0"));
const int cleanUp = KisDomUtils::toInt(element.attribute(COLORIZE_CLEANUP, "0"));
+ const bool limitToDevice = KisDomUtils::toInt(element.attribute(COLORIZE_LIMIT_TO_DEVICE, "0"));
mask->setUseEdgeDetection(useEdgeDetection);
mask->setEdgeDetectionSize(edgeDetectionSize);
mask->setFuzzyRadius(radius);
mask->setCleanUpAmount(qreal(cleanUp) / 100.0);
+ mask->setLimitToDeviceBounds(limitToDevice);
delete mask->setColorSpace(colorSpace);
mask->setImage(image);
diff --git a/plugins/impex/libkra/kis_kra_savexml_visitor.cpp b/plugins/impex/libkra/kis_kra_savexml_visitor.cpp
index 33716777be9..81d7b6fea9d 100644
--- a/plugins/impex/libkra/kis_kra_savexml_visitor.cpp
+++ b/plugins/impex/libkra/kis_kra_savexml_visitor.cpp
@@ -424,6 +424,7 @@ void KisSaveXmlVisitor::saveMask(QDomElement & el, const QString & maskType, con
el.setAttribute(COLORIZE_EDGE_DETECTION_SIZE, KisDomUtils::toString(colorizeMask->edgeDetectionSize()));
el.setAttribute(COLORIZE_FUZZY_RADIUS, KisDomUtils::toString(colorizeMask->fuzzyRadius()));
el.setAttribute(COLORIZE_CLEANUP, int(100 * colorizeMask->cleanUpAmount()));
+ el.setAttribute(COLORIZE_LIMIT_TO_DEVICE, colorizeMask->limitToDeviceBounds());
}
}
diff --git a/plugins/impex/libkra/kis_kra_tags.h b/plugins/impex/libkra/kis_kra_tags.h
index 4dc80affdf4..249df5a7d08 100644
--- a/plugins/impex/libkra/kis_kra_tags.h
+++ b/plugins/impex/libkra/kis_kra_tags.h
@@ -104,6 +104,7 @@ const QString COLORIZE_USE_EDGE_DETECTION = "use-edge-detection";
const QString COLORIZE_EDGE_DETECTION_SIZE = "edge-detection-size";
const QString COLORIZE_FUZZY_RADIUS = "fuzzy-radius";
const QString COLORIZE_CLEANUP = "cleanup";
+const QString COLORIZE_LIMIT_TO_DEVICE = "limit-to-device";
const QString TRANSFORM_MASK = "transformmask";
const QString UUID = "uuid";
const QString VISIBLE = "visible";
diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp
index 6cc6d079e02..b7ca2afc932 100644
--- a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp
+++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.cpp
@@ -72,6 +72,7 @@ KisToolLazyBrushOptionsWidget::KisToolLazyBrushOptionsWidget(KisCanvasResourcePr
connect(m_d->ui->intEdgeDetectionSize, SIGNAL(valueChanged(int)), SLOT(slotEdgeDetectionSizeChanged(int)));
connect(m_d->ui->intRadius, SIGNAL(valueChanged(int)), SLOT(slotRadiusChanged(int)));
connect(m_d->ui->intCleanUp, SIGNAL(valueChanged(int)), SLOT(slotCleanUpChanged(int)));
+ connect(m_d->ui->chkLimitToDevice, SIGNAL(toggled(bool)), SLOT(slotLimitToDeviceChanged(bool)));
m_d->ui->intEdgeDetectionSize->setRange(0, 100);
m_d->ui->intEdgeDetectionSize->setExponentRatio(2.0);
@@ -226,7 +227,8 @@ void KisToolLazyBrushOptionsWidget::slotUpdateNodeProperties()
KisSignalsBlocker b2(m_d->ui->chkUseEdgeDetection,
m_d->ui->intEdgeDetectionSize,
m_d->ui->intRadius,
- m_d->ui->intCleanUp);
+ m_d->ui->intCleanUp,
+ m_d->ui->chkLimitToDevice);
// not implemented yet!
//m_d->ui->chkAutoUpdates->setEnabled(m_d->activeMask);
@@ -254,6 +256,9 @@ void KisToolLazyBrushOptionsWidget::slotUpdateNodeProperties()
m_d->ui->intRadius->setValue(2 * (m_d->activeMask ? m_d->activeMask->fuzzyRadius() : 15));
m_d->ui->intCleanUp->setEnabled(m_d->activeMask);
m_d->ui->intCleanUp->setValue(100 * (m_d->activeMask ? m_d->activeMask->cleanUpAmount() : 0.7));
+
+ m_d->ui->chkLimitToDevice->setEnabled(m_d->activeMask);
+ m_d->ui->chkLimitToDevice->setChecked(m_d->activeMask && m_d->activeMask->limitToDeviceBounds());
}
void KisToolLazyBrushOptionsWidget::slotCurrentNodeChanged(KisNodeSP node)
@@ -362,3 +367,9 @@ void KisToolLazyBrushOptionsWidget::slotCleanUpChanged(int value)
m_d->activeMask->setCleanUpAmount(qreal(value) / 100.0);
}
+void KisToolLazyBrushOptionsWidget::slotLimitToDeviceChanged(bool value)
+{
+ KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->activeMask);
+ m_d->activeMask->setLimitToDeviceBounds(value);
+}
+
diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.h b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.h
index e3b41631491..8512f6f5339 100644
--- a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.h
+++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.h
@@ -54,6 +54,7 @@ private Q_SLOTS:
void slotEdgeDetectionSizeChanged(int value);
void slotRadiusChanged(int value);
void slotCleanUpChanged(int value);
+ void slotLimitToDeviceChanged(bool value);
void slotUpdateNodeProperties();
diff --git a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.ui b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.ui
index d4841eef3e7..08bb910e5aa 100644
--- a/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.ui
+++ b/plugins/tools/tool_lazybrush/kis_tool_lazy_brush_options_widget.ui
@@ -43,6 +43,13 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="chkLimitToDevice">
+ <property name="text">
+ <string>Limit to layer bounds</string>
+ </property>
+ </widget>
+ </item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
More information about the kimageshop
mailing list