Complete viewport update

This commit is contained in:
Bodmer 2020-10-11 22:36:02 +01:00
parent ee91f723e7
commit 505ca81a70
8 changed files with 248 additions and 233 deletions

View File

@ -359,9 +359,13 @@ bool TFT_eSPI::getUnicodeIndex(uint16_t unicode, uint16_t *index)
// Expects file to be open
void TFT_eSPI::drawGlyph(uint16_t code)
{
uint16_t fg = textcolor;
uint16_t bg = textbgcolor;
if (code < 0x21)
{
if (code == 0x20) {
//if (fg!=bg) fillRect(cursor_x, cursor_y, gFont.spaceWidth, gFont.yAdvance, bg);
cursor_x += gFont.spaceWidth;
return;
}
@ -377,18 +381,15 @@ void TFT_eSPI::drawGlyph(uint16_t code)
uint16_t gNum = 0;
bool found = getUnicodeIndex(code, &gNum);
uint16_t fg = textcolor;
uint16_t bg = textbgcolor;
if (found)
{
if (textwrapX && (cursor_x + gWidth[gNum] + gdX[gNum] > _width))
if (textwrapX && (cursor_x + gWidth[gNum] + gdX[gNum] > width()))
{
cursor_y += gFont.yAdvance;
cursor_x = 0;
}
if (textwrapY && ((cursor_y + gFont.yAdvance) >= _height)) cursor_y = 0;
if (textwrapY && ((cursor_y + gFont.yAdvance) >= height())) cursor_y = 0;
if (cursor_x == 0) cursor_x -= gdX[gNum];
uint8_t* pbuffer = nullptr;
@ -402,15 +403,17 @@ void TFT_eSPI::drawGlyph(uint16_t code)
}
#endif
int16_t xs = 0;
uint32_t dl = 0;
uint8_t pixel;
int16_t cy = cursor_y + gFont.maxAscent - gdY[gNum];
int16_t cx = cursor_x + gdX[gNum];
int16_t xs = cx;
uint32_t dl = 0;
uint8_t pixel;
startWrite(); // Avoid slow ESP32 transaction overhead for every pixel
//if (fg!=bg) fillRect(cursor_x, cursor_y, gxAdvance[gNum], gFont.yAdvance, bg);
for (int y = 0; y < gHeight[gNum]; y++)
{
#ifdef FONT_FS_AVAILABLE

View File

@ -26,6 +26,26 @@
#include "Processors/TFT_eSPI_Generic.c"
#endif
// Clipping macro for pushImage
#define PI_CLIP \
if (_vpOoB) return; \
x+= _xDatum; \
y+= _yDatum; \
\
if ((x >= _vpW) || (y >= _vpH)) return; \
\
int32_t dx = 0; \
int32_t dy = 0; \
int32_t dw = w; \
int32_t dh = h; \
\
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; } \
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; } \
\
if ((x + dw) > _vpW ) dw = _vpW - x; \
if ((y + dh) > _vpH ) dh = _vpH - y; \
\
if (dw < 1 || dh < 1) return;
/***************************************************************************************
** Function name: begin_tft_write (was called spi_begin)
@ -91,50 +111,63 @@ inline void TFT_eSPI::begin_tft_read(void){
***************************************************************************************/
void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDatum)
{
// Set to whole screen in case of error
_xDatum = 0;
_yDatum = 0;
_vpX = 0;
_vpY = 0;
_vpW = _width;
_vpH = _height;
// Viewport
_xDatum = x; // Datum x position in screen coordinates
_yDatum = y; // Datum y position in screen coordinates
_xWidth = w; // Viewport width
_yHeight = h; // Viewport height
_vpDatum = false;
// Clipped viewport
_vpX = 0; // Viewport top left corner x coordinate
_vpY = 0; // Viewport top left corner y coordinate
_vpW = _width; // Equivalent of TFT width (Nb: viewport right edge coord + 1)
_vpH = _height; // Equivalent of TFT height (Nb: viewport bottom edge coord + 1)
_vpDatum = false; // Datum is at top left corner of screen (true = top left of viewport)
_vpOoB = false; // Out of Bounds flag (true is all of viewport is off screen)
// Check if out of bounds
if ((x >= _width) || (y >= _height)) return;
// Clip viewport to screen area
if (x<0) { w += x; x = 0; }
if (y<0) { h += y; y = 0; }
if ((x + w) > _width ) { w = _width - x; }
if ((y + h) > _height) { h = _height - y; }
// Clip
if (x < 0) { x = 0; }
if (y < 0) { y = 0; }
//Serial.print(" x=");Serial.print( x);Serial.print(", y=");Serial.print( y);
//Serial.print(", w=");Serial.print(w);Serial.print(", h=");Serial.println(h);
if ((x + w) > _width ) w = _width - x;
if ((y + h) > _height) h = _height - y;
// Check if out of bounds
if (w < 1 || h < 1) return;
if (vpDatum)
{
_xDatum = x;
_yDatum = y;
_vpX = 0;
_vpY = 0;
_vpW = w;
_vpH = h;
}
else
// Check if viewport is entirely out of bounds
if (w < 1 || h < 1)
{
// Set default values and Out of Bounds flag in case of error
_xDatum = 0;
_yDatum = 0;
_vpX = x;
_vpY = y;
_vpW = x + w;
_vpH = y + h;
_xWidth = _width;
_yHeight = _height;
_vpOoB = true; // Set Out of Bounds flag to inhibit all drawing
return;
}
if (!vpDatum)
{
_xDatum = 0; // Reset to top left of screen if not useing a viewport datum
_yDatum = 0;
_xWidth = _width;
_yHeight = _height;
}
// Store the on screen viewport metrics and datum position
_vpX = x;
_vpY = y;
_vpW = x + w;
_vpH = y + h;
_vpDatum = vpDatum;
//Serial.print(" _xDatum=");Serial.print( _xDatum);Serial.print(", _yDatum=");Serial.print( _yDatum);
//Serial.print(", _xWidth=");Serial.print(_xWidth);Serial.print(", _yHeight=");Serial.println(_yHeight);
//Serial.print(" _vpX=");Serial.print( _vpX);Serial.print(", _vpY=");Serial.print( _vpY);
//Serial.print(", _vpW=");Serial.print(_vpW);Serial.print(", _vpH=");Serial.println(_vpH);
}
/***************************************************************************************
@ -143,15 +176,18 @@ void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDa
***************************************************************************************/
void TFT_eSPI::resetViewport(void)
{
// Set to whole screen
// Reset viewport to the whole screen
_xDatum = 0;
_yDatum = 0;
_vpX = 0;
_vpY = 0;
_vpW = _width;
_vpH = _height;
_xWidth = _width;
_yHeight = _height;
_vpDatum = false;
_vpOoB = false;
}
/***************************************************************************************
@ -198,10 +234,10 @@ void TFT_eSPI::frameViewport(uint16_t color, int32_t w)
int32_t _hTemp = _vpH; _vpH = _height;
bool _dTemp = _vpDatum; _vpDatum = false;
fillRect(_xDatum + _xTemp - w, _yDatum + _yTemp - w, _wTemp - _xTemp + w + w, w, color);
fillRect(_xDatum + _xTemp - w, _yDatum + _yTemp, w, _hTemp -_yTemp, color);
fillRect(_xDatum + _wTemp, _yDatum + _yTemp, w, _hTemp - _yTemp, color);
fillRect(_xDatum + _xTemp - w, _yDatum + _hTemp, _wTemp - _xTemp + w + w, w, color);
fillRect(_xTemp - _xDatum, _yTemp - w - _yDatum, _wTemp - _xTemp + w + w, w, color);
fillRect(_xTemp - w - _xDatum, _yTemp - _yDatum, w, _hTemp - _yTemp, color);
fillRect(_wTemp - _xDatum, _yTemp - _yDatum, w, _hTemp - _yTemp, color);
fillRect(_xTemp - w - _xDatum, _hTemp - _yDatum, _wTemp - _xTemp + w + w, w, color);
_vpX = _xTemp;
_vpY = _yTemp;
@ -308,13 +344,8 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
_init_width = _width = w; // Set by specific xxxxx_Defines.h file or by users sketch
_init_height = _height = h; // Set by specific xxxxx_Defines.h file or by users sketch
// Set display clip window to whole screen
_xDatum = 0;
_yDatum = 0;
_vpX = 0;
_vpY = 0;
_vpW = _width;
_vpH = _height;
// Reset the viewport to the whole screen
resetViewport();
rotation = 0;
cursor_y = cursor_x = 0;
@ -626,17 +657,8 @@ void TFT_eSPI::setRotation(uint8_t m)
addr_row = 0xFFFF;
addr_col = 0xFFFF;
if (!_vpDatum)
{
// Reset viewport to whole screen
_xDatum = 0;
_yDatum = 0;
_vpX = 0;
_vpY = 0;
_vpW = _width;
_vpH = _height;
}
// Reset the viewport to the whole screen
resetViewport();
}
@ -804,6 +826,19 @@ uint32_t TFT_eSPI::readcommand32(uint8_t cmd_function, uint8_t index)
***************************************************************************************/
uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
{
if (_vpOoB) return 0;
x0+= _xDatum;
y0+= _yDatum;
// Range checking
if ((x0 < _vpX) || (y0 < _vpY) ||(x0 >= _vpW) || (y0 >= _vpH)) return 0;
#ifdef CGRAM_OFFSET
x0+=colstart;
y0+=rowstart;
#endif
#if defined(TFT_PARALLEL_8_BIT)
CS_L;
@ -813,13 +848,15 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
// Set masked pins D0- D7 to input
busDir(dir_mask, INPUT);
#if !defined (SSD1963_DRIVER)
// Dummy read to throw away don't care value
readByte();
#endif
// Fetch the 16 bit BRG pixel
//uint16_t rgb = (readByte() << 8) | readByte();
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) | defined (SSD1963_DRIVER)// Read 3 bytes
// Read window pixel 24 bit RGB values and fill in LS bits
uint16_t rgb = ((readByte() & 0xF8) << 8) | ((readByte() & 0xFC) << 3) | (readByte() >> 3);
@ -924,7 +961,21 @@ void TFT_eSPI::setCallback(getColorCallback getCol)
***************************************************************************************/
void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data)
{
if ((x > _width) || (y > _height) || (w == 0) || (h == 0)) return;
if (_vpOoB) return;
x+= _xDatum;
y+= _yDatum;
// Clipping
if ((x >= _vpW) || (y >= _vpH)) return;
if (x < _vpX) { w += x - _vpX; x = _vpX; }
if (y < _vpY) { h += y - _vpY; y = _vpY; }
if ((x + w) > _vpW) w = _vpW - x;
if ((y + h) > _vpH) h = _vpH - y;
if ((w < 1) || (h < 1)) return;
#if defined(TFT_PARALLEL_8_BIT)
@ -935,13 +986,13 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
// Set masked pins D0- D7 to input
busDir(dir_mask, INPUT);
// Dummy read to throw away don't care value
readByte();
// Total pixel count
uint32_t len = w * h;
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes
// Dummy read to throw away don't care value
readByte();
// Fetch the 24 bit RGB value
while (len--) {
// Assemble the RGB 16 bit colour
@ -950,7 +1001,23 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
// Swapped byte order for compatibility with pushRect()
*data++ = (rgb<<8) | (rgb>>8);
}
#elif defined (SSD1963_DRIVER)
// Fetch the 18 bit BRG pixels
while (len--) {
uint16_t bgr = ((readByte() & 0xF8) >> 3);; // CS_L adds a small delay
bgr |= ((readByte() & 0xFC) << 3);
bgr |= (readByte() << 8);
// Swap Red and Blue (could check MADCTL setting to see if this is needed)
uint16_t rgb = (bgr>>11) | (bgr<<11) | (bgr & 0x7E0);
// Swapped byte order for compatibility with pushRect()
*data++ = (rgb<<8) | (rgb>>8);
}
#else // ILI9481 reads as 16 bits
// Dummy read to throw away don't care value
readByte();
// Fetch the 16 bit BRG pixels
while (len--) {
#ifdef ILI9486_DRIVER
@ -1049,21 +1116,7 @@ void TFT_eSPI::pushRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
***************************************************************************************/
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data)
{
if ((x >= _vpW) || (y >= _vpH)) return;
int32_t dx = 0;
int32_t dy = 0;
int32_t dw = w;
int32_t dh = h;
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
if ((x + dw) > _vpW ) dw = _vpW - x;
if ((y + dh) > _vpH ) dh = _vpH - y;
if (dw < 1 || dh < 1) return;
PI_CLIP;
begin_tft_write();
inTransaction = true;
@ -1093,21 +1146,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
***************************************************************************************/
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *data, uint16_t transp)
{
if ((x >= _vpW) || (y >= _vpH)) return;
int32_t dx = 0;
int32_t dy = 0;
int32_t dw = w;
int32_t dh = h;
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
if ((x + dw) > _vpW ) dw = _vpW - x;
if ((y + dh) > _vpH ) dh = _vpH - y;
if (dw < 1 || dh < 1) return;
PI_CLIP;
begin_tft_write();
inTransaction = true;
@ -1167,20 +1206,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data)
{
// Requires 32 bit aligned access, so use PROGMEM 16 bit word functions
if ((x >= _vpW) || (y >= _vpH)) return;
int32_t dx = 0;
int32_t dy = 0;
int32_t dw = w;
int32_t dh = h;
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
if ((x + dw) > _vpW ) dw = _vpW - x;
if ((y + dh) > _vpH ) dh = _vpH - y;
if (dw < 1 || dh < 1) return;
PI_CLIP;
begin_tft_write();
inTransaction = true;
@ -1203,7 +1229,6 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
end_tft_write();
}
/***************************************************************************************
** Function name: pushImage - for FLASH (PROGMEM) stored images
** Description: plot 16 bit image with 1 colour being transparent
@ -1211,20 +1236,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data, uint16_t transp)
{
// Requires 32 bit aligned access, so use PROGMEM 16 bit word functions
if ((x >= _vpW) || (y >= _vpH)) return;
int32_t dx = 0;
int32_t dy = 0;
int32_t dw = w;
int32_t dh = h;
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
if ((x + dw) > _vpW ) dw = _vpW - x;
if ((y + dh) > _vpH ) dh = _vpH - y;
if (dw < 1 || dh < 1) return;
PI_CLIP;
begin_tft_write();
inTransaction = true;
@ -1280,21 +1292,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
***************************************************************************************/
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, bool bpp8, uint16_t *cmap)
{
if ((x >= _vpW) || (y >= _vpH)) return;
int32_t dx = 0;
int32_t dy = 0;
int32_t dw = w;
int32_t dh = h;
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
if ((x + dw) > _vpW ) dw = _vpW - x;
if ((y + dh) > _vpH ) dh = _vpH - y;
if (dw < 1 || dh < 1) return;
PI_CLIP;
begin_tft_write();
inTransaction = true;
@ -1437,20 +1435,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
***************************************************************************************/
void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *data, uint8_t transp, bool bpp8, uint16_t *cmap)
{
if ((x >= _vpW) || (y >= _vpH)) return;
int32_t dx = 0;
int32_t dy = 0;
int32_t dw = w;
int32_t dh = h;
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; }
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; }
if ((x + dw) > _vpW ) dw = _vpW - x;
if ((y + dh) > _vpH ) dh = _vpH - y;
if (dw < 1 || dh < 1) return;
PI_CLIP;
begin_tft_write();
inTransaction = true;
@ -2476,8 +2461,7 @@ uint8_t TFT_eSPI::getTextDatum(void)
// Return the size of the display (per current rotation)
int16_t TFT_eSPI::width(void)
{
if (_vpDatum) return _vpW - _vpX;
else return _width;
return _xWidth;
}
@ -2487,8 +2471,7 @@ int16_t TFT_eSPI::width(void)
***************************************************************************************/
int16_t TFT_eSPI::height(void)
{
if (_vpDatum) return _vpH - _vpY;
else return _height;
return _yHeight;
}
@ -2628,28 +2611,34 @@ int16_t TFT_eSPI::fontHeight(void)
***************************************************************************************/
void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size)
{
if ((x >= _vpW) || // Clip right
(y >= _vpH) || // Clip bottom
((x + 6 * size - 1) < _vpX) || // Clip left
((y + 8 * size - 1) < _vpY)) // Clip top
return;
if (_vpOoB) return;
int32_t xd = x + _xDatum;
int32_t yd = y + _yDatum;
if (c < 32) return;
#ifdef LOAD_GLCD
//>>>>>>>>>>>>>>>>>>
#ifdef LOAD_GFXFF
#ifdef LOAD_GFXFF
if(!gfxFont) { // 'Classic' built-in font
#endif
#endif
//>>>>>>>>>>>>>>>>>>
bool fillbg = (bg != color);
if ((xd >= _vpW) || // Clip right
( yd >= _vpH) || // Clip bottom
((xd + 6 * size - 1) < _vpX) || // Clip left
((yd + 8 * size - 1) < _vpY)) // Clip top
return;
if ((size==1) && fillbg && x >= _vpX && (x + 6 * size - 1) < _vpW) {
bool fillbg = (bg != color);
bool clip = xd < _vpX || xd + 6 * textsize >= _vpW || yd < _vpY || yd + 8 * textsize >= _vpH;
if ((size==1) && fillbg && !clip) {
uint8_t column[6];
uint8_t mask = 0x1;
begin_tft_write();
setWindow(x, y, x+5, y+8);
setWindow(xd, yd, xd+5, yd+8);
for (int8_t i = 0; i < 5; i++ ) column[i] = pgm_read_byte(font + (c * 5) + i);
column[5] = 0;
@ -2668,6 +2657,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
else {
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
for (int8_t i = 0; i < 6; i++ ) {
uint8_t line;
if (i == 5)
@ -2694,9 +2684,9 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
#ifdef LOAD_GFXFF
#ifdef LOAD_GFXFF
} else { // Custom font
#endif
#endif
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
#endif // LOAD_GLCD
@ -2789,14 +2779,6 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{
//begin_tft_write(); // Must be called before setWindow
if( _vpDatum)
{
x0+= _xDatum;
x1+= _xDatum;
y0+= _yDatum;
y1+= _yDatum;
}
#if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x0, y0); swap_coord(x1, y1); }
#endif
@ -2870,15 +2852,14 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h)
***************************************************************************************/
void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
{
if (_vpOoB) return;
x+= _xDatum;
y+= _yDatum;
// Range checking
if ((x < _vpX) || (y < _vpY) ||(x >= _vpW) || (y >= _vpH)) return;
if( _vpDatum)
{
x+= _xDatum;
y+= _yDatum;
}
#ifdef CGRAM_OFFSET
x+=colstart;
y+=rowstart;
@ -3077,6 +3058,11 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t
***************************************************************************************/
void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
{
if (_vpOoB) return;
x+= _xDatum;
y+= _yDatum;
// Clipping
if ((x < _vpX) || (x >= _vpW) || (y >= _vpH)) return;
@ -3102,6 +3088,11 @@ void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
***************************************************************************************/
void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
{
if (_vpOoB) return;
x+= _xDatum;
y+= _yDatum;
// Clipping
if ((y < _vpY) || (x >= _vpW) || (y >= _vpH)) return;
@ -3127,6 +3118,11 @@ void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
***************************************************************************************/
void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color)
{
if (_vpOoB) return;
x+= _xDatum;
y+= _yDatum;
// Clipping
if ((x >= _vpW) || (y >= _vpH)) return;
@ -3138,6 +3134,15 @@ void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col
if ((w < 1) || (h < 1)) return;
//Serial.print(" _xDatum=");Serial.print( _xDatum);Serial.print(", _yDatum=");Serial.print( _yDatum);
//Serial.print(", _xWidth=");Serial.print(_xWidth);Serial.print(", _yHeight=");Serial.println(_yHeight);
//Serial.print(" _vpX=");Serial.print( _vpX);Serial.print(", _vpY=");Serial.print( _vpY);
//Serial.print(", _vpW=");Serial.print(_vpW);Serial.print(", _vpH=");Serial.println(_vpH);
//Serial.print(" x=");Serial.print( y);Serial.print(", y=");Serial.print( y);
//Serial.print(", w=");Serial.print(w);Serial.print(", h=");Serial.println(h);
begin_tft_write();
setWindow(x, y, x + w - 1, y + h - 1);
@ -3581,7 +3586,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y)
// Any UTF-8 decoding must be done before calling drawChar()
int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
{
if (!uniCode) return 0;
if (_vpOoB || !uniCode) return 0;
if (font==1) {
#ifdef LOAD_GLCD
@ -3645,19 +3650,23 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
}
#endif
if (x + width * textsize < (int16_t)_vpX || x >= _vpW) return width * textsize ;
int32_t xd = x + _xDatum;
int32_t yd = y + _yDatum;
if ((xd + width * textsize < _vpX || xd >= _vpW) && (yd + height * textsize < _vpY || yd >= _vpH)) return width * textsize ;
int32_t w = width;
int32_t pX = 0;
int32_t pY = y;
uint8_t line = 0;
bool clip = xd < _vpX || xd + width * textsize >= _vpW || yd < _vpY || yd + height * textsize >= _vpH;
#ifdef LOAD_FONT2 // chop out code if we do not need it
if (font == 2) {
w = w + 6; // Should be + 7 but we need to compensate for width increment
w = w / 8;
if (textcolor == textbgcolor || textsize != 1 || x < _vpX || x + width * textsize >= _vpW) {
if (textcolor == textbgcolor || textsize != 1 || clip) {
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
@ -3698,9 +3707,10 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
end_tft_write();
}
else { // Faster drawing of characters and background using block write
begin_tft_write();
setWindow(x, y, x + width - 1, y + height - 1);
setWindow(xd, yd, xd + width - 1, yd + height - 1);
uint8_t mask;
for (int32_t i = 0; i < height; i++) {
@ -3734,7 +3744,8 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
inTransaction = true;
w *= height; // Now w is total number of pixels in the character
if (textcolor == textbgcolor && x >= _vpX && x + width * textsize <= _vpW) {
if (textcolor == textbgcolor && !clip) {
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
@ -3750,12 +3761,12 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
line &= 0x7F;
line++;
if (ts) {
px = x + textsize * (pc % width); // Keep these px and py calculations outside the loop as they are slow
py = y + textsize * (pc / width);
px = xd + textsize * (pc % width); // Keep these px and py calculations outside the loop as they are slow
py = yd + textsize * (pc / width);
}
else {
px = x + pc % width; // Keep these px and py calculations outside the loop as they are slow
py = y + pc / width;
px = xd + pc % width; // Keep these px and py calculations outside the loop as they are slow
py = yd + pc / width;
}
while (line--) { // In this case the while(line--) is faster
pc++; // This is faster than putting pc+=line before while()?
@ -3768,8 +3779,8 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
else {tft_Write_16(textcolor);}
px += textsize;
if (px >= (x + width * textsize)) {
px = x;
if (px >= (xd + width * textsize)) {
px = xd;
py += textsize;
}
}
@ -3781,11 +3792,11 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
}
}
else {
// Text colour != background and textsize = 1 and character is within screen area
// Text colour != background and textsize = 1 and character is within viewport area
// so use faster drawing of characters and background using block write
if (textsize == 1 && x >= _vpX && x + width <= _vpW)
if (textcolor != textbgcolor && textsize == 1 && !clip)
{
setWindow(x, y, x + width - 1, y + height - 1);
setWindow(xd, yd, xd + width - 1, yd + height - 1);
// Maximum font size is equivalent to 180x180 pixels in area
while (w > 0) {
@ -3969,11 +3980,6 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
padding += 2;
break;
}
/* // Check coordinates are OK, adjust if not
if (poX < 0) poX = 0;
if (poX+cwidth > width()) poX = width() - cwidth;
if (poY < 0) poY = 0;
if (poY+cheight-baseline> height()) poY = height() - cheight; //*/
}
@ -4010,7 +4016,16 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
#ifdef SMOOTH_FONT
if(fontLoaded) {
if (textcolor!=textbgcolor) fillRect(poX, poY, cwidth, cheight, textbgcolor);
/*
// The above only works for a single text line, not if the text is going to wrap...
// So need to use code like this in a while loop to fix it:
if (textwrapX && (cursor_x + width * textsize > this->width())) {
cursor_y += height;
cursor_x = 0;
}
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
cursor_x += drawChar(uniCode, cursor_x, cursor_y, textfont);
*/
setCursor(poX, poY);
while (n < len) {

View File

@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.3.0"
#define TFT_ESPI_VERSION "2.3.1"
/***************************************************************************************
** Section 1: Load required header files
@ -736,10 +736,13 @@ class TFT_eSPI : public Print {
int32_t addr_row, addr_col; // Window position - used to minimise window commands
// Viewport variables
int32_t _vpX, _vpY, _vpW, _vpH;
int32_t _vpX, _vpY, _vpW, _vpH; // Note: x start, y start, x end + 1, y end + 1
int32_t _xDatum;
int32_t _yDatum;
int32_t _xWidth;
int32_t _yHeight;
bool _vpDatum;
bool _vpOoB;
uint32_t fontsloaded; // Bit field of fonts loaded

View File

@ -45,12 +45,11 @@ void loop() {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
if (drawTime < 100) tft.drawString("Font 1 not loaded!", 0, 108, 2);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
drawTime = millis();
for (int i = 0; i < 1000; i++) {
tft.drawNumber(i, 0, 0, 2);
@ -60,12 +59,11 @@ void loop() {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
if (drawTime < 200) tft.drawString("Font 2 not loaded!", 0, 108, 2);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
drawTime = millis();
for (int i = 0; i < 1000; i++) {
tft.drawNumber(i, 0, 0, 4);
@ -75,12 +73,11 @@ void loop() {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
if (drawTime < 200) tft.drawString("Font 4 not loaded!", 0, 108, 2);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
drawTime = millis();
for (int i = 0; i < 1000; i++) {
yield(); tft.drawNumber(i, 0, 0, 6);
@ -90,12 +87,11 @@ void loop() {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
if (drawTime < 200) tft.drawString("Font 6 not loaded!", 0, 108, 2);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
drawTime = millis();
for (int i = 0; i < 1000; i++) {
yield(); tft.drawNumber(i, 0, 0, 7);
@ -105,12 +101,11 @@ void loop() {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.drawFloat(drawTime / 2890.0, 3, 0, 80, 4);
if (drawTime < 200) tft.drawString("Font 7 not loaded!", 0, 108, 2);
delay(4000);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
drawTime = millis();
drawTime = millis();
for (int i = 0; i < 100; i++) {
yield(); tft.drawNumber(i, 0, 0, 8);
@ -120,8 +115,7 @@ void loop() {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.drawFloat(drawTime / 190.0, 3, 0, 80, 4);
if (drawTime < 200) tft.drawString("Font 8 not loaded!", 0, 108, 2);
delay(4000);
}

View File

@ -89,7 +89,7 @@ void setup() {
spr.setTextColor(TFT_WHITE, bg_color);
spr.setTextDatum(MC_DATUM);
spr.setTextPadding(spr_width);
spr.drawNumber(0, spr_width/2, 0);
spr.drawNumber(0, spr_width/2, spr.fontHeight()/2);
spr.pushSprite(DIAL_CENTRE_X - spr_width / 2, DIAL_CENTRE_Y - spr.fontHeight() / 2);
// Plot the label text
@ -203,7 +203,7 @@ void plotNeedle(int16_t angle, uint16_t ms_delay)
}
// Update the number at the centre of the dial
spr.drawNumber(old_angle+120, spr_width/2, 0);
spr.drawNumber(old_angle+120, spr_width/2, spr.fontHeight()/2);
spr.pushSprite(120 - spr_width / 2, 120 - spr.fontHeight() / 2);
// Slow needle down slightly as it approaches the new position

View File

@ -132,7 +132,7 @@ void loop() {
for (int16_t angle = 30; angle <= 360; angle += 30)
{
spr.fillSprite(TFT_BLACK); // Clear the Sprite
spr.drawNumber(num, 20, 15, 4); // Plot number, in Sprite at 15,15 and with font 4
spr.drawNumber(num, 20, 15, 4); // Plot number, in Sprite at 20,15 and with font 4
spr.pushRotated(angle, TFT_BLACK); // Plot rotated Sprite, black being transparent
num++;
}
@ -143,7 +143,7 @@ void loop() {
for (int16_t angle = -90; angle < 270; angle += 30)
{
spr.fillSprite(TFT_BLACK); // Clear the Sprite
spr.drawNumber(angle+90, 15, 15, 4); // Plot number, in Sprite at 15,15 and with font 4
spr.drawNumber(angle+90, 20, 15, 4); // Plot number, in Sprite at 20,15 and with font 4
spr.pushRotated(angle, TFT_BLACK); // Plot rotated Sprite, black being transparent
num++;
}

View File

@ -1,6 +1,6 @@
{
"name": "TFT_eSPI",
"version": "2.3.0",
"version": "2.3.1",
"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.3.0
version=2.3.1
author=Bodmer
maintainer=Bodmer
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32