25struct RectangleCommand;
30class RectangleBuilder;
89template <Driver DriverT, FramebufferLike FramebufferT>
class Display {
93 auto_sleep_enabled_(auto_sleep), physical_width_(driver_.
width()), physical_height_(driver_.
height()),
94 display_mode_(
mode) {}
105 [[nodiscard]] auto
width() const noexcept -> std::
size_t {
110 [[nodiscard]]
auto height() const noexcept -> std::
size_t {
121 auto set_auto_sleep(
bool enabled)
noexcept ->
void { auto_sleep_enabled_ = enabled; }
127 const auto m =
mode();
144 framebuffer_.set_pixel(x, y, color, orientation_);
148 return framebuffer_.get_pixel(x, y, orientation_);
175 framebuffer_.set_pixel(cmd.position.x, cmd.position.y, cmd.color, orientation_);
179 Graphics::draw_text(framebuffer_, cmd.position, cmd.text, *cmd.font, cmd.foreground, cmd.background, orientation_);
183 auto draw_bitmap(std::size_t x, std::size_t y, std::span<const std::uint8_t> data, std::size_t w, std::size_t h,
184 std::size_t target_w = 0, std::size_t target_h = 0) ->
void {
188 auto draw_bitmap(std::size_t x, std::size_t y, std::span<const Color> data, std::size_t w, std::size_t h,
189 std::size_t target_w = 0, std::size_t target_h = 0) ->
void {
190 auto bytes = std::span<const std::uint8_t>(
reinterpret_cast<const std::uint8_t *
>(data.data()), data.size());
194 template <
typename T>
195 auto draw_bitmap(std::size_t x, std::size_t y,
const std::vector<T> &data, std::size_t w, std::size_t h,
196 std::size_t target_w = 0, std::size_t target_h = 0) ->
void {
197 draw_bitmap(x, y, std::span(data), w, h, target_w, target_h);
201 std::size_t target_width = 0, std::size_t target_height = 0)
202 -> std::expected<void, Error> {
205 return std::unexpected(image_res.error());
208 const auto &img = *image_res;
209 std::size_t draw_w = (target_width > 0) ? target_width : img.width;
210 std::size_t draw_h = (target_height > 0) ? target_height : img.height;
212 for (std::size_t dy = 0; dy < draw_h; ++dy) {
213 for (std::size_t dx = 0; dx < draw_w; ++dx) {
214 std::size_t sx = dx * img.width / draw_w;
215 std::size_t sy = dy * img.height / draw_h;
216 std::size_t src_idx = (sy * img.width + sx) * img.channels;
221 if (img.channels >= 3) {
222 r = img.data[src_idx];
223 g = img.data[src_idx + 1];
224 b = img.data[src_idx + 2];
225 }
else if (img.channels == 1) {
226 r = g = b = img.data[src_idx];
231 if (r < 128 && g < 128 && b < 128) {
233 }
else if (r > 200 && g < 100 && b < 100) {
235 }
else if (r > 200 && g > 200 && b < 100) {
237 }
else if (r < 100 && g < 100 && b > 200) {
239 }
else if (r < 100 && g > 200 && b < 100) {
251 return ImageIO::save_png(filename, framebuffer_.width(), framebuffer_.height(), 3, rgb_data);
271 auto refresh() -> std::expected<void, Error> {
280 if (auto_sleep_enabled_) {
287 return std::unexpected(res.error());
295 if (
auto res = driver_.display_planes(get_planes()); !res) {
296 return std::unexpected(res.error());
299 if (
auto res = driver_.display(get_buffer()); !res) {
300 return std::unexpected(res.error());
304 if (auto_sleep_enabled_) {
308 if (
auto res = driver_.sleep(); !res) {
309 return std::unexpected(res.error());
315 auto sleep() -> std::expected<void, Error> {
return driver_.sleep(); }
316 auto wake() -> std::expected<void, Error> {
return driver_.wake(); }
317 auto power_off() -> std::expected<void, Error> {
return driver_.power_off(); }
318 auto power_on() -> std::expected<void, Error> {
return driver_.power_on(); }
320 [[nodiscard]]
auto supports_wake() const noexcept ->
bool {
return driver_.supports_wake(); }
323 auto driver() -> DriverT & {
return driver_; }
324 auto driver() const -> const DriverT & {
return driver_; }
328 auto framebuffer() const -> const FramebufferT & {
return framebuffer_; }
331 [[nodiscard]]
auto get_planes() const -> std::vector<std::span<const std::
byte>> {
return framebuffer_.get_planes(); }
333 [[nodiscard]]
auto get_buffer() const -> std::span<const std::
byte> {
return framebuffer_.data(); }
336 FramebufferT framebuffer_;
338 bool auto_sleep_enabled_;
339 std::size_t physical_width_;
340 std::size_t physical_height_;
394template <
typename DriverType>
395 requires Driver<DriverType> && DriverTraits<DriverType>
397 bool auto_sleep =
true)
398 -> std::expected<Display<DriverType, MonoFramebuffer>,
Error> {
399 return create_display<DriverType, MonoFramebuffer>(device, mode, orientation, auto_sleep);
413template <
typename DriverType, FramebufferLike FramebufferT>
414 requires Driver<DriverType> && DriverTraits<DriverType>
416 bool auto_sleep =
true) -> std::expected<Display<DriverType, FramebufferT>,
Error> {
426 if (!FramebufferT::supports_mode(mode)) {
430 auto driver = DriverType(device);
431 if (
auto result = driver.init(mode); !result) {
432 return std::unexpected(result.error());
Fluent builder pattern for constructing drawing commands.
Compile-time driver capability traits system.
Definition builders.hpp:493
Definition device.hpp:158
Definition display.hpp:89
auto draw(const LineCommand &cmd) -> void
Definition display.hpp:161
auto text(std::string_view content="") -> TextBuilder
Definition display.hpp:158
auto set_auto_sleep(bool enabled) noexcept -> void
Definition display.hpp:121
Display(Display &&) noexcept=default
Display(DriverT driver, DisplayMode mode, Orientation orientation=Orientation::Portrait0, bool auto_sleep=true)
Definition display.hpp:91
Display(const Display &)=delete
auto circle() -> CircleBuilder
Definition display.hpp:156
auto draw(const CircleCommand &cmd) -> void
Definition display.hpp:170
auto power_off() -> std::expected< void, Error >
Definition display.hpp:317
auto draw(const RectangleCommand &cmd) -> void
Definition display.hpp:165
auto orientation() const noexcept -> Orientation
Definition display.hpp:119
auto supports_wake() const noexcept -> bool
Definition display.hpp:320
auto clear(Color color=Color::White) -> void
Definition display.hpp:151
auto draw_bitmap(std::size_t x, std::size_t y, std::span< const Color > data, std::size_t w, std::size_t h, std::size_t target_w=0, std::size_t target_h=0) -> void
Definition display.hpp:188
auto set_pixel(std::size_t x, std::size_t y, Color color) -> void
Definition display.hpp:143
auto power_on() -> std::expected< void, Error >
Definition display.hpp:318
auto get_num_planes() const noexcept -> std::size_t
Definition display.hpp:124
auto supports_power_control() const noexcept -> bool
Definition display.hpp:321
auto draw(const TextCommand &cmd) -> void
Definition display.hpp:178
auto is_color() const noexcept -> bool
Definition display.hpp:123
auto wake() -> std::expected< void, Error >
Definition display.hpp:316
auto draw_bitmap(std::size_t x, std::size_t y, std::span< const std::uint8_t > data, std::size_t w, std::size_t h, std::size_t target_w=0, std::size_t target_h=0) -> void
Definition display.hpp:183
auto save_framebuffer_to_png(std::string_view filename) const -> std::expected< void, Error >
Definition display.hpp:249
auto get_pixel(std::size_t x, std::size_t y) const -> Color
Definition display.hpp:147
auto auto_sleep_enabled() const noexcept -> bool
Definition display.hpp:120
auto height() const noexcept -> std::size_t
Definition display.hpp:110
auto driver() const -> const DriverT &
Definition display.hpp:324
auto available_colors() const -> std::vector< Color >
Definition display.hpp:126
auto effective_width() const noexcept -> std::size_t
Definition display.hpp:115
auto draw(const PointCommand &cmd) -> void
Definition display.hpp:174
auto framebuffer() -> FramebufferT &
Definition display.hpp:327
auto framebuffer() const -> const FramebufferT &
Definition display.hpp:328
auto rectangle() -> RectangleBuilder
Definition display.hpp:155
auto draw_bitmap_from_file(std::size_t x, std::size_t y, std::string_view file_path, std::size_t target_width=0, std::size_t target_height=0) -> std::expected< void, Error >
Definition display.hpp:200
auto point() -> PointBuilder
Definition display.hpp:157
auto effective_height() const noexcept -> std::size_t
Definition display.hpp:116
auto refresh() -> std::expected< void, Error >
Refresh the display by transferring framebuffer to hardware.
Definition display.hpp:271
auto sleep() -> std::expected< void, Error >
Definition display.hpp:315
auto width() const noexcept -> std::size_t
Definition display.hpp:105
auto mode() const noexcept -> DisplayMode
Definition display.hpp:117
auto operator=(const Display &) -> Display &=delete
auto driver() -> DriverT &
Definition display.hpp:323
auto line() -> LineBuilder
Definition display.hpp:154
auto draw_bitmap(std::size_t x, std::size_t y, const std::vector< T > &data, std::size_t w, std::size_t h, std::size_t target_w=0, std::size_t target_h=0) -> void
Definition display.hpp:195
static auto draw_line(FB &fb, Point start, Point end, LineStyle style, Color color, Orientation orientation) -> void
Draw a line on the framebuffer.
Definition graphics.hpp:171
static auto draw_circle(FB &fb, Point center, std::size_t radius, LineStyle style, Color color, DrawFill fill, Orientation orientation) -> void
Draw a circle on the framebuffer.
Definition graphics.hpp:265
static auto draw_rectangle(FB &fb, Point top_left, Point bottom_right, LineStyle style, Color color, DrawFill fill, Orientation orientation) -> void
Draw a rectangle on the framebuffer.
Definition graphics.hpp:226
static auto draw_bitmap(FB &fb, Point pos, std::span< const std::uint8_t > data, std::size_t w, std::size_t h, std::size_t target_w, std::size_t target_h, Orientation orientation) -> void
Draw a bitmap on the framebuffer.
Definition graphics.hpp:376
static auto draw_text(FB &fb, Point pos, std::string_view text, const Font &font, Color foreground, Color background, Orientation orientation) -> void
Draw text string on the framebuffer.
Definition graphics.hpp:328
static auto load_image(std::string_view path, int desired_channels=0) -> std::expected< ImageResult, Error >
Definition image_io.cpp:36
static auto save_png(std::string_view path, std::size_t width, std::size_t height, int channels, std::span< const std::uint8_t > data) -> std::expected< void, Error >
Definition image_io.cpp:82
static auto framebuffer_to_rgb(const FB &fb) -> std::vector< std::uint8_t >
Definition image_io.hpp:328
Definition builders.hpp:113
Definition builders.hpp:643
Definition builders.hpp:283
Definition builders.hpp:779
Immutable command structures for drawing operations.
C++20 concept defining the Driver interface contract.
Image loading/saving utilities using stb_image library.
auto create_display(Device &device, DisplayMode mode, Orientation orientation=Orientation::Portrait0, bool auto_sleep=true) -> std::expected< Display< DriverType, MonoFramebuffer >, Error >
Convenience factory for mono-plane displays.
Definition display.hpp:396
constexpr auto num_planes(DisplayMode mode) noexcept -> std::size_t
Get number of color planes required for a display mode.
Definition driver.hpp:97
constexpr auto is_color_mode(DisplayMode mode) noexcept -> bool
Check if mode supports color (non-grayscale).
Definition driver.hpp:80
@ InvalidMode
Invalid display mode specified.
Orientation
Definition types.hpp:66
@ Portrait180
180° rotation (upside down portrait)
@ Portrait0
Default portrait orientation (0° rotation)
Color
Definition types.hpp:32
@ White
White (or lightest gray in grayscale modes)
@ Yellow
Yellow (BWY and Spectra6 modes)
@ Blue
Blue (Spectra6 mode only)
@ Green
Green (Spectra6 mode only)
@ Black
Black (or darkest gray in grayscale modes)
@ Red
Red (BWR and Spectra6 modes)
@ Solid
Continuous solid line.
DisplayMode
Definition driver.hpp:46
@ BWY
Black, White, Yellow (3 colors, typically 2-bit)
@ Spectra6
6-color: Black, White, Red, Yellow, Blue, Green (3-bit)
@ Grayscale4
2-bit 4-level grayscale
@ BWR
Black, White, Red (3 colors, typically 2-bit)
Command for drawing a circle.
Definition commands.hpp:174
Definition errors.hpp:140
Command for drawing a line between two points.
Definition commands.hpp:84
Command for drawing a point (pixel or multi-pixel dot).
Definition commands.hpp:218
Command for drawing a rectangle.
Definition commands.hpp:129
Command for drawing text.
Definition commands.hpp:281
Driver capabilities trait template.
Definition capabilities.hpp:110