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);
97
102 struct KRITAIMAGE_EXPORT SwitchFrameCommand : public KisCommandUtils::FlipFlopCommand {
103 struct KRITAIMAGE_EXPORT SharedStorage {
109 int value;
110 };
111
113
114 public:
115 SwitchFrameCommand(KisImageSP image, int time, bool finalize, SharedStorageSP storage);
116 ~SwitchFrameCommand() override;
117
118 private:
119 void partA() override;
120 void partB() override;
121
122 private:
126 };
127
133 {
134 public:
135 KeepNodesSelectedCommand(const KisNodeList &selectedBefore,
136 const KisNodeList &selectedAfter,
137 KisNodeSP activeBefore,
138 KisNodeSP activeAfter,
139 KisImageSP image,
140 bool finalize, KUndo2Command *parent = 0);
141 void partB() override;
142
143 private:
149 };
150
151 struct KRITAIMAGE_EXPORT SelectGlobalSelectionMask : public KUndo2Command
152 {
153 public:
156 void redo() override;
157
158 private:
160 };
161
162 class KRITAIMAGE_EXPORT RemoveNodeHelper {
163 public:
164 virtual ~RemoveNodeHelper();
165 protected:
166 struct ReplacementNode;
167 virtual void addCommandImpl(KUndo2Command *cmd) = 0;
168
173 bool doRedoUpdates = true;
174 bool doUndoUpdates = true;
176 bool relinkClones = false;
177 };
178
179 void safeRemoveMultipleNodes(KisNodeList nodes, KisImageSP image);
180 void safeReplaceMultipleNodes(KisNodeList removedNodes, KisImageSP image,
181 std::optional<ReplacementNode> replacementNode);
182 private:
183 bool checkIsSourceForClone(KisNodeSP src, const KisNodeList &nodes);
184 static bool scanForLastLayer(KisImageWSP image, KisNodeList nodesToRemove);
185 };
186
188 SimpleRemoveLayers(const KisNodeList &nodes,
189 KisImageSP image);
190
191 void populateChildCommands() override;
192
193 protected:
194 void addCommandImpl(KUndo2Command *cmd) override;
195
196 private:
201 };
202
204 {
205 public:
206 KisSimpleUpdateCommand(KisNodeList nodes, bool finalize, KUndo2Command *parent = 0);
207 void partB() override;
208 static void updateNodes(const KisNodeList &nodes);
209 private:
211 };
212
213 template <typename T>
214 bool checkNodesDiffer(KisNodeList nodes, std::function<T(KisNodeSP)> checkerFunc)
215 {
216 bool valueDiffers = false;
217 bool initialized = false;
218 T currentValue = T();
219 Q_FOREACH (KisNodeSP node, nodes) {
220 if (!initialized) {
221 currentValue = checkerFunc(node);
222 initialized = true;
223 } else if (currentValue != checkerFunc(node)) {
224 valueDiffers = true;
225 break;
226 }
227 }
228 return valueDiffers;
229 }
230
234 template <typename NodePointer, typename Functor>
235 void recursiveApplyNodes(NodePointer node, Functor func)
236 {
237 func(node);
238
239 node = node->firstChild();
240 while (node) {
241 recursiveApplyNodes(node, func);
242 node = node->nextSibling();
243 }
244 }
245
246
253 KRITAIMAGE_EXPORT KisNodeSP recursiveFindNode(KisNodeSP node, std::function<bool(KisNodeSP)> func);
254
258 KRITAIMAGE_EXPORT KisNodeSP findNodeByUuid(KisNodeSP root, const QUuid &uuid);
259
260 KRITAIMAGE_EXPORT QList<KisNodeSP> findNodesByName(KisNodeSP root, const QString &name, bool recursive, bool partialMatch);
261
262 KRITAIMAGE_EXPORT KisNodeSP findNodeByName(KisNodeSP root, const QString &name);
263
264 KRITAIMAGE_EXPORT KisImageSP findImageByHierarchy(KisNodeSP node);
265
266 template <class T>
268 return dynamic_cast<T*>(recursiveFindNode(root, [] (KisNodeSP node) {
269 return bool(dynamic_cast<T*>(node.data()));
270 }).data());
271 }
272
273 // Methods used by filter manager, filter stroke strategy to get times associated with frameIDs.
274 // Important for avoiding instanced frame data being processed twice!
275 KRITAIMAGE_EXPORT int fetchLayerActiveRasterFrameTime(KisNodeSP node);
276 KRITAIMAGE_EXPORT KisTimeSpan fetchLayerActiveRasterFrameSpan(KisNodeSP node, const int time);
277 KRITAIMAGE_EXPORT QSet<int> fetchLayerIdenticalRasterFrameTimes(KisNodeSP node, const int& frameTime);
278
279 KRITAIMAGE_EXPORT QSet<int> filterTimesForOnlyRasterKeyedTimes(KisNodeSP node, const QSet<int> &times);
280
281 /* Returns a set of times associated with every unique frame from a selection. */
282 KRITAIMAGE_EXPORT QSet<int> fetchUniqueFrameTimes(KisNodeSP node, QSet<int> selectedTimes, bool filterActiveFrameID);
283}
284
285Q_DECLARE_OPERATORS_FOR_FLAGS(KisLayerUtils::MergeFlags);
286
287#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)
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 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