Krita Source Code Documentation
Loading...
Searching...
No Matches
KoCompositeOpAlphaDarken.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006 Cyrille Berger <cberger@cberger.net>
3 * SPDX-FileCopyrightText: 2011 Silvio Heinrich <plassy@web.de>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8#ifndef KOCOMPOSITEOPALPHADARKEN_H_
9#define KOCOMPOSITEOPALPHADARKEN_H_
10
11#include "KoColorSpaceMaths.h"
12#include "KoCompositeOpBase.h"
14
18template<class Traits, class ParamsWrapper>
20{
21 typedef typename Traits::channels_type channels_type;
22
23 static const qint32 channels_nb = Traits::channels_nb;
24 static const qint32 alpha_pos = Traits::alpha_pos;
25
26public:
29
31
32 void composite(const KoCompositeOp::ParameterInfo& params) const override
33 {
34 if(params.maskRowStart != 0)
35 genericComposite<true>(params);
36 else
37 genericComposite<false>(params);
38 }
39
40 template<bool useMask>
42 {
43 using namespace Arithmetic;
44
45 ParamsWrapper paramsWrapper(params);
46
47 qint32 srcInc = (params.srcRowStride == 0) ? 0 : channels_nb;
48 channels_type flow = scale<channels_type>(paramsWrapper.flow);
49 channels_type opacity = scale<channels_type>(paramsWrapper.opacity);
50 quint8* dstRowStart = params.dstRowStart;
51 const quint8* srcRowStart = params.srcRowStart;
52 const quint8* maskRowStart = params.maskRowStart;
53
54 for (qint32 r = params.rows; r > 0; --r) {
55 const channels_type* src = reinterpret_cast<const channels_type*>(srcRowStart);
56 channels_type* dst = reinterpret_cast<channels_type*>(dstRowStart);
57 const quint8* mask = maskRowStart;
58
59 for(qint32 c=params.cols; c>0; --c) {
60 channels_type srcAlpha = (alpha_pos == -1) ? unitValue<channels_type>() : src[alpha_pos];
61 channels_type dstAlpha = (alpha_pos == -1) ? unitValue<channels_type>() : dst[alpha_pos];
62 channels_type mskAlpha = useMask ? mul(scale<channels_type>(*mask), srcAlpha) : srcAlpha;
63
64 srcAlpha = mul(mskAlpha, opacity);
65
66 if(dstAlpha != zeroValue<channels_type>()) {
67 for(qint32 i=0; i <channels_nb; i++) {
68 if(i != alpha_pos)
69 dst[i] = lerp(dst[i], src[i], srcAlpha);
70 }
71 }
72 else {
73 for(qint32 i=0; i <channels_nb; i++) {
74 if(i != alpha_pos)
75 dst[i] = src[i];
76 }
77 }
78
79 if(alpha_pos != -1) {
80 dst[alpha_pos] = calculateAlpha(params, paramsWrapper, flow, opacity, srcAlpha, dstAlpha, mskAlpha);
81 }
82
83 src += srcInc;
84 dst += channels_nb;
85
86 if(useMask)
87 ++mask;
88 }
89
90 srcRowStart += params.srcRowStride;
91 dstRowStart += params.dstRowStride;
92 maskRowStart += params.maskRowStride;
93 }
94 }
95
97 const ParamsWrapper &paramsWrapper,
98 channels_type flow,
99 channels_type opacity,
100 channels_type srcAlpha,
101 channels_type dstAlpha,
102 channels_type mskAlpha)
103 {
104 using namespace Arithmetic;
105
106 channels_type fullFlowAlpha;
107 channels_type averageOpacity = scale<channels_type>(paramsWrapper.averageOpacity);
108
114 if (averageOpacity > opacity) {
127 channels_type reverseBlend = KoColorSpaceMaths<channels_type>::divide(dstAlpha, averageOpacity);
128 fullFlowAlpha = averageOpacity > dstAlpha ? lerp(srcAlpha, averageOpacity, reverseBlend) : dstAlpha;
129 } else {
130 fullFlowAlpha = opacity > dstAlpha ? lerp(dstAlpha, opacity, mskAlpha) : dstAlpha;
131 }
132
133 if (params.flow == 1.0f) {
134 return fullFlowAlpha;
135 } else {
136 channels_type zeroFlowAlpha = ParamsWrapper::calculateZeroFlowAlphaLegacy(srcAlpha, dstAlpha);
137 return lerp(zeroFlowAlpha, fullFlowAlpha, flow);
138 }
139 }
140};
141
142#endif // KOCOMPOSITEOPALPHADARKEN_H_
const QString COMPOSITE_ALPHA_DARKEN
QPointF lerp(const QPointF &p1, const QPointF &p2, qreal t)
static dst_compositetype divide(_T a, _Tdst b)
void genericComposite(const KoCompositeOp::ParameterInfo &params) const
void composite(const KoCompositeOp::ParameterInfo &params) const override
Traits::channels_type channels_type
static channels_type calculateAlpha(const KoCompositeOp::ParameterInfo &params, const ParamsWrapper &paramsWrapper, channels_type flow, channels_type opacity, channels_type srcAlpha, channels_type dstAlpha, channels_type mskAlpha)
KoCompositeOpAlphaDarken(const KoColorSpace *cs)
void composite(quint8 *dstRowStart, qint32 dstRowStride, const quint8 *srcRowStart, qint32 srcRowStride, const quint8 *maskRowStart, qint32 maskRowStride, qint32 rows, qint32 numColumns, float opacity, const QBitArray &channelFlags=QBitArray()) const
static QString categoryMix()