File indexing completed on 2024-05-12 15:58:49
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "KisBatchNodeUpdate.h" 0008 0009 #include "kis_node.h" 0010 #include "kis_layer_utils.h" 0011 0012 KisBatchNodeUpdate::KisBatchNodeUpdate(const std::vector<std::pair<KisNodeSP, QRect>> &rhs) 0013 : std::vector<std::pair<KisNodeSP, QRect>>(rhs) 0014 { 0015 0016 } 0017 0018 void KisBatchNodeUpdate::addUpdate(KisNodeSP node, const QRect &rc) 0019 { 0020 push_back(std::make_pair(node, rc)); 0021 } 0022 0023 void KisBatchNodeUpdate::compress() 0024 { 0025 *this = compressed(); 0026 } 0027 0028 KisBatchNodeUpdate KisBatchNodeUpdate::compressed() const 0029 { 0030 KisBatchNodeUpdate newUpdateData; 0031 0032 KisNodeList rootNodes; 0033 0034 std::transform(begin(), end(), std::back_inserter(rootNodes), 0035 [] (const std::pair<KisNodeSP, QRect> &update) {return update.first; }); 0036 0037 rootNodes = KisLayerUtils::sortAndFilterMergableInternalNodes(rootNodes, true); 0038 0039 Q_FOREACH (KisNodeSP root, rootNodes) { 0040 QRect dirtyRect; 0041 0042 for (auto it = begin(); it != end(); ++it) { 0043 if (it->first == root || KisLayerUtils::checkIsChildOf(it->first, {root})) { 0044 dirtyRect |= it->second; 0045 } 0046 } 0047 0048 newUpdateData.push_back(std::make_pair(root, dirtyRect)); 0049 } 0050 0051 return newUpdateData; 0052 } 0053 0054 KisBatchNodeUpdate &KisBatchNodeUpdate::operator|=(const KisBatchNodeUpdate &rhs) 0055 { 0056 if (this == &rhs) 0057 return *this; 0058 0059 reserve(size() + rhs.size()); 0060 0061 std::copy(rhs.begin(), rhs.end(), std::back_inserter(*this)); 0062 std::sort(begin(), end(), [](const std::pair<KisNodeSP, QRect> &lhs, const std::pair<KisNodeSP, QRect> &rhs) { return lhs.first.data() < rhs.first.data(); }); 0063 0064 if (size() <= 1) 0065 return *this; 0066 0067 for (auto prevIt = begin(), it = next(prevIt); it != end();) { 0068 if (prevIt->first == it->first) { 0069 prevIt->second |= it->second; 0070 it = erase(it); 0071 } else { 0072 ++prevIt; 0073 ++it; 0074 } 0075 } 0076 0077 return *this; 0078 } 0079 0080 QDebug operator<<(QDebug dbg, const KisBatchNodeUpdate &update) 0081 { 0082 dbg.nospace() << "KisBatchNodeUpdate ("; 0083 0084 for (auto it = update.begin(); it != update.end(); ++it) { 0085 dbg.nospace() << it->first << "->" << it->second; 0086 0087 if (next(it) != update.end()) { 0088 dbg.nospace() << "; "; 0089 } 0090 } 0091 0092 return dbg; 0093 }