File indexing completed on 2024-05-26 04:33:20
0001 /* 0002 * This file is part of Krita 0003 * 0004 * SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include <KisSequentialIteratorProgress.h> 0010 #include <KoUpdater.h> 0011 #include <cstring> 0012 #include <filter/kis_filter_configuration.h> 0013 #include <generator/kis_generator_registry.h> 0014 #include <kis_debug.h> 0015 #include <kis_fill_painter.h> 0016 #include <kis_global.h> 0017 #include <kis_image.h> 0018 #include <kis_layer.h> 0019 #include <kis_paint_device.h> 0020 #include <kis_processing_information.h> 0021 #include <kis_selection.h> 0022 #include <kis_types.h> 0023 #include <klocalizedstring.h> 0024 #include <kpluginfactory.h> 0025 0026 #include "SeExprExpressionContext.h" 0027 #include "generator.h" 0028 #include "kis_wdg_seexpr.h" 0029 #include "ui_wdgseexpr.h" 0030 0031 /****************************************************************************/ 0032 /* KisSeExprGeneratorConfiguration */ 0033 /****************************************************************************/ 0034 0035 class KisSeExprGeneratorConfiguration : public KisFilterConfiguration 0036 { 0037 public: 0038 KisSeExprGeneratorConfiguration(const QString &name, qint32 version, KisResourcesInterfaceSP resourcesInterface) 0039 : KisFilterConfiguration(name, version, resourcesInterface) 0040 { 0041 } 0042 0043 KisSeExprGeneratorConfiguration(const KisSeExprGeneratorConfiguration &rhs) 0044 : KisFilterConfiguration(rhs) 0045 { 0046 } 0047 0048 virtual KisFilterConfigurationSP clone() const override 0049 { 0050 return new KisSeExprGeneratorConfiguration(*this); 0051 } 0052 0053 QString script() const 0054 { 0055 return this->getString("script", QStringLiteral(BASE_SCRIPT)); 0056 } 0057 }; 0058 0059 K_PLUGIN_FACTORY_WITH_JSON(KritaSeExprGeneratorFactory, "generator.json", registerPlugin<KritaSeExprGenerator>();) 0060 0061 KritaSeExprGenerator::KritaSeExprGenerator(QObject *parent, const QVariantList &) 0062 : QObject(parent) 0063 { 0064 KisGeneratorRegistry::instance()->add(new KisSeExprGenerator()); 0065 } 0066 0067 KritaSeExprGenerator::~KritaSeExprGenerator() 0068 { 0069 } 0070 0071 KisSeExprGenerator::KisSeExprGenerator() 0072 : KisGenerator(id(), KoID("basic"), i18n("&SeExpr...")) 0073 { 0074 setColorSpaceIndependence(FULLY_INDEPENDENT); 0075 setSupportsPainting(true); 0076 } 0077 0078 KisFilterConfigurationSP KisSeExprGenerator::factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const 0079 { 0080 return new KisSeExprGeneratorConfiguration(id().id(), 1, resourcesInterface); 0081 } 0082 0083 KisFilterConfigurationSP KisSeExprGenerator::defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const 0084 { 0085 KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface); 0086 0087 QVariant v; 0088 v.setValue(QString("Disney_noisecolor2")); 0089 config->setProperty("pattern", v); 0090 return config; 0091 } 0092 0093 KisConfigWidget *KisSeExprGenerator::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const 0094 { 0095 Q_UNUSED(dev); 0096 return new KisWdgSeExpr(parent); 0097 } 0098 0099 void KisSeExprGenerator::generate(KisProcessingInformation dstInfo, const QSize &size, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const 0100 { 0101 KisPaintDeviceSP device = dstInfo.paintDevice(); 0102 0103 Q_ASSERT(!device.isNull()); 0104 Q_ASSERT(config); 0105 0106 if (config) { 0107 QString script = config->getString("script"); 0108 0109 QRect bounds = QRect(dstInfo.topLeft(), size); 0110 QRect whole_image_bounds = device->defaultBounds()->bounds(); 0111 0112 SeExprExpressionContext expression(script); 0113 0114 expression.m_vars["u"] = new SeExprVariable(); 0115 expression.m_vars["v"] = new SeExprVariable(); 0116 expression.m_vars["w"] = new SeExprVariable(whole_image_bounds.width()); 0117 expression.m_vars["h"] = new SeExprVariable(whole_image_bounds.height()); 0118 0119 if (expression.isValid() && expression.returnType().isFP(3)) { 0120 double pixel_stride_x = 1. / whole_image_bounds.width(); 0121 double pixel_stride_y = 1. / whole_image_bounds.height(); 0122 double &u = expression.m_vars["u"]->m_value; 0123 double &v = expression.m_vars["v"]->m_value; 0124 0125 // SeExpr already outputs floating-point RGB 0126 const KoColorSpace *dst = device->colorSpace(); 0127 const KoColorSpace *src = KoColorSpaceRegistry::instance()->colorSpace(RGBAColorModelID.id(), Float32BitsColorDepthID.id(), KoColorSpaceRegistry::instance()->p709SRGBProfile()); 0128 auto conv = KoColorSpaceRegistry::instance()->createColorConverter(src, dst, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()); 0129 0130 KisSequentialIteratorProgress it(device, bounds, progressUpdater); 0131 0132 while (it.nextPixel()) { 0133 u = pixel_stride_x * (it.x() + .5); 0134 v = pixel_stride_y * (it.y() + .5); 0135 0136 const double *value = expression.evalFP(); 0137 0138 KoColor c(src); 0139 reinterpret_cast<float *>(c.data())[0] = value[0]; 0140 reinterpret_cast<float *>(c.data())[1] = value[1]; 0141 reinterpret_cast<float *>(c.data())[2] = value[2]; 0142 c.setOpacity(OPACITY_OPAQUE_F); 0143 0144 conv->transform(c.data(), it.rawData(), 1); 0145 } 0146 delete conv; 0147 } 0148 } 0149 } 0150 0151 #include "generator.moc"