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 */