File indexing completed on 2024-05-19 04:26:32

0001 /*
0002  *  SPDX-FileCopyrightText: 2004, 2007-2010 Cyrille Berger <cberger@cberger.net>
0003  *  SPDX-FileCopyrightText: 2018 Ivan Santa Maria <ghevan@gmail.com>
0004  *  SPDX-FileCopyrightText: 2022 L. E. Segovia <amy@amyspark.me>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include <cmath>
0010 
0011 
0012 #include <QDomDocument>
0013 
0014 #include "KoMultiArchBuildSupport.h"
0015 #include "kis_base_mask_generator.h"
0016 #include "kis_fast_math.h"
0017 #include "kis_rect_mask_generator.h"
0018 #include "kis_rect_mask_generator_p.h"
0019 
0020 
0021 #include "kis_brush_mask_applicator_factories.h"
0022 #include "kis_brush_mask_applicator_base.h"
0023 
0024 #include <qnumeric.h>
0025 
0026 KisRectangleMaskGenerator::KisRectangleMaskGenerator(qreal radius, qreal ratio, qreal fh, qreal fv, int spikes, bool antialiasEdges)
0027     : KisMaskGenerator(radius, ratio, fh, fv, spikes, antialiasEdges, RECTANGLE, DefaultId), d(new Private)
0028 {
0029     setScale(1.0, 1.0);
0030 
0031     // store the variable locally to allow vector implementation read it easily
0032     d->copyOfAntialiasEdges = antialiasEdges;
0033     d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisRectangleMaskGenerator>>(this));
0034 }
0035 
0036 KisRectangleMaskGenerator::KisRectangleMaskGenerator(const KisRectangleMaskGenerator &rhs)
0037     : KisMaskGenerator(rhs),
0038       d(new Private(*rhs.d))
0039 {
0040     d->applicator.reset(createOptimizedClass<MaskApplicatorFactory<KisRectangleMaskGenerator>>(this));
0041 }
0042 
0043 KisMaskGenerator* KisRectangleMaskGenerator::clone() const
0044 {
0045     return new KisRectangleMaskGenerator(*this);
0046 }
0047 
0048 KisRectangleMaskGenerator::~KisRectangleMaskGenerator()
0049 {
0050 }
0051 
0052 void KisRectangleMaskGenerator::setScale(qreal scaleX, qreal scaleY)
0053 {
0054     KisMaskGenerator::setScale(scaleX, scaleY);
0055 
0056     d->xcoeff = 2.0 / effectiveSrcWidth();
0057     d->ycoeff = 2.0 / effectiveSrcHeight();
0058     d->xfadecoeff = (horizontalFade() == 0) ? 1 : (2.0 / (horizontalFade() * effectiveSrcWidth()));
0059     d->yfadecoeff = (verticalFade() == 0)   ? 1 : (2.0 / (verticalFade() * effectiveSrcHeight()));
0060 
0061     setSoftness(this->softness());
0062 }
0063 
0064 void KisRectangleMaskGenerator::setSoftness(qreal softness)
0065 {
0066     KisMaskGenerator::setSoftness(softness);
0067     qreal safeSoftnessCoeff = qreal(1.0) / qMax(qreal(0.01), softness);
0068 
0069     d->transformedFadeX = d->xfadecoeff * safeSoftnessCoeff;
0070     d->transformedFadeY = d->yfadecoeff * safeSoftnessCoeff;
0071 }
0072 
0073 bool KisRectangleMaskGenerator::shouldVectorize() const
0074 {
0075     return !shouldSupersample() && spikes() == 2;
0076 }
0077 
0078 KisBrushMaskApplicatorBase *KisRectangleMaskGenerator::applicator() const
0079 {
0080     return d->applicator.data();
0081 }
0082 
0083 void KisRectangleMaskGenerator::setMaskScalarApplicator()
0084 {
0085     d->applicator.reset(
0086         createScalarClass<MaskApplicatorFactory<KisRectangleMaskGenerator>>(
0087             this));
0088 }
0089 
0090 quint8 KisRectangleMaskGenerator::valueAt(qreal x, qreal y) const
0091 {
0092     if (isEmpty()) return 255;
0093     qreal xr = qAbs(x /*- m_xcenter*/);
0094     qreal yr = qAbs(y /*- m_ycenter*/);
0095     fixRotation(xr, yr);
0096 
0097     xr = qAbs(xr);
0098     yr = qAbs(yr);
0099 
0100     qreal nxr = xr * d->xcoeff;
0101     qreal nyr = yr * d->ycoeff;
0102 
0103     if (nxr > 1.0 || nyr > 1.0) return 255;
0104 
0105     if (antialiasEdges()) {
0106         xr += 1.0;
0107         yr += 1.0;
0108     }
0109 
0110     qreal fxr = xr * d->transformedFadeX;
0111     qreal fyr = yr * d->transformedFadeY;
0112 
0113     qreal fxnorm = nxr * (fxr - 1.0) / (fxr - nxr);
0114     qreal fynorm = nyr * (fyr - 1.0) / (fyr - nyr);
0115 
0116     qreal retValue = 0;
0117 
0118     if(fxr > 1.0) {
0119         retValue = fxnorm;
0120      }
0121 
0122     if (fxnorm < fynorm && fyr > 1.0) {
0123         retValue = fynorm;
0124      }
0125 
0126     return retValue * 255;
0127 }
0128