Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_curve_circle_mask_generator.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include <cmath>
8
9#include <QDomDocument>
10#include <QVector>
11
13
16
19#include "kis_cubic_curve.h"
20
21
22KisCurveCircleMaskGenerator::KisCurveCircleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, const KisCubicCurve &curve, bool antialiasEdges)
23 : KisMaskGenerator(diameter, ratio, fh, fv, spikes, antialiasEdges, CIRCLE, SoftId), d(new Private(antialiasEdges))
24{
25 // here we set resolution for the maximum size of the brush!
26 d->curveResolution = qRound(qMax(width(), height()) * OVERSAMPLING);
27 d->curveData = curve.floatTransfer(d->curveResolution + 2);
28 d->curvePoints = curve.curvePoints();
29 setCurveString(curve.toString());
30 d->dirty = false;
31
32 setScale(1.0, 1.0);
33
35}
36
43
47
52
53void KisCurveCircleMaskGenerator::setScale(qreal scaleX, qreal scaleY)
54{
56
57 qreal width = effectiveSrcWidth();
58 qreal height = effectiveSrcHeight();
59
60 d->xcoef = 2.0 / width;
61 d->ycoef = 2.0 / height;
62
63 d->fadeMaker.setSquareNormCoeffs(d->xcoef, d->ycoef);
64}
65
67{
68 return !shouldSupersample() && spikes() == 2;
69}
70
72{
73 return d->applicator.data();
74}
75
76inline quint8 KisCurveCircleMaskGenerator::Private::value(qreal dist) const
77{
78 qreal distance = dist * curveResolution;
79
80 quint16 alphaValue = distance;
81 qreal alphaValueF = distance - alphaValue;
82
83 qreal alpha = (
84 (1.0 - alphaValueF) * curveData.at(alphaValue) +
85 alphaValueF * curveData.at(alphaValue+1));
86
87 return (1.0 - alpha) * 255;
88}
89
90quint8 KisCurveCircleMaskGenerator::valueAt(qreal x, qreal y) const
91{
92 if (isEmpty()) return 255;
93 qreal xr = x;
94 qreal yr = qAbs(y);
95 fixRotation(xr, yr);
96
97 qreal dist = norme(xr * d->xcoef, yr * d->ycoef);
98
99 quint8 value;
100 if (d->fadeMaker.needFade(dist, &value)) {
101 return value;
102 }
103
104 return d->value(dist);
105}
106
107void KisCurveCircleMaskGenerator::toXML(QDomDocument& doc, QDomElement& e) const
108{
110 e.setAttribute("softness_curve", curveString());
111}
112
114{
115 // performance
116 if (!d->dirty && softness == 1.0) return;
117
118 d->dirty = true;
120 KisCurveCircleMaskGenerator::transformCurveForSoftness(softness,d->curvePoints, d->curveResolution+2, d->curveData);
121 d->dirty = false;
122}
123
125{
126 QList<KisCubicCurvePoint> newList = points;
127 newList.detach();
128
129 int size = newList.size();
130 if (size == 2){
131 // make place for new point in the centre
132 newList.append(newList.at(1));
133 newList[1].setPosition((newList.at(0).position() + newList.at(2).position()) * 0.5);
134 newList[1].setAsCorner(false);
135 // transform it
136 newList[1].setY(qBound<qreal>(0.0,newList.at(1).y() * softness,1.0));
137 }else{
138 // transform all points except first and last
139 for (int i = 1; i < size-1; i++){
140 newList[i].setY(qBound<qreal>(0.0,newList.at(i).y() * softness,1.0));
141 }
142 }
143
144 // compute the data
145 KisCubicCurve curve(newList);
146 result = curve.floatTransfer( curveResolution );
147}
148
float value(const T *src, size_t ch)
qreal distance(const QPointF &p1, const QPointF &p2)
auto createOptimizedClass(Args &&...param)
auto createScalarClass(Args &&...params)
quint8 valueAt(qreal x, qreal y) const override
const QScopedPointer< Private > d
static void transformCurveForSoftness(qreal softness, const QList< KisCubicCurvePoint > &points, int curveResolution, QVector< qreal > &result)
void toXML(QDomDocument &, QDomElement &) const override
KisCurveCircleMaskGenerator(qreal radius, qreal ratio, qreal fh, qreal fv, int spikes, const KisCubicCurve &curve, bool antialiasEdges)
KisMaskGenerator * clone() const override
void setScale(qreal scaleX, qreal scaleY) override
QScopedPointer< KisBrushMaskApplicatorBase > applicator
void setCurveString(const QString &curveString)
virtual void setSoftness(qreal softness)
virtual bool shouldSupersample() const
virtual void toXML(QDomDocument &, QDomElement &) const
const QScopedPointer< Private > d
void fixRotation(qreal &xr, qreal &yr) const
virtual void setScale(qreal scaleX, qreal scaleY)
const KoID SoftId("soft", ki18n("Soft"))
generate brush mask from former softbrush paintop, where softness is based on curve
static const int OVERSAMPLING
QString toString() const
const QVector< qreal > floatTransfer(int size=256) const
const QList< KisCubicCurvePoint > & curvePoints() const