[krita/kazakov/lazy-brush-remastered] /: Implement "Limit to layer bounds" feature of the Colorize Mask

Boudewijn Rempt boud at valdyas.org
Thu Dec 14 12:23:32 UTC 2017


I just tested it, and it seems to work fine. I guess it's too much
code for a review request? If so, let's just merge it to master.

On Mon, 11 Dec 2017, Dmitry Kazakov wrote:

> 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">
> 

-- 
Boudewijn Rempt | http://www.krita.org, http://www.valdyas.org


More information about the kimageshop mailing list