Krita

Filter.cpp
1 /*
2  * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <[email protected]>
3  *
4  * SPDX-License-Identifier: LGPL-2.0-or-later
5  */
6 #include "Filter.h"
7 
8 #include <KoCanvasResourceProvider.h>
9 
10 #include <kis_canvas_resource_provider.h>
11 #include <kis_filter.h>
12 #include <kis_properties_configuration.h>
13 #include <kis_filter_configuration.h>
14 #include <kis_filter_manager.h>
15 #include <kis_filter_registry.h>
16 #include <KisDocument.h>
17 #include <kis_paint_device.h>
18 #include <kis_paint_device_frames_interface.h>
19 #include <KisPart.h>
20 #include <KisView.h>
21 
22 #include <strokes/kis_filter_stroke_strategy.h>
23 #include <krita_utils.h>
24 #include <KisGlobalResourcesInterface.h>
25 
26 #include "Krita.h"
27 #include "Document.h"
28 #include "InfoObject.h"
29 #include "Node.h"
30 
31 struct Filter::Private {
32  Private() {}
33  QString name;
34  InfoObject *configuration {0};
35 };
36 
37 Filter::Filter()
38  : QObject(0)
39  , d(new Private)
40 {
41 }
42 
43 Filter::~Filter()
44 {
45  delete d->configuration;
46  delete d;
47 }
48 
49 bool Filter::operator==(const Filter &other) const
50 {
51  return (d->name == other.d->name
52  && d->configuration == other.d->configuration);
53 }
54 
55 bool Filter::operator!=(const Filter &other) const
56 {
57  return !(operator==(other));
58 }
59 
60 
61 QString Filter::name() const
62 {
63  return d->name;
64 }
65 
66 void Filter::setName(const QString &name)
67 {
68  d->name = name;
69  delete d->configuration;
70 
71  KisFilterSP filter = KisFilterRegistry::instance()->value(d->name);
72  d->configuration = new InfoObject(filter->defaultConfiguration(KisGlobalResourcesInterface::instance()));
73 }
74 
75 InfoObject* Filter::configuration() const
76 {
77  return d->configuration;
78 }
79 
80 void Filter::setConfiguration(InfoObject* value)
81 {
82  d->configuration = value;
83 }
84 
85 bool Filter::apply(Node *node, int x, int y, int w, int h)
86 {
87  if (node->locked()) return false;
88 
89  KisFilterSP filter = KisFilterRegistry::instance()->value(d->name);
90  if (!filter) return false;
91 
92  KisPaintDeviceSP dev = node->paintDevice();
93  if (!dev) return false;
94 
95  QRect applyRect = QRect(x, y, w, h);
96  KisFilterConfigurationSP config = static_cast<KisFilterConfiguration*>(d->configuration->configuration().data());
97  filter->process(dev, applyRect, config->cloneWithResourcesSnapshot());
98  return true;
99 }
100 
101 bool Filter::startFilter(Node *node, int x, int y, int w, int h)
102 {
103  if (node->locked()) return false;
104 
105  KisFilterSP filter = KisFilterRegistry::instance()->value(d->name);
106  if (!filter) return false;
107 
108  KisImageWSP image = node->image();
109  if (!image) return false;
110 
111  KisFilterConfigurationSP filterConfig = static_cast<KisFilterConfiguration*>(d->configuration->configuration().data());
112 
113  image->waitForDone();
114  QRect initialApplyRect = QRect(x, y, w, h);
115 
116  QRect applyRect = initialApplyRect;
117 
118  KisPaintDeviceSP paintDevice = node->paintDevice();
119  if (paintDevice && filter->needsTransparentPixels(filterConfig.data(), paintDevice->colorSpace())) {
120  applyRect |= image->bounds();
121  }
122 
123  KisResourcesSnapshotSP resources = new KisResourcesSnapshot(image, node->node());
124 
125  Document *document = Krita::instance()->activeDocument();
126  if (document && KisPart::instance()->viewCount(document->document()) > 0) {
127  Q_FOREACH (QPointer<KisView> view, KisPart::instance()->views()) {
128  if (view && view->document() == document->document()) {
129  resources = new KisResourcesSnapshot(image, node->node(), view->resourceProvider()->resourceManager());
130  break;
131  }
132  }
133  }
134  delete document;
135 
136  KisStrokeId currentStrokeId = image->startStroke(new KisFilterStrokeStrategy(filter,
137  KisFilterConfigurationSP(filterConfig),
138  resources));
139 
140  QRect processRect = filter->changedRect(applyRect, filterConfig.data(), 0);
141  processRect &= image->bounds();
142 
143  image->addJob(currentStrokeId, new KisFilterStrokeStrategy::FilterJobData());
144 
145 
146  image->endStroke(currentStrokeId);
147  image->waitForDone();
148 
149  return true;
150 }
151 
152 KisFilterConfigurationSP Filter::filterConfig()
153 {
154  KisFilterConfigurationSP config = KisFilterRegistry::instance()->get(d->name)->factoryConfiguration(KisGlobalResourcesInterface::instance());
155  Q_FOREACH(const QString property, d->configuration->properties().keys()) {
156  config->setProperty(property, d->configuration->property(property));
157  }
158  return config;
159 }
InfoObject wrap a properties map.
Definition: InfoObject.h:19
The Document class encapsulates a Krita Document/Image.
Definition: Document.h:33
bool locked() const
locked checks whether the Node is locked.
Definition: Node.cpp:404
Filter: represents a filter and its configuration.
Definition: Filter.h:30
static Krita * instance()
instance retrieve the singleton instance of the Application object.
Definition: Krita.cpp:402
QFuture< void > filter(Sequence &sequence, KeepFunctor filterFunction)
KSharedConfigPtr config()
Document * activeDocument() const
Definition: Krita.cpp:104
Node represents a layer or mask in a Krita image's Node hierarchy.
Definition: Node.h:21
QString name(StandardShortcut id)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Sep 29 2023 04:08:11 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.