KoCompositeOps.h 24 KB
Newer Older
1 2
/*
 *  Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
3
 *  Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
4 5 6 7
 *
 * 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
8
 * version 2.1 of the License, or (at your option) any later version.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * 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 _KOCOMPOSITEOPS_H_
#define _KOCOMPOSITEOPS_H_

24 25
#include <boost/type_traits.hpp>

26 27
#include <KoColorSpace.h>
#include <KoColorSpaceTraits.h>
28
#include <KoColorSpaceMaths.h>
29

30
#include "compositeops/KoCompositeOpGeneric.h"
31
#include "compositeops/KoCompositeOpOver.h"
32
#include "compositeops/KoCompositeOpCopyChannel.h"
Halla Rempt's avatar
Halla Rempt committed
33
#include "compositeops/KoCompositeOpAlphaDarken.h"
34 35
#include "compositeops/KoCompositeOpErase.h"
#include "compositeops/KoCompositeOpCopy2.h"
36
#include "compositeops/KoCompositeOpDissolve.h"
37
#include "compositeops/KoCompositeOpBehind.h"
38 39
#include "compositeops/KoCompositeOpDestinationIn.h"
#include "compositeops/KoCompositeOpDestinationAtop.h"
Dmitry Kazakov's avatar
Dmitry Kazakov committed
40
#include "compositeops/KoCompositeOpGreater.h"
41
#include "compositeops/KoAlphaDarkenParamsWrapper.h"
42 43
#include "KoOptimizedCompositeOpFactory.h"

44
namespace _Private {
45 46 47 48 49 50 51

template<class Traits, bool flag>
struct AddGeneralOps
{
    static void add(KoColorSpace* cs) { Q_UNUSED(cs); }
};

52 53 54 55
template<class Traits>
struct OptimizedOpsSelector
{
    static KoCompositeOp* createAlphaDarkenOp(const KoColorSpace *cs) {
56 57 58 59 60
        if (useCreamyAlphaDarken()) {
            return new KoCompositeOpAlphaDarken<Traits, KoAlphaDarkenParamsWrapperCreamy>(cs);
        } else {
            return new KoCompositeOpAlphaDarken<Traits, KoAlphaDarkenParamsWrapperHard>(cs);
        }
61
    }
62 63 64
    static KoCompositeOp* createOverOp(const KoColorSpace *cs) {
        return new KoCompositeOpOver<Traits>(cs);
    }
65 66 67 68 69 70
};

template<>
struct OptimizedOpsSelector<KoBgrU8Traits>
{
    static KoCompositeOp* createAlphaDarkenOp(const KoColorSpace *cs) {
71 72 73
        return useCreamyAlphaDarken() ?
            KoOptimizedCompositeOpFactory::createAlphaDarkenOpCreamy32(cs) :
            KoOptimizedCompositeOpFactory::createAlphaDarkenOpHard32(cs);
74
    }
75 76 77
    static KoCompositeOp* createOverOp(const KoColorSpace *cs) {
        return KoOptimizedCompositeOpFactory::createOverOp32(cs);
    }
78 79 80 81 82 83
};

template<>
struct OptimizedOpsSelector<KoLabU8Traits>
{
    static KoCompositeOp* createAlphaDarkenOp(const KoColorSpace *cs) {
84 85 86
        return useCreamyAlphaDarken() ?
            KoOptimizedCompositeOpFactory::createAlphaDarkenOpCreamy32(cs) :
            KoOptimizedCompositeOpFactory::createAlphaDarkenOpHard32(cs);
87
    }
88 89 90
    static KoCompositeOp* createOverOp(const KoColorSpace *cs) {
        return KoOptimizedCompositeOpFactory::createOverOp32(cs);
    }
91 92
};

93 94 95 96
template<>
struct OptimizedOpsSelector<KoRgbF32Traits>
{
    static KoCompositeOp* createAlphaDarkenOp(const KoColorSpace *cs) {
97 98 99
        return useCreamyAlphaDarken() ?
            KoOptimizedCompositeOpFactory::createAlphaDarkenOpCreamy128(cs) :
            KoOptimizedCompositeOpFactory::createAlphaDarkenOpHard128(cs);
100

101 102 103 104 105 106
    }
    static KoCompositeOp* createOverOp(const KoColorSpace *cs) {
        return KoOptimizedCompositeOpFactory::createOverOp128(cs);
    }
};

107 108 109
template<class Traits>
struct AddGeneralOps<Traits, true>
{
110 111 112 113 114
     typedef typename Traits::channels_type Arg;
     typedef Arg (*CompositeFunc)(Arg, Arg);
     static const qint32 alpha_pos = Traits::alpha_pos;

     template<CompositeFunc func>
115 116
     static void add(KoColorSpace* cs, const QString& id, const QString& description, const QString& category) {
         cs->addCompositeOp(new KoCompositeOpGenericSC<Traits, func>(cs, id, description, category));
117 118 119
     }

     static void add(KoColorSpace* cs) {
120
         cs->addCompositeOp(OptimizedOpsSelector<Traits>::createOverOp(cs));
121
         cs->addCompositeOp(OptimizedOpsSelector<Traits>::createAlphaDarkenOp(cs));
122 123
         cs->addCompositeOp(new KoCompositeOpCopy2<Traits>(cs));
         cs->addCompositeOp(new KoCompositeOpErase<Traits>(cs));
124
         cs->addCompositeOp(new KoCompositeOpBehind<Traits>(cs));
125 126
         cs->addCompositeOp(new KoCompositeOpDestinationIn<Traits>(cs));
         cs->addCompositeOp(new KoCompositeOpDestinationAtop<Traits>(cs));
Dmitry Kazakov's avatar
Dmitry Kazakov committed
127
         cs->addCompositeOp(new KoCompositeOpGreater<Traits>(cs));
128

129 130 131 132
         add<&cfOverlay<Arg>       >(cs, COMPOSITE_OVERLAY       , i18n("Overlay")       , KoCompositeOp::categoryMix());
         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());
133
         add<&cfHardMixPhotoshop<Arg>>(cs, COMPOSITE_HARD_MIX_PHOTOSHOP, i18n("Hard Mix (Photoshop)")      , KoCompositeOp::categoryMix());
134
         add<&cfGeometricMean<Arg> >(cs, COMPOSITE_GEOMETRIC_MEAN, i18n("Geometric Mean"), KoCompositeOp::categoryMix());
135 136
         add<&cfParallel<Arg>      >(cs, COMPOSITE_PARALLEL      , i18n("Parallel")      , KoCompositeOp::categoryMix());
         add<&cfAllanon<Arg>       >(cs, COMPOSITE_ALLANON       , i18n("Allanon")       , KoCompositeOp::categoryMix());
137
         add<&cfHardOverlay<Arg>   >(cs, COMPOSITE_HARD_OVERLAY  , i18n("Hard Overlay")  , KoCompositeOp::categoryMix());
138 139 140 141 142 143
         add<&cfInterpolation<Arg> >(cs, COMPOSITE_INTERPOLATION , i18n("Interpolation") , KoCompositeOp::categoryMix());
         add<&cfInterpolationB<Arg> >(cs, COMPOSITE_INTERPOLATIONB , i18n("Interpolation - 2X") , KoCompositeOp::categoryMix());
         add<&cfPenumbraA<Arg>     >(cs, COMPOSITE_PENUMBRAA     , i18n("Penumbra A")    , KoCompositeOp::categoryMix());
         add<&cfPenumbraB<Arg>     >(cs, COMPOSITE_PENUMBRAB     , i18n("Penumbra B")    , KoCompositeOp::categoryMix());
         add<&cfPenumbraC<Arg>     >(cs, COMPOSITE_PENUMBRAC     , i18n("Penumbra C")    , KoCompositeOp::categoryMix());
         add<&cfPenumbraD<Arg>     >(cs, COMPOSITE_PENUMBRAD     , i18n("Penumbra D")    , KoCompositeOp::categoryMix());
144

145 146 147
         add<&cfScreen<Arg>      >(cs, COMPOSITE_SCREEN      , i18n("Screen")      , KoCompositeOp::categoryLight());
         add<&cfColorDodge<Arg>  >(cs, COMPOSITE_DODGE       , i18n("Color Dodge") , KoCompositeOp::categoryLight());
         add<&cfAddition<Arg>    >(cs, COMPOSITE_LINEAR_DODGE, i18n("Linear Dodge"), KoCompositeOp::categoryLight());
148
         add<&cfLightenOnly<Arg> >(cs, COMPOSITE_LIGHTEN     , i18n("Lighten")     , KoCompositeOp::categoryLight());
149
         add<&cfHardLight<Arg>   >(cs, COMPOSITE_HARD_LIGHT  , i18n("Hard Light")  , KoCompositeOp::categoryLight());
150 151
         add<&cfSoftLightIFSIllusions<Arg>>(cs, COMPOSITE_SOFT_LIGHT_IFS_ILLUSIONS, i18n("Soft Light (IFS Illusions)")  , KoCompositeOp::categoryLight());
         add<&cfSoftLightPegtopDelphi<Arg>>(cs, COMPOSITE_SOFT_LIGHT_PEGTOP_DELPHI, i18n("Soft Light (Pegtop-Delphi)")  , KoCompositeOp::categoryLight());
Halla Rempt's avatar
Halla Rempt committed
152 153
         add<&cfSoftLightSvg<Arg>   >(cs, COMPOSITE_SOFT_LIGHT_SVG, i18n("Soft Light (SVG)")  , KoCompositeOp::categoryLight());
         add<&cfSoftLight<Arg>   >(cs, COMPOSITE_SOFT_LIGHT_PHOTOSHOP, i18n("Soft Light (Photoshop)")  , KoCompositeOp::categoryLight());
154
         add<&cfGammaLight<Arg>  >(cs, COMPOSITE_GAMMA_LIGHT , i18n("Gamma Light") , KoCompositeOp::categoryLight());
155
         add<&cfGammaIllumination<Arg>  >(cs, COMPOSITE_GAMMA_ILLUMINATION , i18n("Gamma Illumination") , KoCompositeOp::categoryLight());
156
         add<&cfVividLight<Arg>  >(cs, COMPOSITE_VIVID_LIGHT , i18n("Vivid Light") , KoCompositeOp::categoryLight());
157
         add<&cfFlatLight<Arg>  >(cs, COMPOSITE_FLAT_LIGHT   , i18n("Flat Light") , KoCompositeOp::categoryLight());
158
         add<&cfPinLight<Arg>    >(cs, COMPOSITE_PIN_LIGHT   , i18n("Pin Light")   , KoCompositeOp::categoryLight());
159
         add<&cfLinearLight<Arg> >(cs, COMPOSITE_LINEAR_LIGHT, i18n("Linear Light"), KoCompositeOp::categoryLight());
160 161 162 163 164 165
         add<&cfPNormA<Arg>       >(cs, COMPOSITE_PNORM_A       , i18n("P-Norm A")      , KoCompositeOp::categoryLight());
         add<&cfPNormB<Arg>       >(cs, COMPOSITE_PNORM_B       , i18n("P-Norm B")      , KoCompositeOp::categoryLight());
         add<&cfSuperLight<Arg> >(cs, COMPOSITE_SUPER_LIGHT  , i18n("Super Light") , KoCompositeOp::categoryLight());
         add<&cfTintIFSIllusions<Arg>     >(cs, COMPOSITE_TINT_IFS_ILLUSIONS     , i18n("Tint (IFS Illusions)")    , KoCompositeOp::categoryLight());
         add<&cfFogLightenIFSIllusions<Arg>     >(cs, COMPOSITE_FOG_LIGHTEN_IFS_ILLUSIONS     , i18n("Fog Lighten (IFS Illusions)")    , KoCompositeOp::categoryLight());
         add<&cfEasyDodge<Arg>  >(cs, COMPOSITE_EASY_DODGE       , i18n("Easy Dodge") , KoCompositeOp::categoryLight());
166

167
         add<&cfColorBurn<Arg>  >(cs, COMPOSITE_BURN        , i18n("Color Burn") , KoCompositeOp::categoryDark());
168 169
         add<&cfLinearBurn<Arg> >(cs, COMPOSITE_LINEAR_BURN , i18n("Linear Burn"), KoCompositeOp::categoryDark());
         add<&cfDarkenOnly<Arg> >(cs, COMPOSITE_DARKEN      , i18n("Darken")     , KoCompositeOp::categoryDark());
170
         add<&cfGammaDark<Arg>  >(cs, COMPOSITE_GAMMA_DARK  , i18n("Gamma Dark") , KoCompositeOp::categoryDark());
171 172 173
         add<&cfShadeIFSIllusions<Arg>     >(cs, COMPOSITE_SHADE_IFS_ILLUSIONS     , i18n("Shade (IFS_Illusions)")    , KoCompositeOp::categoryDark());
         add<&cfFogDarkenIFSIllusions<Arg>     >(cs, COMPOSITE_FOG_DARKEN_IFS_ILLUSIONS     , i18n("Fog Darken (IFS Illusions)")    , KoCompositeOp::categoryDark());
         add<&cfEasyBurn<Arg>  >(cs, COMPOSITE_EASY_BURN        , i18n("Easy Burn") , KoCompositeOp::categoryDark());
174

Silvio Heinrich's avatar
Silvio Heinrich committed
175 176 177 178 179
         add<&cfAddition<Arg>        >(cs, COMPOSITE_ADD             , i18n("Addition")         , KoCompositeOp::categoryArithmetic());
         add<&cfSubtract<Arg>        >(cs, COMPOSITE_SUBTRACT        , i18n("Subtract")         , KoCompositeOp::categoryArithmetic());
         add<&cfInverseSubtract<Arg> >(cs, COMPOSITE_INVERSE_SUBTRACT, i18n("Inversed-Subtract"), KoCompositeOp::categoryArithmetic());
         add<&cfMultiply<Arg>        >(cs, COMPOSITE_MULT            , i18n("Multiply")         , KoCompositeOp::categoryArithmetic());
         add<&cfDivide<Arg>          >(cs, COMPOSITE_DIVIDE          , i18n("Divide")           , KoCompositeOp::categoryArithmetic());
180

181 182 183 184 185 186 187
         add<&cfModulo<Arg>               >(cs, COMPOSITE_MOD                    , i18n("Modulo")                   , KoCompositeOp::categoryModulo());
         add<&cfModuloContinuous<Arg>     >(cs, COMPOSITE_MOD_CON                , i18n("Modulo - Continuous")      , KoCompositeOp::categoryModulo());
         add<&cfDivisiveModulo<Arg>       >(cs, COMPOSITE_DIVISIVE_MOD           , i18n("Divisive Modulo")          , KoCompositeOp::categoryModulo());
         add<&cfDivisiveModuloContinuous<Arg> >(cs, COMPOSITE_DIVISIVE_MOD_CON   , i18n("Divisive Modulo - Continuous")   , KoCompositeOp::categoryModulo());
         add<&cfModuloShift<Arg>          >(cs, COMPOSITE_MODULO_SHIFT           , i18n("Modulo Shift")             , KoCompositeOp::categoryModulo());
         add<&cfModuloShiftContinuous<Arg> >(cs, COMPOSITE_MODULO_SHIFT_CON      , i18n("Modulo Shift - Continuous")      , KoCompositeOp::categoryModulo());

188 189 190 191
         add<&cfArcTangent<Arg>           >(cs, COMPOSITE_ARC_TANGENT          , i18n("Arcus Tangent")        , KoCompositeOp::categoryNegative());
         add<&cfDifference<Arg>           >(cs, COMPOSITE_DIFF                 , i18n("Difference")           , KoCompositeOp::categoryNegative());
         add<&cfExclusion<Arg>            >(cs, COMPOSITE_EXCLUSION            , i18n("Exclusion")            , KoCompositeOp::categoryNegative());
         add<&cfEquivalence<Arg>          >(cs, COMPOSITE_EQUIVALENCE          , i18n("Equivalence")          , KoCompositeOp::categoryNegative());
192
         add<&cfAdditiveSubtractive<Arg>  >(cs, COMPOSITE_ADDITIVE_SUBTRACTIVE , i18n("Additive-Subtractive") , KoCompositeOp::categoryNegative());
193
         add<&cfNegation<Arg>             >(cs, COMPOSITE_NEGATION             , i18n("Negation")             , KoCompositeOp::categoryNegative());
Miguel Lopez's avatar
Miguel Lopez committed
194
         
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
         add<&cfXor<Arg>                  >(cs, COMPOSITE_XOR                  , i18n("XOR")                  , KoCompositeOp::categoryBinary());
         add<&cfOr<Arg>                   >(cs, COMPOSITE_OR                   , i18n("OR")                   , KoCompositeOp::categoryBinary());
         add<&cfAnd<Arg>                  >(cs, COMPOSITE_AND                  , i18n("AND")                  , KoCompositeOp::categoryBinary());
         add<&cfNand<Arg>                 >(cs, COMPOSITE_NAND                 , i18n("NAND")                 , KoCompositeOp::categoryBinary());
         add<&cfNor<Arg>                  >(cs, COMPOSITE_NOR                  , i18n("NOR")                  , KoCompositeOp::categoryBinary());
         add<&cfXnor<Arg>                 >(cs, COMPOSITE_XNOR                 , i18n("XNOR")                 , KoCompositeOp::categoryBinary());
         add<&cfImplies<Arg>              >(cs, COMPOSITE_IMPLICATION          , i18n("IMPLICATION")          , KoCompositeOp::categoryBinary());
         add<&cfNotImplies<Arg>           >(cs, COMPOSITE_NOT_IMPLICATION      , i18n("NOT IMPLICATION")      , KoCompositeOp::categoryBinary());
         add<&cfConverse<Arg>             >(cs, COMPOSITE_CONVERSE             , i18n("CONVERSE")             , KoCompositeOp::categoryBinary());
         add<&cfNotConverse<Arg>          >(cs, COMPOSITE_NOT_CONVERSE         , i18n("NOT CONVERSE")         , KoCompositeOp::categoryBinary());

         add<&cfReflect<Arg> >(cs, COMPOSITE_REFLECT                         , i18n("Reflect")                , KoCompositeOp::categoryQuadratic());
         add<&cfGlow<Arg>    >(cs, COMPOSITE_GLOW                            , i18n("Glow")                   , KoCompositeOp::categoryQuadratic());
         add<&cfFreeze<Arg>  >(cs, COMPOSITE_FREEZE                          , i18n("Freeze")                 , KoCompositeOp::categoryQuadratic());
         add<&cfHeat<Arg>    >(cs, COMPOSITE_HEAT                            , i18n("Heat")                   , KoCompositeOp::categoryQuadratic());
         add<&cfGleat<Arg>   >(cs, COMPOSITE_GLEAT                           , i18n("Glow-Heat")                  , KoCompositeOp::categoryQuadratic());
         add<&cfHelow<Arg>   >(cs, COMPOSITE_HELOW                           , i18n("Heat-Glow")                  , KoCompositeOp::categoryQuadratic());
         add<&cfReeze<Arg>   >(cs, COMPOSITE_REEZE                           , i18n("Reflect-Freeze")                  , KoCompositeOp::categoryQuadratic());
         add<&cfFrect<Arg>   >(cs, COMPOSITE_FRECT                           , i18n("Freeze-Reflect")                  , KoCompositeOp::categoryQuadratic());
         add<&cfFhyrd<Arg>   >(cs, COMPOSITE_FHYRD                           , i18n("Heat-Glow & Freeze-Reflect Hybrid")     , KoCompositeOp::categoryQuadratic());
215 216 217

         cs->addCompositeOp(new KoCompositeOpDissolve<Traits>(cs, KoCompositeOp::categoryMisc()));
     }
218 219 220
};

template<class Traits, bool flag>
221
struct AddRGBOps
222 223 224 225 226
{
    static void add(KoColorSpace* cs) { Q_UNUSED(cs); }
};

template<class Traits>
227
struct AddRGBOps<Traits, true>
228 229
{
    typedef float Arg;
230

231 232 233
    static const qint32 red_pos   = Traits::red_pos;
    static const qint32 green_pos = Traits::green_pos;
    static const qint32 blue_pos  = Traits::blue_pos;
234

235
    template<void compositeFunc(Arg, Arg, Arg, Arg&, Arg&, Arg&)>
236

237 238
    static void add(KoColorSpace* cs, const QString& id, const QString& description, const QString& category) {
        cs->addCompositeOp(new KoCompositeOpGenericHSL<Traits, compositeFunc>(cs, id, description, category));
239
    }
240

241
    static void add(KoColorSpace* cs) {
242

243 244 245
        cs->addCompositeOp(new KoCompositeOpCopyChannel<Traits,red_pos  >(cs, COMPOSITE_COPY_RED  , i18n("Copy Red")  , KoCompositeOp::categoryMisc()));
        cs->addCompositeOp(new KoCompositeOpCopyChannel<Traits,green_pos>(cs, COMPOSITE_COPY_GREEN, i18n("Copy Green"), KoCompositeOp::categoryMisc()));
        cs->addCompositeOp(new KoCompositeOpCopyChannel<Traits,blue_pos >(cs, COMPOSITE_COPY_BLUE , i18n("Copy Blue") , KoCompositeOp::categoryMisc()));
246
        add<&cfTangentNormalmap  <HSYType,Arg> >(cs, COMPOSITE_TANGENT_NORMALMAP  , i18n("Tangent Normalmap")  , KoCompositeOp::categoryMisc());
247
        add<&cfReorientedNormalMapCombine <HSYType, Arg> >(cs, COMPOSITE_COMBINE_NORMAL, i18n("Combine Normal Maps"), KoCompositeOp::categoryMisc());
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
        add<&cfColor             <HSYType,Arg> >(cs, COMPOSITE_COLOR         , i18nc("HSY Color", "Color")              , KoCompositeOp::categoryHSY());
        add<&cfHue               <HSYType,Arg> >(cs, COMPOSITE_HUE           , i18nc("HSY Hue", "Hue")                , KoCompositeOp::categoryHSY());
        add<&cfSaturation        <HSYType,Arg> >(cs, COMPOSITE_SATURATION    , i18nc("HSY Saturation", "Saturation")         , KoCompositeOp::categoryHSY());
        add<&cfIncreaseSaturation<HSYType,Arg> >(cs, COMPOSITE_INC_SATURATION, i18nc("HSY Incease Saturation", "Increase Saturation"), KoCompositeOp::categoryHSY());
        add<&cfDecreaseSaturation<HSYType,Arg> >(cs, COMPOSITE_DEC_SATURATION, i18nc("HSY Decrease Saturation", "Decrease Saturation"), KoCompositeOp::categoryHSY());
        add<&cfLightness         <HSYType,Arg> >(cs, COMPOSITE_LUMINIZE      , i18nc("HSY Luminosity", "Luminosity")         , KoCompositeOp::categoryHSY());
        add<&cfIncreaseLightness <HSYType,Arg> >(cs, COMPOSITE_INC_LUMINOSITY, i18nc("HSY Increase Luminosity", "Increase Luminosity"), KoCompositeOp::categoryHSY());
        add<&cfDecreaseLightness <HSYType,Arg> >(cs, COMPOSITE_DEC_LUMINOSITY, i18nc("HSY Decrease Luminosity", "Decrease Luminosity"), KoCompositeOp::categoryHSY());
        add<&cfDarkerColor <HSYType,Arg> >(cs, COMPOSITE_DARKER_COLOR, i18nc("HSY PSD Darker Color", "Darker Color"), KoCompositeOp::categoryDark());//darker color as PSD does it//
        add<&cfLighterColor <HSYType,Arg> >(cs, COMPOSITE_LIGHTER_COLOR, i18nc("HSY PSD Lighter Color", "Lighter Color"), KoCompositeOp::categoryLight());//lighter color as PSD does it//

        add<&cfColor             <HSIType,Arg> >(cs, COMPOSITE_COLOR_HSI         , i18nc("HSI Color", "Color HSI")              , KoCompositeOp::categoryHSI());
        add<&cfHue               <HSIType,Arg> >(cs, COMPOSITE_HUE_HSI           , i18nc("HSI Hue", "Hue HSI")                , KoCompositeOp::categoryHSI());
        add<&cfSaturation        <HSIType,Arg> >(cs, COMPOSITE_SATURATION_HSI    , i18nc("HSI Saturation", "Saturation HSI")         , KoCompositeOp::categoryHSI());
        add<&cfIncreaseSaturation<HSIType,Arg> >(cs, COMPOSITE_INC_SATURATION_HSI, i18nc("HSI Increase Saturation", "Increase Saturation HSI"), KoCompositeOp::categoryHSI());
        add<&cfDecreaseSaturation<HSIType,Arg> >(cs, COMPOSITE_DEC_SATURATION_HSI, i18nc("HSI Decrease Saturation", "Decrease Saturation HSI"), KoCompositeOp::categoryHSI());
        add<&cfLightness         <HSIType,Arg> >(cs, COMPOSITE_INTENSITY         , i18nc("HSI Intensity", "Intensity")              , KoCompositeOp::categoryHSI());
        add<&cfIncreaseLightness <HSIType,Arg> >(cs, COMPOSITE_INC_INTENSITY     , i18nc("HSI Increase Intensity", "Increase Intensity")     , KoCompositeOp::categoryHSI());
        add<&cfDecreaseLightness <HSIType,Arg> >(cs, COMPOSITE_DEC_INTENSITY     , i18nc("HSI Decrease Intensity", "Decrease Intensity")     , KoCompositeOp::categoryHSI());

        add<&cfColor             <HSLType,Arg> >(cs, COMPOSITE_COLOR_HSL         , i18nc("HSL Color", "Color HSL")              , KoCompositeOp::categoryHSL());
        add<&cfHue               <HSLType,Arg> >(cs, COMPOSITE_HUE_HSL           , i18nc("HSL HSL", "Hue HSL")                , KoCompositeOp::categoryHSL());
        add<&cfSaturation        <HSLType,Arg> >(cs, COMPOSITE_SATURATION_HSL    , i18nc("HSL Saturation", "Saturation HSL")         , KoCompositeOp::categoryHSL());
        add<&cfIncreaseSaturation<HSLType,Arg> >(cs, COMPOSITE_INC_SATURATION_HSL, i18nc("HSL Increase Saturation", "Increase Saturation HSL"), KoCompositeOp::categoryHSL());
        add<&cfDecreaseSaturation<HSLType,Arg> >(cs, COMPOSITE_DEC_SATURATION_HSL, i18nc("HSL Decrease Saturation", "Decrease Saturation HSL"), KoCompositeOp::categoryHSL());
        add<&cfLightness         <HSLType,Arg> >(cs, COMPOSITE_LIGHTNESS         , i18nc("HSL Lightness", "Lightness")              , KoCompositeOp::categoryHSL());
        add<&cfIncreaseLightness <HSLType,Arg> >(cs, COMPOSITE_INC_LIGHTNESS     , i18nc("HSL Increase Lightness", "Increase Lightness")     , KoCompositeOp::categoryHSL());
        add<&cfDecreaseLightness <HSLType,Arg> >(cs, COMPOSITE_DEC_LIGHTNESS     , i18nc("HSL Decrease Lightness", "Decrease Lightness")     , KoCompositeOp::categoryHSL());

        add<&cfColor             <HSVType,Arg> >(cs, COMPOSITE_COLOR_HSV         , i18nc("HSV Color", "Color HSV")              , KoCompositeOp::categoryHSV());
        add<&cfHue               <HSVType,Arg> >(cs, COMPOSITE_HUE_HSV           , i18nc("HSV Hue", "Hue HSV")                , KoCompositeOp::categoryHSV());
        add<&cfSaturation        <HSVType,Arg> >(cs, COMPOSITE_SATURATION_HSV    , i18nc("HSV Saturation", "Saturation HSV")         , KoCompositeOp::categoryHSV());
        add<&cfIncreaseSaturation<HSVType,Arg> >(cs, COMPOSITE_INC_SATURATION_HSV, i18nc("HSV Increase Saturation", "Increase Saturation HSV"), KoCompositeOp::categoryHSV());
        add<&cfDecreaseSaturation<HSVType,Arg> >(cs, COMPOSITE_DEC_SATURATION_HSV, i18nc("HSV Decrease Saturation", "Decrease Saturation HSV"), KoCompositeOp::categoryHSV());
        add<&cfLightness         <HSVType,Arg> >(cs, COMPOSITE_VALUE             , i18nc("HSV Value", "Value")                  , KoCompositeOp::categoryHSV());
        add<&cfIncreaseLightness <HSVType,Arg> >(cs, COMPOSITE_INC_VALUE         , i18nc("HSV Increase Value", "Increase Value")         , KoCompositeOp::categoryHSV());
        add<&cfDecreaseLightness <HSVType,Arg> >(cs, COMPOSITE_DEC_VALUE         , i18nc("HSV Decrease Value", "Decrease Value")         , KoCompositeOp::categoryHSV());
285 286 287
    }
};

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311



template<class Traits, bool flag>
struct AddGeneralAlphaOps
{
    static void add(KoColorSpace* cs) { Q_UNUSED(cs); }
};

template<class Traits>
struct AddGeneralAlphaOps<Traits, true>
{
    typedef float Arg;
    static const qint32 alpha_pos  = Traits::alpha_pos;
    template<void compositeFunc(Arg, Arg, Arg&, Arg&)>


    static void add(KoColorSpace* cs, const QString& id, const QString& description, const QString& category)
    {
        cs->addCompositeOp(new KoCompositeOpGenericSCAlpha<Traits, compositeFunc>(cs, id, description, category));
    }

    static void add(KoColorSpace* cs)
    {
312
        add<&cfAdditionSAI <HSVType,Arg> >(cs, COMPOSITE_LUMINOSITY_SAI         , i18n("Luminosity/Shine (SAI)")         , KoCompositeOp::categoryHSV());
313 314 315 316 317 318 319 320 321
    }


};





322
}
323

324 325 326 327




328 329 330 331 332 333 334
/**
 * This function add to the colorspace all the composite ops defined by
 * the pigment library.
 */
template<class _Traits_>
void addStandardCompositeOps(KoColorSpace* cs)
{
335
    typedef typename _Traits_::channels_type channels_type;
336

337
    static const bool useGeneralOps = true;
338 339
    static const bool useRGBOps = (boost::is_base_of<KoBgrTraits<channels_type>, _Traits_>::value
                                || boost::is_base_of<KoRgbTraits<channels_type>, _Traits_>::value);
340

341 342 343 344
    _Private::AddGeneralOps      <_Traits_, useGeneralOps>::add(cs);
    _Private::AddRGBOps          <_Traits_, useRGBOps    >::add(cs);
    _Private::AddGeneralAlphaOps <_Traits_, useGeneralOps>::add(cs);

345 346
}

347 348 349 350 351 352
template<class _Traits_>
KoCompositeOp* createAlphaDarkenCompositeOp(const KoColorSpace *cs)
{
    return _Private::OptimizedOpsSelector<_Traits_>::createAlphaDarkenOp(cs);
}

353
#endif