From 793c0f73be5951b027a9f7400431d8e305910d31 Mon Sep 17 00:00:00 2001 From: jsseab Date: Wed, 14 Aug 2024 14:23:57 +0200 Subject: [PATCH 01/10] Add method drawBitmapAutoIncrement Added faster drawBitmap that uses TFT auto-increment address feature --- Adafruit_SPITFT.cpp | 37 +++++++++++++++++++++++++++++++++++++ Adafruit_SPITFT.h | 3 +++ 2 files changed, 40 insertions(+) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index df98cf5b..8a0de84a 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -950,6 +950,43 @@ void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { } } +/**************************************************************************/ +/*! + @brief Draw a RAM-resident 1-bit image at the specified (x,y) position, + using the specified foreground (for set bits) and background (unset bits) + colors. This is a clone of the Adafruit_GFX method but much faster since it + uses the address auto-increment of the TFT. + @param x Top left corner x coordinate + @param y Top left corner y coordinate + @param bitmap byte array with monochrome bitmap + @param w Width of bitmap in pixels + @param h Height of bitmap in pixels + @param color 16-bit 5-6-5 Color to draw pixels with + @param bg 16-bit 5-6-5 Color to draw background with +*/ +/**************************************************************************/ +void Adafruit_SPITFT::drawBitmapAutoIncrement(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, + int16_t h, uint16_t color, uint16_t bg) { + + int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte + uint8_t b = 0; + + if ((x >= 0) && (x < (_width - w + 1)) && (y >= 0) && (y < (_height - h + 1))) { + setAddrWindow(x, y, w, h); + startWrite(); + for (int16_t j = 0; j < h; j++, y++) { + for (int16_t i = 0; i < w; i++) { + if (i & 7) + b <<= 1; + else + b = bitmap[j * byteWidth + i / 8]; + SPI_WRITE16((b & 0x80) ? color : bg); + } + } + endWrite(); + } +} + /*! @brief Swap bytes in an array of pixels; converts little-to-big or big-to-little endian. Used by writePixels() below in some diff --git a/Adafruit_SPITFT.h b/Adafruit_SPITFT.h index 4111d957..b44c2cd8 100644 --- a/Adafruit_SPITFT.h +++ b/Adafruit_SPITFT.h @@ -216,6 +216,9 @@ class Adafruit_SPITFT : public Adafruit_GFX { // before ending the transaction. It's more efficient than starting a // transaction every time. void writePixel(int16_t x, int16_t y, uint16_t color); + void drawBitmapAutoIncrement(int16_t x, int16_t y, uint8_t *bitmap, + int16_t w, int16_t h, uint16_t color, uint16_t bg); + void writePixels(uint16_t *colors, uint32_t len, bool block = true, bool bigEndian = false); void writeColor(uint16_t color, uint32_t len); From 5349ccf7e4cea47977638bcca9cabad33791c902 Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 10:05:22 +0200 Subject: [PATCH 02/10] Change name to drawBitmapFast instead Change name to drawBitmapFast instead --- Adafruit_SPITFT.cpp | 2 +- Adafruit_SPITFT.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index 8a0de84a..77dbb13c 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -965,7 +965,7 @@ void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { @param bg 16-bit 5-6-5 Color to draw background with */ /**************************************************************************/ -void Adafruit_SPITFT::drawBitmapAutoIncrement(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, +void Adafruit_SPITFT::drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte diff --git a/Adafruit_SPITFT.h b/Adafruit_SPITFT.h index b44c2cd8..faaddfff 100644 --- a/Adafruit_SPITFT.h +++ b/Adafruit_SPITFT.h @@ -216,8 +216,8 @@ class Adafruit_SPITFT : public Adafruit_GFX { // before ending the transaction. It's more efficient than starting a // transaction every time. void writePixel(int16_t x, int16_t y, uint16_t color); - void drawBitmapAutoIncrement(int16_t x, int16_t y, uint8_t *bitmap, - int16_t w, int16_t h, uint16_t color, uint16_t bg); + void drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, + int16_t w, int16_t h, uint16_t color, uint16_t bg); void writePixels(uint16_t *colors, uint32_t len, bool block = true, bool bigEndian = false); From 7eef1f138f272a8916b80c5c22be55d53ecec462 Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 10:29:04 +0200 Subject: [PATCH 03/10] Fix no image shown by drawBitmapFast Fix no image shown by drawBitmapFast --- Adafruit_SPITFT.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index 77dbb13c..ff87e898 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -954,8 +954,11 @@ void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { /*! @brief Draw a RAM-resident 1-bit image at the specified (x,y) position, using the specified foreground (for set bits) and background (unset bits) - colors. This is a clone of the Adafruit_GFX method but much faster since it - uses the address auto-increment of the TFT. + colors. This is a clone of the Adafruit_GFX method but without a call to + setAddrWindow for each pixel. Instead the window is setup once, and then + all pixels are written. This relise on the address auto-increment of the TFT. + Note that the image must fit within the display bounds, otherwise nothing is + done. @param x Top left corner x coordinate @param y Top left corner y coordinate @param bitmap byte array with monochrome bitmap @@ -972,8 +975,8 @@ void Adafruit_SPITFT::drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, int1 uint8_t b = 0; if ((x >= 0) && (x < (_width - w + 1)) && (y >= 0) && (y < (_height - h + 1))) { - setAddrWindow(x, y, w, h); startWrite(); + setAddrWindow(x, y, w, h); for (int16_t j = 0; j < h; j++, y++) { for (int16_t i = 0; i < w; i++) { if (i & 7) From eaac92f23869a83e315112dc73f7c7d43f35b41b Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 10:33:25 +0200 Subject: [PATCH 04/10] Fix typo in comment --- Adafruit_SPITFT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index ff87e898..67d12811 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -956,7 +956,7 @@ void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { using the specified foreground (for set bits) and background (unset bits) colors. This is a clone of the Adafruit_GFX method but without a call to setAddrWindow for each pixel. Instead the window is setup once, and then - all pixels are written. This relise on the address auto-increment of the TFT. + all pixels are written. This relies on the address auto-increment of the TFT. Note that the image must fit within the display bounds, otherwise nothing is done. @param x Top left corner x coordinate From 7ed3a9938ee093125e7eaf6c6b8653d31048a5c2 Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 11:09:11 +0200 Subject: [PATCH 05/10] Modify drawBitmapFast to implement clipping --- Adafruit_SPITFT.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index 67d12811..18521965 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -957,8 +957,7 @@ void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { colors. This is a clone of the Adafruit_GFX method but without a call to setAddrWindow for each pixel. Instead the window is setup once, and then all pixels are written. This relies on the address auto-increment of the TFT. - Note that the image must fit within the display bounds, otherwise nothing is - done. + If the image does not fit within the display bounds, clipping is applied. @param x Top left corner x coordinate @param y Top left corner y coordinate @param bitmap byte array with monochrome bitmap @@ -971,14 +970,26 @@ void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { void Adafruit_SPITFT::drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { - int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte - uint8_t b = 0; - - if ((x >= 0) && (x < (_width - w + 1)) && (y >= 0) && (y < (_height - h + 1))) { + // Sanity check of X and Y position + if ((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) { + + int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte + uint8_t b = 0; + + int16_t wclip = w; + int16_t hclip = h; + + // Clipped width and height + if (((x + w - _width) > 0) && (x < _width)) + wclip = _width - x; + + if (((y + h - _height) > 0) && (y < _height)) + hclip = _height - y; + startWrite(); - setAddrWindow(x, y, w, h); - for (int16_t j = 0; j < h; j++, y++) { - for (int16_t i = 0; i < w; i++) { + setAddrWindow(x, y, wclip, hclip); + for (int16_t j = 0; j < hclip; j++, y++) { + for (int16_t i = 0; i < wclip; i++) { if (i & 7) b <<= 1; else From 0967c23e84063f4cc5a34629c19b4e24a5cc97b4 Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 11:10:13 +0200 Subject: [PATCH 06/10] Formatting --- Adafruit_SPITFT.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index 18521965..7d7a4edd 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -972,10 +972,8 @@ void Adafruit_SPITFT::drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, int1 // Sanity check of X and Y position if ((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) { - int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte uint8_t b = 0; - int16_t wclip = w; int16_t hclip = h; From 170accb187745a08981ff45d6dae9cc3e88b0eb4 Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 11:22:38 +0200 Subject: [PATCH 07/10] Simplify arithmetics --- Adafruit_SPITFT.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index 7d7a4edd..51986d2c 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -976,13 +976,15 @@ void Adafruit_SPITFT::drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, int1 uint8_t b = 0; int16_t wclip = w; int16_t hclip = h; + int16_t wmax = _width - x; + int16_t hmax = _height - y; // Clipped width and height - if (((x + w - _width) > 0) && (x < _width)) - wclip = _width - x; + if (w > wmax) + wclip = wmax; - if (((y + h - _height) > 0) && (y < _height)) - hclip = _height - y; + if (h > hmax) + hclip = hmax; startWrite(); setAddrWindow(x, y, wclip, hclip); From b7c822b7a55cd2e242b6436af6627361181778e2 Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 11:24:34 +0200 Subject: [PATCH 08/10] Remove local variable --- Adafruit_SPITFT.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index 51986d2c..735b0ba7 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -976,15 +976,13 @@ void Adafruit_SPITFT::drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, int1 uint8_t b = 0; int16_t wclip = w; int16_t hclip = h; - int16_t wmax = _width - x; - int16_t hmax = _height - y; // Clipped width and height - if (w > wmax) - wclip = wmax; + if (w > (_width - x)) + wclip = _width - x; - if (h > hmax) - hclip = hmax; + if (h > (_height - y)) + hclip = _height - y; startWrite(); setAddrWindow(x, y, wclip, hclip); From ece7f6f39680b9b8838ef2727b56cc0626189bd9 Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 11:27:38 +0200 Subject: [PATCH 09/10] Invert if condition and use early return instead --- Adafruit_SPITFT.cpp | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Adafruit_SPITFT.cpp b/Adafruit_SPITFT.cpp index 735b0ba7..4253741d 100644 --- a/Adafruit_SPITFT.cpp +++ b/Adafruit_SPITFT.cpp @@ -969,34 +969,34 @@ void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { /**************************************************************************/ void Adafruit_SPITFT::drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { - // Sanity check of X and Y position - if ((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) { - int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte - uint8_t b = 0; - int16_t wclip = w; - int16_t hclip = h; - - // Clipped width and height - if (w > (_width - x)) - wclip = _width - x; - - if (h > (_height - y)) - hclip = _height - y; + if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) + return; - startWrite(); - setAddrWindow(x, y, wclip, hclip); - for (int16_t j = 0; j < hclip; j++, y++) { - for (int16_t i = 0; i < wclip; i++) { - if (i & 7) - b <<= 1; - else - b = bitmap[j * byteWidth + i / 8]; - SPI_WRITE16((b & 0x80) ? color : bg); - } + int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte + uint8_t b = 0; + int16_t wclip = w; + int16_t hclip = h; + + // Clipped width and height + if (w > (_width - x)) + wclip = _width - x; + + if (h > (_height - y)) + hclip = _height - y; + + startWrite(); + setAddrWindow(x, y, wclip, hclip); + for (int16_t j = 0; j < hclip; j++, y++) { + for (int16_t i = 0; i < wclip; i++) { + if (i & 7) + b <<= 1; + else + b = bitmap[j * byteWidth + i / 8]; + SPI_WRITE16((b & 0x80) ? color : bg); } - endWrite(); } + endWrite(); } /*! From 7ad826c2ba4a883e4399bd012555d369a77ef510 Mon Sep 17 00:00:00 2001 From: jsseab Date: Thu, 15 Aug 2024 11:28:30 +0200 Subject: [PATCH 10/10] Formatting --- Adafruit_SPITFT.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Adafruit_SPITFT.h b/Adafruit_SPITFT.h index faaddfff..d9d38add 100644 --- a/Adafruit_SPITFT.h +++ b/Adafruit_SPITFT.h @@ -218,7 +218,6 @@ class Adafruit_SPITFT : public Adafruit_GFX { void writePixel(int16_t x, int16_t y, uint16_t color); void drawBitmapFast(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg); - void writePixels(uint16_t *colors, uint32_t len, bool block = true, bool bigEndian = false); void writeColor(uint16_t color, uint32_t len);