Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_layer_utils.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef __KIS_LAYER_UTILS_H
8#define __KIS_LAYER_UTILS_H
9
10#include <functional>
11
12#include "kundo2command.h"
13#include "kis_types.h"
14#include "kritaimage_export.h"
15#include "kis_command_utils.h"
16#include "kis_time_span.h"
17#include "kis_image.h"
18#include <future>
19
20class KoProperties;
21class KoColor;
22class QUuid;
23
24namespace KisMetaData
25{
26 class MergeStrategy;
27}
28
29namespace KisLayerUtils
30{
35 Q_DECLARE_FLAGS(MergeFlags, MergeFlag)
36
37 KRITAIMAGE_EXPORT void sortMergeableNodes(KisNodeSP root, QList<KisNodeSP> &inputNodes, QList<KisNodeSP> &outputNodes);
38 KRITAIMAGE_EXPORT KisNodeList sortMergeableNodes(KisNodeSP root, KisNodeList nodes);
39 KRITAIMAGE_EXPORT void filterMergeableNodes(KisNodeList &nodes, bool allowMasks = false);
40 KRITAIMAGE_EXPORT KisNodeList sortAndFilterAnyMergeableNodesSafe(const KisNodeList &nodes, KisImageSP image);
41 KRITAIMAGE_EXPORT bool checkIsChildOf(KisNodeSP node, const KisNodeList &parents);
42 KRITAIMAGE_EXPORT void filterUnlockedNodes(KisNodeList &nodes);
43 KRITAIMAGE_EXPORT void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea);
44 KRITAIMAGE_EXPORT QRect recursiveTightNodeVisibleBounds(KisNodeSP rootNode);
45
53 KRITAIMAGE_EXPORT bool checkIsCloneOf(KisNodeSP node, const KisNodeList &nodes);
54 KRITAIMAGE_EXPORT void forceAllDelayedNodesUpdate(KisNodeSP root);
55 KRITAIMAGE_EXPORT bool hasDelayedNodeWithUpdates(KisNodeSP root);
56
57 KRITAIMAGE_EXPORT void forceAllHiddenOriginalsUpdate(KisNodeSP root);
58
59 KRITAIMAGE_EXPORT KisNodeList sortAndFilterMergeableInternalNodes(KisNodeList nodes, bool allowMasks = false);
60 KRITAIMAGE_EXPORT KisNodeList sortMergeableInternalNodes(KisNodeList nodes);
61
62 KRITAIMAGE_EXPORT void mergeDown(KisImageSP image, KisLayerSP layer, const KisMetaData::MergeStrategy* strategy, MergeFlags flags = None);
63
64 KRITAIMAGE_EXPORT QSet<int> fetchLayerFrames(KisNodeSP node);
65 KRITAIMAGE_EXPORT QSet<int> fetchLayerFramesRecursive(KisNodeSP rootNode);
66
67 KRITAIMAGE_EXPORT void mergeMultipleLayers(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, MergeFlags flags = None);
68 KRITAIMAGE_EXPORT void newLayerFromVisible(KisImageSP image, KisNodeSP putAfter, MergeFlags flags = None);
69
74 KRITAIMAGE_EXPORT void mergeMultipleNodes(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, MergeFlags flags = None);
75
76 KRITAIMAGE_EXPORT bool tryMergeSelectionMasks(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter);
77
78 KRITAIMAGE_EXPORT void flattenLayer(KisImageSP image, KisLayerSP layer, MergeFlags flags = None);
79 KRITAIMAGE_EXPORT void flattenImage(KisImageSP image, KisNodeSP activeNode, MergeFlags flags = None);
80
81 KRITAIMAGE_EXPORT void addCopyOfNameTag(KisNodeSP node);
82 KRITAIMAGE_EXPORT KisNodeList findNodesWithProps(KisNodeSP root, const KoProperties &props, bool excludeRoot);
83
84 KRITAIMAGE_EXPORT void changeImageDefaultProjectionColor(KisImageSP image, const KoColor &color);
85
86 KRITAIMAGE_EXPORT KisNodeSP findRoot(KisNodeSP node);
87
88 KRITAIMAGE_EXPORT bool canChangeImageProfileInvisibly(KisImageSP image);
89
90 KRITAIMAGE_EXPORT void splitAlphaToMask(KisImageSP image, KisNodeSP node, const QString& maskName);
91
92 KRITAIMAGE_EXPORT std::future<KisNodeSP> convertToPaintLayer(KisImageSP image, KisNodeSP src);
93
94 typedef QMap<int, QSet<KisNodeSP> > FrameJobs;
95 void updateFrameJobs(FrameJobs *jobs, KisNodeSP node);
96 void updateFrameJobsRecursive(FrameJobs *jobs, KisNodeSP rootNode);
102 void updateFrameJobsNonRecursive(FrameJobs *jobs, KisNodeSP rootNode, bool frameTimesRecursive = false);
103
108 struct KRITAIMAGE_EXPORT SwitchFrameCommand : public KisCommandUtils::FlipFlopCommand {
109 struct KRITAIMAGE_EXPORT SharedStorage {
115 int value;
116 };
117
119
120 public:
121 SwitchFrameCommand(KisImageSP image, int time, bool finalize, SharedStorageSP storage);
122 ~SwitchFrameCommand() override;
123
124 private:
125 void partA() override;
126 void partB() override;
127
128 private:
132 };
133
139 {
140 public:
141 KeepNodesSelectedCommand(const KisNodeList &selectedBefore,
142 const KisNodeList &selectedAfter,
143 KisNodeSP activeBefore,
144 KisNodeSP activeAfter,
145 KisImageSP image,
146 bool finalize, KUndo2Command *parent = 0);
147 void partB() override;
148
149 private:
155 };
156
157 struct KRITAIMAGE_EXPORT SelectGlobalSelectionMask : public KUndo2Command
158 {
159 public:
162 void redo() override;
163
164 private:
166 };
167
168 class KRITAIMAGE_EXPORT RemoveNodeHelper {
169 public:
170 virtual ~RemoveNodeHelper();
171 protected:
172 struct ReplacementNode;
173 virtual void addCommandImpl(KUndo2Command *cmd) = 0;
174
179 bool doRedoUpdates = true;
180 bool doUndoUpdates = true;
182 bool relinkClones = false;
183 };
184
185 void safeRemoveMultipleNodes(KisNodeList nodes, KisImageSP image);
186 void safeReplaceMultipleNodes(KisNodeList removedNodes, KisImageSP image,
187 std::optional<ReplacementNode> replacementNode);
188 private:
189 bool checkIsSourceForClone(KisNodeSP src, const KisNodeList &nodes);
190 static bool scanForLastLayer(KisImageWSP image, KisNodeList nodesToRemove);
191 };
192
194 SimpleRemoveLayers(const KisNodeList &nodes,
195 KisImageSP image);
196
197 void populateChildCommands() override;
198
199 protected:
200 void addCommandImpl(KUndo2Command *cmd) override;
201
202 private:
207 };
208
210 {
211 public:
212 KisSimpleUpdateCommand(KisNodeList nodes, bool finalize, KUndo2Command *parent = 0);
213 void partB() override;
214 static void updateNodes(const KisNodeList &nodes);
215 private:
217 };
218
219 template <typename T>
220 bool checkNodesDiffer(KisNodeList nodes, std::function<T(KisNodeSP)> checkerFunc)
221 {
222 bool valueDiffers = false;
223 bool initialized = false;
224 T currentValue = T();
225 Q_FOREACH (KisNodeSP node, nodes) {
226 if (!initialized) {
227 currentValue = checkerFunc(node);
228 initialized = true;
229 } else if (currentValue != checkerFunc(node)) {
230 valueDiffers = true;
231 break;
232 }
233 }
234 return valueDiffers;
235 }
236
240 template <typename NodePointer, typename Functor>
241 void recursiveApplyNodes(NodePointer node, Functor func)
242 {
243 func(node);
244
245 node = node->firstChild();
246 while (node) {
247 recursiveApplyNodes(node, func);
248 node = node->nextSibling();
249 }
250 }
251
252
259 KRITAIMAGE_EXPORT KisNodeSP recursiveFindNode(KisNodeSP node, std::function<bool(KisNodeSP)> func);
260
264 KRITAIMAGE_EXPORT KisNodeSP findNodeByUuid(KisNodeSP root, const QUuid &uuid);
265
266 KRITAIMAGE_EXPORT QList<KisNodeSP> findNodesByName(KisNodeSP root, const QString &name, bool recursive, bool partialMatch);
267
268 KRITAIMAGE_EXPORT KisNodeSP findNodeByName(KisNodeSP root, const QString &name);
269
270 KRITAIMAGE_EXPORT KisNodeSP findIsolationRoot(KisNodeSP node);
271
272 KRITAIMAGE_EXPORT KisImageSP findImageByHierarchy(KisNodeSP node);
273
274 template <class T>
276 return dynamic_cast<T*>(recursiveFindNode(root, [] (KisNodeSP node) {
277 return bool(dynamic_cast<T*>(node.data()));
278 }).data());
279 }
280
281 // Methods used by filter manager, filter stroke strategy to get times associated with frameIDs.
282 // Important for avoiding instanced frame data being processed twice!
283 KRITAIMAGE_EXPORT int fetchLayerActiveRasterFrameTime(KisNodeSP node);
284 KRITAIMAGE_EXPORT KisTimeSpan fetchLayerActiveRasterFrameSpan(KisNodeSP node, const int time);
285 KRITAIMAGE_EXPORT QSet<int> fetchLayerIdenticalRasterFrameTimes(KisNodeSP node, const int& frameTime);
286
287 KRITAIMAGE_EXPORT QSet<int> filterTimesForOnlyRasterKeyedTimes(KisNodeSP node, const QSet<int> &times);
288
289 /* Returns a set of times associated with every unique frame from a selection. */
290 KRITAIMAGE_EXPORT QSet<int> fetchUniqueFrameTimes(KisNodeSP node, QSet<int> selectedTimes, bool filterActiveFrameID);
291}
292
293Q_DECLARE_OPERATORS_FOR_FLAGS(KisLayerUtils::MergeFlags);
294
295#endif /* __KIS_LAYER_UTILS_H */
Q_DECLARE_FLAGS(KisUpdaterContextSnapshotEx, KisUpdaterContextSnapshotExTag)
virtual void addCommandImpl(KUndo2Command *cmd)=0
Q_DECLARE_OPERATORS_FOR_FLAGS(KisLayerUtils::MergeFlags)
void flattenImage(KisImageSP image, KisNodeSP activeNode, MergeFlags flags)
bool checkIsCloneOf(KisNodeSP node, const KisNodeList &nodes)
KisNodeSP findIsolationRoot(KisNodeSP node)
QSet< int > fetchLayerFrames(KisNodeSP node)
QSet< int > fetchUniqueFrameTimes(KisNodeSP node, QSet< int > selectedTimes, bool filterActiveFrameID)
bool hasDelayedNodeWithUpdates(KisNodeSP root)
void updateFrameJobs(FrameJobs *jobs, KisNodeSP node)
QSet< int > filterTimesForOnlyRasterKeyedTimes(KisNodeSP node, const QSet< int > &times)
void updateFrameJobsRecursive(FrameJobs *jobs, KisNodeSP rootNode)
KisNodeSP recursiveFindNode(KisNodeSP node, std::function< bool(KisNodeSP)> func)
void splitAlphaToMask(KisImageSP image, KisNodeSP node, const QString &maskName)
void changeImageDefaultProjectionColor(KisImageSP image, const KoColor &color)
KisTimeSpan fetchLayerActiveRasterFrameSpan(KisNodeSP node, const int time)
KisNodeList sortAndFilterMergeableInternalNodes(KisNodeList nodes, bool allowMasks)
QMap< int, QSet< KisNodeSP > > FrameJobs
bool checkNodesDiffer(KisNodeList nodes, std::function< T(KisNodeSP)> checkerFunc)
void sortMergeableNodes(KisNodeSP root, KisNodeList &inputNodes, KisNodeList &outputNodes)
QRect recursiveTightNodeVisibleBounds(KisNodeSP rootNode)
KisImageSP findImageByHierarchy(KisNodeSP node)
KisNodeSP findNodeByName(KisNodeSP root, const QString &name)
void flattenLayer(KisImageSP image, KisLayerSP layer, MergeFlags flags)
KisNodeSP findRoot(KisNodeSP node)
QList< KisNodeSP > findNodesByName(KisNodeSP root, const QString &name, bool recursive, bool partialMatch)
KisNodeList findNodesWithProps(KisNodeSP root, const KoProperties &props, bool excludeRoot)
void addCopyOfNameTag(KisNodeSP node)
KisNodeSP findNodeByUuid(KisNodeSP root, const QUuid &uuid)
T * findNodeByType(KisNodeSP root)
void newLayerFromVisible(KisImageSP image, KisNodeSP putAfter, MergeFlags flags)
void filterUnlockedNodes(KisNodeList &nodes)
bool canChangeImageProfileInvisibly(KisImageSP image)
void recursiveApplyNodes(NodePointer node, Functor func)
int fetchLayerActiveRasterFrameTime(KisNodeSP node)
KisNodeList sortAndFilterAnyMergeableNodesSafe(const KisNodeList &nodes, KisImageSP image)
void filterMergeableNodes(KisNodeList &nodes, bool allowMasks)
void forceAllHiddenOriginalsUpdate(KisNodeSP root)
QSet< int > fetchLayerIdenticalRasterFrameTimes(KisNodeSP node, const int &frameTime)
bool checkIsChildOf(KisNodeSP node, const KisNodeList &parents)
void updateFrameJobsNonRecursive(FrameJobs *jobs, KisNodeSP rootNode, bool frameTimesRecursive)
updateFrameJobsNonRecursive updates the frame jobs non-recursively, that is, on the rootNode only.
void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea)
void mergeMultipleLayers(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, MergeFlags flags)
void mergeDown(KisImageSP image, KisLayerSP layer, const KisMetaData::MergeStrategy *strategy, MergeFlags flags)
bool tryMergeSelectionMasks(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter)
std::future< KisNodeSP > convertToPaintLayer(KisImageSP image, KisNodeSP src)
void forceAllDelayedNodesUpdate(KisNodeSP root)
QSet< int > fetchLayerFramesRecursive(KisNodeSP rootNode)
KisNodeList sortMergeableInternalNodes(KisNodeList nodes)
void mergeMultipleNodes(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, MergeFlags flags)
The AggregateCommand struct is a command with delayed initialization. On first redo() populateChildCo...
The SwitchFrameCommand struct Switches to frame with undo/redo support.
QSharedPointer< SharedStorage > SharedStorageSP