Commit 875b4515 authored by Bodmer's avatar Bodmer

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
parent 5ab0a08d
...@@ -681,10 +681,22 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp) ...@@ -681,10 +681,22 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
** Function name: readPixelValue ** Function name: readPixelValue
** Description: Read the color map index of a pixel at defined coordinates ** Description: Read the color map index of a pixel at defined coordinates
*************************************************************************************x*/ *************************************************************************************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 ((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 (_bpp == 4)
{ {
if ((x & 0x01) == 0) if ((x & 0x01) == 0)
...@@ -692,7 +704,31 @@ uint8_t TFT_eSprite::readPixelValue(int32_t x, int32_t y) ...@@ -692,7 +704,31 @@ uint8_t TFT_eSprite::readPixelValue(int32_t x, int32_t y)
else else
return _img4[((x+y*_iwidth)>>1)] & 0x0F; // odd index = bits 3 .. 0. 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) ...@@ -1227,8 +1263,8 @@ void TFT_eSprite::scroll(int16_t dx, int16_t dy)
{ // move pixels one by one { // move pixels one by one
for (uint16_t xp = 0; xp < w; xp++) 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, readPixelValue(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 (dy <= 0) { ty++; fy++; } if (dy <= 0) { ty++; fy++; }
else { ty--; fy--; } else { ty--; fy--; }
......
...@@ -110,8 +110,9 @@ class TFT_eSprite : public TFT_eSPI { ...@@ -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 // Read the colour of a pixel at x,y and return value in 565 format
uint16_t readPixel(int32_t x0, int32_t y0); uint16_t readPixel(int32_t x0, int32_t y0);
// return the color map index of the pixel at x,y (used when scrolling) // return the numerical value of the pixel at x,y (used when scrolling)
uint8_t readPixelValue(int32_t x, int32_t y); // 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. // 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); void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
......
...@@ -1591,7 +1591,7 @@ void TFT_eSPI::readRectRGB(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_ ...@@ -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 // Optimised midpoint circle algorithm
void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) 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 dx = 1;
int32_t dy = r+r; int32_t dy = r+r;
int32_t p = -(r>>1); 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) ...@@ -1617,19 +1617,19 @@ void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
dx+=2; dx+=2;
p+=dx; p+=dx;
x++;
// These are ordered to minimise coordinate changes in x or y // These are ordered to minimise coordinate changes in x or y
// drawPixel can then send fewer bounding box commands // 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 - x, y0 - r, color); drawPixel(x0 - x, y0 - r, color);
drawPixel(x0 + x, y0 - r, color); drawPixel(x0 + x, y0 - r, 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);
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; inTransaction = false;
...@@ -1639,7 +1639,7 @@ void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) ...@@ -1639,7 +1639,7 @@ void TFT_eSPI::drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: drawCircleHelper ** 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) 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 ...@@ -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 ** Description: draw a filled circle
***************************************************************************************/ ***************************************************************************************/
// Optimised midpoint circle algorithm, changed to horizontal lines (faster in sprites) // 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) 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 dx = 1;
int32_t dy = r+r; int32_t dy = r+r;
int32_t ly = y0;
int32_t p = -(r>>1); int32_t p = -(r>>1);
int32_t xo = 0;
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write() //begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true; inTransaction = true;
drawFastHLine(x0 - r, y0, dy+1, color); drawFastHLine(x0 - r, y0, dy+1, color);
while(x<r){ while(xo<r){
if(p>=0) { if(p>=0) {
drawFastHLine(x0 - xo, y0 + r, 2 * xo+1, color);
drawFastHLine(x0 - xo, y0 - r, 2 * xo+1, color);
dy-=2; dy-=2;
p-=dy; p-=dy;
r--; r--;
...@@ -1704,13 +1709,11 @@ void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) ...@@ -1704,13 +1709,11 @@ void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
dx+=2; dx+=2;
p+=dx; p+=dx;
xo = x;
x++;
drawFastHLine(x0 - r, y0 + x, 2 * r+1, color); drawFastHLine(x0 - r, y0 + x, 2 * r+1, color);
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); x++;
drawFastHLine(x0 - x, y0 - r, 2 * x+1, color);
} }
inTransaction = false; inTransaction = false;
...@@ -1720,7 +1723,7 @@ void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) ...@@ -1720,7 +1723,7 @@ void TFT_eSPI::fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
/*************************************************************************************** /***************************************************************************************
** Function name: fillCircleHelper ** 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) // 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) 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 ...@@ -1734,6 +1737,8 @@ void TFT_eSPI::fillCircleHelper(int32_t x0, int32_t y0, int32_t r, uint8_t corne
while (y < r) { while (y < r) {
if (f >= 0) { 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--; r--;
ddF_y += 2; ddF_y += 2;
f += ddF_y; f += ddF_y;
...@@ -1743,14 +1748,8 @@ void TFT_eSPI::fillCircleHelper(int32_t x0, int32_t y0, int32_t r, uint8_t corne ...@@ -1743,14 +1748,8 @@ void TFT_eSPI::fillCircleHelper(int32_t x0, int32_t y0, int32_t r, uint8_t corne
ddF_x += 2; ddF_x += 2;
f += ddF_x; f += ddF_x;
if (cornername & 0x1) { if (cornername & 0x1) drawFastHLine(x0 - r, y0 + y, r + r + delta, color);
drawFastHLine(x0 - r, y0 + y, r + r + delta, color); if (cornername & 0x2) 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);
}
} }
} }
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_ #ifndef _TFT_eSPIH_
#define _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 ** Section 1: Load required header files
......
{ {
"name": "TFT_eSPI", "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", "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", "description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32",
"repository": "repository":
......
name=TFT_eSPI name=TFT_eSPI
version=2.1.9 version=2.2.0
author=Bodmer author=Bodmer
maintainer=Bodmer maintainer=Bodmer
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32 sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment