[PATCH 09/15] Added even more composite modes.
Silvio Heinrich
plassy at web.de
Sun Jan 9 17:57:18 CET 2011
Including HSL composite modes (Color, Saturation, Luminosity, Hue).
The HSL CompositeOps will only be added to RGB color spaces.
---
libs/pigment/KoCompositeOp.h | 5 +-
libs/pigment/compositeops/KoCompositeOpFunctions.h | 214 +++++++++++++++++++-
libs/pigment/compositeops/KoCompositeOpGeneric.h | 2 +-
libs/pigment/compositeops/KoCompositeOps.h | 135 ++++++++++---
4 files changed, 316 insertions(+), 40 deletions(-)
diff --git a/libs/pigment/KoCompositeOp.h b/libs/pigment/KoCompositeOp.h
index 6f84313..920fe3e 100644
--- a/libs/pigment/KoCompositeOp.h
+++ b/libs/pigment/KoCompositeOp.h
@@ -43,11 +43,14 @@ const QString COMPOSITE_DIFF = "diff";
const QString COMPOSITE_MULT = "multiply";
const QString COMPOSITE_DIVIDE = "divide";
const QString COMPOSITE_ARC_TANGENT = "arc_tangent";
+const QString COMPOSITE_EQUIVALENCE = "equivalence";
const QString COMPOSITE_GEOMETRIC_MEAN = "geometric_mean";
const QString COMPOSITE_DODGE = "dodge";
const QString COMPOSITE_LINEAR_DODGE = "linear_dodge";
const QString COMPOSITE_BURN = "burn";
const QString COMPOSITE_LINEAR_BURN = "linear_burn";
+const QString COMPOSITE_ALLANON = "allanon";
+const QString COMPOSITE_PARALLEL = "parallel";
const QString COMPOSITE_BUMPMAP = "bumpmap";
const QString COMPOSITE_CLEAR = "clear";
const QString COMPOSITE_DISSOLVE = "dissolve";
@@ -74,7 +77,7 @@ const QString COMPOSITE_GAMMA_DARK = "gamma_dark";
const QString COMPOSITE_EXCLUSION = "exclusion";
const QString COMPOSITE_INVERTED_DIVIDE = "inverted_divide"; // XXX: not implemented anywhere yet
const QString COMPOSITE_VIVID_LIGHT = "vivid_light";
-const QString COMPOSITE_LINEAR_LIGHT = "linear light"; // XXX: not implemented anywhere yet
+const QString COMPOSITE_LINEAR_LIGHT = "linear light";
const QString COMPOSITE_PIN_LIGHT = "pin_light";
const QString COMPOSITE_HARD_MIX = "hard mix"; // XXX: not implemented anywhere yet
const QString COMPOSITE_PASS_THROUGH = "pass through"; // XXX: not implemented anywhere yet
diff --git a/libs/pigment/compositeops/KoCompositeOpFunctions.h b/libs/pigment/compositeops/KoCompositeOpFunctions.h
index 25e5112..417df68 100644
--- a/libs/pigment/compositeops/KoCompositeOpFunctions.h
+++ b/libs/pigment/compositeops/KoCompositeOpFunctions.h
@@ -76,6 +76,18 @@ inline T clamp(typename KoColorSpaceMathsTraits<T>::compositetype a) {
return qBound<composite_type>(KoColorSpaceMathsTraits<T>::zeroValue, a, KoColorSpaceMathsTraits<T>::unitValue);
}
+template<class T>
+inline T min(T a, T b, T c) {
+ b = (a < b) ? a : b;
+ return (b < c) ? b : c;
+}
+
+template<class T>
+inline T max(T a, T b, T c) {
+ b = (a > b) ? a : b;
+ return (b > c) ? b : c;
+}
+
/* ------------------------ Auxiliary Functions --------------------------- /
* definitions of auxiliary functions needed by the blending functions
* or the KoCompositeOp* classes to calculate the pixel colors
@@ -87,17 +99,121 @@ inline T unionShapeOpacy(T a, T b) {
return T(composite_type(a) + b - mul(a,b));
}
-template<class T, T blendFunc(T,T)>
-inline T blend(T src, T srcAlpha, T dst, T dstAlpha) {
- return mul(inv(srcAlpha), dstAlpha, dst) + mul(inv(dstAlpha), srcAlpha, src) + mul(dstAlpha, srcAlpha, blendFunc(src, dst));
+template<class T>
+inline T blend(T src, T srcAlpha, T dst, T dstAlpha, T cfValue) {
+ return mul(inv(srcAlpha), dstAlpha, dst) + mul(inv(dstAlpha), srcAlpha, src) + mul(dstAlpha, srcAlpha, cfValue);
+}
+
+template<class TReal>
+inline TReal getLuminosity(TReal r, TReal g, TReal b) {
+ return TReal(0.3)*r + TReal(0.59)*g + TReal(0.11)*b;
+}
+
+template<class TReal>
+inline void setLuminosity(TReal& r, TReal& g, TReal& b, TReal lum) {
+
+ TReal d = lum - getLuminosity(r, g, b);
+
+ r += d;
+ g += d;
+ b += d;
+
+ TReal l = getLuminosity(r, g, b);
+ TReal n = min(r, g, b);
+ TReal x = max(r, g, b);
+
+ if(n < TReal(0.0)) {
+ r = l + ((r-l) * l) / (l-n);
+ g = l + ((g-l) * l) / (l-n);
+ b = l + ((b-l) * l) / (l-n);
+ }
+
+ if(x > TReal(1.0)) {
+ r = l + ((r-l) * (TReal(1.0)-l)) / (x-l);
+ g = l + ((g-l) * (TReal(1.0)-l)) / (x-l);
+ b = l + ((b-l) * (TReal(1.0)-l)) / (x-l);
+ }
+}
+
+template<class TReal>
+inline TReal getSaturation(TReal r, TReal g, TReal b) {
+ return max(r,g,b) - min(r,g,b);
+}
+
+template<class TReal>
+inline void setSaturation(TReal& r, TReal& g, TReal& b, TReal sat) {
+ TReal& min = r;
+ TReal& mid = g;
+ TReal& max = b;
+
+ if(mid < min) {
+ TReal& tmp = min;
+ min = mid;
+ mid = tmp;
+ }
+
+ if(max < mid) {
+ TReal& tmp = mid;
+ mid = max;
+ max = tmp;
+ }
+
+ if(mid < min) {
+ TReal& tmp = min;
+ min = mid;
+ mid = tmp;
+ }
+
+ if(max > min) {
+ mid = ((mid-min) * sat) / (max-min);
+ max = sat;
+ } else {
+ mid = TReal(0.0);
+ max = TReal(0.0);
+ }
+
+ min = TReal(0.0);
}
/* ---------------- Blending/Compositing functions ------------------------ /
* definitions of standard blending/compositing functions compatible
- * to the ISO 32000-1 specification (for PDF filed) which also defines
+ * to the ISO 32000-1 specification (for PDF files) which also defines
* the compositing functions who are also used in Adobe Photoshop (c)
*/
+template<class TReal>
+inline void cfColor(TReal sr, TReal sg, TReal sb, TReal& dr, TReal& dg, TReal& db) {
+ TReal lum = getLuminosity(dr, dg, db);
+ dr = sr;
+ dg = sg;
+ db = sb;
+ setLuminosity(dr, dg, db, lum);
+}
+
+template<class TReal>
+inline void cfLuminosity(TReal sr, TReal sg, TReal sb, TReal& dr, TReal& dg, TReal& db) {
+ setLuminosity(dr, dg, db, getLuminosity(sr, sg, sb));
+}
+
+template<class TReal>
+inline void cfSaturation(TReal sr, TReal sg, TReal sb, TReal& dr, TReal& dg, TReal& db) {
+ TReal sat = getSaturation(sr, sg, sb);
+ TReal lum = getLuminosity(dr, dg, db);
+ setSaturation(dr, dg, db, sat);
+ setLuminosity(dr, dg, db, lum);
+}
+
+template<class TReal>
+inline void cfHue(TReal sr, TReal sg, TReal sb, TReal& dr, TReal& dg, TReal& db) {
+ TReal sat = getSaturation(dr, dg, db);
+ TReal lum = getLuminosity(dr, dg, db);
+ dr = sr;
+ dg = sg;
+ db = sb;
+ setSaturation(dr, dg, db, sat);
+ setLuminosity(dr, dg, db, lum);
+}
+
template<class T>
inline T cfColorBurn(T src, T dst) {
if(src != KoColorSpaceMathsTraits<T>::zeroValue)
@@ -178,8 +294,10 @@ inline T cfVividLight(T src, T dst) {
typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
if(src < KoColorSpaceMathsTraits<T>::halfValue) {
+
if(src == KoColorSpaceMathsTraits<T>::zeroValue)
- return KoColorSpaceMathsTraits<T>::zeroValue; //TODO: maybe better to return unitValue, must be verified
+ return (dst == KoColorSpaceMathsTraits<T>::unitValue) ?
+ KoColorSpaceMathsTraits<T>::unitValue : KoColorSpaceMathsTraits<T>::zeroValue;
// min(1,max(0,1-(1-dst) / (2*src)))
composite_type src2 = composite_type(src) + src;
@@ -188,7 +306,8 @@ inline T cfVividLight(T src, T dst) {
}
if(src == KoColorSpaceMathsTraits<T>::unitValue)
- return KoColorSpaceMathsTraits<T>::unitValue; //TODO: maybe better to return zeroValue, must be verified
+ return (dst == KoColorSpaceMathsTraits<T>::zeroValue) ?
+ KoColorSpaceMathsTraits<T>::zeroValue : KoColorSpaceMathsTraits<T>::unitValue;
// min(1,max(0, dst / (2*(1-src)))
composite_type srci2 = inv(src);
@@ -199,7 +318,7 @@ inline T cfVividLight(T src, T dst) {
template<class T>
inline T cfPinLight(T src, T dst) {
typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
- // TODO: verify that the formular is correct (the first max would be useless here)
+ // TODO: verify that the formula is correct (the first max would be useless here)
// max(0, max(2*src-1, min(dst, 2*src)))
composite_type src2 = composite_type(src) + src;
composite_type a = qMin<composite_type>(dst, src2);
@@ -219,6 +338,40 @@ inline T cfArcTangent(T src, T dst) {
}
template<class T>
+inline T cfAllanon(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ // (dst + src) / 2 [or (dst + src) * 0.5]
+ return T((composite_type(src) + dst) * KoColorSpaceMathsTraits<T>::halfValue / KoColorSpaceMathsTraits<T>::unitValue);
+}
+
+template<class T>
+inline T cfLinearLight(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ // min(1,max(0,(dst + 2*src)-1))
+ return clamp<T>((composite_type(src) + src + dst) - KoColorSpaceMathsTraits<T>::unitValue);
+}
+
+template<class T>
+inline T cfParallel(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+
+ // min(max(2 / (1/dst + 1/src), 0), 1)
+ composite_type unit = KoColorSpaceMathsTraits<T>::unitValue;
+ composite_type s = (src != KoColorSpaceMathsTraits<T>::zeroValue) ? div<T>(unit, src) : unit;
+ composite_type d = (dst != KoColorSpaceMathsTraits<T>::zeroValue) ? div<T>(unit, dst) : unit;
+
+ return clamp<T>((unit+unit) * KoColorSpaceMathsTraits<T>::unitValue / (d+s));
+}
+
+template<class T>
+inline T cfEquivalence(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ // 1 - abs(dst - src)
+ composite_type x = composite_type(dst) - src;
+ return (x < KoColorSpaceMathsTraits<T>::zeroValue) ? T(-x) : T(x);
+}
+
+template<class T>
inline T cfGammaDark(T src, T dst) {
if(src == KoColorSpaceMathsTraits<T>::zeroValue)
return KoColorSpaceMathsTraits<T>::zeroValue;
@@ -350,4 +503,51 @@ public:
}
};
+
+
+
+
+template<class Traits, void compositeFunc(float, float, float, float&, float&, float&)>
+class KoCompositeOpGenericLum : public KoCompositeOpBase< Traits, KoCompositeOpGenericLum<Traits,compositeFunc> >
+{
+ typedef KoCompositeOpBase< Traits, KoCompositeOpGenericLum<Traits,compositeFunc> > base_class;
+ typedef typename Traits::channels_type channels_type;
+
+ static const qint32 red_pos = Traits::red_pos;
+ static const qint32 green_pos = Traits::green_pos;
+ static const qint32 blue_pos = Traits::blue_pos;
+
+public:
+ KoCompositeOpGenericLum(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true)
+ : base_class(cs, id, description, category, userVisible) { }
+
+public:
+ template<bool alphaLocked, bool allChannelFlags>
+ inline static channels_type composeColorChannels(const channels_type* src, channels_type srcAlpha,
+ channels_type* dst, channels_type dstAlpha,
+ channels_type opacity, const QBitArray& channelFlags) {
+ Q_UNUSED(channelFlags);
+
+ srcAlpha = mul(srcAlpha, opacity);
+ channels_type newDstAlpha = unionShapeOpacy(srcAlpha, dstAlpha);
+
+ if(newDstAlpha != KoColorSpaceMathsTraits<channels_type>::zeroValue) {
+ float srcR = scale<float>(src[red_pos]);
+ float srcG = scale<float>(src[green_pos]);
+ float srcB = scale<float>(src[blue_pos]);
+
+ float dstR = scale<float>(dst[red_pos]);
+ float dstG = scale<float>(dst[green_pos]);
+ float dstB = scale<float>(dst[blue_pos]);
+
+ compositeFunc(srcR, srcG, srcB, dstR, dstG, dstB);
+ dst[red_pos] = div(blend(src[red_pos] , srcAlpha, dst[red_pos] , dstAlpha, scale<channels_type>(dstR)), newDstAlpha);
+ dst[green_pos] = div(blend(src[green_pos], srcAlpha, dst[green_pos], dstAlpha, scale<channels_type>(dstG)), newDstAlpha);
+ dst[blue_pos] = div(blend(src[blue_pos] , srcAlpha, dst[blue_pos] , dstAlpha, scale<channels_type>(dstB)), newDstAlpha);
+ }
+
+ return newDstAlpha;
+ }
+};
+
#endif // KOCOMPOSITEOPFUNCTIONS_H_
diff --git a/libs/pigment/compositeops/KoCompositeOpGeneric.h b/libs/pigment/compositeops/KoCompositeOpGeneric.h
index 92ca590..6a03e6b 100644
--- a/libs/pigment/compositeops/KoCompositeOpGeneric.h
+++ b/libs/pigment/compositeops/KoCompositeOpGeneric.h
@@ -53,7 +53,7 @@ public:
if(newDstAlpha != KoColorSpaceMathsTraits<channels_type>::zeroValue) {
for(qint32 i=0; i <channels_nb; i++) {
if(i != alpha_pos && (allChannelFlags || channelFlags.testBit(i))) {
- channels_type result = blend<channels_type,compositeFunc>(src[i], srcAlpha, dst[i], dstAlpha);
+ channels_type result = blend(src[i], srcAlpha, dst[i], dstAlpha, compositeFunc(src[i],dst[i]));
dst[i] = div(result, newDstAlpha);
}
}
diff --git a/libs/pigment/compositeops/KoCompositeOps.h b/libs/pigment/compositeops/KoCompositeOps.h
index 000d2f8..d553128 100644
--- a/libs/pigment/compositeops/KoCompositeOps.h
+++ b/libs/pigment/compositeops/KoCompositeOps.h
@@ -21,14 +21,20 @@
#ifndef _KOCOMPOSITEOPS_H_
#define _KOCOMPOSITEOPS_H_
+#include <boost/type_traits.hpp>
+
#include "KoColorSpace.h"
+#include "KoColorSpaceTraits.h"
-// #include "compositeops/KoCompositeOpAdd.h"
+#include "compositeops/KoCompositeOpFunctions.h"
+#include "compositeops/KoCompositeOpGeneric.h"
#include "compositeops/KoCompositeOpAlphaDarken.h"
+#include "compositeops/KoCompositeOpErase.h"
+#include "compositeops/KoCompositeOpCopy2.h"
+// #include "compositeops/KoCompositeOpAdd.h"
// #include "compositeops/KoCompositeOpBurn.h"
// #include "compositeops/KoCompositeOpDivide.h"
// #include "compositeops/KoCompositeOpDodge.h"
-#include "compositeops/KoCompositeOpErase.h"
// #include "compositeops/KoCompositeOpMultiply.h"
// #include "compositeops/KoCompositeOpOver.h"
// #include "compositeops/KoCompositeOpOverlay.h"
@@ -37,8 +43,91 @@
// #include "compositeops/KoCompositeOpInversedSubtract.h"
// #include "compositeops/KoCompositeOpSoftlight.h"
// #include "compositeops/KoCompositeOpHardlight.h"
-#include "compositeops/KoCompositeOpCopy2.h"
-#include "compositeops/KoCompositeOpGeneric.h"
+
+
+namespace Private {
+
+template<class Traits, bool flag>
+struct AddGeneralOps
+{
+ static void add(KoColorSpace* cs) { Q_UNUSED(cs); }
+};
+
+template<class Traits>
+struct AddGeneralOps<Traits, true>
+{
+ typedef typename Traits::channels_type Arg;
+
+ template<Arg compositeFunc(Arg, Arg)>
+ static void add(KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true) {
+ cs->addCompositeOp(new KoCompositeOpGeneric<Traits, compositeFunc>(cs, id, description, category, userVisible));
+ }
+
+ static void add(KoColorSpace* cs) {
+ cs->addCompositeOp(new KoCompositeOpAlphaDarken<Traits>(cs));
+ cs->addCompositeOp(new KoCompositeOpCopy2<Traits>(cs));
+ cs->addCompositeOp(new KoCompositeOpErase<Traits>(cs));
+
+ add<&cfOver>(cs, COMPOSITE_OVER, i18n("Normal"), KoCompositeOp::categoryMix());
+
+ add<&cfColorBurn> (cs, COMPOSITE_BURN , i18n("Color Burn") , KoCompositeOp::categoryLight());
+ add<&cfColorDodge> (cs, COMPOSITE_DODGE , i18n("Color Dodge") , KoCompositeOp::categoryLight());
+ add<&cfLinearBurn> (cs, COMPOSITE_LINEAR_BURN , i18n("Linear Burn") , KoCompositeOp::categoryLight());
+ add<&cfAddition> (cs, COMPOSITE_LINEAR_DODGE, i18n("Linear Dodge"), KoCompositeOp::categoryLight());
+ add<&cfDarkenOnly> (cs, COMPOSITE_DARKEN , i18n("Darken") , KoCompositeOp::categoryLight());
+ add<&cfLightenOnly>(cs, COMPOSITE_LIGHTEN , i18n("Lighten") , KoCompositeOp::categoryLight());
+ add<&cfHardLight> (cs, COMPOSITE_HARD_LIGHT , i18n("Hard Light") , KoCompositeOp::categoryLight());
+ add<&cfSoftLight> (cs, COMPOSITE_SOFT_LIGHT , i18n("Soft Light") , KoCompositeOp::categoryLight());
+ add<&cfGammaLight> (cs, COMPOSITE_GAMMA_LIGHT , i18n("Gamma Light") , KoCompositeOp::categoryLight());
+ add<&cfGammaDark> (cs, COMPOSITE_GAMMA_DARK , i18n("Gamma Dark") , KoCompositeOp::categoryLight());
+ add<&cfVividLight> (cs, COMPOSITE_VIVID_LIGHT , i18n("Vivid Light") , KoCompositeOp::categoryLight());
+ add<&cfPinLight> (cs, COMPOSITE_PIN_LIGHT , i18n("Pin Light") , KoCompositeOp::categoryLight());
+ add<&cfLinearLight>(cs, COMPOSITE_LINEAR_LIGHT, i18n("Linear Light"), KoCompositeOp::categoryLight());
+
+ add<&cfAddition> (cs, COMPOSITE_ADD , i18n("Addition") , KoCompositeOp::categoryArithmetic());
+ add<&cfSubtract> (cs, COMPOSITE_SUBTRACT , i18n("Subtract") , KoCompositeOp::categoryArithmetic());
+ add<&cfDifference>(cs, COMPOSITE_DIFF , i18n("Difference"), KoCompositeOp::categoryArithmetic());
+ add<&cfMultiply> (cs, COMPOSITE_MULT , i18n("Multiply") , KoCompositeOp::categoryArithmetic());
+ add<&cfDivide> (cs, COMPOSITE_DIVIDE , i18n("Divide") , KoCompositeOp::categoryArithmetic());
+ add<&cfExclusion> (cs, COMPOSITE_EXCLUSION, i18n("Exclusion") , KoCompositeOp::categoryArithmetic());
+
+ add<&cfScreen> (cs, COMPOSITE_SCREEN , i18n("Screen") , KoCompositeOp::categoryColor());
+ add<&cfOverlay>(cs, COMPOSITE_OVERLAY, i18n("Overlay"), KoCompositeOp::categoryColor());
+
+ add<&cfArcTangent> (cs, COMPOSITE_ARC_TANGENT , i18n("Arcus Tangent") , KoCompositeOp::categoryMisc());
+ add<&cfGeometricMean>(cs, COMPOSITE_GEOMETRIC_MEAN, i18n("Geometric Mean"), KoCompositeOp::categoryMisc());
+ add<&cfAllanon> (cs, COMPOSITE_ALLANON , i18n("Allanon") , KoCompositeOp::categoryMisc());
+ add<&cfParallel> (cs, COMPOSITE_PARALLEL , i18n("Parallel") , KoCompositeOp::categoryMisc());
+ add<&cfEquivalence> (cs, COMPOSITE_EQUIVALENCE , i18n("Equivalence") , KoCompositeOp::categoryMisc());
+ }
+};
+
+template<class Traits, bool flag>
+struct AddHSLOps
+{
+ static void add(KoColorSpace* cs) { Q_UNUSED(cs); }
+};
+
+template<class Traits>
+struct AddHSLOps<Traits, true>
+{
+ typedef float Arg;
+
+ template<void compositeFunc(Arg, Arg, Arg, Arg&, Arg&, Arg&)>
+ static void add(KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true) {
+ cs->addCompositeOp(new KoCompositeOpGenericLum<Traits, compositeFunc>(cs, id, description, category, userVisible));
+ }
+
+ static void add(KoColorSpace* cs) {
+ add<&cfColor>(cs, COMPOSITE_COLOR, i18n("Color"), KoCompositeOp::categoryColor());
+ add<&cfHue> (cs, COMPOSITE_HUE , i18n("Hue") , KoCompositeOp::categoryColor());
+
+ add<&cfLuminosity>(cs, COMPOSITE_LUMINIZE , i18n("Luminosity"), KoCompositeOp::categoryMix());
+ add<&cfSaturation>(cs, COMPOSITE_SATURATION, i18n("Saturation"), KoCompositeOp::categoryMix());
+ }
+};
+
+}
/**
* This function add to the colorspace all the composite ops defined by
@@ -47,13 +136,16 @@
template<class _Traits_>
void addStandardCompositeOps(KoColorSpace* cs)
{
+ //cs->addCompositeOp(new KoCompositeOpAlphaDarken<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpCopy2<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpErase<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpAdd<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpAlphaDarken<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpAlphaDarken<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpBurn<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpCopy2<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpCopy2<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpDivide<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpDodge<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpErase<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpErase<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpMultiply<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpOver<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpOverlay<_Traits_>(cs));
@@ -62,32 +154,13 @@ void addStandardCompositeOps(KoColorSpace* cs)
//cs->addCompositeOp(new KoCompositeOpSoftlight<_Traits_>(cs));
//cs->addCompositeOp(new KoCompositeOpHardlight<_Traits_>(cs));
- typedef typename _Traits_::channels_type T;
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfOver<T> >(cs, COMPOSITE_OVER, i18n("Normal"), KoCompositeOp::categoryMix()));
+ typedef typename _Traits_::channels_type channels_type;
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfColorBurn<T> >(cs, COMPOSITE_BURN , i18n("Color Burn"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfColorDodge<T> >(cs, COMPOSITE_DODGE , i18n("Color Dodge"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfLinearBurn<T> >(cs, COMPOSITE_LINEAR_BURN , i18n("Linear Burn"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfAddition<T> >(cs, COMPOSITE_LINEAR_DODGE, i18n("Linear Dodge"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDarkenOnly<T> >(cs, COMPOSITE_DARKEN , i18n("Darken"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfLightenOnly<T> >(cs, COMPOSITE_LIGHTEN , i18n("Lighten"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfHardLight<T> >(cs, COMPOSITE_HARD_LIGHT , i18n("Hard Light"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfSoftLight<T> >(cs, COMPOSITE_SOFT_LIGHT , i18n("Soft Light"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfGammaLight<T> >(cs, COMPOSITE_GAMMA_LIGHT , i18n("Gamma Light"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfGammaDark<T> >(cs, COMPOSITE_GAMMA_DARK , i18n("Gamma Dark"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfVividLight<T> >(cs, COMPOSITE_VIVID_LIGHT , i18n("Vivid Light"), KoCompositeOp::categoryLight()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfPinLight<T> >(cs, COMPOSITE_PIN_LIGHT , i18n("Pin Light"), KoCompositeOp::categoryLight()));
+ static const bool useGeneralOps = true;
+ static const bool useHSLOps = boost::is_base_of<KoRgbTraits<channels_type>, _Traits_>::value;
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfScreen<T> >(cs, COMPOSITE_SCREEN , i18n("Screen"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfOverlay<T> >(cs, COMPOSITE_OVERLAY , i18n("Overlay"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfAddition<T> >(cs, COMPOSITE_ADD , i18n("Addition"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfSubtract<T> >(cs, COMPOSITE_SUBTRACT , i18n("Subtract"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDifference<T> >(cs, COMPOSITE_DIFF , i18n("Difference"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfMultiply<T> >(cs, COMPOSITE_MULT , i18n("Multiply"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDivide<T> >(cs, COMPOSITE_DIVIDE , i18n("Divide"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfExclusion<T> >(cs, COMPOSITE_EXCLUSION , i18n("Exclusion"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfArcTangent<T> >(cs, COMPOSITE_ARC_TANGENT , i18n("Arcus Tangent"), KoCompositeOp::categoryArithmetic()));
- cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfGeometricMean<T> >(cs, COMPOSITE_GEOMETRIC_MEAN, i18n("Geometric Mean"), KoCompositeOp::categoryArithmetic()));
+ Private::AddGeneralOps<_Traits_, useGeneralOps>::add(cs);
+ Private::AddHSLOps <_Traits_, useHSLOps >::add(cs);
}
#endif
--
1.7.1
More information about the kimageshop
mailing list