Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_exr_layers_sorter.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QDomDocument>
10#include <QDomElement>
11
12#include "kis_image.h"
13#include "exr_extra_tags.h"
15#include "kis_paint_layer.h"
16
17
19{
20 Private(const QDomDocument &_extraData, KisImageSP _image)
21 : extraData(_extraData), image(_image) {}
22
23 const QDomDocument &extraData;
25
26 QMap<QString, QDomElement> pathToElementMap;
27 QMap<QString, int> pathToOrderingMap;
28
29 QMap<KisNodeSP, int> nodeToOrderingMap;
30
31 void createOrderingMap();
32 void processLayers(KisNodeSP root);
33 void sortLayers(KisNodeSP root);
34};
35
36QString getNodePath(KisNodeSP node) {
37 KIS_ASSERT_RECOVER(node) { return "UNDEFINED"; }
38
39 QString path;
40
41 KisNodeSP parentNode = node->parent();
42 while(parentNode) {
43 if (!path.isEmpty()) {
44 path.prepend(".");
45 }
46 path.prepend(node->name());
47
48 node = parentNode;
49 parentNode = node->parent();
50 }
51
52 return path;
53}
54
56{
57 int index = 0;
58 QDomElement el = extraData.documentElement().firstChildElement();
59
60
61 while (!el.isNull()) {
62 QString path = el.attribute(EXR_NAME);
63 pathToElementMap.insert(path, el);
64 pathToOrderingMap.insert(path, index);
65
66 el = el.nextSiblingElement();
67 index++;
68 }
69}
70
71template <typename T>
72T fetchMapValueLazy(const QMap<QString, T> &map, QString path)
73{
74 if (map.contains(path)) return map[path];
75
76
77 typename QMap<QString, T>::const_iterator it = map.constBegin();
78 typename QMap<QString, T>::const_iterator end = map.constEnd();
79
80 for (; it != end; ++it) {
81 if (it.key().startsWith(path)) {
82 return it.value();
83 }
84 }
85
86 return T();
87}
88
90{
91 if (root && root->parent()) {
92 QString path = getNodePath(root);
93
94 nodeToOrderingMap.insert(root, fetchMapValueLazy(pathToOrderingMap, path));
95
96 if (KisPaintLayer *paintLayer = dynamic_cast<KisPaintLayer*>(root.data())) {
97 QDomElement el = pathToElementMap[path];
98
107 KisSaveXmlVisitor::loadPaintLayerAttributes(el, paintLayer, false);
108 }
109 }
110
111 KisNodeSP child = root->firstChild();
112 while (child) {
113 processLayers(child);
114 child = child->nextSibling();
115 }
116}
117
119{
120 CompareNodesFunctor(const QMap<KisNodeSP, int> &map)
121 : m_nodeToOrderingMap(map) {}
122
123 bool operator() (KisNodeSP lhs, KisNodeSP rhs) {
124 return m_nodeToOrderingMap[lhs] < m_nodeToOrderingMap[rhs];
125 }
126
127private:
128 const QMap<KisNodeSP, int> &m_nodeToOrderingMap;
129};
130
131
133{
134 QList<KisNodeSP> childNodes;
135
136 // first move all the children to the list
137 KisNodeSP child = root->firstChild();
138 while (child) {
139 KisNodeSP lastChild = child;
140 child = child->nextSibling();
141
142 childNodes.append(lastChild);
143 image->removeNode(lastChild);
144 }
145
146 // sort the list
147 std::stable_sort(childNodes.begin(), childNodes.end(), CompareNodesFunctor(nodeToOrderingMap));
148
149 // put the children back
150 Q_FOREACH (KisNodeSP node, childNodes) {
151 image->addNode(node, root, root->childCount());
152 }
153
154 // recursive calls
155 child = root->firstChild();
156 while (child) {
157 sortLayers(child);
158 child = child->nextSibling();
159 }
160}
161
162KisExrLayersSorter::KisExrLayersSorter(const QDomDocument &extraData, KisImageSP image)
163 : m_d(new Private(extraData, image))
164{
165 KIS_ASSERT_RECOVER_RETURN(!extraData.isNull());
166 m_d->createOrderingMap();
167
168 m_d->processLayers(image->root());
169 m_d->sortLayers(image->root());
170}
171
QScopedPointer< Private > m_d
KisExrLayersSorter(const QDomDocument &extraData, KisImageSP image)
static void loadPaintLayerAttributes(const QDomElement &el, KisPaintLayer *layer, bool loadLayerOffset)
const char EXR_NAME[]
#define KIS_ASSERT_RECOVER(cond)
Definition kis_assert.h:55
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
T fetchMapValueLazy(const QMap< QString, T > &map, QString path)
QString getNodePath(KisNodeSP node)
const QMap< KisNodeSP, int > & m_nodeToOrderingMap
CompareNodesFunctor(const QMap< KisNodeSP, int > &map)
QString name() const
QMap< KisNodeSP, int > nodeToOrderingMap
QMap< QString, QDomElement > pathToElementMap
Private(const QDomDocument &_extraData, KisImageSP _image)
KisNodeSP firstChild() const
Definition kis_node.cpp:361
quint32 childCount() const
Definition kis_node.cpp:414
KisNodeWSP parent
Definition kis_node.cpp:86
KisNodeSP nextSibling() const
Definition kis_node.cpp:408