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

0001 /*
0002  *  SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_WRAPPED_LINE_ITERATOR_BASE_H
0008 #define __KIS_WRAPPED_LINE_ITERATOR_BASE_H
0009 
0010 
0011 template <class IteratorStrategy, class BaseClass>
0012     class KisWrappedLineIteratorBase : public BaseClass
0013 {
0014 public:
0015     KisWrappedLineIteratorBase(KisDataManager *dataManager,
0016                                const KisWrappedRect &splitRect,
0017                                qint32 offsetX, qint32 offsetY,
0018                                bool writable,
0019                                KisIteratorCompleteListener *listener)
0020         : m_splitRect(splitRect)
0021     {
0022         Q_ASSERT(m_splitRect.isSplit());
0023 
0024         m_iterators.resize(4);
0025         for (int i = 0; i < 4; i++) {
0026             QRect rc = m_splitRect[i];
0027             if (rc.isEmpty()) continue;
0028 
0029             m_iterators[i] = m_strategy.createIterator(dataManager,
0030                                                        rc,
0031                                                        offsetX, offsetY,
0032                                                        writable,
0033                                                        listener);
0034         }
0035         m_strategy.completeInitialization(&m_iterators, &m_splitRect);
0036         m_iterationAreaSize =
0037             m_strategy.originalRectToColumnsRows(m_splitRect.originalRect());
0038 
0039         m_currentIterator = m_strategy.leftColumnIterator();
0040     }
0041 
0042     bool nextPixel() {
0043         int result = m_currentIterator->nextPixel();
0044         if (!result) {
0045             result = trySwitchColumn();
0046         }
0047 
0048         m_currentPos.rx()++;
0049         return m_currentPos.rx() < m_iterationAreaSize.width();
0050     }
0051 
0052     bool nextPixels(qint32 n) {
0053         int result = m_currentIterator->nextPixels(n);
0054         if (!result) {
0055             result = trySwitchColumn();
0056         }
0057 
0058         m_currentPos.rx() += n;
0059         return m_currentPos.rx() < m_iterationAreaSize.width();
0060     }
0061 
0062     void nextRow() {
0063         if (!m_strategy.trySwitchIteratorStripe()) {
0064             m_strategy.iteratorsToNextRow();
0065         }
0066 
0067         m_currentIterator = m_strategy.leftColumnIterator();
0068         m_currentPos.rx() = 0;
0069         m_currentPos.ry()++;
0070     }
0071 
0072     void nextColumn() {
0073         nextRow();
0074     }
0075 
0076     const quint8* oldRawData() const {
0077         return m_currentIterator->oldRawData();
0078     }
0079 
0080     const quint8* rawDataConst() const {
0081         return m_currentIterator->rawDataConst();
0082     }
0083 
0084     quint8* rawData() {
0085         return m_currentIterator->rawData();
0086     }
0087 
0088     qint32 nConseqPixels() const {
0089         qint32 iteratorChunk =
0090             m_currentIterator->nConseqPixels();
0091         return qMin(iteratorChunk,
0092                     m_iterationAreaSize.width() - m_currentPos.x());
0093     }
0094 
0095     qint32 x() const {
0096         return (m_splitRect.originalRect().topLeft() +
0097                 m_strategy.columnRowToXY(m_currentPos)).x();
0098     }
0099 
0100     qint32 y() const {
0101         return (m_splitRect.originalRect().topLeft() +
0102                 m_strategy.columnRowToXY(m_currentPos)).y();
0103     }
0104 
0105     void resetPixelPos() {
0106         errKrita << "CRITICAL: resetPixelPos() is not implemented";
0107     }
0108 
0109     void resetRowPos() {
0110         errKrita << "CRITICAL: resetRowPos() is not implemented";
0111     }
0112 
0113     void resetColumnPos() {
0114         resetRowPos();
0115     }
0116 
0117 private:
0118     bool trySwitchColumn() {
0119         int result = true;
0120 
0121         if (m_currentIterator == m_strategy.leftColumnIterator() &&
0122             m_strategy.rightColumnIterator()) {
0123 
0124             m_currentIterator = m_strategy.rightColumnIterator();
0125 
0126         } else if (m_strategy.trySwitchColumnForced()) {
0127 
0128             m_currentIterator = m_strategy.leftColumnIterator();
0129 
0130         } else {
0131             result = false;
0132         }
0133 
0134         return result;
0135     }
0136 
0137 private:
0138 
0139     KisWrappedRect m_splitRect;
0140     QSize m_iterationAreaSize; // columns x rows
0141     QPoint m_currentPos; // column, row
0142     QVector<typename IteratorStrategy::IteratorTypeSP> m_iterators;
0143     typename IteratorStrategy::IteratorTypeSP m_currentIterator;
0144     IteratorStrategy m_strategy;
0145 };
0146 
0147 #endif /* __KIS_WRAPPED_LINE_ITERATOR_BASE_H */