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 }