File indexing completed on 2024-05-12 15:58:16

0001 /*
0002  *  SPDX-FileCopyrightText: 2011 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_FULL_REFRESH_WALKER_H
0008 #define __KIS_FULL_REFRESH_WALKER_H
0009 
0010 #include "kis_merge_walker.h"
0011 #include "kis_refresh_subtree_walker.h"
0012 
0013 
0014 class KisFullRefreshWalker : public KisRefreshSubtreeWalker, public KisMergeWalker
0015 {
0016 public:
0017     using KisRefreshSubtreeWalker::Flag;
0018     using KisRefreshSubtreeWalker::Flags;
0019 
0020 public:
0021     KisFullRefreshWalker(QRect cropRect, Flags flags = None)
0022         : KisRefreshSubtreeWalker(cropRect, flags),
0023           KisMergeWalker(cropRect, NO_FILTHY)
0024     {
0025     }
0026 
0027     UpdateType type() const override {
0028         return KisRefreshSubtreeWalker::flags() & NoFilthyMode ?
0029             FULL_REFRESH_NO_FILTHY : FULL_REFRESH;
0030     }
0031 
0032     void startTrip(KisProjectionLeafSP startWith) override {
0033         if(m_firstRun) {
0034             m_firstRun = false;
0035 
0036             m_currentUpdateType = UPDATE;
0037             KisMergeWalker::startTrip(startWith);
0038 
0039             m_currentUpdateType = FULL_REFRESH;
0040 
0041             if (!startWith->dependsOnLowerNodes()) {
0042                 KisRefreshSubtreeWalker::startTrip(startWith);
0043             } else {
0044                 KIS_SAFE_ASSERT_RECOVER_NOOP(!startWith->canHaveChildLayers());
0045             }
0046 
0047             m_firstRun = true;
0048         }
0049         else {
0050             if(m_currentUpdateType == FULL_REFRESH) {
0051                 KisRefreshSubtreeWalker::startTrip(startWith);
0052             }
0053             else {
0054                 KisMergeWalker::startTrip(startWith);
0055             }
0056         }
0057     }
0058 
0059     void registerChangeRect(KisProjectionLeafSP leaf, NodePosition position) override {
0060         if(m_currentUpdateType == FULL_REFRESH) {
0061             KisRefreshSubtreeWalker::registerChangeRect(leaf, position);
0062         }
0063         else {
0064             /**
0065              * Merge walker thinks that we changed the original of the
0066              * dirty node (dirtyNode == startNode()), but that is not
0067              * true in case of full refresh walker, because all the
0068              * children of the dirty node are dirty as well, that is
0069              * why we shouldn't rely on usual registerChangeRect()
0070              * mechanism for this node. That is why we just unite the
0071              * changeRects of all its children here.
0072              */
0073 
0074             if(isStartLeaf(leaf)&& !leaf->isRoot()) {
0075                 KisRefreshSubtreeWalker::calculateChangeRect(leaf, requestedRect());
0076             }
0077             else {
0078                 KisMergeWalker::registerChangeRect(leaf, position);
0079             }
0080         }
0081     }
0082     void registerNeedRect(KisProjectionLeafSP leaf, NodePosition position) override {
0083         if(m_currentUpdateType == FULL_REFRESH) {
0084             KisRefreshSubtreeWalker::registerNeedRect(leaf, position);
0085         }
0086         else {
0087             KisMergeWalker::registerNeedRect(leaf, position);
0088         }
0089     }
0090     void adjustMasksChangeRect(KisProjectionLeafSP firstMask) override {
0091         if(m_currentUpdateType == FULL_REFRESH) {
0092             KisRefreshSubtreeWalker::adjustMasksChangeRect(firstMask);
0093         }
0094         else {
0095             KisMergeWalker::adjustMasksChangeRect(firstMask);
0096         }
0097     }
0098 
0099 private:
0100     UpdateType m_currentUpdateType { UPDATE };
0101     bool m_firstRun { true };
0102 };
0103 
0104 #endif /* __KIS_FULL_REFRESH_WALKER_H */