diff --git a/libs/display/EInkDisplay/include/EInkDisplay.h b/libs/display/EInkDisplay/include/EInkDisplay.h index 2a98dcd..bb22f42 100644 --- a/libs/display/EInkDisplay/include/EInkDisplay.h +++ b/libs/display/EInkDisplay/include/EInkDisplay.h @@ -29,7 +29,7 @@ class EInkDisplay { // Frame buffer operations void clearScreen(uint8_t color = 0xFF) const; void drawImage(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool fromProgmem = false) const; - + void drawImageTransparent(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool fromProgmem = false) const; #ifndef EINK_DISPLAY_SINGLE_BUFFER_MODE void swapBuffers(); #endif diff --git a/libs/display/EInkDisplay/src/EInkDisplay.cpp b/libs/display/EInkDisplay/src/EInkDisplay.cpp index 6eaf138..77b7f28 100644 --- a/libs/display/EInkDisplay/src/EInkDisplay.cpp +++ b/libs/display/EInkDisplay/src/EInkDisplay.cpp @@ -343,6 +343,38 @@ void EInkDisplay::drawImage(const uint8_t* imageData, const uint16_t x, const ui if (Serial) Serial.printf("[%lu] Image drawn to frame buffer\n", millis()); } +// Draws only black pixels from the image, leaves white pixels clear (unchanged in framebuffer) +void EInkDisplay::drawImageTransparent(const uint8_t* imageData, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, + const bool fromProgmem) const { + if (!frameBuffer) { + Serial.printf("[%lu] ERROR: Frame buffer not allocated!\n", millis()); + return; + } + + // Calculate bytes per line for the image + const uint16_t imageWidthBytes = w / 8; + + // Copy only black pixels to frame buffer + for (uint16_t row = 0; row < h; row++) { + const uint16_t destY = y + row; + if (destY >= DISPLAY_HEIGHT) + break; + + const uint16_t destOffset = destY * DISPLAY_WIDTH_BYTES + (x / 8); + const uint16_t srcOffset = row * imageWidthBytes; + + for (uint16_t col = 0; col < imageWidthBytes; col++) { + if ((x / 8 + col) >= DISPLAY_WIDTH_BYTES) + break; + + uint8_t srcByte = fromProgmem ? pgm_read_byte(&imageData[srcOffset + col]) : imageData[srcOffset + col]; + frameBuffer[destOffset + col] &= srcByte; + } + } + + Serial.printf("[%lu] Transparent image drawn to frame buffer\n", millis()); +} + void EInkDisplay::writeRamBuffer(uint8_t ramBuffer, const uint8_t* data, uint32_t size) { const char* bufferName = (ramBuffer == CMD_WRITE_RAM_BW) ? "BW" : "RED"; const unsigned long startTime = millis();