diff --git a/libs/image/kis_curve_circle_mask_generator.cpp b/libs/image/kis_curve_circle_mask_generator.cpp index 77a39565a7..88853ee2fb 100644 --- a/libs/image/kis_curve_circle_mask_generator.cpp +++ b/libs/image/kis_curve_circle_mask_generator.cpp @@ -1,192 +1,187 @@ /* * Copyright (c) 2010 Lukáš Tvrdý * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include //MSVC requires that Vc come first #include #include #ifdef HAVE_VC #if defined(__clang__) #pragma GCC diagnostic ignored "-Wundef" #pragma GCC diagnostic ignored "-Wlocal-type-template-args" #endif #if defined _MSC_VER // Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false' #pragma warning ( push ) #pragma warning ( disable : 4244 ) #pragma warning ( disable : 4800 ) #endif #include #include #if defined _MSC_VER #pragma warning ( pop ) #endif #endif #include #include #include #include #include "kis_fast_math.h" #include "kis_base_mask_generator.h" #include "kis_antialiasing_fade_maker.h" #include "kis_brush_mask_applicator_factories.h" #include "kis_curve_circle_mask_generator.h" #include "kis_curve_circle_mask_generator_p.h" #include "kis_cubic_curve.h" KisCurveCircleMaskGenerator::KisCurveCircleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, const KisCubicCurve &curve, bool antialiasEdges) : KisMaskGenerator(diameter, ratio, fh, fv, spikes, antialiasEdges, CIRCLE, SoftId), d(new Private(antialiasEdges)) { // here we set resolution for the maximum size of the brush! d->curveResolution = qRound(qMax(width(), height()) * OVERSAMPLING); d->curveData = curve.floatTransfer(d->curveResolution + 2); d->curvePoints = curve.points(); setCurveString(curve.toString()); d->dirty = false; setScale(1.0, 1.0); d->applicator.reset(createOptimizedClass >(this)); } KisCurveCircleMaskGenerator::KisCurveCircleMaskGenerator(const KisCurveCircleMaskGenerator &rhs) : KisMaskGenerator(rhs), d(new Private(*rhs.d)) { d->applicator.reset(createOptimizedClass >(this)); } KisCurveCircleMaskGenerator::~KisCurveCircleMaskGenerator() { } KisMaskGenerator* KisCurveCircleMaskGenerator::clone() const { return new KisCurveCircleMaskGenerator(*this); } void KisCurveCircleMaskGenerator::setScale(qreal scaleX, qreal scaleY) { KisMaskGenerator::setScale(scaleX, scaleY); qreal width = effectiveSrcWidth(); qreal height = effectiveSrcHeight(); d->xcoef = 2.0 / width; d->ycoef = 2.0 / height; d->fadeMaker.setSquareNormCoeffs(d->xcoef, d->ycoef); } -bool KisCurveCircleMaskGenerator::shouldSupersample() const -{ - return effectiveSrcWidth() < 10 || effectiveSrcHeight() < 10; -} - bool KisCurveCircleMaskGenerator::shouldVectorize() const { return !shouldSupersample() && spikes() == 2; } KisBrushMaskApplicatorBase* KisCurveCircleMaskGenerator::applicator() { return d->applicator.data(); } inline quint8 KisCurveCircleMaskGenerator::Private::value(qreal dist) const { qreal distance = dist * curveResolution; quint16 alphaValue = distance; qreal alphaValueF = distance - alphaValue; qreal alpha = ( (1.0 - alphaValueF) * curveData.at(alphaValue) + alphaValueF * curveData.at(alphaValue+1)); return (1.0 - alpha) * 255; } quint8 KisCurveCircleMaskGenerator::valueAt(qreal x, qreal y) const { if (isEmpty()) return 255; qreal xr = x; qreal yr = qAbs(y); fixRotation(xr, yr); qreal dist = norme(xr * d->xcoef, yr * d->ycoef); quint8 value; if (d->fadeMaker.needFade(dist, &value)) { return value; } return d->value(dist); } void KisCurveCircleMaskGenerator::toXML(QDomDocument& doc, QDomElement& e) const { KisMaskGenerator::toXML(doc, e); e.setAttribute("softness_curve", curveString()); } void KisCurveCircleMaskGenerator::setSoftness(qreal softness) { // performance if (!d->dirty && softness == 1.0) return; d->dirty = true; KisMaskGenerator::setSoftness(softness); KisCurveCircleMaskGenerator::transformCurveForSoftness(softness,d->curvePoints, d->curveResolution+2, d->curveData); d->dirty = false; } void KisCurveCircleMaskGenerator::transformCurveForSoftness(qreal softness,const QList &points, int curveResolution, QVector< qreal >& result) { QList newList = points; newList.detach(); int size = newList.size(); if (size == 2){ // make place for new point in the centre newList.append(newList.at(1)); newList[1] = (newList.at(0) + newList.at(2)) * 0.5; // transoform it newList[1].setY(qBound(0.0,newList.at(1).y() * softness,1.0)); }else{ // transform all points except first and last for (int i = 1; i < size-1; i++){ newList[i].setY(qBound(0.0,newList.at(i).y() * softness,1.0)); } } // compute the data KisCubicCurve curve(newList); result = curve.floatTransfer( curveResolution ); } void KisCurveCircleMaskGenerator::resetMaskApplicator(bool forceScalar) { d->applicator.reset(createOptimizedClass >(this,forceScalar)); } diff --git a/libs/image/kis_curve_circle_mask_generator.h b/libs/image/kis_curve_circle_mask_generator.h index 1b75196209..49a37fe5a6 100644 --- a/libs/image/kis_curve_circle_mask_generator.h +++ b/libs/image/kis_curve_circle_mask_generator.h @@ -1,78 +1,76 @@ /* * Copyright (c) 2010 Lukáš Tvrdý * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _KIS_CURVE_CIRCLE_MASK_GENERATOR_H_ #define _KIS_CURVE_CIRCLE_MASK_GENERATOR_H_ #include #include #include #include "kritaimage_export.h" #include "kis_mask_generator.h" class KisCubicCurve; class QDomElement; class QDomDocument; class QPointF; /** * This mask generator use softness/hardness defined by user curve * It used to be soft brush paintop. */ class KRITAIMAGE_EXPORT KisCurveCircleMaskGenerator : public KisMaskGenerator { public: struct FastRowProcessor; public: KisCurveCircleMaskGenerator(qreal radius, qreal ratio, qreal fh, qreal fv, int spikes,const KisCubicCurve& curve, bool antialiasEdges); KisCurveCircleMaskGenerator(const KisCurveCircleMaskGenerator &rhs); ~KisCurveCircleMaskGenerator() override; KisMaskGenerator* clone() const override; quint8 valueAt(qreal x, qreal y) const override; void setScale(qreal scaleX, qreal scaleY) override; - bool shouldSupersample() const override; - void toXML(QDomDocument& , QDomElement&) const override; void setSoftness(qreal softness) override; bool shouldVectorize() const override; KisBrushMaskApplicatorBase* applicator() override; void resetMaskApplicator(bool forceScalar); static void transformCurveForSoftness(qreal softness,const QList &points, int curveResolution, QVector &result); private: qreal norme(qreal a, qreal b) const { return a*a + b*b; } private: struct Private; const QScopedPointer d; }; #endif diff --git a/libs/image/kis_gauss_rect_mask_generator.cpp b/libs/image/kis_gauss_rect_mask_generator.cpp index 621501a608..6f629de92f 100644 --- a/libs/image/kis_gauss_rect_mask_generator.cpp +++ b/libs/image/kis_gauss_rect_mask_generator.cpp @@ -1,149 +1,144 @@ /* * Copyright (c) 2010 Lukáš Tvrdý * Copyright (c) 2011 Geoffry Song * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include //MSVC requires that Vc come first #include #include #include #ifdef HAVE_VC #if defined(__clang__) #pragma GCC diagnostic ignored "-Wundef" #pragma GCC diagnostic ignored "-Wlocal-type-template-args" #endif #if defined _MSC_VER // Lets shut up the "possible loss of data" and "forcing value to bool 'true' or 'false' #pragma warning ( push ) #pragma warning ( disable : 4244 ) #pragma warning ( disable : 4800 ) #endif #include #include #if defined _MSC_VER #pragma warning ( pop ) #endif #endif #include #include #include #include #include "kis_fast_math.h" #include "kis_base_mask_generator.h" #include "kis_antialiasing_fade_maker.h" #include "kis_brush_mask_applicator_factories.h" #include "kis_brush_mask_applicator_base.h" #include "kis_gauss_rect_mask_generator.h" #include "kis_gauss_rect_mask_generator_p.h" #define M_SQRT_2 1.41421356237309504880 #ifdef Q_OS_WIN // on windows we get our erf() from boost #include #define erf(x) boost::math::erf(x) #endif KisGaussRectangleMaskGenerator::KisGaussRectangleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges) : KisMaskGenerator(diameter, ratio, fh, fv, spikes, antialiasEdges, RECTANGLE, GaussId), d(new Private(antialiasEdges)) { setScale(1.0, 1.0); d->applicator.reset(createOptimizedClass >(this)); } KisGaussRectangleMaskGenerator::KisGaussRectangleMaskGenerator(const KisGaussRectangleMaskGenerator &rhs) : KisMaskGenerator(rhs), d(new Private(*rhs.d)) { d->applicator.reset(createOptimizedClass >(this)); } KisMaskGenerator* KisGaussRectangleMaskGenerator::clone() const { return new KisGaussRectangleMaskGenerator(*this); } void KisGaussRectangleMaskGenerator::setScale(qreal scaleX, qreal scaleY) { KisMaskGenerator::setScale(scaleX, scaleY); qreal width = effectiveSrcWidth(); qreal height = effectiveSrcHeight(); qreal xfade = (1.0 - horizontalFade()/2.0) * width * 0.1; qreal yfade = (1.0 - verticalFade()/2.0) * height * 0.1; d->xfade = 1.0 / (M_SQRT_2 * xfade); d->yfade = 1.0 / (M_SQRT_2 * yfade); d->halfWidth = width * 0.5 - 2.5 * xfade; d->halfHeight = height * 0.5 - 2.5 * yfade; d->alphafactor = 255.0 / (4.0 * erf(d->halfWidth * d->xfade) * erf(d->halfHeight * d->yfade)); d->fadeMaker.setLimits(0.5 * width, 0.5 * height); } KisGaussRectangleMaskGenerator::~KisGaussRectangleMaskGenerator() { } inline quint8 KisGaussRectangleMaskGenerator::Private::value(qreal xr, qreal yr) const { return (quint8) 255 - (quint8) (alphafactor * (erf((halfWidth + xr) * xfade) + erf((halfWidth - xr) * xfade)) * (erf((halfHeight + yr) * yfade) + erf((halfHeight - yr) * yfade))); } quint8 KisGaussRectangleMaskGenerator::valueAt(qreal x, qreal y) const { if (isEmpty()) return 255; qreal xr = x; qreal yr = qAbs(y); fixRotation(xr, yr); quint8 value; if (d->fadeMaker.needFade(xr, yr, &value)) { return value; } return d->value(xr, yr); } -bool KisGaussRectangleMaskGenerator::shouldSupersample() const -{ - return effectiveSrcWidth() < 10 || effectiveSrcHeight() < 10; -} - bool KisGaussRectangleMaskGenerator::shouldVectorize() const { return !shouldSupersample() && spikes() == 2; } KisBrushMaskApplicatorBase* KisGaussRectangleMaskGenerator::applicator() { return d->applicator.data(); } void KisGaussRectangleMaskGenerator::resetMaskApplicator(bool forceScalar) { d->applicator.reset(createOptimizedClass >(this,forceScalar)); } diff --git a/libs/image/kis_gauss_rect_mask_generator.h b/libs/image/kis_gauss_rect_mask_generator.h index 2360a9a3dd..2500e8f70d 100644 --- a/libs/image/kis_gauss_rect_mask_generator.h +++ b/libs/image/kis_gauss_rect_mask_generator.h @@ -1,54 +1,53 @@ /* * Copyright (c) 2010 Lukáš Tvrdý * Copyright (c) 2011 Geoffry Song * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _KIS_GAUSS_RECT_MASK_GENERATOR_H_ #define _KIS_GAUSS_RECT_MASK_GENERATOR_H_ #include "kritaimage_export.h" #include "kis_mask_generator.h" /** * This mask generator uses a Gaussian-blurred rectangle */ class KRITAIMAGE_EXPORT KisGaussRectangleMaskGenerator : public KisMaskGenerator { public: struct FastRowProcessor; public: KisGaussRectangleMaskGenerator(qreal diameter, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges); KisGaussRectangleMaskGenerator(const KisGaussRectangleMaskGenerator &rhs); ~KisGaussRectangleMaskGenerator() override; KisMaskGenerator* clone() const override; quint8 valueAt(qreal x, qreal y) const override; void setScale(qreal scaleX, qreal scaleY) override; - bool shouldSupersample() const override; bool shouldVectorize() const override; KisBrushMaskApplicatorBase* applicator() override; void resetMaskApplicator(bool forceScalar); private: struct Private; const QScopedPointer d; }; #endif