Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_curve_rect_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
11#include <kis_fast_math.h>
15
19#include "kis_cubic_curve.h"
20
21
22KisCurveRectangleMaskGenerator::KisCurveRectangleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, const KisCubicCurve &curve, bool antialiasEdges)
23 : KisMaskGenerator(diameter, ratio, fh, fv, spikes, antialiasEdges, RECTANGLE, SoftId), d(new Private(antialiasEdges))
24{
25 d->curveResolution = qRound( qMax(width(),height()) * OVERSAMPLING);
26 d->curveData = curve.floatTransfer( d->curveResolution + 1);
27 d->curvePoints = curve.curvePoints();
28 setCurveString(curve.toString());
29 d->dirty = false;
30
31 setScale(1.0, 1.0);
32
34}
35
42
47
48void KisCurveRectangleMaskGenerator::setScale(qreal scaleX, qreal scaleY)
49{
51
52 qreal halfWidth = 0.5 * effectiveSrcWidth();
53 qreal halfHeight = 0.5 * effectiveSrcHeight();
54
55 d->xcoeff = 1.0 / halfWidth;
56 d->ycoeff = 1.0 / halfHeight;
57
58 d->fadeMaker.setLimits(halfWidth, halfHeight);
59}
60
64
65quint8 KisCurveRectangleMaskGenerator::Private::value(qreal xr, qreal yr) const
66{
67 xr = qAbs(xr) * xcoeff;
68 yr = qAbs(yr) * ycoeff;
69
70 int sIndex = qRound(xr * (curveResolution));
71 int tIndex = qRound(yr * (curveResolution));
72
73 int sIndexInverted = curveResolution - sIndex;
74 int tIndexInverted = curveResolution - tIndex;
75
76 qreal blend = (curveData.at(sIndex) * (1.0 - curveData.at(sIndexInverted)) *
77 curveData.at(tIndex) * (1.0 - curveData.at(tIndexInverted)));
78
79 return (1.0 - blend) * 255;
80}
81
82quint8 KisCurveRectangleMaskGenerator::valueAt(qreal x, qreal y) const
83{
84 if (isEmpty()) return 255;
85 qreal xr = x;
86 qreal yr = qAbs(y);
87 fixRotation(xr, yr);
88
89 quint8 value;
90 if (d->fadeMaker.needFade(xr, yr, &value)) {
91 return value;
92 }
93
94 return d->value(xr, yr);
95}
96
97void KisCurveRectangleMaskGenerator::toXML(QDomDocument& doc, QDomElement& e) const
98{
100 e.setAttribute("softness_curve", curveString());
101}
102
104{
105 // performance
106 if (!d->dirty && softness == 1.0) return;
107 d->dirty = true;
109 KisCurveCircleMaskGenerator::transformCurveForSoftness(softness,d->curvePoints, d->curveResolution + 1, d->curveData);
110 d->dirty = false;
111}
112
114{
115 return !shouldSupersample() && spikes() == 2;
116}
117
119{
120 return d->applicator.data();
121}
122
129
float value(const T *src, size_t ch)
auto createOptimizedClass(Args &&...param)
auto createScalarClass(Args &&...params)
static void transformCurveForSoftness(qreal softness, const QList< KisCubicCurvePoint > &points, int curveResolution, QVector< qreal > &result)
void toXML(QDomDocument &, QDomElement &) const override
KisCurveRectangleMaskGenerator(qreal radius, qreal ratio, qreal fh, qreal fv, int spikes, const KisCubicCurve &curve, bool antialiasEdges)
void setScale(qreal scaleX, qreal scaleY) override
QScopedPointer< KisBrushMaskApplicatorBase > applicator
quint8 valueAt(qreal x, qreal y) const override
KisMaskGenerator * clone() const override
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