[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(©Painter, OPACITY_OPAQUE_U8, info);
+ // this will apply the opacy and the composite mode (selected by the user) to copyPainter
+ m_compositeOption.applyOpacityRate(©Painter, info, 0.0, 0.5);
+ m_compositeOption.applyCompositeOp(©Painter);
// 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