Commit 823e207d authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Implement "Hard Mix (Photoshop)" composite op

Hard Max (Photoshop) is supposed to set the channel either
to 0.0 or 1.0, not blend it in a smooth way, like our version does.
parent dde3d2f3
......@@ -83,6 +83,7 @@ KoCompositeOpRegistry::KoCompositeOpRegistry()
m_map.insert(m_categories[4], KoID(COMPOSITE_ERASE , i18n("Erase")));
m_map.insert(m_categories[4], KoID(COMPOSITE_ALPHA_DARKEN , i18n("Alpha Darken")));
m_map.insert(m_categories[4], KoID(COMPOSITE_HARD_MIX , i18n("Hard Mix")));
m_map.insert(m_categories[4], KoID(COMPOSITE_HARD_MIX_PHOTOSHOP, i18n("Hard Mix (Photoshop)")));
m_map.insert(m_categories[4], KoID(COMPOSITE_GRAIN_MERGE , i18n("Grain Merge")));
m_map.insert(m_categories[4], KoID(COMPOSITE_GRAIN_EXTRACT , i18n("Grain Extract")));
m_map.insert(m_categories[4], KoID(COMPOSITE_PARALLEL , i18n("Parallel")));
......
......@@ -61,6 +61,7 @@ const QString COMPOSITE_GRAIN_MERGE = "grain_merge";
const QString COMPOSITE_GRAIN_EXTRACT = "grain_extract";
const QString COMPOSITE_EXCLUSION = "exclusion";
const QString COMPOSITE_HARD_MIX = "hard mix";
const QString COMPOSITE_HARD_MIX_PHOTOSHOP = "hard_mix_photoshop";
const QString COMPOSITE_OVERLAY = "overlay";
const QString COMPOSITE_BEHIND = "behind";
const QString COMPOSITE_GREATER = "greater";
......
......@@ -378,6 +378,16 @@ inline T cfHardMix(T src, T dst) {
return (dst > Arithmetic::halfValue<T>()) ? cfColorDodge(src,dst) : cfColorBurn(src,dst);
}
template<class T>
inline T cfHardMixPhotoshop(T src, T dst) {
using namespace Arithmetic;
typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
const composite_type sum = composite_type(src) + dst;
return sum > unitValue<T>() ? unitValue<T>() : zeroValue<T>();
}
template<class T>
inline T cfAdditiveSubtractive(T src, T dst) {
using namespace Arithmetic;
......
......@@ -119,6 +119,7 @@ struct AddGeneralOps<Traits, true>
add<&cfGrainMerge<Arg> >(cs, COMPOSITE_GRAIN_MERGE , i18n("Grain Merge") , KoCompositeOp::categoryMix());
add<&cfGrainExtract<Arg> >(cs, COMPOSITE_GRAIN_EXTRACT , i18n("Grain Extract") , KoCompositeOp::categoryMix());
add<&cfHardMix<Arg> >(cs, COMPOSITE_HARD_MIX , i18n("Hard Mix") , KoCompositeOp::categoryMix());
add<&cfHardMixPhotoshop<Arg>>(cs, COMPOSITE_HARD_MIX_PHOTOSHOP, i18n("Hard Mix (Photoshop)") , KoCompositeOp::categoryMix());
add<&cfGeometricMean<Arg> >(cs, COMPOSITE_GEOMETRIC_MEAN, i18n("Geometric Mean"), KoCompositeOp::categoryMix());
add<&cfParallel<Arg> >(cs, COMPOSITE_PARALLEL , i18n("Parallel") , KoCompositeOp::categoryMix());
add<&cfAllanon<Arg> >(cs, COMPOSITE_ALLANON , i18n("Allanon") , KoCompositeOp::categoryMix());
......
......@@ -111,7 +111,7 @@ QString psd_blendmode_to_composite_op(const QString& blendmode)
// 'pLit' = pin light
if (blendmode == "pLit") return COMPOSITE_PIN_LIGHT;
// 'hMix' = hard mix
if (blendmode == "hMix") return COMPOSITE_HARD_MIX;
if (blendmode == "hMix") return COMPOSITE_HARD_MIX_PHOTOSHOP;
// 'diff' = difference
if (blendmode == "diff") return COMPOSITE_DIFF;
// 'smud' = exclusion
......@@ -175,7 +175,7 @@ QString composite_op_to_psd_blendmode(const QString& compositeop)
// 'pLit' = pin light
if (compositeop == COMPOSITE_PIN_LIGHT) return "pLit";
// 'hMix' = hard mix
if (compositeop == COMPOSITE_HARD_MIX) return "hMix";
if (compositeop == COMPOSITE_HARD_MIX_PHOTOSHOP) return "hMix";
// 'diff' = difference
if (compositeop == COMPOSITE_DIFF) return "diff";
// 'smud' = exclusion
......
......@@ -100,7 +100,7 @@ QString compositeOpToBlendMode(const QString &compositeOp)
mode = "linearLight";
} else if (compositeOp == COMPOSITE_PIN_LIGHT) {
mode = "pinLight";
} else if (compositeOp == COMPOSITE_HARD_MIX) {
} else if (compositeOp == COMPOSITE_HARD_MIX_PHOTOSHOP) {
mode = "hardMix";
} else if (compositeOp == COMPOSITE_DIFF) {
mode = "Dfrn";
......@@ -766,7 +766,7 @@ void convertAndSetBlendMode(const QString &mode,
} else if (mode == "pinLight") {
compositeOp = COMPOSITE_PIN_LIGHT;
} else if (mode == "hardMix") {
compositeOp = COMPOSITE_HARD_MIX;
compositeOp = COMPOSITE_HARD_MIX_PHOTOSHOP;
} else if (mode == "Dfrn") {
compositeOp = COMPOSITE_DIFF;
} else if (mode == "Xclu") {
......
......@@ -93,7 +93,8 @@ KisMaskingBrushCompositeOpBase *createTypedOp(const QString &id, int pixelSize,
} else if (id == COMPOSITE_LINEAR_DODGE) {
result = new KisMaskingBrushCompositeOp<channel_type, maskingAddition>(pixelSize, alphaOffset);
} else if (id == COMPOSITE_HARD_MIX) {
result = new KisMaskingBrushCompositeOp<channel_type, cfHardMix>(pixelSize, alphaOffset);
// NOTE: we call it "Hard Mix", but it is actually "Hard Mix (Photoshop)"
result = new KisMaskingBrushCompositeOp<channel_type, cfHardMixPhotoshop>(pixelSize, alphaOffset);
}
KIS_SAFE_ASSERT_RECOVER (result && "Unknown composite op for masking brush!") {
......@@ -156,6 +157,9 @@ QStringList KisMaskingBrushCompositeOpFactory::supportedCompositeOpIds()
ids << COMPOSITE_BURN;
ids << COMPOSITE_LINEAR_BURN;
ids << COMPOSITE_LINEAR_DODGE;
// NOTE: we call it "Hard Mix", but it is actually "Hard Mix (Photoshop)"
ids << COMPOSITE_HARD_MIX;
return ids;
}
......@@ -447,7 +447,7 @@ void KisCompositeOpComboBox::slotPinLight()
void KisCompositeOpComboBox::slotHardMix()
{
selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_HARD_MIX));
selectCompositeOp(KoCompositeOpRegistry::instance().getKoID(COMPOSITE_HARD_MIX_PHOTOSHOP));
}
void KisCompositeOpComboBox::slotDifference()
......
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