File indexing completed on 2024-12-22 04:11:39

0001 /*
0002  *  SPDX-FileCopyrightText: 2006 Cyrille Berger <cberger@cberger.net>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #ifndef _KOCOMPOSITEOPOVER_H_
0008 #define _KOCOMPOSITEOPOVER_H_
0009 
0010 #include "KoCompositeOpAlphaBase.h"
0011 #include <KoCompositeOpRegistry.h>
0012 #include <klocalizedstring.h>
0013 
0014 template<class _CSTraits, int channel>
0015 struct KoCompositeOpOverCompositor {
0016     typedef typename _CSTraits::channels_type channels_type;
0017     inline static void composeColorChannels(channels_type srcBlend,
0018                                             const channels_type* srcN,
0019                                             channels_type* dstN,
0020                                             bool allChannelFlags,
0021                                             const QBitArray & channelFlags) {
0022         if (channel != _CSTraits::alpha_pos && (allChannelFlags || channelFlags.testBit(channel)))
0023             dstN[channel] = KoColorSpaceMaths<channels_type>::blend(srcN[channel], dstN[channel], srcBlend);
0024         KoCompositeOpOverCompositor<_CSTraits, channel - 1>::composeColorChannels(srcBlend, srcN, dstN, allChannelFlags, channelFlags);
0025     }
0026 };
0027 
0028 template<class _CSTraits>
0029 struct KoCompositeOpOverCompositor<_CSTraits, -1> {
0030     typedef typename _CSTraits::channels_type channels_type;
0031     inline static void composeColorChannels(channels_type /*srcBlend*/,
0032                                             const channels_type* /*srcN*/,
0033                                             channels_type* /*dstN*/,
0034                                             bool /*allChannelFlags*/,
0035                                             const QBitArray & /*channelFlags*/) {
0036     }
0037 };
0038 
0039 /**
0040  * A template version of the over composite operation to use in colorspaces.
0041  */
0042 template<class _CSTraits>
0043 class KoCompositeOpOver : public KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpOver<_CSTraits>, false >
0044 {
0045     typedef typename _CSTraits::channels_type channels_type;
0046 public:
0047 
0048     KoCompositeOpOver(const KoColorSpace * cs)
0049             : KoCompositeOpAlphaBase<_CSTraits, KoCompositeOpOver<_CSTraits>, false >(cs, COMPOSITE_OVER, KoCompositeOp::categoryMix()) {
0050     }
0051 
0052 public:
0053     inline static channels_type selectAlpha(channels_type srcAlpha, channels_type dstAlpha) {
0054         Q_UNUSED(dstAlpha);
0055         return srcAlpha;
0056     }
0057 
0058 public:
0059    inline static void composeColorChannels(channels_type srcBlend,
0060                                             const channels_type* srcN,
0061                                             channels_type* dstN,
0062                                             bool allChannelFlags,
0063                                             const QBitArray & channelFlags) {
0064         if (srcBlend == NATIVE_OPACITY_OPAQUE) {
0065             for (int i = 0; (uint)i <  _CSTraits::channels_nb; i++) {
0066                 if (i != _CSTraits::alpha_pos && (allChannelFlags || channelFlags.testBit(i)))
0067                     dstN[i] = srcN[i];
0068             }
0069         } else {
0070             KoCompositeOpOverCompositor<_CSTraits, _CSTraits::channels_nb-1>::composeColorChannels(srcBlend, srcN, dstN, allChannelFlags, channelFlags);
0071         }
0072     }
0073 
0074 };
0075 
0076 #endif