8#ifndef KISMASKINGBRUSHCOMPOSITEOP_H
9#define KISMASKINGBRUSHCOMPOSITEOP_H
21#include <kritaui_export.h>
46template <
typename channels_type>
55template <
typename channels_type,
int composite_function,
bool use_strength,
bool use_soft_texturing>
58template <
typename channels_type>
61 channels_type
apply(channels_type src, channels_type dst)
67template <
typename channels_type>
73 channels_type
apply(channels_type src, channels_type dst)
79template <
typename channels_type>
90 channels_type
apply(channels_type src, channels_type dst)
96template <
typename channels_type>
99 channels_type
apply(channels_type src, channels_type dst)
105template <
typename channels_type>
111 channels_type
apply(channels_type src, channels_type dst)
117template <
typename channels_type>
128 channels_type
apply(channels_type src, channels_type dst)
134template <
typename channels_type>
137 channels_type
apply(channels_type src, channels_type dst)
143template <
typename channels_type>
149 channels_type
apply(channels_type src, channels_type dst)
155template <
typename channels_type>
166 channels_type
apply(channels_type src, channels_type dst)
196 if (isUnitValueFuzzy<T>(src)) {
197 return isZeroValueFuzzy<T>(dst) ? zeroValue<T>() : unitValue<T>();
206inline typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type
214inline typename std::enable_if<!std::numeric_limits<T>::is_integer, T>::type
223template <
typename channels_type>
226 channels_type
apply(channels_type src, channels_type dst)
232template <
typename channels_type,
bool use_soft_texturing>
238 channels_type
apply(channels_type src, channels_type dst)
240 if constexpr (use_soft_texturing) {
263 if(isZeroValueFuzzy<T>(src)) {
264 return isUnitValueFuzzy<T>(dst) ? zeroValue<T>() : unitValue<T>();
279template <
typename channels_type>
282 channels_type
apply(channels_type src, channels_type dst)
288template <
typename channels_type>
294 channels_type
apply(channels_type src, channels_type dst)
300template <
typename channels_type>
311 channels_type
apply(channels_type src, channels_type dst)
324template <
typename channels_type>
327 channels_type
apply(channels_type src, channels_type dst)
331 if (isZeroValueFuzzy<channels_type>(dst)) {
332 return zeroValue<channels_type>();
334 return qMin(composite_type(src) + dst, composite_type(unitValue<channels_type>()));
338template <
typename channels_type,
bool use_soft_texturing>
344 channels_type
apply(channels_type src, channels_type dst)
348 if (isZeroValueFuzzy<channels_type>(dst)) {
349 return zeroValue<channels_type>();
351 if constexpr (use_soft_texturing) {
353 composite_type(unitValue<channels_type>()));
356 composite_type(unitValue<channels_type>()));
368template <
typename channels_type>
371 channels_type
apply(channels_type src, channels_type dst)
376 composite_type(src) + dst - unitValue<channels_type>());
380template <
typename channels_type>
386 channels_type
apply(channels_type src, channels_type dst)
390 return qMax(composite_type(zeroValue<channels_type>()),
392 - unitValue<channels_type>());
396template <
typename channels_type>
407 channels_type
apply(channels_type src, channels_type dst)
411 return qMax(composite_type(zeroValue<channels_type>()),
412 composite_type(unionShapeOpacity(src, invertedStrength) + dst - unitValue<channels_type>()));
416template <
typename channels_type>
419 channels_type
apply(channels_type src, channels_type dst)
425template <
typename channels_type>
431 channels_type
apply(channels_type src, channels_type dst)
437template <
typename channels_type>
448 channels_type
apply(channels_type src, channels_type dst)
467 const composite_type srcScaleFactor =
static_cast<composite_type
>(2);
468 const composite_type dstScaleFactor =
static_cast<composite_type
>(3);
470 dstScaleFactor * dst - srcScaleFactor * inv(src),
474template <
typename channels_type>
477 channels_type
apply(channels_type src, channels_type dst)
483template <
typename channels_type,
bool use_soft_texturing>
489 channels_type
apply(channels_type src, channels_type dst)
491 if constexpr (use_soft_texturing) {
507template <
typename channels_type>
510 channels_type
apply(channels_type src, channels_type dst)
515 composite_type(dst) - src);
519template <
typename channels_type>
530 channels_type
apply(channels_type src, channels_type dst)
534 return qMax(composite_type(zeroValue<channels_type>()),
535 composite_type(dst) - (composite_type(src) + invertedStrength));
539template <
typename channels_type>
545 channels_type
apply(channels_type src, channels_type dst)
554template <
typename channels_type,
bool use_soft_texturing>
565 channels_type
apply(channels_type src, channels_type dst)
569 if constexpr (use_soft_texturing) {
570 return kisBoundFast(composite_type(zeroValue<channels_type>()),
571 div(dst, invertedStrength) -
573 composite_type(unitValue<channels_type>()));
575 return kisBoundFast(composite_type(zeroValue<channels_type>()),
576 div(dst, invertedStrength) - (composite_type(src) + invertedStrength),
577 composite_type(unitValue<channels_type>()));
582template <
typename channels_type,
bool use_soft_texturing>
593 channels_type
apply(channels_type src, channels_type dst)
598 if constexpr (use_soft_texturing) {
599 const composite_type modifiedDst = div(dst, invertedStrength);
601 const composite_type multiply = modifiedDst * inv(srcTimesStrength) / unitValue<channels_type>();
602 const composite_type height = modifiedDst - srcTimesStrength;
603 return kisBoundFast(composite_type(zeroValue<channels_type>()),
604 qMax(multiply, height),
605 composite_type(unitValue<channels_type>()));
607 const composite_type modifiedDst = div(dst, invertedStrength) - invertedStrength;
608 const composite_type multiply = modifiedDst * inv(src) / unitValue<channels_type>();
609 const composite_type height = modifiedDst - src;
610 return kisBoundFast(composite_type(zeroValue<channels_type>()),
611 qMax(multiply, height),
612 composite_type(unitValue<channels_type>()));
617template <
typename channels_type>
629 channels_type
apply(channels_type src, channels_type dst)
633 dst * weight / unitValue<channels_type>() - src,
638template <
typename channels_type>
650 channels_type
apply(channels_type src, channels_type dst)
660template <
typename channels_type>
673 channels_type
apply(channels_type src, channels_type dst)
676 const composite_type modifiedDst = dst * weight / unitValue<channels_type>();
677 const composite_type multiply = inv(src) * modifiedDst / unitValue<channels_type>();
680 qMax(multiply, height),
685template <
typename channels_type>
698 channels_type
apply(channels_type src, channels_type dst)
701 const composite_type modifiedDst = dst + dst * weight / unitValue<channels_type>();
703 const composite_type multiply = modifiedDst * inv(srcTimesStrength) / unitValue<channels_type>();
706 qMax(multiply, height),
713template <
typename channels_type,
int composite_function,
bool mask_is_alpha =
false,
714 bool use_strength =
false,
bool use_soft_texturing =
false>
718 using MaskPixel =
typename std::conditional<mask_is_alpha, quint8, KoGrayU8Traits::Pixel>::type;
720 template <bool use_strength_ = use_strength, typename = typename std::enable_if<!use_strength_>::type>
726 template <bool use_strength_ = use_strength, typename = typename std::enable_if<use_strength_>::type>
733 void composite(
const quint8 *srcRowStart,
int srcRowStride,
734 quint8 *dstRowStart,
int dstRowStride,
735 int columns,
int rows)
override
739 for (
int y = 0; y < rows; y++) {
740 const quint8 *srcPtr = srcRowStart;
741 quint8 *dstPtr = dstRowStart;
743 for (
int x = 0; x < columns; x++) {
750 channels_type *dstDataPtr =
reinterpret_cast<channels_type*
>(dstPtr);
757 srcRowStart += srcRowStride;
758 dstRowStart += dstRowStride;
KisMaskingBrushCompositeFuncTypes
@ KIS_MASKING_BRUSH_COMPOSITE_BURN
@ KIS_MASKING_BRUSH_COMPOSITE_LINEAR_HEIGHT_PHOTOSHOP
@ KIS_MASKING_BRUSH_COMPOSITE_SUBTRACT
@ KIS_MASKING_BRUSH_COMPOSITE_HEIGHT
@ KIS_MASKING_BRUSH_COMPOSITE_DODGE
@ KIS_MASKING_BRUSH_COMPOSITE_LINEAR_DODGE
@ KIS_MASKING_BRUSH_COMPOSITE_MULT
@ KIS_MASKING_BRUSH_COMPOSITE_OVERLAY
@ KIS_MASKING_BRUSH_COMPOSITE_HARD_MIX_SOFTER_PHOTOSHOP
@ KIS_MASKING_BRUSH_COMPOSITE_HARD_MIX_PHOTOSHOP
@ KIS_MASKING_BRUSH_COMPOSITE_DARKEN
@ KIS_MASKING_BRUSH_COMPOSITE_HEIGHT_PHOTOSHOP
@ KIS_MASKING_BRUSH_COMPOSITE_LINEAR_HEIGHT
@ KIS_MASKING_BRUSH_COMPOSITE_LINEAR_BURN
T cfMultiply(T src, T dst)
T cfDarkenOnly(T src, T dst)
KisMaskingBrushCompositeDetail::CompositeFunction< channels_type, composite_function, use_strength, use_soft_texturing > m_compositeFunction
quint8 preprocessMask(const KoGrayU8Traits::Pixel *pixel)
void composite(const quint8 *srcRowStart, int srcRowStride, quint8 *dstRowStart, int dstRowStride, int columns, int rows) override
KisMaskingBrushCompositeOp(int dstPixelSize, int dstAlphaOffset)
quint8 preprocessMask(const quint8 *pixel)
typename std::conditional< mask_is_alpha, quint8, KoGrayU8Traits::Pixel >::type MaskPixel
KisMaskingBrushCompositeOp(int dstPixelSize, int dstAlphaOffset, qreal strength)
static _Tdst multiply(_T a, _Tdst b)
static _Tdst scaleToA(_T a)
constexpr const T & kisBoundFast(const T &min, const T &val, const T &max)
T unionShapeOpacity(T a, T b)
std::enable_if< std::numeric_limits< T >::is_integer, T >::type colorDodgeAlpha(T src, T dst)
T colorBurnAlpha(T src, T dst)
T colorDodgeAlphaHelper(T src, T dst)
T hardMixSofterPhotoshopAlpha(T src, T dst)
T colorBurnAlphaHelper(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
const channels_type invertedStrength
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
const composite_type weight
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
typename KoColorSpaceMathsTraits< channels_type >::compositetype composite_type
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
const channels_type invertedStrength
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
typename KoColorSpaceMathsTraits< channels_type >::compositetype composite_type
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
const composite_type weight
channels_type apply(channels_type src, channels_type dst)
const channels_type invertedStrength
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
const channels_type invertedStrength
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
typename KoColorSpaceMathsTraits< channels_type >::compositetype composite_type
const composite_type weight
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
const channels_type invertedStrength
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
const channels_type invertedStrength
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
const channels_type invertedStrength
const composite_type weight
channels_type apply(channels_type src, channels_type dst)
typename KoColorSpaceMathsTraits< channels_type >::compositetype composite_type
CompositeFunction(qreal strength)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
channels_type apply(channels_type src, channels_type dst)
channels_type apply(channels_type src, channels_type dst)
CompositeFunction(qreal strength)
const channels_type invertedStrength
CompositeFunction(qreal strength)
const channels_type invertedStrength
channels_type apply(channels_type src, channels_type dst)
StrengthCompositeFunctionBase(qreal strength)
const channels_type strength