File indexing completed on 2024-05-12 15:59:05
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #include "Filter.h" 0007 0008 #include <KoCanvasResourceProvider.h> 0009 0010 #include <kis_canvas_resource_provider.h> 0011 #include <kis_filter.h> 0012 #include <kis_properties_configuration.h> 0013 #include <kis_filter_configuration.h> 0014 #include <kis_filter_manager.h> 0015 #include <kis_filter_registry.h> 0016 #include <KisDocument.h> 0017 #include <kis_paint_device.h> 0018 #include <kis_paint_device_frames_interface.h> 0019 #include <KisPart.h> 0020 #include <KisView.h> 0021 0022 #include <strokes/kis_filter_stroke_strategy.h> 0023 #include <krita_utils.h> 0024 #include <KisGlobalResourcesInterface.h> 0025 0026 #include "Krita.h" 0027 #include "Document.h" 0028 #include "InfoObject.h" 0029 #include "Node.h" 0030 0031 struct Filter::Private { 0032 Private() {} 0033 QString name; 0034 InfoObject *configuration {0}; 0035 }; 0036 0037 Filter::Filter() 0038 : QObject(0) 0039 , d(new Private) 0040 { 0041 } 0042 0043 Filter::~Filter() 0044 { 0045 delete d->configuration; 0046 delete d; 0047 } 0048 0049 bool Filter::operator==(const Filter &other) const 0050 { 0051 return (d->name == other.d->name 0052 && d->configuration == other.d->configuration); 0053 } 0054 0055 bool Filter::operator!=(const Filter &other) const 0056 { 0057 return !(operator==(other)); 0058 } 0059 0060 0061 QString Filter::name() const 0062 { 0063 return d->name; 0064 } 0065 0066 void Filter::setName(const QString &name) 0067 { 0068 d->name = name; 0069 delete d->configuration; 0070 0071 KisFilterSP filter = KisFilterRegistry::instance()->value(d->name); 0072 d->configuration = new InfoObject(filter->defaultConfiguration(KisGlobalResourcesInterface::instance())); 0073 } 0074 0075 InfoObject* Filter::configuration() const 0076 { 0077 return d->configuration; 0078 } 0079 0080 void Filter::setConfiguration(InfoObject* value) 0081 { 0082 d->configuration = value; 0083 } 0084 0085 bool Filter::apply(Node *node, int x, int y, int w, int h) 0086 { 0087 if (node->locked()) return false; 0088 0089 KisFilterSP filter = KisFilterRegistry::instance()->value(d->name); 0090 if (!filter) return false; 0091 0092 KisPaintDeviceSP dev = node->paintDevice(); 0093 if (!dev) return false; 0094 0095 QRect applyRect = QRect(x, y, w, h); 0096 KisFilterConfigurationSP config = static_cast<KisFilterConfiguration*>(d->configuration->configuration().data()); 0097 filter->process(dev, applyRect, config->cloneWithResourcesSnapshot()); 0098 return true; 0099 } 0100 0101 bool Filter::startFilter(Node *node, int x, int y, int w, int h) 0102 { 0103 if (node->locked()) return false; 0104 0105 KisFilterSP filter = KisFilterRegistry::instance()->value(d->name); 0106 if (!filter) return false; 0107 0108 KisImageWSP image = node->image(); 0109 if (!image) return false; 0110 0111 KisFilterConfigurationSP filterConfig = static_cast<KisFilterConfiguration*>(d->configuration->configuration().data()); 0112 0113 image->waitForDone(); 0114 QRect initialApplyRect = QRect(x, y, w, h); 0115 0116 QRect applyRect = initialApplyRect; 0117 0118 KisPaintDeviceSP paintDevice = node->paintDevice(); 0119 if (paintDevice && filter->needsTransparentPixels(filterConfig.data(), paintDevice->colorSpace())) { 0120 applyRect |= image->bounds(); 0121 } 0122 0123 KisResourcesSnapshotSP resources = new KisResourcesSnapshot(image, node->node()); 0124 0125 Document *document = Krita::instance()->activeDocument(); 0126 if (document && KisPart::instance()->viewCount(document->document()) > 0) { 0127 Q_FOREACH (QPointer<KisView> view, KisPart::instance()->views()) { 0128 if (view && view->document() == document->document()) { 0129 resources = new KisResourcesSnapshot(image, node->node(), view->resourceProvider()->resourceManager()); 0130 break; 0131 } 0132 } 0133 } 0134 delete document; 0135 0136 KisStrokeId currentStrokeId = image->startStroke(new KisFilterStrokeStrategy(filter, 0137 KisFilterConfigurationSP(filterConfig), 0138 resources)); 0139 0140 QRect processRect = filter->changedRect(applyRect, filterConfig.data(), 0); 0141 processRect &= image->bounds(); 0142 0143 image->addJob(currentStrokeId, new KisFilterStrokeStrategy::FilterJobData()); 0144 0145 0146 image->endStroke(currentStrokeId); 0147 image->waitForDone(); 0148 0149 return true; 0150 } 0151 0152 KisFilterConfigurationSP Filter::filterConfig() 0153 { 0154 KisFilterConfigurationSP config = KisFilterRegistry::instance()->get(d->name)->factoryConfiguration(KisGlobalResourcesInterface::instance()); 0155 Q_FOREACH(const QString property, d->configuration->properties().keys()) { 0156 config->setProperty(property, d->configuration->property(property)); 0157 } 0158 return config; 0159 }