[PATCH 08/10] Improved the calculation and usage of the opacity rates for the smudge tool.

Silvio Heinrich plassy at web.de
Tue Jan 4 18:31:30 CET 2011


Also replaced the QSliders in the brush options with KisDoubleSliderSpinBoxes
---
 .../defaultpaintops/smudge/kis_smudgeop.cpp        |   31 +++++++++++-----
 .../libpaintop/kis_pressure_composite_option.cpp   |   19 +++++-----
 .../libpaintop/kis_pressure_composite_option.h     |    9 +++--
 .../kis_pressure_composite_option_widget.cpp       |   19 ++++++----
 .../kis_pressure_composite_option_widget.h         |    6 ++--
 .../libpaintop/kis_pressure_rate_option.cpp        |   36 +++++---------------
 .../paintops/libpaintop/kis_pressure_rate_option.h |   13 +++----
 .../libpaintop/kis_pressure_rate_option_widget.cpp |   22 ++++++-----
 .../libpaintop/kis_pressure_rate_option_widget.h   |    6 ++--
 libs/pigment/compositeops/KoCompositeOpCopyOpacy.h |    2 +
 10 files changed, 82 insertions(+), 81 deletions(-)

diff --git a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp
index e03121f..b5627e5 100644
--- a/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp
+++ b/krita/plugins/paintops/defaultpaintops/smudge/kis_smudgeop.cpp
@@ -62,8 +62,6 @@ KisSmudgeOp::~KisSmudgeOp()
 {
 }
 
-
-
 qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
 {
     // Simple error catching
@@ -103,20 +101,28 @@ qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
         brush->mask(maskDab, painter()->paintColor(), scale, scale, 0.0, info, 0.0, 0.0);
     }
     
-    // transforms the fixed paint device with the current brush to alpha color space (to use it as alpha/transparency mask)
+    // transforms the fixed paint device with the current brush to alpha color space
+    // to use it as an alpha/transparency mask
     maskDab->convertTo(KoColorSpaceRegistry::instance()->alpha8());
     
-    // GET the opacy calculated by the rate option (apply is misleading because the opacy will not be applied)
-    quint8 newOpacity = m_rateOption.apply(OPACITY_OPAQUE_U8, info);
+    // save the old opacity value and composite mode
+    quint8               oldOpacity = painter()->opacity();
+    const KoCompositeOp* oldMode    = painter()->compositeOp();
     
     if(!m_firstRun) {
+        // set opacity calculated by the rate option (but fit the rate inbetween the range 0.0 - 0.5)
+        m_rateOption.apply(painter(), info, 0.0, 0.5);
+        
         // set opacity calculated by the rate option
         // then blit the temporary painting device on the canvas at the current brush position
         // the alpha mask (maskDab) will be used here to only blit the pixels that are in the area (shape) of the brush
-        painter()->setOpacity(newOpacity);
         painter()->setCompositeOp(COMPOSITE_OVER);
         painter()->bitBltWithFixedSelection(x, y, m_tempDev, maskDab, maskDab->bounds().width(), maskDab->bounds().height());
-        painter()->setOpacity(newOpacity);
+        
+        // apply the opacity rate calculated by the rate option for smudging the alpha channel
+        // (this time we use the full range of the rate value)
+        m_rateOption.apply(painter(), info);
+        
         painter()->setCompositeOp(COMPOSITE_COPY_OPACITY);
         painter()->bitBltWithFixedSelection(x, y, m_tempDev, maskDab, maskDab->bounds().width(), maskDab->bounds().height());
     }
@@ -138,9 +144,9 @@ qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
     // if the user selected the color smudge option
     // we will mix some color into the temorary painting device (m_tempDev)
     if(m_compositeOption.isChecked()) {
-        // this will apply the composite mode and the opacy (selected by the user)
-        // to copyPainter
-        m_compositeOption.apply(&copyPainter, OPACITY_OPAQUE_U8, info);
+        // this will apply the opacy and the composite mode (selected by the user) to copyPainter
+        m_compositeOption.applyOpacityRate(&copyPainter, info, 0.0, 0.5);
+        m_compositeOption.applyCompositeOp(&copyPainter);
         
         // paint a rectangle with the current color (foreground color)
         // into the temporary painting device
@@ -150,5 +156,10 @@ qreal KisSmudgeOp::paintAt(const KisPaintInformation& info)
     }
     
     copyPainter.end();
+    
+    // restore orginal opacy and composite mode values
+    painter()->setOpacity(oldOpacity);
+    painter()->setCompositeOp(oldMode);
+    
     return spacing(scale);
 }
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp
index 6d82865..510768f 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.cpp
@@ -47,25 +47,26 @@ void KisPressureCompositeOption::readOptionSetting(const KisPropertiesConfigurat
 {
     KisCurveOption::readOptionSetting(setting);
     m_compositeOp = setting->getString("CompositeOp");
-    m_rate        = setting->getInt("CompositeRateValue");
+    m_rate        = setting->getDouble("CompositeRateValue");
     
     if(m_compositeOp == "") //TODO: test if compositeOp is valid instead of just testing for an empty string
         m_compositeOp = COMPOSITE_OVER;
 }
 
-void KisPressureCompositeOption::apply(KisPainter* painter, qint8 opacity, const KisPaintInformation& info) const
+
+void KisPressureCompositeOption::applyOpacityRate(KisPainter* painter, const KisPaintInformation& info, qreal scaleMin, qreal scaleMax) const
 {
     if(!isChecked())
         return;
     
-    QString oldCompositeOp = painter->compositeOp()->id();
-    
-    opacity = (m_rate * 255) / 100;
-    opacity = qBound((qint32)OPACITY_TRANSPARENT_U8,
-                     (qint32)(double(opacity) * computeValue(info) / PRESSURE_DEFAULT),
-                     (qint32)OPACITY_OPAQUE_U8);
+    qreal  rate    = scaleMin + (scaleMax - scaleMin) * m_rate; // scale m_rate into the range scaleMin - scaleMax
+    quint8 opacity = qBound(OPACITY_TRANSPARENT_U8, (quint8)(rate * computeValue(info) * 255.0), OPACITY_OPAQUE_U8);
     
-    painter->setCompositeOp(m_compositeOp);
     painter->setOpacity(opacity);
 }
 
+void KisPressureCompositeOption::applyCompositeOp(KisPainter* painter) const
+{
+    if(isChecked())
+        painter->setCompositeOp(m_compositeOp);
+}
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h
index 1ed6ff7..c30e8f4 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option.h
@@ -38,7 +38,8 @@ public:
      * Set the composite mode and opacity of the painter based on the user selection
      * and the pressure curve (if checked)
      */
-    void apply(KisPainter* painter, qint8 opacity, const KisPaintInformation& info) const;
+    void applyOpacityRate(KisPainter* painter, const KisPaintInformation& info, qreal scaleMin=0.0, qreal scaleMax=1.0) const;
+    void applyCompositeOp(KisPainter* painter) const;
 
     void writeOptionSetting(KisPropertiesConfiguration* setting) const;
     void readOptionSetting(const KisPropertiesConfiguration* setting);
@@ -46,12 +47,12 @@ public:
     void setCompositeOp(const QString& compositeOp) { m_compositeOp = compositeOp; }
     QString getCompositeOp() { return m_compositeOp; }
     
-    void setRate(int rate) { m_rate = rate; }
-    int getRate() { return m_rate; }
+    void setRate(qreal rate) { m_rate = qBound(0.0, rate, 1.0); }
+    qreal getRate() const { return m_rate; }
     
 private:
     QString m_compositeOp;
-    int     m_rate;
+    qreal   m_rate;
 };
 
 #endif // KIS_PRESSURE_COMPOSITE_OPTION_H
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp
index f075a3c..cfdc50f 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.cpp
@@ -20,6 +20,7 @@
 #include "kis_pressure_composite_option_widget.h"
 #include "kis_pressure_composite_option.h"
 
+#include <kis_slider_spin_box.h>
 #include <KoCompositeOp.h>
 
 #include <QWidget>
@@ -32,6 +33,8 @@
 
 #include <klocale.h>
 
+const static int MAX_SLIDER_VALUE = 1000;
+
 KisPressureCompositeOptionWidget::KisPressureCompositeOptionWidget()
     : KisCurveOptionWidget(new KisPressureCompositeOption())
 {
@@ -52,21 +55,21 @@ KisPressureCompositeOptionWidget::KisPressureCompositeOptionWidget()
     m_compositeOpBox->addItem(COMPOSITE_HARD_LIGHT);
     m_compositeOpBox->addItem(COMPOSITE_SOFT_LIGHT);
     
-    m_rateSlider = new QSlider();
-    m_rateSlider->setMinimum(0);
-    m_rateSlider->setMaximum(100);
-    m_rateSlider->setPageStep(1);
-    m_rateSlider->setValue(90);
-    m_rateSlider->setOrientation(Qt::Horizontal);
+    m_rateSlider = new KisDoubleSliderSpinBox();
+    m_rateSlider->setRange(0.0, 1.0, 2);
+    m_rateSlider->setValue(0.3);
+    m_rateSlider->setSingleStep(0.01);
+    m_rateSlider->setSuffix("%");
     
     connect(m_compositeOpBox, SIGNAL(activated(QString)), this, SLOT(compositeOpChanged(QString)));
-    connect(m_rateSlider, SIGNAL(valueChanged(int)), this, SLOT(rateChanged(int)));
+    connect(m_rateSlider, SIGNAL(valueChanged(qreal)), this, SLOT(rateChanged(qreal)));
     
     QGridLayout* gridLayout = new QGridLayout();
     gridLayout->addWidget(modeLabel, 0, 0);
     gridLayout->addWidget(m_compositeOpBox, 0, 1);
     gridLayout->addWidget(rateLabel, 1, 0);
     gridLayout->addWidget(m_rateSlider, 1, 1);
+    gridLayout->setColumnStretch(1, 1);
 
     QVBoxLayout* vBoxLayout = new QVBoxLayout;
     vBoxLayout->addLayout(gridLayout);
@@ -102,7 +105,7 @@ void KisPressureCompositeOptionWidget::compositeOpChanged(const QString& composi
     emit sigSettingChanged();
 }
 
-void KisPressureCompositeOptionWidget::rateChanged(int rate)
+void KisPressureCompositeOptionWidget::rateChanged(qreal rate)
 {
     static_cast<KisPressureCompositeOption*>(curveOption())->setRate(rate);
     emit sigSettingChanged();
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.h b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.h
index 30c09ce..5bc3073 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.h
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_composite_option_widget.h
@@ -23,7 +23,7 @@
 #include "kis_curve_option_widget.h"
 
 class QComboBox;
-class QSlider;
+class KisDoubleSliderSpinBox;
 
 class PAINTOP_EXPORT KisPressureCompositeOptionWidget : public KisCurveOptionWidget
 {
@@ -36,11 +36,11 @@ public:
     
 private slots:
      void compositeOpChanged(const QString& compositeOp);
-     void rateChanged(int rate);
+     void rateChanged(qreal rate);
     
 private:
     QComboBox* m_compositeOpBox;
-    QSlider*   m_rateSlider;
+    KisDoubleSliderSpinBox* m_rateSlider;
 };
 
 #endif // KIS_PRESSURE_COMPOSITE_OPTION_WIDGET_H
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_rate_option.cpp b/krita/plugins/paintops/libpaintop/kis_pressure_rate_option.cpp
index f2949d8..bd643d1 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_rate_option.cpp
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_rate_option.cpp
@@ -22,7 +22,7 @@
 
 #include <klocale.h>
 
-#include <kis_paint_device.h>
+#include <kis_painter.h>
 #include <widgets/kis_curve_widget.h>
 
 #include <KoColor.h>
@@ -33,44 +33,26 @@ KisPressureRateOption::KisPressureRateOption()
 {
 }
 
-void KisPressureRateOption::setRate(int rate)
-{
-    m_rate = rate;
-}
-
-int KisPressureRateOption::rate() const
-{
-    return m_rate;
-}
-
 void KisPressureRateOption::writeOptionSetting(KisPropertiesConfiguration* setting) const
 {
     KisCurveOption::writeOptionSetting(setting);
     setting->setProperty("RateValue", m_rate);
-    setting->setProperty("RateVersion", "2");
 }
 
 void KisPressureRateOption::readOptionSetting(const KisPropertiesConfiguration* setting)
 {
     KisCurveOption::readOptionSetting(setting);
-    if (setting->getString("RateVersion", "1") == "1") {
-        m_rate = setting->getInt("RatePressure");
-        setChecked(true);
-    } else {
-        m_rate = setting->getInt("RateValue");
-    }
+    m_rate = setting->getDouble("RateValue");
 }
 
-quint8 KisPressureRateOption::apply(quint8 opacity, const KisPaintInformation& info) const
+void KisPressureRateOption::apply(KisPainter* painter, const KisPaintInformation& info, qreal scaleMin, qreal scaleMax) const
 {
-    opacity = (m_rate * 255) / 100;
-
-    if (isChecked()) {
-        opacity = qBound((qint32)OPACITY_TRANSPARENT_U8,
-                         (qint32)(double(opacity) * computeValue(info) / PRESSURE_DEFAULT),
-                         (qint32)OPACITY_OPAQUE_U8);
-    }
+    if(!isChecked())
+        return;
+    
+    qreal  rate    = scaleMin + (scaleMax - scaleMin) * m_rate;
+    quint8 opacity = qBound(OPACITY_TRANSPARENT_U8, (quint8)(m_rate * computeValue(info) * 255.0), OPACITY_OPAQUE_U8);
 
-    return opacity;
+    painter->setOpacity(opacity);
 }
 
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_rate_option.h b/krita/plugins/paintops/libpaintop/kis_pressure_rate_option.h
index 4a7010e..c0d9d66 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_rate_option.h
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_rate_option.h
@@ -27,6 +27,7 @@
 
 class QSlider;
 class KisPropertiesConfiguration;
+class KisPainter;
 
 /**
  * The pressure opacity option defines a curve that is used to
@@ -39,21 +40,19 @@ public:
 
     /**
      * Set the opacity of the painter based on the rate
-     * and the curve (if checked) and return the old opacity
-     * of the painter.
+     * and the curve (if checked)
      */
-    quint8 apply(quint8 opacity, const KisPaintInformation& info) const;
+    void apply(KisPainter* painter, const KisPaintInformation& info, qreal scaleMin=0.0, qreal scaleMax=1.0) const;
 
     void writeOptionSetting(KisPropertiesConfiguration* setting) const;
 
     void readOptionSetting(const KisPropertiesConfiguration* setting);
 
-    void setRate(int rate);
-    
-    int rate() const;
+    void setRate(qreal rate) { m_rate = rate; }
+    qreal rate() const { return m_rate; }
     
 private:
-    int m_rate;
+    qreal m_rate;
 };
 
 #endif
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_rate_option_widget.cpp b/krita/plugins/paintops/libpaintop/kis_pressure_rate_option_widget.cpp
index c0e664c..b0841cd 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_rate_option_widget.cpp
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_rate_option_widget.cpp
@@ -19,6 +19,8 @@
  */
 
 #include "kis_pressure_rate_option_widget.h"
+#include "kis_pressure_rate_option.h"
+#include <kis_slider_spin_box.h>
 
 #include <QWidget>
 #include <QCheckBox>
@@ -29,23 +31,23 @@
 
 #include <klocale.h>
 
-#include "kis_pressure_rate_option.h"
-
 KisPressureRateOptionWidget::KisPressureRateOptionWidget()
     : KisCurveOptionWidget(new KisPressureRateOption())
 {
     QWidget* w = new QWidget;
     QLabel* rateLabel = new QLabel(i18n("Rate: "));
-    m_rateSlider = new QSlider();
-    m_rateSlider->setMinimum(0);
-    m_rateSlider->setMaximum(100);
-    m_rateSlider->setPageStep(1);
-    m_rateSlider->setValue(90);
-    m_rateSlider->setOrientation(Qt::Horizontal);
-    connect(m_rateSlider, SIGNAL(valueChanged(int)),SLOT(rateChanged(int)));
+    m_rateSlider = new KisDoubleSliderSpinBox();
+    m_rateSlider->setRange(0.0, 1.0, 2);
+    m_rateSlider->setSingleStep(0.01);
+    m_rateSlider->setValue(0.3);
+    m_rateSlider->setSuffix("%");
+    
+    connect(m_rateSlider, SIGNAL(valueChanged(qreal)),SLOT(rateChanged(qreal)));
+    
     QHBoxLayout* hl = new QHBoxLayout;
     hl->addWidget(rateLabel);
     hl->addWidget(m_rateSlider);
+    hl->setStretchFactor(m_rateSlider, 1);
 
     QVBoxLayout* vl = new QVBoxLayout;
     vl->addLayout(hl);
@@ -62,7 +64,7 @@ void KisPressureRateOptionWidget::readOptionSetting(const KisPropertiesConfigura
     m_rateSlider->setValue(static_cast<KisPressureRateOption*>(curveOption())->rate());
 }
 
-void KisPressureRateOptionWidget::rateChanged(int rate)
+void KisPressureRateOptionWidget::rateChanged(qreal rate)
 {
     static_cast<KisPressureRateOption*>(curveOption())->setRate(rate);
     emit sigSettingChanged();
diff --git a/krita/plugins/paintops/libpaintop/kis_pressure_rate_option_widget.h b/krita/plugins/paintops/libpaintop/kis_pressure_rate_option_widget.h
index 05c768e..e53250f 100644
--- a/krita/plugins/paintops/libpaintop/kis_pressure_rate_option_widget.h
+++ b/krita/plugins/paintops/libpaintop/kis_pressure_rate_option_widget.h
@@ -22,7 +22,7 @@
 
 #include "kis_curve_option_widget.h"
 
-class QSlider;
+class KisDoubleSliderSpinBox;
 
 class PAINTOP_EXPORT KisPressureRateOptionWidget : public KisCurveOptionWidget
 {
@@ -34,10 +34,10 @@ public:
     void readOptionSetting(const KisPropertiesConfiguration* setting);
     
 private slots:
-    void rateChanged(int rate);
+    void rateChanged(qreal rate);
     
 private:
-    QSlider* m_rateSlider;
+    KisDoubleSliderSpinBox* m_rateSlider;
 };
 
 #endif // KIS_PRESSURE_RATE_OPTION_WIDGET_H
diff --git a/libs/pigment/compositeops/KoCompositeOpCopyOpacy.h b/libs/pigment/compositeops/KoCompositeOpCopyOpacy.h
index 34224a0..2ffc3d5 100644
--- a/libs/pigment/compositeops/KoCompositeOpCopyOpacy.h
+++ b/libs/pigment/compositeops/KoCompositeOpCopyOpacy.h
@@ -56,6 +56,8 @@ public:
                    quint8 U8_opacity,
                    const QBitArray & channelFlags) const
     {
+        Q_UNUSED(channelFlags);
+        
         bool          useMask = maskRowStart != 0;
         channels_type opacity = KoColorSpaceMaths<quint8,channels_type>::scaleToA(U8_opacity);
         
-- 
1.7.1




More information about the kimageshop mailing list