File indexing completed on 2024-05-12 15:58:40
0001 /* 0002 * SPDX-FileCopyrightText: 2008 Cyrille Berger <cberger@cberger.net> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef _KIS_REPEAT_ITERATORS_PIXEL_H_ 0008 #define _KIS_REPEAT_ITERATORS_PIXEL_H_ 0009 0010 #include <QRect> 0011 #include "kis_shared.h" 0012 #include "tiles3/kis_hline_iterator.h" 0013 #include "tiles3/kis_vline_iterator.h" 0014 0015 template<class T> 0016 class KisRepeatHLineIteratorPixelBase; 0017 template<class T> 0018 class KisRepeatVLineIteratorPixelBase; 0019 0020 /** 0021 * This iterator is an iterator that will "artificially" extend the paint device with the 0022 * value of the border when trying to access values outside the range of data. 0023 */ 0024 template<class T> 0025 class KisRepeatLineIteratorPixelBase : public KisShared 0026 { 0027 Q_DISABLE_COPY(KisRepeatLineIteratorPixelBase) 0028 public: 0029 0030 friend class KisRepeatHLineIteratorPixelBase<T>; 0031 friend class KisRepeatVLineIteratorPixelBase<T>; 0032 /** 0033 * @param dm data manager 0034 * @param x x of top left corner 0035 * @param y y of top left corner 0036 * @param offsetx x offset 0037 * @param offsety y offset 0038 * @param _rc indicates the rectangle that truly contains data 0039 * @param completeListener completion listener 0040 */ 0041 inline KisRepeatLineIteratorPixelBase(KisDataManager *dm, qint32 x, qint32 y, qint32 offsetx, qint32 offsety, const QRect& _rc, KisIteratorCompleteListener *completeListener); 0042 virtual inline ~KisRepeatLineIteratorPixelBase(); 0043 public: 0044 inline qint32 x() const { 0045 return m_realX; 0046 } 0047 inline qint32 y() const { 0048 return m_realY; 0049 } 0050 inline const quint8 * oldRawData() const { 0051 return m_iterator->oldRawData(); 0052 } 0053 0054 private: 0055 KisDataManager* m_dm; 0056 qint32 m_realX, m_realY; 0057 qint32 m_offsetX, m_offsetY; 0058 QRect m_dataRect; 0059 T* m_iterator; 0060 KisIteratorCompleteListener *m_completeListener; 0061 }; 0062 0063 /** 0064 * This iterator is an iterator that will "artificially" extend the paint device with the 0065 * value of the border when trying to access values outside the range of data. 0066 */ 0067 template<class T> 0068 class KisRepeatHLineIteratorPixelBase : public KisRepeatLineIteratorPixelBase<T> 0069 { 0070 public: 0071 /** 0072 * @param dm data manager 0073 * @param x x of top left corner 0074 * @param y y of top left corner 0075 * @param w width 0076 * @param offsetx x offset 0077 * @param offsety y offset 0078 * @param _rc indicates the rectangle that truly contains data 0079 * @param completeListener completion listener 0080 */ 0081 inline KisRepeatHLineIteratorPixelBase(KisDataManager *dm, qint32 x, qint32 y, qint32 w, qint32 offsetx, qint32 offsety, const QRect& _rc, KisIteratorCompleteListener *completeListener); 0082 inline ~KisRepeatHLineIteratorPixelBase() override; 0083 inline bool nextPixel(); 0084 /** 0085 * Reach next row. 0086 */ 0087 inline void nextRow(); 0088 private: 0089 void createIterator(); 0090 private: 0091 qint32 m_startX; 0092 qint32 m_startIteratorX; 0093 qint32 m_width; 0094 }; 0095 0096 /** 0097 * This iterator is an iterator that will "artificially" extend the paint device with the 0098 * value of the border when trying to access values outside the range of data. 0099 */ 0100 template<class T> 0101 class KisRepeatVLineIteratorPixelBase : public KisRepeatLineIteratorPixelBase<T> 0102 { 0103 public: 0104 /** 0105 * @param dm data manager 0106 * @param x x of top left corner 0107 * @param y y of top left corner 0108 * @param h height 0109 * @param offsetx x offset 0110 * @param offsety y offset 0111 * @param _rc indicates the rectangle that truly contains data 0112 * @param completeListener completion listener 0113 */ 0114 inline KisRepeatVLineIteratorPixelBase(KisDataManager *dm, qint32 x, qint32 y, qint32 h, qint32 offsetx, qint32 offsety, const QRect& _rc, KisIteratorCompleteListener *completeListener); 0115 inline ~KisRepeatVLineIteratorPixelBase() override; 0116 inline KisRepeatVLineIteratorPixelBase<T> & operator ++(); 0117 inline bool nextPixel(); 0118 /** 0119 * Reach next row. 0120 */ 0121 inline void nextColumn(); 0122 private: 0123 void createIterator(); 0124 private: 0125 qint32 m_startY; 0126 qint32 m_startIteratorY; 0127 qint32 m_height; 0128 }; 0129 0130 //------------------------ Implementations ------------------------// 0131 0132 //---------------- KisRepeatLineIteratorPixelBase -----------------// 0133 0134 template<class T> 0135 KisRepeatLineIteratorPixelBase<T>::KisRepeatLineIteratorPixelBase(KisDataManager *dm, qint32 x, qint32 y, qint32 offsetx, qint32 offsety, const QRect& _rc, KisIteratorCompleteListener *completeListener) : 0136 m_dm(dm), 0137 m_realX(x), m_realY(y), 0138 m_offsetX(offsetx), m_offsetY(offsety), 0139 m_dataRect(_rc), 0140 m_iterator(0), 0141 m_completeListener(completeListener) 0142 { 0143 } 0144 0145 template<class T> 0146 KisRepeatLineIteratorPixelBase<T>::~KisRepeatLineIteratorPixelBase() 0147 { 0148 delete m_iterator; 0149 } 0150 0151 //---------------- KisRepeatHLineIteratorPixelBase ----------------// 0152 0153 template<class T> 0154 KisRepeatHLineIteratorPixelBase<T>::KisRepeatHLineIteratorPixelBase(KisDataManager *dm, qint32 x, qint32 y, qint32 w, qint32 offsetx, qint32 offsety, const QRect& _rc, KisIteratorCompleteListener *completeListener) 0155 : KisRepeatLineIteratorPixelBase<T>(dm, x, y, offsetx, offsety , _rc, completeListener), 0156 m_startX(x), m_startIteratorX(x), 0157 m_width(w) 0158 { 0159 // Compute the startx value of the iterator 0160 if (m_startIteratorX < _rc.left()) { 0161 m_startIteratorX = _rc.left(); 0162 } 0163 createIterator(); 0164 } 0165 0166 template<class T> 0167 KisRepeatHLineIteratorPixelBase<T>::~KisRepeatHLineIteratorPixelBase() 0168 { 0169 } 0170 0171 template<class T> 0172 inline bool KisRepeatHLineIteratorPixelBase<T>::nextPixel() 0173 { 0174 Q_ASSERT(this->m_iterator); 0175 if (this->m_realX >= this->m_dataRect.x() && this->m_realX < this->m_dataRect.x() + this->m_dataRect.width() - 1) { 0176 this->m_iterator->nextPixel(); 0177 } 0178 ++this->m_realX; 0179 0180 return (this->m_realX < m_startX + m_width); 0181 } 0182 0183 template<class T> 0184 inline void KisRepeatHLineIteratorPixelBase<T>::nextRow() 0185 { 0186 if (this->m_realY >= this->m_dataRect.y() && this->m_realY < this->m_dataRect.y() + this->m_dataRect.height() - 1) { 0187 this->m_iterator->nextRow(); 0188 } else { 0189 createIterator(); 0190 } 0191 this->m_realX = this->m_startX; 0192 ++this->m_realY; 0193 } 0194 0195 template<class T> 0196 void KisRepeatHLineIteratorPixelBase<T>::createIterator() 0197 { 0198 // Cleanup 0199 delete this->m_iterator; 0200 qint32 startY = this->m_realY; 0201 if (startY < this->m_dataRect.y()) { 0202 startY = this->m_dataRect.top(); 0203 } 0204 if (startY > (this->m_dataRect.y() + this->m_dataRect.height() - 1)) { 0205 startY = (this->m_dataRect.y() + this->m_dataRect.height() - 1); 0206 } 0207 0208 int width = this->m_dataRect.x() + this->m_dataRect.width() - this->m_startIteratorX; 0209 this->m_iterator = new T(this->m_dm, this->m_startIteratorX, startY, width, this->m_offsetX, this->m_offsetY, false, this->m_completeListener); 0210 this->m_realX = this->m_startX; 0211 } 0212 0213 //---------------- KisRepeatVLineIteratorPixelBase ----------------// 0214 0215 template<class T> 0216 KisRepeatVLineIteratorPixelBase<T>::KisRepeatVLineIteratorPixelBase(KisDataManager *dm, qint32 x, qint32 y, qint32 h, qint32 offsetx, qint32 offsety, const QRect& _rc, KisIteratorCompleteListener *completeListener) 0217 : KisRepeatLineIteratorPixelBase<T>(dm, x, y, offsetx, offsety , _rc, completeListener), 0218 m_startY(y), m_startIteratorY(y), 0219 m_height(h) 0220 { 0221 // Compute the startx value of the iterator 0222 if (m_startIteratorY < _rc.top()) { 0223 m_startIteratorY = _rc.top(); 0224 } 0225 createIterator(); 0226 } 0227 0228 template<class T> 0229 KisRepeatVLineIteratorPixelBase<T>::~KisRepeatVLineIteratorPixelBase() 0230 { 0231 } 0232 0233 template<class T> 0234 inline bool KisRepeatVLineIteratorPixelBase<T>::nextPixel() 0235 { 0236 Q_ASSERT(this->m_iterator); 0237 if (this->m_realY >= this->m_dataRect.y() && this->m_realY < this->m_dataRect.y() + this->m_dataRect.height() - 1) { 0238 this->m_iterator->nextPixel(); 0239 } 0240 ++this->m_realY; 0241 return (this->m_realY < m_startY + m_height); 0242 0243 } 0244 0245 template<class T> 0246 inline void KisRepeatVLineIteratorPixelBase<T>::nextColumn() 0247 { 0248 if (this->m_realX >= this->m_dataRect.x() && this->m_realX < this->m_dataRect.x() + this->m_dataRect.width() - 1) { 0249 this->m_iterator->nextColumn(); 0250 } else { 0251 createIterator(); 0252 } 0253 this->m_realY = this->m_startY; 0254 ++this->m_realX; 0255 } 0256 0257 template<class T> 0258 void KisRepeatVLineIteratorPixelBase<T>::createIterator() 0259 { 0260 // Cleanup 0261 delete this->m_iterator; 0262 qint32 startX = this->m_realX; 0263 if (startX < this->m_dataRect.x()) { 0264 startX = this->m_dataRect.x(); 0265 } 0266 if (startX > (this->m_dataRect.x() + this->m_dataRect.width() - 1)) { 0267 startX = (this->m_dataRect.x() + this->m_dataRect.width() - 1); 0268 } 0269 0270 int height = this->m_dataRect.y() + this->m_dataRect.height() - this->m_startIteratorY; 0271 this->m_iterator = new T(this->m_dm, startX, this->m_startIteratorY, height, this->m_offsetX, this->m_offsetY, false, this->m_completeListener); 0272 this->m_realY = this->m_startY; 0273 } 0274 0275 0276 #endif