Untitled
unknown
c_cpp
3 years ago
3.5 kB
11
Indexable
#ifndef KOCOMPOSITEOPWETOVER_H
#define KOCOMPOSITEOPWETOVER_H
#include "KoCompositeOpBase.h"
#include "KoCompositeOpFunctions.h"
#include "KoCompositeOpRegistry.h"
/**
* Wet Normal compositor - uses the greater of two alpha values as final alpha,
* color channels are blended with Over function (Normal blend).
*/
template<class CS_Traits>
class KoCompositeOpWetOver : public KoCompositeOpBase<CS_Traits, KoCompositeOpWetOver<CS_Traits>>
{
typedef KoCompositeOpBase<CS_Traits, KoCompositeOpWetOver<CS_Traits>> base_class;
typedef typename CS_Traits::channels_type channels_type;
typedef typename KoColorSpaceMathsTraits<typename CS_Traits::channels_type>::compositetype composite_type;
static const qint8 channels_nb = CS_Traits::channels_nb;
static const qint8 alpha_pos = CS_Traits::alpha_pos;
public:
KoCompositeOpWetOver(const KoColorSpace *cs)
: base_class(cs, COMPOSITE_WET_OVER, 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;
srcAlpha = mul(srcAlpha, maskAlpha, opacity);
if (alphaLocked) {
if (dstAlpha != zeroValue<channels_type>()) {
for (qint32 i = 0; i < channels_nb; i++) {
if (i != alpha_pos && (allChannelFlags || channelFlags.testBit(i)))
dst[i] = lerp(dst[i], cfOver(src[i], dst[i]), srcAlpha);
}
}
return dstAlpha;
} else {
channels_type newDstAlpha = unionShapeOpacity(srcAlpha, dstAlpha);
if (newDstAlpha != zeroValue<channels_type>()) {
for (qint32 i = 0; i < channels_nb; i++) {
if (i != alpha_pos && (allChannelFlags || channelFlags.testBit(i))) {
//channels_type result = blend(src[i], srcAlpha, dst[i], dstAlpha, src[i]);
channels_type result = blend(src[i], srcAlpha, dst[i], dstAlpha, cfOver(src[i], dst[i]));
dst[i] = div(result, newDstAlpha);
}
}
}
float dA = scale<float>(dstAlpha);
float w = 1.0 / (1.0 + exp(-40.0 * (dA - scale<float>(srcAlpha))));
float a = dA * w + scale<float>(srcAlpha) * (1.0 - w);
if (a < 0.0f) {
a = 0.0f;
}
if (a > 1.0f) {
a = 1.0f;
}
// For a standard Over, the resulting alpha is: a = opacity*dstAlpha + (1-opacity)*srcAlpha
// Let us assume we're blending with a color with srcAlpha = 1 here
// Therefore, opacity = (1.0 - a)/(1.0 - dstAlpha)
if (a < dA)
a = dA;
// float fakeOpacity = 1.0f - (1.0f - a)/(1.0f - dA + 1e-16f);
newDstAlpha = scale<channels_type>(a);
return newDstAlpha;
}
}
};
#endif // KOCOMPOSITEOPWETOVER_H
Editor is loading...