[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