File indexing completed on 2024-05-12 15:58:11
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_cached_gradient_shape_strategy.h" 0008 0009 #include <QRect> 0010 #include "bsplines/kis_bspline_2d.h" 0011 0012 #include <cmath> 0013 0014 #include <functional> 0015 0016 #include "kis_algebra_2d.h" 0017 #include "kis_debug.h" 0018 0019 0020 using namespace KisBSplines; 0021 0022 struct Q_DECL_HIDDEN KisCachedGradientShapeStrategy::Private 0023 { 0024 QRect rc; 0025 qreal xStep; 0026 qreal yStep; 0027 QScopedPointer<KisGradientShapeStrategy> baseStrategy; 0028 QScopedPointer<KisBSpline2D> spline; 0029 }; 0030 0031 KisCachedGradientShapeStrategy::KisCachedGradientShapeStrategy(const QRect &rc, 0032 qreal xStep, 0033 qreal yStep, 0034 KisGradientShapeStrategy *baseStrategy) 0035 : KisGradientShapeStrategy(), 0036 m_d(new Private()) 0037 { 0038 using namespace std::placeholders; // for _1, _2, _3... 0039 0040 KIS_ASSERT_RECOVER_NOOP(rc.width() >= 3 && rc.height() >= 3); 0041 0042 m_d->rc = rc; 0043 m_d->xStep = xStep; 0044 m_d->yStep = yStep; 0045 m_d->baseStrategy.reset(baseStrategy); 0046 0047 qreal xStart = rc.x(); 0048 qreal yStart = rc.y(); 0049 qreal xEnd = rc.x() + rc.width(); 0050 qreal yEnd = rc.y() + rc.height(); 0051 0052 int numSamplesX = std::ceil(qreal(rc.width()) / xStep); 0053 int numSamplesY = std::ceil(qreal(rc.height()) / yStep); 0054 0055 if (numSamplesX < 2 || numSamplesY < 2) { 0056 warnKrita; 0057 warnKrita << "############"; 0058 warnKrita << "WARNING: KisCachedGradientShapeStrategy numSamplesX/Y is too small!" << ppVar(numSamplesX) << ppVar(numSamplesY); 0059 warnKrita << "WARNING:" << ppVar(rc) << ppVar(xStep) << ppVar(yStep); 0060 warnKrita << "WARNING:" << ppVar(numSamplesX) << ppVar(numSamplesY); 0061 0062 numSamplesX = qMax(numSamplesX, 2); 0063 numSamplesY = qMax(numSamplesY, 2); 0064 0065 warnKrita << "WARNING: adjusting:" << ppVar(numSamplesX) << ppVar(numSamplesY); 0066 warnKrita << "############"; 0067 warnKrita; 0068 } 0069 0070 m_d->spline.reset(new KisBSpline2D(xStart, xEnd, numSamplesX, Natural, 0071 yStart, yEnd, numSamplesY, Natural)); 0072 0073 0074 std::function<qreal(qreal, qreal)> valueOp = 0075 std::bind(&KisGradientShapeStrategy::valueAt, m_d->baseStrategy.data(), _1, _2); 0076 0077 m_d->spline->initializeSpline(valueOp); 0078 0079 } 0080 0081 KisCachedGradientShapeStrategy::~KisCachedGradientShapeStrategy() 0082 { 0083 } 0084 0085 double KisCachedGradientShapeStrategy::valueAt(double x, double y) const 0086 { 0087 QPointF pt = KisAlgebra2D::ensureInRect(QPointF(x, y), m_d->rc); 0088 return m_d->spline->value(pt.x(), pt.y()); 0089 }