Commit d8964348 authored by José Luis Vergara's avatar José Luis Vergara
Browse files

Add the new Behind composite Op

BUG:300483
parent 90c81289
......@@ -68,6 +68,7 @@ KoCompositeOpRegistry::KoCompositeOpRegistry()
m_map.insert(m_categories[3], KoID(COMPOSITE_ARC_TANGENT , i18n("Arcus Tangent")));
m_map.insert(m_categories[4], KoID(COMPOSITE_OVER , i18n("Normal")));
m_map.insert(m_categories[4], KoID(COMPOSITE_BEHIND , i18n("Behind")));
m_map.insert(m_categories[4], KoID(COMPOSITE_OVERLAY , i18n("Overlay")));
m_map.insert(m_categories[4], KoID(COMPOSITE_ERASE , i18n("Erase")));
m_map.insert(m_categories[4], KoID(COMPOSITE_ALPHA_DARKEN , i18n("Alpha Darken")));
......
......@@ -47,7 +47,7 @@ const QString COMPOSITE_MULT = "multiply";
const QString COMPOSITE_DIVIDE = "divide";
const QString COMPOSITE_ARC_TANGENT = "arc_tangent";
const QString COMPOSITE_GEOMETRIC_MEAN = "geometric_mean";
const QString COMPOSITE_ADDITIVE_SUBTRACTIVE = "additive_subtractive";
const QString COMPOSITE_ADDITIVE_SUBTRACTIVE = "additive_subtractive";
const QString COMPOSITE_INVERTED_DIVIDE = "inverted_divide"; // XXX: not implemented anywhere yet
const QString COMPOSITE_EQUIVALENCE = "equivalence";
......@@ -58,6 +58,7 @@ const QString COMPOSITE_GRAIN_EXTRACT = "grain_extract";
const QString COMPOSITE_EXCLUSION = "exclusion";
const QString COMPOSITE_HARD_MIX = "hard mix";
const QString COMPOSITE_OVERLAY = "overlay";
const QString COMPOSITE_BEHIND = "behind";
const QString COMPOSITE_DARKEN = "darken";
const QString COMPOSITE_BURN = "burn";
......
/*
* Copyright (c) 2012 José Luis Vergara <pentalis@gmail.com>
*
* 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 _KOCOMPOSITEOPBEHIND_H_
#define _KOCOMPOSITEOPBEHIND_H_
#include "KoCompositeOpBase.h"
/**
* Generic implementation of the Behind composite op, which blends the colors of a foreground layer as if it were in the background instead
*/
template<class CS_Traits>
class KoCompositeOpBehind : public KoCompositeOpBase<CS_Traits, KoCompositeOpBehind<CS_Traits> >
{
typedef KoCompositeOpBase<CS_Traits, KoCompositeOpBehind<CS_Traits> > base_class;
typedef typename CS_Traits::channels_type channels_type;
static const qint8 channels_nb = CS_Traits::channels_nb;
static const qint8 alpha_pos = CS_Traits::alpha_pos;
public:
KoCompositeOpBehind(const KoColorSpace * cs)
: base_class(cs, COMPOSITE_BEHIND, i18n("Behind"), KoCompositeOp::categoryMix()) { }
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 maskAlpha, channels_type opacity,
const QBitArray& channelFlags ) {
using namespace Arithmetic;
if (dstAlpha == unitValue<channels_type>()) return dstAlpha;
channels_type appliedAlpha = mul(maskAlpha, srcAlpha, opacity);
if (appliedAlpha == zeroValue<channels_type>()) return dstAlpha;
channels_type newDstAlpha = unionShapeOpacity(dstAlpha, appliedAlpha);
if (dstAlpha != zeroValue<channels_type>()) {
// blend the color channels as if we were painting on the layer below
for (qint8 channel = 0; channel < channels_nb; ++channel)
if(channel != alpha_pos && (allChannelFlags || channelFlags.testBit(channel)))
dst[channel] = /*each color blended in proportion to their calculated opacity*/
( (dst[channel] * dstAlpha) + (src[channel] * (appliedAlpha - mul(dstAlpha, appliedAlpha))) )
/*------------------------------------------------------------------------------------------------*/
/ newDstAlpha; /*...divided by total new opacity*/
}
else {
// don't blend if the color of the destination is undefined (has zero opacity)
// copy the source channel instead
for (qint8 channel = 0; channel < channels_nb; ++channel)
if(channel != alpha_pos && (allChannelFlags || channelFlags.testBit(channel)))
dst[channel] = src[channel];
}
return newDstAlpha;
}
};
#endif // _KOCOMPOSITEOPBEHIND_H_
\ No newline at end of file
......@@ -47,6 +47,8 @@
#include "compositeops/KoCompositeOpSoftlight.h"
#include "compositeops/KoCompositeOpHardlight.h"
#include "compositeops/KoCompositeOpBehind.h"
namespace _Private {
template<class Traits, bool flag>
......@@ -72,6 +74,7 @@ struct AddGeneralOps<Traits, true>
cs->addCompositeOp(new KoCompositeOpAlphaDarken<Traits>(cs));
cs->addCompositeOp(new KoCompositeOpCopy2<Traits>(cs));
cs->addCompositeOp(new KoCompositeOpErase<Traits>(cs));
cs->addCompositeOp(new KoCompositeOpBehind<Traits>(cs));
add<&cfOverlay<Arg> >(cs, COMPOSITE_OVERLAY , i18n("Overlay") , KoCompositeOp::categoryMix());
add<&cfGrainMerge<Arg> >(cs, COMPOSITE_GRAIN_MERGE , i18n("Grain Merge") , KoCompositeOp::categoryMix());
......@@ -107,7 +110,7 @@ struct AddGeneralOps<Traits, true>
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());
add<&cfAdditiveSubtractive<Arg> >(cs, COMPOSITE_ADDITIVE_SUBTRACTIVE, i18n("Additive-Subtractive"), KoCompositeOp::categoryNegative());
add<&cfAdditiveSubtractive<Arg> >(cs, COMPOSITE_ADDITIVE_SUBTRACTIVE , i18n("Additive-Subtractive") , KoCompositeOp::categoryNegative());
cs->addCompositeOp(new KoCompositeOpDissolve<Traits>(cs, KoCompositeOp::categoryMisc()));
}
......
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