From 875b451590d005d8c2cf98132ca0310e51bf73c2 Mon Sep 17 00:00:00 2001 From: Bodmer Date: Mon, 30 Mar 2020 21:51:26 +0100 Subject: [PATCH] Fix Sprite 1bpp scroll bug Sprite scroll function fixed for 1bpp readPixelValue() updated Performance of circle drawing functions improved. Version raised to 2.2.0 --- Extensions/Sprite.cpp | 44 ++++++++++++++++++++++++++++++++++++---- Extensions/Sprite.h | 5 +++-- TFT_eSPI.cpp | 47 +++++++++++++++++++++---------------------- TFT_eSPI.h | 2 +- library.json | 2 +- library.properties | 2 +- 6 files changed, 69 insertions(+), 33 deletions(-) diff --git a/Extensions/Sprite.cpp b/Extensions/Sprite.cpp index b0d47093..87d07160 100644 --- a/Extensions/Sprite.cpp +++ b/Extensions/Sprite.cpp @@ -681,10 +681,22 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp) ** Function name: readPixelValue ** Description: Read the color map index of a pixel at defined coordinates *************************************************************************************x*/ -uint8_t TFT_eSprite::readPixelValue(int32_t x, int32_t y) +uint16_t TFT_eSprite::readPixelValue(int32_t x, int32_t y) { if ((x < 0) || (x >= _iwidth) || (y < 0) || (y >= _iheight) || !_created) return 0xFF; + if (_bpp == 16) + { + // Return the pixel colour + return readPixel(x, y); + } + + if (_bpp == 8) + { + // Return the pixel byte value + return _img8[x + y * _iwidth]; + } + if (_bpp == 4) { if ((x & 0x01) == 0) @@ -692,7 +704,31 @@ uint8_t TFT_eSprite::readPixelValue(int32_t x, int32_t y) else return _img4[((x+y*_iwidth)>>1)] & 0x0F; // odd index = bits 3 .. 0. } - return readPixel(x, y); + + if (_bpp == 1) + { + if (_rotation == 1) + { + uint16_t tx = x; + x = _dwidth - y - 1; + y = tx; + } + else if (_rotation == 2) + { + x = _dwidth - x - 1; + y = _dheight - y - 1; + } + else if (_rotation == 3) + { + uint16_t tx = x; + x = y; + y = _dheight - tx - 1; + } + // Return 1 or 0 + return (_img8[(x + y * _bitwidth)>>3] >> (7-(x & 0x7))) & 0x01; + } + + return 0; } /*************************************************************************************** @@ -1227,8 +1263,8 @@ void TFT_eSprite::scroll(int16_t dx, int16_t dy) { // move pixels one by one for (uint16_t xp = 0; xp < w; xp++) { - if (dx <= 0) drawPixel(tx + xp, ty, readPixel(fx + xp, fy)); - if (dx > 0) drawPixel(tx - xp, ty, readPixel(fx - xp, fy)); + if (dx <= 0) drawPixel(tx + xp, ty, readPixelValue(fx + xp, fy)); + if (dx > 0) drawPixel(tx - xp, ty, readPixelValue(fx - xp, fy)); } if (dy <= 0) { ty++; fy++; } else { ty--; fy--; } diff --git a/Extensions/Sprite.h b/Extensions/Sprite.h index f1af7e23..74ba6b2b 100644 --- a/Extensions/Sprite.h +++ b/Extensions/Sprite.h @@ -110,8 +110,9 @@ class TFT_eSprite : public TFT_eSPI { // Read the colour of a pixel at x,y and return value in 565 format uint16_t readPixel(int32_t x0, int32_t y0); - // return the color map index of the pixel at x,y (used when scrolling) - uint8_t readPixelValue(int32_t x, int32_t y); + // return the numerical value of the pixel at x,y (used when scrolling) + // 16bpp = colour, 8bpp = byte, 4bpp = colour index, 1bpp = 1 or 0 + uint16_t readPixelValue(int32_t x, int32_t y); // Write an image (colour bitmap) to the sprite. Not implemented for _bpp == 4. void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data); diff --git a/TFT_eSPI.cpp b/TFT_eSPI.cpp index 23e8af86..27a7e1b2 100644 --- a/TFT_eSPI.cpp +++ b/TFT_eSPI.cpp @@ -1591,7 +1591,7 @@ void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_ // Optimised midpoint circle algorithm void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) { - int32_t x = 0; + int32_t x = 1; int32_t dx = 1; int32_t dy = r+r; int32_t p = -(r>>1); @@ -1617,19 +1617,19 @@ void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) dx+=2; p+=dx; - x++; - // These are ordered to minimise coordinate changes in x or y // drawPixel can then send fewer bounding box commands drawPixel(x0 + x, y0 + r, color); drawPixel(x0 - x, y0 + r, color); drawPixel(x0 - x, y0 - r, color); drawPixel(x0 + x, y0 - r, color); - - drawPixel(x0 + r, y0 + x, color); - drawPixel(x0 - r, y0 + x, color); - drawPixel(x0 - r, y0 - x, color); - drawPixel(x0 + r, y0 - x, color); + if (r != x) { + drawPixel(x0 + r, y0 + x, color); + drawPixel(x0 - r, y0 + x, color); + drawPixel(x0 - r, y0 - x, color); + drawPixel(x0 + r, y0 - x, color); + } + x++; } inTransaction = false; @@ -1639,7 +1639,7 @@ void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) /*************************************************************************************** ** Function name: drawCircleHelper -** Description: Support function for circle drawing +** Description: Support function for drawRoundRect() ***************************************************************************************/ void TFT_eSPI::drawCircleHelper( int32_t x0, int32_t y0, int32_t r, uint8_t cornername, uint32_t color) { @@ -1682,21 +1682,26 @@ void TFT_eSPI::drawCircleHelper( int32_t x0, int32_t y0, int32_t r, uint8_t corn ** Description: draw a filled circle ***************************************************************************************/ // Optimised midpoint circle algorithm, changed to horizontal lines (faster in sprites) +// Improved algorithm avoids repetition of lines void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) { - int32_t x = 0; + int32_t x = 1; int32_t dx = 1; int32_t dy = r+r; + int32_t ly = y0; int32_t p = -(r>>1); + int32_t xo = 0; //begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write() inTransaction = true; drawFastHLine(x0 - r, y0, dy+1, color); - while(x=0) { + drawFastHLine(x0 - xo, y0 + r, 2 * xo+1, color); + drawFastHLine(x0 - xo, y0 - r, 2 * xo+1, color); dy-=2; p-=dy; r--; @@ -1704,13 +1709,11 @@ void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) dx+=2; p+=dx; - - x++; + xo = x; drawFastHLine(x0 - r, y0 + x, 2 * r+1, color); drawFastHLine(x0 - r, y0 - x, 2 * r+1, color); - drawFastHLine(x0 - x, y0 + r, 2 * x+1, color); - drawFastHLine(x0 - x, y0 - r, 2 * x+1, color); + x++; } inTransaction = false; @@ -1720,7 +1723,7 @@ void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) /*************************************************************************************** ** Function name: fillCircleHelper -** Description: Support function for filled circle drawing +** Description: Support function for fillRoundRect() ***************************************************************************************/ // Support drawing roundrects, changed to horizontal lines (faster in sprites) void TFT_eSPI::fillCircleHelper(int32_t x0, int32_t y0, int32_t r, uint8_t cornername, int32_t delta, uint32_t color) @@ -1734,6 +1737,8 @@ void TFT_eSPI::fillCircleHelper(int32_t x0, int32_t y0, int32_t r, uint8_t corne while (y < r) { if (f >= 0) { + if (cornername & 0x1) drawFastHLine(x0 - y, y0 + r, y + y + delta, color); + if (cornername & 0x2) drawFastHLine(x0 - y, y0 - r, y + y + delta, color); r--; ddF_y += 2; f += ddF_y; @@ -1743,14 +1748,8 @@ void TFT_eSPI::fillCircleHelper(int32_t x0, int32_t y0, int32_t r, uint8_t corne ddF_x += 2; f += ddF_x; - if (cornername & 0x1) { - drawFastHLine(x0 - r, y0 + y, r + r + delta, color); - drawFastHLine(x0 - y, y0 + r, y + y + delta, color); - } - if (cornername & 0x2) { - drawFastHLine(x0 - r, y0 - y, r + r + delta, color); // 11995, 1090 - drawFastHLine(x0 - y, y0 - r, y + y + delta, color); - } + if (cornername & 0x1) drawFastHLine(x0 - r, y0 + y, r + r + delta, color); + if (cornername & 0x2) drawFastHLine(x0 - r, y0 - y, r + r + delta, color); } } diff --git a/TFT_eSPI.h b/TFT_eSPI.h index 11611fcd..ced94489 100644 --- a/TFT_eSPI.h +++ b/TFT_eSPI.h @@ -16,7 +16,7 @@ #ifndef _TFT_eSPIH_ #define _TFT_eSPIH_ -#define TFT_ESPI_VERSION "2.1.9" +#define TFT_ESPI_VERSION "2.2.0" /*************************************************************************************** ** Section 1: Load required header files diff --git a/library.json b/library.json index 06f96773..95662032 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TFT_eSPI", - "version": "2.1.9", + "version": "2.2.0", "keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140", "description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32", "repository": diff --git a/library.properties b/library.properties index 2e9b70ac..858e433c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_eSPI -version=2.1.9 +version=2.2.0 author=Bodmer maintainer=Bodmer sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32