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