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
This commit is contained in:
Bodmer
2020-03-30 21:51:26 +01:00
parent 5ab0a08d1d
commit 875b451590
6 changed files with 69 additions and 33 deletions

View File

@@ -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--; }

View File

@@ -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);

View File

@@ -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<r){
while(xo<r){
if(p>=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);
}
}

View File

@@ -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

View File

@@ -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":

View File

@@ -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