File indexing completed on 2024-12-22 04:11:38
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com> 0003 * SPDX-FileCopyrightText: 2012 José Luis Vergara <pentalis@gmail.com> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #ifndef _KOCOMPOSITEOPDESTINATIONATOP_H_ 0009 #define _KOCOMPOSITEOPDESTINATIONATOP_H_ 0010 0011 #include "KoCompositeOpBase.h" 0012 0013 /** 0014 * Generic implementation of the Destination-atop composite op, based off the behind composite op. 0015 * This is necessary for Open Raster support. 0016 * https://www.w3.org/TR/compositing-1/ 0017 */ 0018 template<class CS_Traits> 0019 class KoCompositeOpDestinationAtop : public KoCompositeOpBase<CS_Traits, KoCompositeOpDestinationAtop<CS_Traits> > 0020 { 0021 typedef KoCompositeOpBase<CS_Traits, KoCompositeOpDestinationAtop<CS_Traits> > base_class; 0022 typedef typename CS_Traits::channels_type channels_type; 0023 0024 static const qint8 channels_nb = CS_Traits::channels_nb; 0025 static const qint8 alpha_pos = CS_Traits::alpha_pos; 0026 0027 public: 0028 KoCompositeOpDestinationAtop(const KoColorSpace * cs) 0029 : base_class(cs, COMPOSITE_DESTINATION_ATOP, KoCompositeOp::categoryMix()) { } 0030 0031 public: 0032 template<bool alphaLocked, bool allChannelFlags> 0033 inline static channels_type composeColorChannels(const channels_type* src, channels_type srcAlpha, 0034 channels_type* dst, channels_type dstAlpha, 0035 channels_type maskAlpha, channels_type opacity, 0036 const QBitArray& channelFlags ) { 0037 using namespace Arithmetic; 0038 0039 channels_type appliedAlpha = mul(maskAlpha, srcAlpha, opacity); 0040 0041 channels_type newDstAlpha = appliedAlpha; 0042 0043 if (dstAlpha != zeroValue<channels_type>() && srcAlpha != zeroValue<channels_type>()) { 0044 // blend the color channels as if we were painting on the layer below 0045 for (qint8 channel = 0; channel < channels_nb; ++channel) 0046 if(channel != alpha_pos && (allChannelFlags || channelFlags.testBit(channel))) { 0047 dst[channel] = lerp(src[channel],dst[channel],dstAlpha); 0048 } 0049 } 0050 else if (srcAlpha != zeroValue<channels_type>()) { 0051 // don't blend if the color of the destination is undefined (has zero opacity) 0052 // copy the source channel instead 0053 for (qint8 channel = 0; channel < channels_nb; ++channel) 0054 if(channel != alpha_pos && (allChannelFlags || channelFlags.testBit(channel))) 0055 dst[channel] = src[channel]; 0056 } 0057 0058 return newDstAlpha; 0059 } 0060 }; 0061 0062 #endif // _KOCOMPOSITEOPDESTINATIONATOP_H_