Untitled
unknown
c_cpp
2 years ago
3.5 kB
7
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...