Commit f838c4ae authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Draft implementation of auto-midpoint adjustment setting for rgba brushes

parent bdd517bf
......@@ -13,19 +13,68 @@ KisColorfulBrush::KisColorfulBrush(const QString &filename)
}
#include <KoColorSpaceMaths.h>
#include <KoColorSpaceTraits.h>
namespace {
qreal estimateImageAverage(const QImage &image) {
qint64 lightnessSum = 0;
qint64 alphaSum = 0;
for (int y = 0; y < image.height(); ++y) {
const QRgb *pixel = reinterpret_cast<const QRgb*>(image.scanLine(y));
for (int i = 0; i < image.width(); ++i) {
lightnessSum += qRound(qGray(*pixel) * qAlpha(*pixel) / 255.0);
alphaSum += qAlpha(*pixel);
pixel++;
}
}
return 255.0 * qreal(lightnessSum) / alphaSum;
}
}
qreal KisColorfulBrush::estimatedSourceMidPoint() const
{
return estimateImageAverage(KisBrush::brushTipImage());
}
qreal KisColorfulBrush::adjustedMidPoint() const
{
return estimateImageAverage(this->brushTipImage());
}
bool KisColorfulBrush::autoAdjustMidPoint() const
{
return m_autoAdjustMidPoint;
}
void KisColorfulBrush::setAutoAdjustMidPoint(bool autoAdjustMidPoint)
{
// TODO: fix in the imagepipe brush
m_autoAdjustMidPoint = autoAdjustMidPoint;
}
QImage KisColorfulBrush::brushTipImage() const
{
QImage image = KisBrush::brushTipImage();
if (isImageType() && brushApplication() != IMAGESTAMP) {
if (m_adjustmentMidPoint != 127 ||
const qreal adjustmentMidPoint =
m_autoAdjustMidPoint ?
estimateImageAverage(image) :
m_adjustmentMidPoint;
if (qAbs(adjustmentMidPoint - 127.0) > 0.1 ||
!qFuzzyIsNull(m_brightnessAdjustment) ||
!qFuzzyIsNull(m_contrastAdjustment)) {
const int half = KoColorSpaceMathsTraits<quint8>::halfValue;
const int unit = KoColorSpaceMathsTraits<quint8>::unitValue;
const qreal midX = m_adjustmentMidPoint;
const qreal midX = adjustmentMidPoint;
const qreal midY = m_brightnessAdjustment > 0 ?
KoColorSpaceMaths<qreal>::blend(unit, half, m_brightnessAdjustment) :
KoColorSpaceMaths<qreal>::blend(0, half, -m_brightnessAdjustment);
......@@ -129,6 +178,7 @@ void KisColorfulBrush::toXML(QDomDocument& d, QDomElement& e) const
e.setAttribute("AdjustmentMidPoint", QString::number(m_adjustmentMidPoint));
e.setAttribute("BrightnessAdjustment", QString::number(m_brightnessAdjustment));
e.setAttribute("ContrastAdjustment", QString::number(m_contrastAdjustment));
e.setAttribute("AutoAdjustMidPoint", QString::number(m_autoAdjustMidPoint));
KisBrush::toXML(d, e);
}
......
......@@ -34,7 +34,14 @@ public:
void setHasColorAndTransparency(bool value);
bool hasColorAndTransparency() const;
qreal estimatedSourceMidPoint() const;
qreal adjustedMidPoint() const;
bool autoAdjustMidPoint() const;
virtual void setAutoAdjustMidPoint(bool autoAdjustMidPoint);
private:
bool m_autoAdjustMidPoint = false;
quint8 m_adjustmentMidPoint = 127;
qreal m_brightnessAdjustment = 0.0;
qreal m_contrastAdjustment = 0.0;
......
......@@ -675,7 +675,7 @@ KisFixedPaintDeviceSP KisBrush::paintDevice(const KoColorSpace * colorSpace,
QImage outputImage = d->brushPyramid->pyramid(this)->createImage(
KisDabShape(scale, shape.ratio(), -angle), subPixelX, subPixelY);
if (normalizeBrush) {
if (0 && normalizeBrush) {
normalalizeRGBADab(outputImage);
}
......
......@@ -176,6 +176,12 @@ public:
}
}
void setAutoAdjustMidPoint(bool value) {
Q_FOREACH (KisGbrBrushSP brush, m_brushes) {
brush->setAutoAdjustMidPoint(value);
}
}
void makeMaskImage(bool preserveAlpha) {
Q_FOREACH (KisGbrBrushSP brush, m_brushes) {
brush->makeMaskImage(preserveAlpha);
......@@ -431,6 +437,12 @@ void KisImagePipeBrush::setContrastAdjustment(qreal value)
d->brushesPipe.setContrastAdjustment(value);
}
void KisImagePipeBrush::setAutoAdjustMidPoint(bool value)
{
KisGbrBrush::setAutoAdjustMidPoint(value);
d->brushesPipe.setAutoAdjustMidPoint(value);
}
const KisBoundary* KisImagePipeBrush::boundary() const
{
KisGbrBrushSP brush = d->brushesPipe.firstBrush();
......
......@@ -72,6 +72,7 @@ public:
void setAdjustmentMidPoint(quint8 value) override;
void setBrightnessAdjustment(qreal value) override;
void setContrastAdjustment(qreal value) override;
void setAutoAdjustMidPoint(bool value) override;
QString parasiteSelection(); // returns random, constant, etc
......
......@@ -68,6 +68,7 @@ KisBrushSP KisPredefinedBrushFactory::createBrush(const QDomElement& brushDefini
colorfulBrush->setAdjustmentMidPoint(brushDefinition.attribute("AdjustmentMidPoint", "127").toInt());
colorfulBrush->setBrightnessAdjustment(brushDefinition.attribute("BrightnessAdjustment").toDouble());
colorfulBrush->setContrastAdjustment(brushDefinition.attribute("ContrastAdjustment").toDouble());
colorfulBrush->setAutoAdjustMidPoint(brushDefinition.attribute("AutoAdjustMidPoint").toInt());
}
auto legacyBrushApplication = [] (KisColorfulBrush *colorfulBrush, bool forceColorToAlpha) {
......
......@@ -225,12 +225,12 @@
<property name="title">
<string>Brush mode</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QComboBox" name="cmbBrushMode"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
......@@ -248,9 +248,20 @@
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="KisSliderSpinBox" name="intAdjustmentMidPoint" native="true"/>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,1">
<item>
<widget class="QCheckBox" name="chkAutoMidPoint">
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
<item>
<widget class="KisSliderSpinBox" name="intAdjustmentMidPoint" native="true"/>
</item>
</layout>
</item>
<item>
<widget class="KisSliderSpinBox" name="intBrightnessAdjustment" native="true"/>
......
......@@ -190,14 +190,17 @@ KisPredefinedBrushChooser::KisPredefinedBrushChooser(QWidget *parent, const char
connect(cmbBrushMode, SIGNAL(currentIndexChanged(int)), SLOT(slotUpdateBrushAdjustmentsState()));
connect(cmbBrushMode, SIGNAL(currentIndexChanged(int)), SLOT(slotWriteBrushMode()));
connect(cmbBrushMode, SIGNAL(currentIndexChanged(int)), SLOT(slotUpdateResetBrushAdjustmentsButtonState()));
connect(chkAutoMidPoint, SIGNAL(toggled(bool)), SLOT(slotUpdateBrushAdjustmentsState()));
connect(intAdjustmentMidPoint, SIGNAL(valueChanged(int)), SLOT(slotWriteBrushAdjustments()));
connect(intBrightnessAdjustment, SIGNAL(valueChanged(int)), SLOT(slotWriteBrushAdjustments()));
connect(intContrastAdjustment, SIGNAL(valueChanged(int)), SLOT(slotWriteBrushAdjustments()));
connect(chkAutoMidPoint, SIGNAL(toggled(bool)), SLOT(slotWriteBrushAdjustments()));
connect(intAdjustmentMidPoint, SIGNAL(valueChanged(int)), SLOT(slotUpdateResetBrushAdjustmentsButtonState()));
connect(intBrightnessAdjustment, SIGNAL(valueChanged(int)), SLOT(slotUpdateResetBrushAdjustmentsButtonState()));
connect(intContrastAdjustment, SIGNAL(valueChanged(int)), SLOT(slotUpdateResetBrushAdjustmentsButtonState()));
connect(chkAutoMidPoint, SIGNAL(toggled(bool)), SLOT(slotUpdateResetBrushAdjustmentsButtonState()));
updateBrushTip(m_itemChooser->currentResource());
}
......@@ -413,6 +416,7 @@ void KisPredefinedBrushChooser::slotUpdateBrushModeButtonsState()
intAdjustmentMidPoint->setValue(colorfulBrush->adjustmentMidPoint());
intBrightnessAdjustment->setValue(qRound(colorfulBrush->brightnessAdjustment() * 100.0));
intContrastAdjustment->setValue(qRound(colorfulBrush->contrastAdjustment() * 100.0));
chkAutoMidPoint->setChecked(colorfulBrush->autoAdjustMidPoint());
}
intAdjustmentMidPoint->setToolTip(i18nc("@info:tooltip", "Luminosity value of the brush that will not change the painting color. All brush pixels darker than neutral point will paint with darker color, pixels lighter than neutral point — lighter."));
......@@ -432,6 +436,7 @@ void KisPredefinedBrushChooser::slotUpdateBrushModeButtonsState()
intAdjustmentMidPoint->setToolTip("");
intBrightnessAdjustment->setToolTip("");
intContrastAdjustment->setToolTip("");
chkAutoMidPoint->setToolTip("");
if (m_hslBrushTipEnabled) {
grpBrushMode->setToolTip(i18nc("@info:tooltip", "The selected brush tip does not have color channels. The brush will work in \"Mask\" mode."));
}
......@@ -451,9 +456,10 @@ void KisPredefinedBrushChooser::slotUpdateBrushAdjustmentsState()
{
const bool adjustmentsEnabled = (cmbBrushMode->currentIndex() == LIGHTNESSMAP) ||
(cmbBrushMode->currentIndex() == GRADIENTMAP);
intAdjustmentMidPoint->setEnabled(adjustmentsEnabled);
intAdjustmentMidPoint->setEnabled(adjustmentsEnabled && !chkAutoMidPoint->isChecked());
intBrightnessAdjustment->setEnabled(adjustmentsEnabled);
intContrastAdjustment->setEnabled(adjustmentsEnabled);
chkAutoMidPoint->setEnabled(adjustmentsEnabled);
}
void KisPredefinedBrushChooser::slotUpdateResetBrushAdjustmentsButtonState()
......@@ -464,9 +470,18 @@ void KisPredefinedBrushChooser::slotUpdateResetBrushAdjustmentsButtonState()
const bool adjustmentsDefault =
intAdjustmentMidPoint->value() == 127 &&
intBrightnessAdjustment->value() == 0 &&
intContrastAdjustment->value() == 0;
intContrastAdjustment->value() == 0 &&
chkAutoMidPoint->isCheckable() == m_autoMidpointAdjustmentIsDefault;
btnResetAdjustments->setEnabled(!adjustmentsDefault && adjustmentsEnabled);
KisColorfulBrush *colorfulBrush = dynamic_cast<KisColorfulBrush*>(m_brush.data());
if (colorfulBrush && adjustmentsEnabled) {
chkAutoMidPoint->setToolTip(i18nc("@info:tooltip", "Brush average: %1\nAdjusted average: %2", colorfulBrush->estimatedSourceMidPoint(), colorfulBrush->adjustedMidPoint()));
} else {
chkAutoMidPoint->setToolTip("");
}
}
void KisPredefinedBrushChooser::slotWriteBrushMode()
......@@ -490,6 +505,7 @@ void KisPredefinedBrushChooser::slotWriteBrushAdjustments()
colorfulBrush->setAdjustmentMidPoint(quint8(intAdjustmentMidPoint->value()));
colorfulBrush->setBrightnessAdjustment(intBrightnessAdjustment->value() / 100.0);
colorfulBrush->setContrastAdjustment(intContrastAdjustment->value() / 100.0);
colorfulBrush->setAutoAdjustMidPoint(chkAutoMidPoint->isChecked());
}
emit sigBrushChanged();
......@@ -500,6 +516,7 @@ void KisPredefinedBrushChooser::slotResetAdjustments()
intAdjustmentMidPoint->setValue(127);
intBrightnessAdjustment->setValue(0);
intContrastAdjustment->setValue(0);
chkAutoMidPoint->setChecked(m_autoMidpointAdjustmentIsDefault);
slotWriteBrushAdjustments();
}
......
......@@ -80,6 +80,7 @@ private:
KisClipboardBrushWidget* m_clipboardBrushWidget;
bool m_hslBrushTipEnabled = false;
bool m_autoMidpointAdjustmentIsDefault = false;
};
#endif // KIS_PREDEFINED_BRUSH_CHOOSER_H_
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment