Commit caef4519 authored by Bodmer's avatar Bodmer

Improve bounds checking update CS management

Add bounds checking to graphics functions
Rationalise variable types and style used to minimse type casting needs
(this change ended up being a more extensive refactoring than
anticipated - but once started...)
Add version reporting to diagnostic sketch
Boost PDQ graphicstest performance
parent e8a00240
......@@ -543,10 +543,10 @@ uint16_t TFT_eSprite::readPixel(int32_t x, int32_t y)
** Function name: pushImage
** Description: push 565 colour image into a defined area of a sprite
*************************************************************************************x*/
void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint16_t *data)
void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data)
{
if ((x >= _iwidth) || (y >= _iheight) || (w == 0) || (h == 0) || !_created) return;
if ((x + (int32_t)w < 0) || (y + (int32_t)h < 0)) return;
if ((x + w < 0) || (y + h < 0)) return;
int32_t xo = 0;
int32_t yo = 0;
......@@ -635,14 +635,14 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, uint1
** Function name: pushImage
** Description: push 565 colour FLASH (PROGMEM) image into a defined area
*************************************************************************************x*/
void TFT_eSprite::pushImage(int32_t x, int32_t y, uint32_t w, uint32_t h, const uint16_t *data)
void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data)
{
#ifdef ESP32
pushImage(x, y, w, h, (uint16_t*) data);
#else
// Partitioned memory FLASH processor
if ((x >= _iwidth) || (y >= _iheight) || (w == 0) || (h == 0) || !_created) return;
if ((x + (int32_t)w < 0) || (y + (int32_t)h < 0)) return;
if ((x + w < 0) || (y + h < 0)) return;
int32_t xo = 0;
int32_t yo = 0;
......@@ -877,7 +877,7 @@ void TFT_eSprite::writeColor(uint16_t color)
** Function name: setScrollRect
** Description: Set scroll area within the sprite and the gap fill colour
*************************************************************************************x*/
void TFT_eSprite::setScrollRect(int32_t x, int32_t y, uint32_t w, uint32_t h, uint16_t color)
void TFT_eSprite::setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color)
{
if ((x >= _iwidth) || (y >= _iheight) || !_created ) return;
......@@ -1082,11 +1082,10 @@ uint8_t TFT_eSprite::getRotation(void)
** Function name: drawPixel
** Description: push a single pixel at an arbitrary position
*************************************************************************************x*/
void TFT_eSprite::drawPixel(uint32_t x, uint32_t y, uint32_t color)
void TFT_eSprite::drawPixel(int32_t x, int32_t y, uint32_t color)
{
// x and y are unsigned so that -ve coordinates turn into large positive ones
// this make bounds checking a bit faster
if ((x >= _iwidth) || (y >= _iheight) || !_created) return;
// Range checking
if ((x < 0) || (y < 0) ||(x >= _width) || (y >= _height) || !_created) return;
if (_bpp == 16)
{
......@@ -1598,12 +1597,12 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color
** Function name: drawChar
** Description: draw a unicode onto the screen
*************************************************************************************x*/
int16_t TFT_eSprite::drawChar(unsigned int uniCode, int x, int y)
int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y)
{
return drawChar(uniCode, x, y, textfont);
}
int16_t TFT_eSprite::drawChar(unsigned int uniCode, int x, int y, int font)
int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
{
if (!_created ) return 0;
......@@ -1647,8 +1646,8 @@ int16_t TFT_eSprite::drawChar(unsigned int uniCode, int x, int y, int font)
if ((font>1) && (font<9) && ((uniCode < 32) || (uniCode > 127))) return 0;
int width = 0;
int height = 0;
int32_t width = 0;
int32_t height = 0;
uint32_t flash_address = 0;
uniCode -= 32;
......@@ -1677,9 +1676,9 @@ int16_t TFT_eSprite::drawChar(unsigned int uniCode, int x, int y, int font)
}
#endif
int w = width;
int pX = 0;
int pY = y;
int32_t w = width;
int32_t pX = 0;
int32_t pY = y;
uint8_t line = 0;
#ifdef LOAD_FONT2 // chop out code if we do not need it
......@@ -1688,11 +1687,11 @@ int16_t TFT_eSprite::drawChar(unsigned int uniCode, int x, int y, int font)
w = w / 8;
if (x + width * textsize >= _iwidth) return width * textsize ;
for (int i = 0; i < height; i++)
for (int32_t i = 0; i < height; i++)
{
if (textcolor != textbgcolor) fillRect(x, pY, width * textsize, textsize, textbgcolor);
for (int k = 0; k < w; k++)
for (int32_t k = 0; k < w; k++)
{
line = pgm_read_byte((uint8_t *)flash_address + w * i + k);
if (line) {
......@@ -1738,8 +1737,8 @@ int16_t TFT_eSprite::drawChar(unsigned int uniCode, int x, int y, int font)
int16_t color = textcolor;
if (_bpp == 16) color = (textcolor >> 8) | (textcolor << 8);
else if (_bpp == 8) color = ((textcolor & 0xE000)>>8 | (textcolor & 0x0700)>>6 | (textcolor & 0x0018)>>3);
int px = 0, py = pY; // To hold character block start and end column and row values
int pc = 0; // Pixel count
int32_t px = 0, py = pY; // To hold character block start and end column and row values
int32_t pc = 0; // Pixel count
uint8_t np = textsize * textsize; // Number of pixels in a drawn pixel
uint8_t tnp = 0; // Temporary copy of np for while loop
uint8_t ts = textsize - 1; // Temporary copy of textsize
......@@ -1845,10 +1844,10 @@ void TFT_eSprite::drawGlyph(uint16_t code)
int16_t xs = 0;
uint16_t dl = 0;
for (int y = 0; y < this->gHeight[gNum]; y++)
for (int32_t y = 0; y < this->gHeight[gNum]; y++)
{
this->fontFile.read(pbuffer, this->gWidth[gNum]);
for (int x = 0; x < this->gWidth[gNum]; x++)
for (int32_t x = 0; x < this->gWidth[gNum]; x++)
{
uint8_t pixel = pbuffer[x];
if (pixel)
......@@ -1897,7 +1896,7 @@ void TFT_eSprite::drawGlyph(uint16_t code)
void TFT_eSprite::printToSprite(String string)
{
if(!this->fontLoaded) return;
int16_t len = string.length();
uint16_t len = string.length();
char cbuffer[len + 1]; // Add 1 for the null
string.toCharArray(cbuffer, len + 1); // Add 1 for the null, otherwise characters get dropped
printToSprite(cbuffer, len);
......@@ -1909,7 +1908,7 @@ void TFT_eSprite::printToSprite(String string)
** Function name: printToSprite
** Description: Write a string to the sprite cursor position
*************************************************************************************x*/
void TFT_eSprite::printToSprite(char *cbuffer, int len) //String string)
void TFT_eSprite::printToSprite(char *cbuffer, uint16_t len) //String string)
{
if(!this->fontLoaded) return;
......
......@@ -29,7 +29,7 @@ class TFT_eSprite : public TFT_eSPI {
void setBitmapColor(uint16_t c, uint16_t b);
void drawPixel(uint32_t x, uint32_t y, uint32_t color);
void drawPixel(int32_t x, int32_t y, uint32_t color);
void drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, uint32_t bg, uint8_t size),
......@@ -45,7 +45,7 @@ class TFT_eSprite : public TFT_eSPI {
// Set the scroll zone, top left corner at x,y with defined width and height
// The colour (optional, black is default) is used to fill the gap after the scroll
setScrollRect(int32_t x, int32_t y, uint32_t w, uint32_t h, uint16_t color = TFT_BLACK),
setScrollRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color = TFT_BLACK),
// Scroll the defined zone dx,dy pixels. Negative values left,up, positive right,down
// dy is optional (default is then no up/down scroll).
// The sprite coordinate frame does not move because pixels are moved
......@@ -81,8 +81,8 @@ class TFT_eSprite : public TFT_eSPI {
uint16_t readPixel(int32_t x0, int32_t y0);
// Write an image (colour bitmap) to the sprite
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint16_t *data);
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, const uint16_t *data);
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, const uint16_t *data);
// Swap the byte order for pushImage() - corrects different image endianness
void setSwapBytes(bool swap);
......@@ -93,8 +93,8 @@ class TFT_eSprite : public TFT_eSPI {
void pushSprite(int32_t x, int32_t y);
void pushSprite(int32_t x, int32_t y, uint16_t transparent);
int16_t drawChar(unsigned int uniCode, int x, int y, int font),
drawChar(unsigned int uniCode, int x, int y);
int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
drawChar(uint16_t uniCode, int32_t x, int32_t y);
// Return the width and height of the sprite
int16_t width(void),
......@@ -106,7 +106,7 @@ class TFT_eSprite : public TFT_eSPI {
// Functions associated with anti-aliased fonts
void drawGlyph(uint16_t code);
void printToSprite(String string);
void printToSprite(char *cbuffer, int len);
void printToSprite(char *cbuffer, uint16_t len);
int16_t printToSprite(int16_t x, int16_t y, uint16_t index);
private:
......
This diff is collapsed.
......@@ -15,7 +15,7 @@
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "1.4.0"
#define TFT_ESPI_VERSION "1.4.1"
//#define ESP32 //Just used to test ESP32 options
......@@ -144,8 +144,8 @@
#define DC_D GPIO.out1_w1tc.val = (1 << (TFT_DC - 32)); \
GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
#else
#define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC - 32));GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
#define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC - 32));GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
#define DC_C GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1tc.val = (1 << (TFT_DC - 32))
#define DC_D GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_DC - 32))
#endif
#else
#if TFT_DC >= 0
......@@ -155,8 +155,8 @@
#define DC_D GPIO.out_w1tc = (1 << TFT_DC); \
GPIO.out_w1ts = (1 << TFT_DC)
#else
#define DC_C GPIO.out_w1tc = (1 << TFT_DC);GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC);GPIO.out_w1ts = (1 << TFT_DC)
#define DC_C GPIO.out_w1tc = (1 << TFT_DC)//;GPIO.out_w1tc = (1 << TFT_DC)
#define DC_D GPIO.out_w1ts = (1 << TFT_DC)//;GPIO.out_w1ts = (1 << TFT_DC)
#endif
#else
#define DC_C
......@@ -193,8 +193,8 @@
#define CS_H GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); \
GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#else
#define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32));GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32));GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#define CS_L GPIO.out1_w1tc.val = (1 << (TFT_CS - 32)); GPIO.out1_w1tc.val = (1 << (TFT_CS - 32))
#define CS_H GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))//;GPIO.out1_w1ts.val = (1 << (TFT_CS - 32))
#endif
#else
#if TFT_CS >= 0
......@@ -203,7 +203,7 @@
#define CS_H GPIO.out_w1tc = (1 << TFT_CS); GPIO.out_w1ts = (1 << TFT_CS)
#else
#define CS_L GPIO.out_w1tc = (1 << TFT_CS);GPIO.out_w1tc = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts = (1 << TFT_CS);GPIO.out_w1ts = (1 << TFT_CS)
#define CS_H GPIO.out_w1ts = (1 << TFT_CS)//;GPIO.out_w1ts = (1 << TFT_CS)
#endif
#else
#define CS_L
......@@ -653,15 +653,15 @@ class TFT_eSPI : public Print {
void init(uint8_t tc = TAB_COLOUR), begin(uint8_t tc = TAB_COLOUR); // Same - begin included for backwards compatibility
// These are virtual so the TFT_eSprite class can override them with sprite specific functions
virtual void drawPixel(uint32_t x, uint32_t y, uint32_t color),
virtual void drawPixel(int32_t x, int32_t y, uint32_t color),
drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, uint32_t bg, uint8_t size),
drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color),
drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color),
drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color),
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
virtual int16_t drawChar(unsigned int uniCode, int x, int y, int font),
drawChar(unsigned int uniCode, int x, int y),
virtual int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
drawChar(uint16_t uniCode, int32_t x, int32_t y),
height(void),
width(void);
......@@ -720,30 +720,30 @@ class TFT_eSPI : public Print {
commandList(const uint8_t *addr);
uint8_t readcommand8(uint8_t cmd_function, uint8_t index);
uint16_t readcommand16(uint8_t cmd_function, uint8_t index);
uint32_t readcommand32(uint8_t cmd_function, uint8_t index);
uint8_t readcommand8(uint8_t cmd_function, uint8_t index = 0);
uint16_t readcommand16(uint8_t cmd_function, uint8_t index = 0);
uint32_t readcommand32(uint8_t cmd_function, uint8_t index = 0);
// Read the colour of a pixel at x,y and return value in 565 format
uint16_t readPixel(int32_t x0, int32_t y0);
// The next functions can be used as a pair to copy screen blocks (or horizontal/vertical lines) to another location
// Read a block of pixels to a data buffer, buffer is 16 bit and the array size must be at least w * h
void readRect(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint16_t *data);
void readRect(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
// Write a block of pixels to the screen
void pushRect(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint16_t *data);
void pushRect(int32_t x0, int32_t y0, int32_t w, int32_t h, uint16_t *data);
// These are used to render images or sprites stored in RAM arrays
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint16_t *data);
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint16_t *data, uint16_t transparent);
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, uint16_t transparent);
// These are used to render images stored in FLASH (PROGMEM)
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, const uint16_t *data, uint16_t transparent);
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, const uint16_t *data);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, const uint16_t *data, uint16_t transparent);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, const uint16_t *data);
// These are used by pushSprite for 1 and 8 bit colours
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint8_t *data, bool bpp8 = true);
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data, bool bpp8 = true);
void pushImage(int32_t x0, int32_t y0, int32_t w, int32_t h, uint8_t *data, uint8_t transparent, bool bpp8 = true);
// Swap the byte order for pushImage() - corrects endianness
void setSwapBytes(bool swap);
......@@ -768,26 +768,26 @@ class TFT_eSPI : public Print {
color565(uint8_t red, uint8_t green, uint8_t blue), // Convert 8 bit red, green and blue to 16 bits
color8to16(uint8_t color332); // Convert 8 bit colour to 16 bits
int16_t drawNumber(long long_num,int poX, int poY, int font),
drawNumber(long long_num,int poX, int poY),
drawFloat(float floatNumber,int decimal,int poX, int poY, int font),
drawFloat(float floatNumber,int decimal,int poX, int poY),
int16_t drawNumber(long long_num, int32_t poX, int32_t poY, uint8_t font),
drawNumber(long long_num, int32_t poX, int32_t poY),
drawFloat(float floatNumber, uint8_t decimal, int32_t poX, int32_t poY, uint8_t font),
drawFloat(float floatNumber, uint8_t decimal, int32_t poX, int32_t poY),
// Handle char arrays
drawString(const char *string, int poX, int poY, int font),
drawString(const char *string, int poX, int poY),
drawCentreString(const char *string, int dX, int poY, int font), // Deprecated, use setTextDatum() and drawString()
drawRightString(const char *string, int dX, int poY, int font), // Deprecated, use setTextDatum() and drawString()
drawString(const char *string, int32_t poX, int32_t poY, uint8_t font),
drawString(const char *string, int32_t poX, int32_t poY),
drawCentreString(const char *string, int32_t dX, int32_t poY, uint8_t font), // Deprecated, use setTextDatum() and drawString()
drawRightString(const char *string, int32_t dX, int32_t poY, uint8_t font), // Deprecated, use setTextDatum() and drawString()
// Handle String type
drawString(const String& string, int poX, int poY, int font),
drawString(const String& string, int poX, int poY),
drawCentreString(const String& string, int dX, int poY, int font), // Deprecated, use setTextDatum() and drawString()
drawRightString(const String& string, int dX, int poY, int font); // Deprecated, use setTextDatum() and drawString()
drawString(const String& string, int32_t poX, int32_t poY, uint8_t font),
drawString(const String& string, int32_t poX, int32_t poY),
drawCentreString(const String& string, int32_t dX, int32_t poY, uint8_t font), // Deprecated, use setTextDatum() and drawString()
drawRightString(const String& string, int32_t dX, int32_t poY, uint8_t font); // Deprecated, use setTextDatum() and drawString()
int16_t textWidth(const char *string, int font),
int16_t textWidth(const char *string, uint8_t font),
textWidth(const char *string),
textWidth(const String& string, int font),
textWidth(const String& string, uint8_t font),
textWidth(const String& string),
fontHeight(int16_t font),
fontHeight(void);
......@@ -852,9 +852,9 @@ class TFT_eSPI : public Print {
int32_t win_xe, win_ye;
uint32_t _init_width, _init_height; // Display w/h as input, used by setRotation()
uint32_t _width, _height; // Display w/h as modified by current rotation
uint32_t addr_row, addr_col;
int32_t _init_width, _init_height; // Display w/h as input, used by setRotation()
int32_t _width, _height; // Display w/h as modified by current rotation
int32_t addr_row, addr_col;
uint32_t fontsloaded;
......
......@@ -324,7 +324,7 @@ uint32_t testHaD()
uint16_t curcolor = 0;
const uint8_t *cmp = &HaD_128x160[0];
tft.startWrite();
while (cmp < &HaD_128x160[sizeof(HaD_128x160)])
{
cnt = pgm_read_byte(cmp++);
......@@ -335,6 +335,7 @@ uint32_t testHaD()
curcolor ^= color;
}
tft.endWrite();
}
tft.endWrite();
......@@ -409,7 +410,7 @@ uint32_t testPixels()
int32_t h = tft.height();
uint32_t start = micros_start();
tft.startWrite();
for (uint16_t y = 0; y < h; y++)
{
for (uint16_t x = 0; x < w; x++)
......@@ -417,7 +418,7 @@ uint32_t testPixels()
tft.drawPixel(x, y, tft.color565(x<<3, y<<3, x*y));
}
}
tft.endWrite();
return micros() - start;
}
......
......@@ -434,7 +434,7 @@ uint32_t testPixels()
int32_t h = tft.height();
uint32_t start = micros_start();
tft.startWrite();
for (uint16_t y = 0; y < h; y++)
{
for (uint16_t x = 0; x < w; x++)
......@@ -442,7 +442,7 @@ uint32_t testPixels()
tft.drawPixel(x, y, tft.color565(x<<3, y<<3, x*y));
}
}
tft.endWrite();
return micros() - start;
}
......
......@@ -41,6 +41,8 @@ void loop(void) {
tft.getSetup(user); //
Serial.printf("\n[code]\n");
Serial.printf("TFT_eSPI ver = " + user.version) +"\n");
Serial.printf("Processor = ESP%i\n", user.esp, HEX);
Serial.printf("Frequency = %i MHz\n", ESP.getCpuFreqMHz());
#ifdef ESP8266
......
{
"name": "TFT_eSPI",
"version": "1.4.0",
"version": "1.4.1",
"keywords": "tft, ePaper, display, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789",
"description": "A TFT and ePaper SPI graphics library for ESP8266 and ESP32",
"repository":
......
name=TFT_eSPI
version=1.4.0
version=1.4.1
author=Bodmer
maintainer=Bodmer
sentence=A fast TFT graphics library for ESP8266 and ESP32 processors for the Arduino IDE
......
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