generated from Projetos/RaspberryPi_app
Code adapted for monochrome 1bpp displays
This commit is contained in:
@@ -97,6 +97,14 @@ void LinuxFBDisplay::writePixel(uint8_t* dst, Color color) const {
|
||||
// ---------------------------------------------------------------------------
|
||||
void LinuxFBDisplay::drawPixelImpl(int16_t x, int16_t y, Color color) {
|
||||
if (!buf_) return;
|
||||
if (bpp_ == 1) {
|
||||
uint8_t* p = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) / 8;
|
||||
uint8_t bit = static_cast<uint32_t>(x) & 7u;
|
||||
if (color) *p |= (1u << bit);
|
||||
else *p &= ~(1u << bit);
|
||||
return;
|
||||
}
|
||||
uint32_t offset = static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * (bpp_ / 8);
|
||||
writePixel(buf_ + offset, color);
|
||||
@@ -109,6 +117,35 @@ void LinuxFBDisplay::drawHLineImpl(int16_t x, int16_t y,
|
||||
int16_t w, Color color) {
|
||||
if (!buf_ || w <= 0) return;
|
||||
|
||||
if (bpp_ == 1) {
|
||||
uint8_t* row = buf_ + static_cast<uint32_t>(y) * line_len_;
|
||||
uint32_t x0 = static_cast<uint32_t>(x);
|
||||
uint32_t x1 = x0 + static_cast<uint32_t>(w) - 1;
|
||||
uint32_t b0 = x0 >> 3;
|
||||
uint32_t b1 = x1 >> 3;
|
||||
// LSB-first: bit mask for pixel x within its byte = 0x01 << (x & 7)
|
||||
// A run from x0 to end-of-byte b0 → 0xFF << (x0 & 7)
|
||||
// A run from start-of-byte b1 to x1 → 0xFF >> (7 - (x1 & 7))
|
||||
if (b0 == b1) {
|
||||
uint8_t mask = (0xFFu << (x0 & 7u)) & (0xFFu >> (7u - (x1 & 7u)));
|
||||
if (color) row[b0] |= mask;
|
||||
else row[b0] &= ~mask;
|
||||
} else {
|
||||
uint8_t lead = 0xFFu << (x0 & 7u);
|
||||
uint8_t trail = 0xFFu >> (7u - (x1 & 7u));
|
||||
if (color) {
|
||||
row[b0] |= lead;
|
||||
if (b1 > b0 + 1) std::memset(row + b0 + 1, 0xFF, b1 - b0 - 1);
|
||||
row[b1] |= trail;
|
||||
} else {
|
||||
row[b0] &= ~lead;
|
||||
if (b1 > b0 + 1) std::memset(row + b0 + 1, 0x00, b1 - b0 - 1);
|
||||
row[b1] &= ~trail;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bytes_pp = bpp_ / 8;
|
||||
uint8_t* row = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * bytes_pp;
|
||||
@@ -143,6 +180,18 @@ void LinuxFBDisplay::drawVLineImpl(int16_t x, int16_t y,
|
||||
int16_t h, Color color) {
|
||||
if (!buf_ || h <= 0) return;
|
||||
|
||||
if (bpp_ == 1) {
|
||||
uint8_t bit = static_cast<uint32_t>(x) & 7u;
|
||||
uint8_t* p = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) / 8;
|
||||
for (int16_t i = 0; i < h; ++i) {
|
||||
if (color) *p |= (1u << bit);
|
||||
else *p &= ~(1u << bit);
|
||||
p += line_len_;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bytes_pp = bpp_ / 8;
|
||||
uint8_t* p = buf_ + static_cast<uint32_t>(y) * line_len_
|
||||
+ static_cast<uint32_t>(x) * bytes_pp;
|
||||
@@ -164,6 +213,36 @@ void LinuxFBDisplay::fillRectImpl(int16_t x, int16_t y,
|
||||
int16_t w, int16_t h, Color color) {
|
||||
if (!buf_ || w <= 0 || h <= 0) return;
|
||||
|
||||
if (bpp_ == 1) {
|
||||
uint32_t x0 = static_cast<uint32_t>(x);
|
||||
uint32_t x1 = x0 + static_cast<uint32_t>(w) - 1;
|
||||
uint32_t b0 = x0 >> 3;
|
||||
uint32_t b1 = x1 >> 3;
|
||||
|
||||
// Fill the first row (handles partial edge bytes correctly).
|
||||
drawHLineImpl(x, y, w, color);
|
||||
|
||||
if (h == 1) return;
|
||||
|
||||
uint8_t* src = buf_ + static_cast<uint32_t>(y) * line_len_ + b0;
|
||||
uint32_t span = b1 - b0 + 1;
|
||||
|
||||
if ((x0 & 7u) == 0 && (x1 & 7u) == 7u) {
|
||||
// Byte-aligned: safe to memcpy the full span to every subsequent row.
|
||||
uint8_t* dst = src + line_len_;
|
||||
for (int16_t r = 1; r < h; ++r) {
|
||||
std::memcpy(dst, src, span);
|
||||
dst += line_len_;
|
||||
}
|
||||
} else {
|
||||
// Unaligned: edge bytes are shared with neighboring pixels,
|
||||
// so each row must be drawn individually.
|
||||
for (int16_t r = 1; r < h; ++r)
|
||||
drawHLineImpl(x, y + r, w, color);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// For 32-bpp with color == black or white, we can use memset for the
|
||||
// entire rectangle. Otherwise, fill the first row with drawHLineImpl
|
||||
// and memcpy it to subsequent rows.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// linux_fb_display.h — GfxCanvas subclass for Linux framebuffer devices.
|
||||
//
|
||||
// Supports XRGB8888 (32 bpp), RGB565 (16 bpp), and 8-bit grayscale.
|
||||
// Supports XRGB8888 (32 bpp), RGB565 (16 bpp), 8-bit grayscale, and 1 bpp (SSD1306).
|
||||
// Uses mmap for zero-copy access to the kernel framebuffer.
|
||||
|
||||
#ifndef LINUX_FB_DISPLAY_H
|
||||
|
||||
Reference in New Issue
Block a user