Span.h
1/* Copyright (C) 2015 Marc Boris Duerner
2
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Lesser General Public
5 License as published by the Free Software Foundation; either
6 version 2.1 of the License, or (at your option) any later version.
7
8 As a special exception, you may use this file as part of a free
9 software library without restriction. Specifically, if other files
10 instantiate templates or use macros or inline functions from this
11 file, or you compile this file and link it with other files to
12 produce an executable, this file does not by itself cause the
13 resulting executable to be covered by the GNU General Public
14 License. This exception does not however invalidate any other
15 reasons why the executable file might be covered by the GNU Library
16 General Public License.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 MA 02110-1301 USA
27*/
28
29#ifndef PT_GFX_BASIC_SPAN_H
30#define PT_GFX_BASIC_SPAN_H
31
32#include <Pt/Gfx/Api.h>
33#include <Pt/Gfx/View.h>
34#include <Pt/Gfx/CopyPixel.h>
35#include <Pt/Types.h>
36
37#include <iterator>
38#include <cstddef>
39#include <cassert>
40
41namespace Pt {
42
43namespace Gfx {
44
45template <typename FormatT, typename TraitsT>
46class SpanIterator;
47
48template <typename FormatT, typename TraitsT>
49class ConstSpanIterator;
50
51
52template <typename FormatT, typename TraitsT>
53class SpanIterator
54{
55 template <typename F, typename T>
56 friend class ConstSpanIterator;
57
58 public:
59 typedef FormatT Format;
60 typedef TraitsT Traits;
61
62 typedef typename Traits::Pixel Pixel;
63 typedef typename Traits::ConstPixel ConstPixel;
64
65 typedef ConstSpanIterator<Format, Traits> ConstIterator;
66
67 public:
68 using iterator_category = std::forward_iterator_tag;
69 using value_type = Pixel;
70 using difference_type = std::ptrdiff_t;
71 using pointer = Pixel*;
72 using reference = Pixel&;
73
74 public:
75 explicit SpanIterator(const Pixel& pixel)
76 : _pixel(pixel)
77 { }
78
79 SpanIterator(const SpanIterator& it)
80 : _pixel(it._pixel)
81 { }
82
83 SpanIterator& operator=(const SpanIterator& it)
84 {
85 _pixel.reset(it._pixel);
86 return *this;
87 }
88
89 bool operator!=(const SpanIterator& it) const
90 { return ! _pixel.equals(it._pixel); }
91
92 bool operator!=(const ConstIterator& it) const
93 { return ! _pixel.equals(it._pixel); }
94
95 bool operator==(const SpanIterator& it) const
96 { return _pixel.equals(it._pixel); }
97
98 bool operator==(const ConstIterator& it) const
99 { return _pixel.equals(it._pixel); }
100
101 Pixel& operator*()
102 { return _pixel; }
103
104 Pixel* operator->()
105 { return &_pixel; }
106
107 SpanIterator& operator++()
108 {
109 _pixel.advance();
110 return *this;
111 }
112
113 SpanIterator& operator+=(Pt::ssize_t n)
114 {
115 _pixel.advance(n);
116 return *this;
117 }
118
119 private:
120 Pixel _pixel;
121};
122
123
124template <typename FormatT, typename TraitsT>
125class ConstSpanIterator
126{
127 template <typename F, typename T>
128 friend class SpanIterator;
129
130 public:
131 typedef FormatT Format;
132 typedef TraitsT Traits;
133
134 typedef typename Traits::Pixel Pixel;
135 typedef typename Traits::ConstPixel ConstPixel;
136
137 typedef SpanIterator<Format, Traits> Iterator;
138
139 public:
140 using iterator_category = std::forward_iterator_tag;
141 using value_type = ConstPixel;
142 using difference_type = std::ptrdiff_t;
143 using pointer = ConstPixel*;
144 using reference = ConstPixel&;
145
146 public:
147 explicit ConstSpanIterator(const ConstPixel& pixel)
148 : _pixel(pixel)
149 { }
150
151 explicit ConstSpanIterator(const Pixel& pixel)
152 : _pixel(pixel)
153 { }
154
155 ConstSpanIterator(const ConstSpanIterator& it)
156 : _pixel(it._pixel)
157 { }
158
159 ConstSpanIterator& operator=(const ConstSpanIterator& it)
160 {
161 _pixel.reset(it._pixel);
162 return *this;
163 }
164
165 bool operator!=(const ConstSpanIterator& it) const
166 { return ! _pixel.equals(it._pixel); }
167
168 bool operator!=(const Iterator& it) const
169 { return ! _pixel.equals(it._pixel); }
170
171 bool operator==(const ConstSpanIterator& it) const
172 { return _pixel.equals(it._pixel); }
173
174 bool operator==(const Iterator& it) const
175 { return _pixel.equals(it._pixel); }
176
177 const ConstPixel& operator*() const
178 { return _pixel; }
179
180 const ConstPixel* operator->() const
181 { return &_pixel; }
182
183 ConstSpanIterator& operator++()
184 {
185 _pixel.advance();
186 return *this;
187 }
188
189 ConstSpanIterator& operator+=(Pt::ssize_t n)
190 {
191 _pixel.advance(n);
192 return *this;
193 }
194
195 private:
196 ConstPixel _pixel;
197};
198
199
200template <typename FormatT, typename TraitsT>
201class Span
202{
203 public:
204 typedef FormatT Format;
205 typedef TraitsT Traits;
206
207 typedef typename TraitsT::Pixel Pixel;
208 typedef typename TraitsT::ConstPixel ConstPixel;
209
210 typedef SpanIterator<Format, Traits> Iterator;
211
212 public:
213 template <typename T>
214 Span(T& view, Pt::ssize_t x, Pt::ssize_t y, std::size_t length)
215 : _p(view, x, y)
216 , _length(length)
217 { }
218
219 Span(const Span& span)
220 : _p(span._p)
221 , _length(span._length)
222 { }
223
224 Span& operator=(const Span& span)
225 {
226 _p.reset(span._p);
227 _length = span._length;
228 return *this;
229 }
230
231 bool empty() const
232 { return _length == 0; }
233
234 std::size_t length() const
235 { return _length; }
236
237 void setLength(std::size_t length)
238 { _length = length; }
239
240 void advance(std::size_t n)
241 { _p.advance(n); }
242
243 void skipPadding()
244 { _p.skipPadding(); }
245
246 void advanceLines(std::size_t n)
247 { _p.advanceLines(n); }
248
249 Pixel& front()
250 { return _p; }
251
252 const Pixel& front() const
253 { return _p; }
254
255 Iterator begin()
256 { return Iterator(_p); }
257
258 Iterator end()
259 {
260 Iterator it(_p);
261 it += _length;
262 return it;
263 }
264
265 private:
266 Pixel _p;
267 std::size_t _length;
268};
269
270
271template <typename FormatT, typename TraitsT>
272class ConstSpan
273{
274 public:
275 typedef FormatT Format;
276 typedef TraitsT Traits;
277
278 typedef typename TraitsT::Pixel Pixel;
279 typedef typename TraitsT::ConstPixel ConstPixel;
280
281 typedef ConstSpanIterator<Format, Traits> Iterator;
282
283 public:
284 template <typename T>
285 ConstSpan(const T& view, Pt::ssize_t x, Pt::ssize_t y, std::size_t length)
286 : _p(view, x, y)
287 , _length(length)
288 { }
289
290 template <typename T>
291 ConstSpan(T& view, Pt::ssize_t x, Pt::ssize_t y, std::size_t length)
292 : _p(view, x, y)
293 , _length(length)
294 { }
295
296 ConstSpan(const ConstSpan& span)
297 : _p(span._p)
298 , _length(span._length)
299 { }
300
301 ConstSpan(const Span<Format, Traits>& span)
302 : _p(span.front())
303 , _length(span.length())
304 { }
305
306 ConstSpan& operator=(const ConstSpan& span)
307 {
308 _p.reset(span._p);
309 _length = span._length;
310 return *this;
311 }
312
313 bool empty() const
314 { return _length == 0; }
315
316 std::size_t length() const
317 { return _length; }
318
319 void setLength(std::size_t length)
320 { _length = length; }
321
322 void advance(std::size_t n)
323 { _p.advance(n); }
324
325 void skipPadding()
326 { _p.skipPadding(); }
327
328 void advanceLines(std::size_t n)
329 { _p.advanceLines(n); }
330
331 ConstPixel& front()
332 { return _p; }
333
334 const ConstPixel& front() const
335 { return _p; }
336
337 Iterator begin() const
338 { return Iterator(_p); }
339
340 Iterator end() const
341 {
342 Iterator it(_p);
343 it += _length;
344 return it;
345 }
346
347 private:
348 ConstPixel _p;
349 std::size_t _length;
350};
351
352
353template <typename T>
354Span<typename T::Format,
355 typename T::Traits> span(T& source,
356 Pt::ssize_t x,
357 Pt::ssize_t y,
358 std::size_t length)
359{
360 return Span<typename T::Format, typename T::Traits>(source, x, y, length);
361}
362
363
364template <typename T>
365ConstSpan<typename T::Format,
366 typename T::Traits> span(const T& source,
367 Pt::ssize_t x,
368 Pt::ssize_t y,
369 std::size_t length)
370{
371 return ConstSpan<typename T::Format, typename T::Traits>(source, x, y, length);
372}
373
374
375template <typename T>
376Span<typename T::Format,
377 ImageTraitsF> spanF(T& source,
378 Pt::ssize_t x,
379 Pt::ssize_t y,
380 std::size_t length)
381{
382 return Span<typename T::Format, ImageTraitsF>(source, x, y, length);
383}
384
385
386template <typename T>
387ConstSpan<typename T::Format,
388 ImageTraitsF> spanF(const T& source,
389 Pt::ssize_t x,
390 Pt::ssize_t y,
391 std::size_t length)
392{
393 return ConstSpan<typename T::Format, ImageTraitsF>(source, x, y, length);
394}
395
396
402template <typename SpanT, typename P>
403void copySpanTo(const SpanT& from, P& to)
404{
405 copyPixel(from.front(), to, from.length());
406}
407
412template <typename FromSpanT, typename ToSpanT>
413void copySpan(const FromSpanT& from, ToSpanT& to)
414{
415 std::size_t n = std::min(from.length(), to.length());
416 copyPixel(from.front(), to.front(), n);
417}
418
419} // namespace Gfx
420
421} // namespace Pt
422
423#endif
Graphics and imaging services.
Definition Api-Argb32Image.h:12
void copySpanTo(const SpanT &from, P &to)
Copies the pixels of a span to a pixel position.
Definition Span.h:403
void copySpan(const FromSpanT &from, ToSpanT &to)
Copies the pixels of a span to another span.
Definition Span.h:413
void copyPixel(const P1 &from, P2 &to)
Copies a single pixel.
Definition CopyPixel.h:146
Core module.
Definition Allocator.h:33