Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_gauss_circle_mask_generator.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
3 * SPDX-FileCopyrightText: 2011 Geoffry Song <goffrie@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#include <cmath>
9
10#include <QDomDocument>
11
13
14#include "kis_fast_math.h"
15
22
23#define M_SQRT_2 1.41421356237309504880
24
25#ifdef Q_OS_WIN
26// on windows we get our erf() from boost
27#include <boost/math/special_functions/erf.hpp>
28#define erf(x) boost::math::erf(x)
29#endif
30
31
32KisGaussCircleMaskGenerator::KisGaussCircleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges)
33 : KisMaskGenerator(diameter, ratio, fh, fv, spikes, antialiasEdges, CIRCLE, GaussId),
34 d(new Private(antialiasEdges))
35{
36 d->ycoef = 1.0 / ratio;
37 d->fade = 1.0 - (fh + fv) / 2.0;
38
39 if (d->fade == 0.0) d->fade = 1e-6;
40 else if (d->fade == 1.0) d->fade = 1.0 - 1e-6; // would become undefined for fade == 0 or 1
41
42 d->center = (2.5 * (6761.0*d->fade-10000.0))/(M_SQRT_2*6761.0*d->fade);
43 d->alphafactor = 255.0 / (2.0 * erf(d->center));
44
46
47}
48
55
60
61void KisGaussCircleMaskGenerator::setScale(qreal scaleX, qreal scaleY)
62{
64 d->ycoef = scaleX / (scaleY * ratio());
65
66 d->distfactor = M_SQRT_2 * 12500.0 / (6761.0 * d->fade * effectiveSrcWidth() / 2.0);
67 d->fadeMaker.setRadius(0.5 * effectiveSrcWidth());
68}
69
73
74inline quint8 KisGaussCircleMaskGenerator::Private::value(qreal dist) const
75{
76 dist *= distfactor;
77 quint8 ret = alphafactor * (erf(dist + center) - erf(dist - center));
78 return (quint8) 255 - ret;
79}
80
82{
83 return !shouldSupersample() && spikes() == 2;
84}
85
87{
88 return d->applicator.data();
89}
90
91quint8 KisGaussCircleMaskGenerator::valueAt(qreal x, qreal y) const
92{
93 if (isEmpty()) return 255;
94 qreal xr = x;
95 qreal yr = qAbs(y);
96 fixRotation(xr, yr);
97
98 qreal dist = sqrt(norme(xr, yr * d->ycoef));
99
100 quint8 value;
101 if (d->fadeMaker.needFade(dist, &value)) {
102 return value;
103 }
104
105 return d->value(dist);
106}
107
float value(const T *src, size_t ch)
auto createOptimizedClass(Args &&...param)
auto createScalarClass(Args &&...params)
QScopedPointer< KisBrushMaskApplicatorBase > applicator
KisGaussCircleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges)
quint8 valueAt(qreal x, qreal y) const override
void setScale(qreal scaleX, qreal scaleY) override
KisMaskGenerator * clone() const override
const QScopedPointer< Private > d
virtual bool shouldSupersample() const
const QScopedPointer< Private > d
void fixRotation(qreal &xr, qreal &yr) const
virtual void setScale(qreal scaleX, qreal scaleY)
const KoID GaussId("gauss", ki18n("Gaussian"))
generate brush mask with a Gaussian-blurred edge