Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_sequential_iterator.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef __KIS_SEQUENTIAL_ITERATOR_H
8#define __KIS_SEQUENTIAL_ITERATOR_H
9
10#include <KoAlwaysInline.h>
11
12#include "kis_types.h"
13#include "kis_paint_device.h"
14#include "kis_iterator_ng.h"
15
16
19
20 template <typename Convertible>
21 DevicePolicy(Convertible sel) : m_dev(sel) {}
22
26
28 return m_dev->createHLineIteratorNG(rect.x(), rect.y(), rect.width());
29 }
30
31 int pixelSize() const {
32 return m_dev->pixelSize();
33 }
34
36};
37
38template <class SourcePolicy = DevicePolicy>
41
42 ReadOnlyIteratorPolicy(SourcePolicy source, const QRect &rect) {
43 m_iter = !rect.isEmpty() ? source.createConstIterator(rect) : 0;
44 }
45
50
51 ALWAYS_INLINE const quint8* rawDataConst() const {
52 return m_rawDataConst;
53 }
54
55 ALWAYS_INLINE const quint8* oldRawData() const {
56 return m_oldRawData;
57 }
58
60
61private:
62 const quint8 *m_rawDataConst {nullptr};
63 const quint8 *m_oldRawData {nullptr};
64};
65
66template <class SourcePolicy = DevicePolicy>
69
70 WritableIteratorPolicy(SourcePolicy source, const QRect &rect) {
71 m_iter = !rect.isEmpty() ? source.createIterator(rect) : 0;
72 }
73
75 m_rawData = m_iter ? m_iter->rawData() : 0;
76 m_oldRawData = m_iter ? m_iter->oldRawData() : 0;
77 }
78
80 return m_rawData;
81 }
82
83 ALWAYS_INLINE const quint8* rawDataConst() const {
84 return m_rawData;
85 }
86
87 ALWAYS_INLINE const quint8* oldRawData() const {
88 return m_oldRawData;
89 }
90
92
93private:
94 quint8 *m_rawData {nullptr};
95 const quint8 *m_oldRawData {nullptr};
96};
97
99{
100 ALWAYS_INLINE void setRange(int /* minimum */, int /* maximum */)
101 {
102 }
103
104 ALWAYS_INLINE void setValue(int /* value */)
105 {
106 }
107
109 {
110 }
111};
112
176template <class IteratorPolicy, class SourcePolicy = DevicePolicy, class ProgressPolicy = NoProgressPolicy>
178{
179public:
180 KisSequentialIteratorBase(SourcePolicy source, const QRect &rect, ProgressPolicy progressPolicy = ProgressPolicy())
181 : m_policy(source, rect),
182 m_progressPolicy(progressPolicy),
183 m_pixelSize(source.pixelSize()),
184 m_rowsLeft(rect.height() - 1),
186 m_iteratorX(0),
187 m_iteratorY(0),
188 m_isStarted(false)
189 {
191 m_policy.m_iter ? m_policy.m_iter->nConseqPixels() : 0;
192
193 m_policy.updatePointersCache();
194 m_iteratorX = m_policy.m_iter ? m_policy.m_iter->x() : 0;
195 m_iteratorY = m_policy.m_iter ? m_policy.m_iter->y() : 0;
196
197 m_progressPolicy.setRange(rect.top(), rect.top() + rect.height());
198 m_progressPolicy.setValue(rect.top());
199 }
200
202 m_progressPolicy.setFinished();
203 }
204
205 inline int nConseqPixels() const {
206 return m_isStarted ? m_columnsLeft : 1;
207 }
208
209 inline bool nextPixels(int numPixels) {
210 // leave one step for the nextPixel() call
211 numPixels--;
212
213 m_columnsLeft -= numPixels;
214 m_columnOffset += numPixels * m_pixelSize;
215
216 return nextPixel();
217 }
218
219 inline bool nextPixel() {
220 if (!m_isStarted) {
221 m_isStarted = true;
222 return m_policy.m_iter;
223 }
224
226
227 if (m_columnsLeft > 0) {
229 return true;
230 } else {
231 bool result = m_policy.m_iter->nextPixels(m_numConseqPixels);
232 if (result) {
233 m_columnOffset = 0;
234 m_columnsLeft = m_numConseqPixels = m_policy.m_iter->nConseqPixels();
235 m_policy.updatePointersCache();
236 } else if (m_rowsLeft > 0) {
237 m_rowsLeft--;
238 m_policy.m_iter->nextRow();
239 m_columnOffset = 0;
240 m_columnsLeft = m_numConseqPixels = m_policy.m_iter->nConseqPixels();
241 m_policy.updatePointersCache();
242 m_progressPolicy.setValue(m_policy.m_iter->y());
243 } else if (m_rowsLeft == 0) {
244 // report that we have completed iteration
245 m_progressPolicy.setValue(m_policy.m_iter->y() + 1);
246 }
247
248 m_iteratorX = m_policy.m_iter->x();
249 m_iteratorY = m_policy.m_iter->y();
250 }
251 return m_columnsLeft > 0;
252 }
253
254
255 ALWAYS_INLINE int x() const {
257 }
258
259 ALWAYS_INLINE int y() const {
260 return m_iteratorY;
261 }
262
263 // SFINAE: This method becomes undefined for const version of the
264 // iterator automatically
266 return m_policy.rawData() + m_columnOffset;
267 }
268
269 ALWAYS_INLINE const quint8* rawDataConst() const {
270 return m_policy.rawDataConst() + m_columnOffset;
271 }
272
273 ALWAYS_INLINE const quint8* oldRawData() const {
274 return m_policy.oldRawData() + m_columnOffset;
275 }
276
277private:
278 Q_DISABLE_COPY(KisSequentialIteratorBase)
279 IteratorPolicy m_policy;
280 ProgressPolicy m_progressPolicy;
281 const int m_pixelSize;
283
286
290
292};
293
296
297#endif /* __KIS_SEQUENTIAL_ITERATOR_H */
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
#define ALWAYS_INLINE
virtual const quint8 * oldRawData() const =0
virtual const quint8 * rawDataConst() const =0
quint32 pixelSize() const
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
KisHLineConstIteratorSP createHLineConstIteratorNG(qint32 x, qint32 y, qint32 w) const
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE int x() const
ALWAYS_INLINE const quint8 * oldRawData() const
ALWAYS_INLINE int y() const
ALWAYS_INLINE const quint8 * rawDataConst() const
KisSequentialIteratorBase(SourcePolicy source, const QRect &rect, ProgressPolicy progressPolicy=ProgressPolicy())
KisPaintDeviceSP m_dev
KisHLineIteratorSP createIterator(const QRect &rect)
KisHLineConstIteratorSP createConstIterator(const QRect &rect)
DevicePolicy(KisPaintDeviceSP dev)
DevicePolicy(Convertible sel)
ALWAYS_INLINE void setValue(int)
ALWAYS_INLINE void setFinished()
ALWAYS_INLINE void setRange(int, int)
ReadOnlyIteratorPolicy(SourcePolicy source, const QRect &rect)
ALWAYS_INLINE void updatePointersCache()
KisHLineConstIteratorSP IteratorTypeSP
ALWAYS_INLINE const quint8 * oldRawData() const
ALWAYS_INLINE const quint8 * rawDataConst() const
KisHLineIteratorSP IteratorTypeSP
WritableIteratorPolicy(SourcePolicy source, const QRect &rect)
ALWAYS_INLINE void updatePointersCache()
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE const quint8 * oldRawData() const
ALWAYS_INLINE const quint8 * rawDataConst() const