HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
pixmap_span.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2023.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
9#pragma once
10
11#include "../utility/module.hpp"
12#include <cstddef>
13#include <span>
14#include <memory>
15
16hi_warning_push();
17// C26459: You called an STL function 'std::copy' with a raw pointer paramter... (stl.1)
18// Using iterators adds a lot of code without any extra safety.
19hi_warning_ignore_msvc(26459);
20
21namespace hi { inline namespace v1 {
22template<typename T, typename Allocator>
23class pixmap;
24
30template<typename T>
32public:
33 using value_type = T;
34 using reference = value_type&;
35 using const_reference = value_type const&;
36 using pointer = value_type *;
37 using const_pointer = value_type const *;
38 using row_type = std::span<value_type>;
39 using const_row_type = std::span<value_type const>;
40 using nc_value_type = std::remove_const_t<value_type>;
41 using size_type = size_t;
42
43 template<typename PixmapView>
44 struct row_iterator {
45 PixmapView *_ptr;
46 size_t _y;
47
48 // clang-format off
49 constexpr row_iterator(row_iterator const &) noexcept = default;
50 constexpr row_iterator(row_iterator &&) noexcept = default;
51 constexpr row_iterator &operator=(row_iterator const &) noexcept = default;
52 constexpr row_iterator &operator=(row_iterator &&) noexcept = default;
53 [[nodiscard]] constexpr row_iterator(PixmapView *ptr, size_t y) noexcept : _ptr(ptr), _y(y) {}
54 [[nodiscard]] constexpr friend bool operator==(row_iterator const &, row_iterator const &) noexcept = default;
55 constexpr row_iterator &operator++() noexcept { ++_y; return *this; }
56 constexpr row_iterator &operator++(int) noexcept { auto tmp = *this; ++_y; return tmp; }
57 constexpr row_iterator &operator--() noexcept { --_y; return *this; }
58 constexpr row_iterator &operator--(int) noexcept { auto tmp = *this; --_y; return tmp; }
59 [[nodiscard]] constexpr auto operator*() const noexcept { return (*_ptr)[_y]; }
60 // clang-format on
61 };
62
63 template<typename PixmapView>
64 struct row_range {
65 PixmapView *_ptr;
66
67 // clang-format off
68 constexpr row_range(row_range const &) noexcept = default;
69 constexpr row_range(row_range &&) noexcept = default;
70 constexpr row_range &operator=(row_range const &) noexcept = default;
71 constexpr row_range &operator=(row_range &&) noexcept = default;
72 [[nodiscard]] constexpr row_range(PixmapView *ptr) noexcept : _ptr(ptr) {}
73 [[nodiscard]] constexpr auto begin() const noexcept { return row_iterator{_ptr, 0_uz}; }
74 [[nodiscard]] constexpr auto end() const noexcept { return row_iterator{_ptr, _ptr->height()}; }
75 // clang-format on
76 };
77
78 ~pixmap_span() = default;
79 constexpr pixmap_span(pixmap_span const&) noexcept = default;
80 constexpr pixmap_span(pixmap_span&&) noexcept = default;
81 constexpr pixmap_span& operator=(pixmap_span const&) noexcept = default;
82 constexpr pixmap_span& operator=(pixmap_span&&) noexcept = default;
83 [[nodiscard]] constexpr pixmap_span() noexcept = default;
84
85 [[nodiscard]] constexpr pixmap_span(value_type *data, size_type width, size_type height, size_type stride) noexcept :
86 _data(data), _width(width), _height(height), _stride(stride)
87 {
88 }
89
90 [[nodiscard]] constexpr pixmap_span(value_type *data, size_type width, size_type height) noexcept :
91 pixmap_span(data, width, height, width)
92 {
93 }
94
95 template<std::same_as<std::remove_const_t<value_type>> O, typename Allocator>
96 [[nodiscard]] constexpr pixmap_span(pixmap<O, Allocator> const& other) noexcept :
97 pixmap_span(other.data(), other.width(), other.height())
98 {
99 }
100
101 template<std::same_as<std::remove_const_t<value_type>> O, typename Allocator>
102 [[nodiscard]] constexpr pixmap_span(pixmap<O, Allocator>& other) noexcept :
103 pixmap_span(other.data(), other.width(), other.height())
104 {
105 }
106
107 template<std::same_as<std::remove_const_t<value_type>> O, typename Allocator>
108 [[nodiscard]] constexpr pixmap_span(pixmap<O, Allocator>&& other) = delete;
109
110 [[nodiscard]] constexpr size_type empty() const noexcept
111 {
112 return _width == 0 and _height == 0;
113 }
114
115 [[nodiscard]] constexpr size_type width() const noexcept
116 {
117 return _width;
118 }
119
120 [[nodiscard]] constexpr size_type height() const noexcept
121 {
122 return _height;
123 }
124
125 [[nodiscard]] constexpr size_type stride() const noexcept
126 {
127 return _stride;
128 }
129
130 [[nodiscard]] constexpr pointer data() noexcept
131 {
132 return _data;
133 }
134
135 [[nodiscard]] constexpr const_pointer data() const noexcept
136 {
137 return _data;
138 }
139
140 constexpr reference operator()(size_type x, size_type y) noexcept
141 {
142 hi_axiom(x < _width);
143 hi_axiom(y < _height);
144 return _data[y * _stride + x];
145 }
146
147 constexpr const_reference operator()(size_type x, size_type y) const noexcept
148 {
149 hi_axiom(x < _width);
150 hi_axiom(y < _height);
151 return _data[y * _stride + x];
152 }
153
154 [[nodiscard]] constexpr row_type operator[](size_type y) noexcept
155 {
156 hi_axiom(y < _height);
157 return {_data + y * _stride, _width};
158 }
159
160 [[nodiscard]] constexpr const_row_type operator[](size_type y) const noexcept
161 {
162 hi_axiom(y < _height);
163 return {_data + y * _stride, _width};
164 }
165
166 [[nodiscard]] constexpr auto rows() noexcept
167 {
168 return row_range{this};
169 }
170
171 [[nodiscard]] constexpr auto rows() const noexcept
172 {
173 return row_range{this};
174 }
175
176 [[nodiscard]] constexpr pixmap_span subimage(size_type x, size_type y, size_type new_width, size_type new_height) noexcept
177 {
178 return {_data + y * _stride + x, new_width, new_height, _stride};
179 }
180
181 [[nodiscard]] constexpr pixmap_span<value_type const>
182 subimage(size_type x, size_type y, size_type new_width, size_type new_height) const noexcept
183 {
184 return {_data + y * _stride + x, new_width, new_height, _stride};
185 }
186
187 constexpr friend void copy(pixmap_span src, pixmap_span<std::remove_const_t<value_type>> dst) noexcept
188 {
189 hi_axiom(src.width() == dst.width());
190 hi_axiom(src.height() == dst.height());
191
192 if (src.width() == src.stride() and dst.width() == dst.stride()) {
193 std::copy(src.data(), src.data() + src.width() * src.height(), dst.data());
194 } else {
195 for (auto y = 0_uz; y != src.height(); ++y) {
196 hilet src_line = src[y];
197 hilet dst_line = dst[y];
198 std::copy(src_line.begin(), src_line.end(), dst_line.begin());
199 }
200 }
201 }
202
203 constexpr friend void fill(pixmap_span dst, value_type value = value_type{}) noexcept
204 {
205 if (dst._width == dst._stride) {
206 std::fill_n(dst._data, dst._width, dst._height, value);
207 } else {
208 for (auto line: dst.rows()) {
209 std::fill(line.begin(), line.end(), value);
210 }
211 }
212 }
213
214private:
215 value_type *_data = nullptr;
216 size_type _width = 0;
217 size_type _height = 0;
218 size_type _stride = 0;
219};
220
221template<typename T, typename Allocator>
222pixmap_span(pixmap<T, Allocator> const& other) -> pixmap_span<T const>;
223
224template<typename T, typename Allocator>
225pixmap_span(pixmap<T, Allocator>& other) -> pixmap_span<T>;
226
227}} // namespace hi::v1
228
229hi_warning_pop();
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
A non-owning 2D pixel-based image.
Definition pixmap_span.hpp:31
A 2D pixel-based image.
Definition pixmap.hpp:35
Definition pixmap_span.hpp:44
Definition pixmap_span.hpp:64
T copy(T... args)
T fill(T... args)
T fill_n(T... args)