[PATCH 03/15] Added KoCompositeOpGeneric class to easily create new composite modes by just defining a composition function.
Silvio Heinrich
plassy at web.de
Sat Jan 8 03:46:10 CET 2011
The KoCompositeOpGeneric class is a template that takes a function pointer
to a composition function as a second template parameter.
So for the most composition modes it is not needed anymore
to derive a new class from KoCompositionOp (or from one of its derivates)
---
libs/pigment/KoCompositeOp.h | 2 +
libs/pigment/compositeops/KoCompositeOpBurn.h | 2 +-
libs/pigment/compositeops/KoCompositeOpDodge.h | 2 +-
libs/pigment/compositeops/KoCompositeOpFunctions.h | 64 +++++++++++++++++---
libs/pigment/compositeops/KoCompositeOpGeneric.h | 65 ++++++++++++++++++++
libs/pigment/compositeops/KoCompositeOps.h | 56 +++++++++++------
6 files changed, 162 insertions(+), 29 deletions(-)
create mode 100644 libs/pigment/compositeops/KoCompositeOpGeneric.h
diff --git a/libs/pigment/KoCompositeOp.h b/libs/pigment/KoCompositeOp.h
index f6fb236..73c923e 100644
--- a/libs/pigment/KoCompositeOp.h
+++ b/libs/pigment/KoCompositeOp.h
@@ -43,7 +43,9 @@ const QString COMPOSITE_DIFF = "diff";
const QString COMPOSITE_MULT = "multiply";
const QString COMPOSITE_DIVIDE = "divide";
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_BUMPMAP = "bumpmap";
const QString COMPOSITE_CLEAR = "clear";
const QString COMPOSITE_DISSOLVE = "dissolve";
diff --git a/libs/pigment/compositeops/KoCompositeOpBurn.h b/libs/pigment/compositeops/KoCompositeOpBurn.h
index 3315373..857efea 100644
--- a/libs/pigment/compositeops/KoCompositeOpBurn.h
+++ b/libs/pigment/compositeops/KoCompositeOpBurn.h
@@ -35,7 +35,7 @@ class KoCompositeOpBurn : public KoCompositeOpBase< _CSTraits, KoCompositeOpBurn
public:
KoCompositeOpBurn(const KoColorSpace* cs)
- : KoCompositeOpBase< _CSTraits, KoCompositeOpBurn<_CSTraits> >(cs, COMPOSITE_BURN, i18n("Burn"), KoCompositeOp::categoryLight()) { }
+ : KoCompositeOpBase< _CSTraits, KoCompositeOpBurn<_CSTraits> >(cs, COMPOSITE_BURN, i18n("Burn"), KoCompositeOp::categoryLight(), true) { }
public:
inline static channels_type composeColorChannels(const channels_type* src, channels_type srcAlpha,
diff --git a/libs/pigment/compositeops/KoCompositeOpDodge.h b/libs/pigment/compositeops/KoCompositeOpDodge.h
index 019695a..815d273 100644
--- a/libs/pigment/compositeops/KoCompositeOpDodge.h
+++ b/libs/pigment/compositeops/KoCompositeOpDodge.h
@@ -35,7 +35,7 @@ class KoCompositeOpDodge : public KoCompositeOpBase< _CSTraits, KoCompositeOpDod
static const qint32 alpha_pos = _CSTraits::alpha_pos;
public:
KoCompositeOpDodge(const KoColorSpace * cs)
- : KoCompositeOpBase< _CSTraits, KoCompositeOpDodge<_CSTraits> >(cs, COMPOSITE_DODGE, i18n("Dodge"), KoCompositeOp::categoryLight()) { }
+ : KoCompositeOpBase< _CSTraits, KoCompositeOpDodge<_CSTraits> >(cs, COMPOSITE_DODGE, i18n("Dodge"), KoCompositeOp::categoryLight(), true) { }
public:
inline static channels_type composeColorChannels(const channels_type* src, channels_type srcAlpha,
diff --git a/libs/pigment/compositeops/KoCompositeOpFunctions.h b/libs/pigment/compositeops/KoCompositeOpFunctions.h
index bdd3af7..0656fa5 100644
--- a/libs/pigment/compositeops/KoCompositeOpFunctions.h
+++ b/libs/pigment/compositeops/KoCompositeOpFunctions.h
@@ -56,7 +56,8 @@ inline T inv(T a) {
template<class T>
inline T clamp(typename KoColorSpaceMathsTraits<T>::compositetype a) {
- return (a > KoColorSpaceMathsTraits<T>::unitValue) ? KoColorSpaceMathsTraits<T>::unitValue : T(a);
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ return qBound<composite_type>(KoColorSpaceMathsTraits<T>::zeroValue, a, KoColorSpaceMathsTraits<T>::unitValue);
}
template<class T>
@@ -89,24 +90,69 @@ inline T blend(T src, T srcAlpha, T dst, T dstAlpha, TFunc blendFunc) {
template<class T>
inline T cfColorBurn(T src, T dst) {
- typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
-
if(src != KoColorSpaceMathsTraits<T>::zeroValue)
return inv(clamp<T>(div(inv(dst), src)));
-
return KoColorSpaceMathsTraits<T>::zeroValue;
}
template<class T>
-inline T cfColorDodge(T src, T dst) {
+inline T cfLinearBurn(T src, T dst) {
typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
-
+ return clamp<T>(composite_type(src) + dst - KoColorSpaceMathsTraits<T>::unitValue);
+}
+
+template<class T>
+inline T cfColorDodge(T src, T dst) {
if(src != KoColorSpaceMathsTraits<T>::unitValue)
return clamp<T>(div(dst, inv(src)));
-
return KoColorSpaceMathsTraits<T>::unitValue;
}
+template<class T>
+inline T cfAddition(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ return clamp<T>(composite_type(src) + dst);
+}
+
+template<class T>
+inline T cfSubtract(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ return clamp<T>(composite_type(dst) - src);
+}
+
+template<class T>
+inline T cfExclusion(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ composite_type x = mul(src, dst);
+ return clamp<T>(composite_type(dst) + src - (x + x));
+}
+
+template<class T>
+inline T cfDivide(T src, T dst) {
+ typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
+ if(src == KoColorSpaceMathsTraits<T>::zeroValue)
+ return dst;
+ return clamp<T>(div(dst, src));
+}
+
+template<class T>
+inline T cfOver(T src, T dst) { Q_UNUSED(dst); return src; }
+
+template<class T>
+inline T cfMultiply(T src, T dst) { return mul(src, dst); }
+
+template<class T>
+inline T cfDifference(T src, T dst) { return qMax(src,dst) - qMin(src,dst); }
+
+template<class T>
+inline T cfScreen(T src, T dst) { return unionShapeOpacy(src, dst); }
+
+template<class T>
+inline T cfDarkenOnly(T src, T dst) { return qMin(src, dst); }
+
+template<class T>
+inline T cfLightenOnly(T src, T dst) { return qMax(src, dst); }
+
/**
* A template base class that can be used for most composite modes/ops
*
@@ -132,8 +178,8 @@ class KoCompositeOpBase : public KoCompositeOp
public:
- KoCompositeOpBase(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category)
- : KoCompositeOp(cs, id, description, category) { }
+ KoCompositeOpBase(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible)
+ : KoCompositeOp(cs, id, description, category, userVisible) { }
private:
template<bool alphaLocked>
diff --git a/libs/pigment/compositeops/KoCompositeOpGeneric.h b/libs/pigment/compositeops/KoCompositeOpGeneric.h
new file mode 100644
index 0000000..805b017
--- /dev/null
+++ b/libs/pigment/compositeops/KoCompositeOpGeneric.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011 Silvio Heinrich <plassy at web.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _KOCOMPOSITEO_GENERIC_H_
+#define _KOCOMPOSITEO_GENERIC_H_
+
+#include "KoCompositeOpFunctions.h"
+
+/**
+ * A template version of the burn composite operation to use in colorspaces.
+ */
+template<
+ class Traits,
+ typename Traits::channels_type compositeFunc(typename Traits::channels_type, typename Traits::channels_type)
+>
+class KoCompositeOpGeneric : public KoCompositeOpBase< Traits, KoCompositeOpGeneric<Traits,compositeFunc> >
+{
+ typedef KoCompositeOpBase< Traits, KoCompositeOpGeneric<Traits,compositeFunc> > base_class;
+ typedef typename Traits::channels_type channels_type;
+ typedef typename KoColorSpaceMathsTraits<channels_type>::compositetype composite_type;
+
+ static const qint32 channels_nb = Traits::channels_nb;
+ static const qint32 alpha_pos = Traits::alpha_pos;
+
+public:
+ KoCompositeOpGeneric(const KoColorSpace* cs, const QString& id, const QString& description, const QString& category, bool userVisible=true)
+ : base_class(cs, id, description, category, userVisible) { }
+
+public:
+ inline static channels_type composeColorChannels(const channels_type* src, channels_type srcAlpha,
+ channels_type* dst, channels_type dstAlpha,
+ channels_type opacity, const QBitArray& channelFlags) {
+ srcAlpha = mul(srcAlpha, opacity);
+ channels_type newDstAlpha = unionShapeOpacy(srcAlpha, dstAlpha);
+
+ if(newDstAlpha != KoColorSpaceMathsTraits<channels_type>::zeroValue) {
+ for(qint32 i=0; i <channels_nb; i++) {
+ if(i != alpha_pos && channelFlags.testBit(i)) {
+ channels_type result = blend(src[i], srcAlpha, dst[i], dstAlpha, compositeFunc);
+ dst[i] = div(result, newDstAlpha);
+ }
+ }
+ }
+
+ return newDstAlpha;
+ }
+};
+
+#endif // _KOCOMPOSITEO_GENERIC_H_
diff --git a/libs/pigment/compositeops/KoCompositeOps.h b/libs/pigment/compositeops/KoCompositeOps.h
index d278234..7949865 100644
--- a/libs/pigment/compositeops/KoCompositeOps.h
+++ b/libs/pigment/compositeops/KoCompositeOps.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Cyrille Berger <cberger at cberger.net>
+ * Copyright (c) 2011 Silvio Heinrich <plassy at web.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,21 +23,22 @@
#include "KoColorSpace.h"
-#include "compositeops/KoCompositeOpAdd.h"
+// #include "compositeops/KoCompositeOpAdd.h"
#include "compositeops/KoCompositeOpAlphaDarken.h"
-#include "compositeops/KoCompositeOpBurn.h"
+// #include "compositeops/KoCompositeOpBurn.h"
#include "compositeops/KoCompositeOpDivide.h"
-#include "compositeops/KoCompositeOpDodge.h"
+// #include "compositeops/KoCompositeOpDodge.h"
#include "compositeops/KoCompositeOpErase.h"
-#include "compositeops/KoCompositeOpMultiply.h"
-#include "compositeops/KoCompositeOpOver.h"
+// #include "compositeops/KoCompositeOpMultiply.h"
+// #include "compositeops/KoCompositeOpOver.h"
#include "compositeops/KoCompositeOpOverlay.h"
-#include "compositeops/KoCompositeOpScreen.h"
-#include "compositeops/KoCompositeOpSubtract.h"
+// #include "compositeops/KoCompositeOpScreen.h"
+// #include "compositeops/KoCompositeOpSubtract.h"
#include "compositeops/KoCompositeOpInversedSubtract.h"
#include "compositeops/KoCompositeOpSoftlight.h"
#include "compositeops/KoCompositeOpHardlight.h"
#include "compositeops/KoCompositeOpCopy2.h"
+#include "compositeops/KoCompositeOpGeneric.h"
/**
* This function add to the colorspace all the composite ops defined by
@@ -45,20 +47,38 @@
template<class _Traits_>
void addStandardCompositeOps(KoColorSpace* cs)
{
- cs->addCompositeOp(new KoCompositeOpAdd<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpAdd<_Traits_>(cs));
cs->addCompositeOp(new KoCompositeOpAlphaDarken<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpBurn<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpBurn<_Traits_>(cs));
cs->addCompositeOp(new KoCompositeOpCopy2<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpDivide<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpDodge<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpDivide<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpDodge<_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));
- cs->addCompositeOp(new KoCompositeOpScreen<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpSubtract<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpSoftlight<_Traits_>(cs));
- cs->addCompositeOp(new KoCompositeOpHardlight<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpMultiply<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpOver<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpOverlay<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpScreen<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpSubtract<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpSoftlight<_Traits_>(cs));
+ //cs->addCompositeOp(new KoCompositeOpHardlight<_Traits_>(cs));
+
+ typedef typename _Traits_::channels_type type;
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfOver <type> >(cs, COMPOSITE_OVER, i18n("Normal"), KoCompositeOp::categoryMix()));
+
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfColorBurn <type> >(cs, COMPOSITE_BURN , i18n("Color Burn"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfColorDodge <type> >(cs, COMPOSITE_DODGE , i18n("Color Dodge"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfLinearBurn <type> >(cs, COMPOSITE_LINEAR_BURN , i18n("Linear Burn"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfAddition <type> >(cs, COMPOSITE_LINEAR_DODGE, i18n("Linear Dodge"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDarkenOnly <type> >(cs, COMPOSITE_DARKEN , i18n("Darken"), KoCompositeOp::categoryLight()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfLightenOnly<type> >(cs, COMPOSITE_LIGHTEN , i18n("Lighten"), KoCompositeOp::categoryLight()));
+
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfAddition <type> >(cs, COMPOSITE_ADD , i18n("Addition"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfSubtract <type> >(cs, COMPOSITE_SUBTRACT , i18n("Subtract"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDifference<type> >(cs, COMPOSITE_DIFF , i18n("Difference"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfMultiply <type> >(cs, COMPOSITE_MULT , i18n("Multiply"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfDivide <type> >(cs, COMPOSITE_DIVIDE , i18n("Divide"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfExclusion <type> >(cs, COMPOSITE_EXCLUSION, i18n("Exclusion"), KoCompositeOp::categoryArithmetic()));
+ cs->addCompositeOp(new KoCompositeOpGeneric< _Traits_, &cfScreen <type> >(cs, COMPOSITE_SCREEN , i18n("Screen"), KoCompositeOp::categoryArithmetic()));
}
#endif
--
1.7.1
More information about the kimageshop
mailing list