idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
mono_framebuffer.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
13#include <idfxx/epaper/panel>
14#include <idfxx/error>
15
16#include <algorithm>
17#include <cstddef>
18#include <cstdint>
19#include <span>
20#include <vector>
21
26namespace idfxx::epaper {
27
55public:
57 using pixel_type = bool;
58
59#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
69 [[nodiscard]] mono_framebuffer(size_t width, size_t height)
71#endif
72
82 [[nodiscard]] static result<mono_framebuffer> make(size_t width, size_t height) {
83 if (width == 0 || height == 0) {
85 }
86 return mono_framebuffer{width, height, std::vector<uint8_t>(((width + 7) / 8) * height, 0xFF)};
87 }
88
90 [[nodiscard]] size_t width() const noexcept { return _width; }
91
93 [[nodiscard]] size_t height() const noexcept { return _height; }
94
103 [[nodiscard]] size_t stride_bytes() const noexcept { return (_width + 7) / 8; }
104
114 void set_pixel(size_t x, size_t y, bool ink) noexcept {
115 if (x >= _width || y >= _height) {
116 return;
117 }
118 uint8_t& byte = _data[y * stride_bytes() + x / 8];
119 uint8_t mask = static_cast<uint8_t>(1u << (7 - x % 8));
120 // Controller RAM convention: a set bit is white, a cleared bit is ink.
121 if (ink) {
122 byte &= static_cast<uint8_t>(~mask);
123 } else {
124 byte |= mask;
125 }
126 }
127
136 [[nodiscard]] bool get_pixel(size_t x, size_t y) const noexcept {
137 if (x >= _width || y >= _height) {
138 return false;
139 }
140 return (_data[y * stride_bytes() + x / 8] & (1u << (7 - x % 8))) == 0;
141 }
142
147 void fill(bool ink) noexcept { std::ranges::fill(_data, ink ? uint8_t{0x00} : uint8_t{0xFF}); }
148
150 void clear() noexcept { fill(false); }
151
161 [[nodiscard]] std::span<const uint8_t> data() const noexcept { return _data; }
162
172 [[nodiscard]] std::span<const uint8_t> row(size_t y) const noexcept {
173 return std::span<const uint8_t>(_data).subspan(y * stride_bytes(), stride_bytes());
174 }
175
176#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
189 void flush(panel& panel, size_t x = 0, size_t y = 0) const { unwrap(try_flush(panel, x, y)); }
190
204 void flush_rows(panel& panel, size_t y_start, size_t y_end) const { unwrap(try_flush_rows(panel, y_start, y_end)); }
205#endif
206
218 [[nodiscard]] result<void> try_flush(panel& panel, size_t x = 0, size_t y = 0) const {
219 return panel.try_write(*this, x, y);
220 }
221
235 [[nodiscard]] result<void> try_flush_rows(panel& panel, size_t y_start, size_t y_end) const {
236 return panel.try_write_rows(*this, y_start, y_end);
237 }
238
239private:
240 mono_framebuffer(size_t width, size_t height, std::vector<uint8_t> data)
241 : _width(width)
242 , _height(height)
243 , _data(std::move(data)) {}
244
245 size_t _width;
246 size_t _height;
247 std::vector<uint8_t> _data;
248};
249
250} // namespace idfxx::epaper
In-memory framebuffer for monochrome (1 bit per pixel) ePaper displays.
void fill(bool ink) noexcept
Sets every pixel to the given state.
result< void > try_flush_rows(panel &panel, size_t y_start, size_t y_end) const
Uploads a horizontal band of the framebuffer to a panel's RAM.
size_t stride_bytes() const noexcept
Returns the number of bytes per row.
std::span< const uint8_t > data() const noexcept
Returns the raw row-major pixel data.
static result< mono_framebuffer > make(size_t width, size_t height)
Creates a framebuffer of the given dimensions, with all pixels white.
std::span< const uint8_t > row(size_t y) const noexcept
Returns the raw bytes of a single row.
void flush(panel &panel, size_t x=0, size_t y=0) const
Uploads the full framebuffer to a panel's RAM.
void flush_rows(panel &panel, size_t y_start, size_t y_end) const
Uploads a horizontal band of the framebuffer to a panel's RAM.
bool pixel_type
The value type written by set_pixel — true is black ink.
result< void > try_flush(panel &panel, size_t x=0, size_t y=0) const
Uploads the full framebuffer to a panel's RAM.
size_t width() const noexcept
Returns the width in pixels.
void set_pixel(size_t x, size_t y, bool ink) noexcept
Inks or blanks a single pixel.
size_t height() const noexcept
Returns the height in pixels.
bool get_pixel(size_t x, size_t y) const noexcept
Returns the state of a single pixel.
void clear() noexcept
Blanks every pixel to white (equivalent to fill(false)).
mono_framebuffer(size_t width, size_t height)
Creates a framebuffer of the given dimensions, with all pixels white.
Abstract base class for ePaper display panels.
Definition panel.hpp:116
result< void > try_write(const mono_framebuffer &fb, size_t x=0, size_t y=0)
Uploads a monochrome framebuffer to the controller's RAM.
result< void > try_write_rows(const mono_framebuffer &fb, size_t row_start, size_t row_end, size_t x=0, size_t y=0)
Uploads a horizontal band of a monochrome framebuffer.
ePaper display driver classes.
Definition color.hpp:19
constexpr std::unexpected< std::error_code > error(E e) noexcept
Creates an unexpected error from an error code enum.
Definition error.hpp:187
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
Definition error.hpp:307
@ invalid_arg
Invalid argument.
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:120