Feature update

Add ILI9225 support
Add viewport feature to Sprites
Rationalise common TFT_eSPI and Sprite functions and variables to use inherited functions width(), height(), rotation(), write(), pivot, cursor, swapBytes.
This commit is contained in:
Bodmer
2020-12-01 20:06:32 +00:00
parent 27216f89cc
commit 42e6fc87ff
16 changed files with 842 additions and 920 deletions
+214 -170
View File
@@ -57,11 +57,13 @@ inline void TFT_eSPI::begin_tft_write(void){
locked = false;
spi.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE));
CS_L;
SET_BUS_WRITE_MODE
}
#else
CS_L;
#endif
SET_BUS_WRITE_MODE;
#endif
}
/***************************************************************************************
@@ -76,10 +78,10 @@ inline void TFT_eSPI::end_tft_write(void){
CS_H;
spi.endTransaction();
}
SET_BUS_READ_MODE;
}
SET_BUS_READ_MODE;
#else
if(!inTransaction) {CS_H;}
if(!inTransaction) {CS_H; SET_BUS_READ_MODE;}
#endif
}
@@ -111,26 +113,25 @@ 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)
{
// Viewport
// Viewport metrics (not clipped)
_xDatum = x; // Datum x position in screen coordinates
_yDatum = y; // Datum y position in screen coordinates
_xWidth = w; // Viewport width
_yHeight = h; // Viewport height
// 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)
// Full size default viewport
_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)
_vpOoB = false; // Out of Bounds flag (true is all of viewport is off screen)
_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)
// 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; }
if ((x + w) > width() ) { w = width() - x; }
if ((y + h) > height() ) { h = height() - y; }
//Serial.print(" x=");Serial.print( x);Serial.print(", y=");Serial.print( y);
//Serial.print(", w=");Serial.print(w);Serial.print(", h=");Serial.println(h);
@@ -141,21 +142,21 @@ void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDa
// Set default values and Out of Bounds flag in case of error
_xDatum = 0;
_yDatum = 0;
_xWidth = _width;
_yHeight = _height;
_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
_xDatum = 0; // Reset to top left of screen if not using a viewport datum
_yDatum = 0;
_xWidth = _width;
_yHeight = _height;
_xWidth = width();
_yHeight = height();
}
// Store the on screen viewport metrics and datum position
// Store the clipped screen viewport metrics and datum position
_vpX = x;
_vpY = y;
_vpW = x + w;
@@ -205,23 +206,22 @@ bool TFT_eSPI::checkViewport(int32_t x, int32_t y, int32_t w, int32_t h)
***************************************************************************************/
void TFT_eSPI::resetViewport(void)
{
// Reset viewport to the whole screen
// Reset viewport to the whole screen (or sprite) area
_vpDatum = false;
_vpOoB = false;
_xDatum = 0;
_yDatum = 0;
_vpX = 0;
_vpY = 0;
_vpW = _width;
_vpH = _height;
_xWidth = _width;
_yHeight = _height;
_vpDatum = false;
_vpOoB = false;
_vpW = width();
_vpH = height();
_xWidth = width();
_yHeight = height();
}
/***************************************************************************************
** Function name: getViewportX
** Description: Get x position of the viewport
** Description: Get x position of the viewport datum
***************************************************************************************/
int32_t TFT_eSPI::getViewportX(void)
{
@@ -230,7 +230,7 @@ int32_t TFT_eSPI::getViewportX(void)
/***************************************************************************************
** Function name: getViewportY
** Description: Get y position of the viewport
** Description: Get y position of the viewport datum
***************************************************************************************/
int32_t TFT_eSPI::getViewportY(void)
{
@@ -243,7 +243,7 @@ int32_t TFT_eSPI::getViewportY(void)
***************************************************************************************/
int32_t TFT_eSPI::getViewportWidth(void)
{
return _vpW - _vpX;
return _xWidth;
}
/***************************************************************************************
@@ -252,12 +252,12 @@ int32_t TFT_eSPI::getViewportWidth(void)
***************************************************************************************/
int32_t TFT_eSPI::getViewportHeight(void)
{
return _vpH - _vpY;
return _yHeight;
}
/***************************************************************************************
** Function name: getViewportDatum
** Description: Get datum of the viewport (true = viewport corner)
** Description: Get datum flag of the viewport (true = viewport corner)
***************************************************************************************/
bool TFT_eSPI::getViewportDatum(void)
{
@@ -270,37 +270,52 @@ bool TFT_eSPI::getViewportDatum(void)
***************************************************************************************/
void TFT_eSPI::frameViewport(uint16_t color, int32_t w)
{
// Save datum position
bool _dT = _vpDatum;
// If w is positive the frame is drawn inside the viewport
// a large positive width will clear the screen inside the viewport
if (w>0)
{
fillRect(_vpX, _vpY, _vpW - _vpX, w, color);
fillRect(_vpX, _vpY + w, w, _vpH - _vpY - w - w, color);
fillRect(_vpW - w, _vpY + w, w, _vpH - _vpY - w - w, color);
fillRect(_vpX, _vpH - w, _vpW - _vpX, w, color);
// Set vpDatum true to simplify coordinate derivation
_vpDatum = true;
fillRect(0, 0, _vpW - _vpX, w, color); // Top
fillRect(0, w, w, _vpH - _vpY - w - w, color); // Left
fillRect(_xWidth - w, w, w, _yHeight - w - w, color); // Right
fillRect(0, _yHeight - w, _xWidth, w, color); // Bottom
}
else
// If w is negative the frame is drawn outside the viewport
// a large negative width will clear the screen outside the viewport
{
w = -w;
int32_t _xTemp = _vpX; _vpX = 0;
int32_t _yTemp = _vpY; _vpY = 0;
int32_t _wTemp = _vpW; _vpW = _width;
int32_t _hTemp = _vpH; _vpH = _height;
bool _dTemp = _vpDatum; _vpDatum = false;
// Save old values
int32_t _xT = _vpX; _vpX = 0;
int32_t _yT = _vpY; _vpY = 0;
int32_t _wT = _vpW;
int32_t _hT = _vpH;
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);
// Set vpDatum false so frame can be drawn outside window
_vpDatum = false; // When false the full width and height is accessed
_vpH = height();
_vpW = width();
_vpX = _xTemp;
_vpY = _yTemp;
_vpW = _wTemp;
_vpH = _hTemp;
_vpDatum = _dTemp;
// Draw frame
fillRect(_xT - w - _xDatum, _yT - w - _yDatum, _wT - _xT + w + w, w, color); // Top
fillRect(_xT - w - _xDatum, _yT - _yDatum, w, _hT - _yT, color); // Left
fillRect(_wT - _xDatum, _yT - _yDatum, w, _hT - _yT, color); // Right
fillRect(_xT - w - _xDatum, _hT - _yDatum, _wT - _xT + w + w, w, color); // Bottom
// Restore old values
_vpX = _xT;
_vpY = _yT;
_vpW = _wT;
_vpH = _hT;
}
// Restore vpDatum
_vpDatum = _dT;
}
/***************************************************************************************
@@ -438,8 +453,8 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
addr_row = 0xFFFF;
addr_col = 0xFFFF;
_xpivot = 0;
_ypivot = 0;
_xPivot = 0;
_yPivot = 0;
cspinmask = 0;
dcpinmask = 0;
@@ -1365,6 +1380,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
begin_tft_write();
inTransaction = true;
bool swap = _swapBytes;
setWindow(x, y, x + dw - 1, y + dh - 1); // Sets CS low and sent RAMWR
@@ -1373,7 +1389,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
if (bpp8)
{
bool swap = _swapBytes; _swapBytes = false;
_swapBytes = false;
uint8_t blue[] = {0, 11, 21, 31}; // blue 2 to 5 bit colour lookup table
@@ -1413,7 +1429,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
}
else if (cmap != nullptr) // Must be 4bpp
{
bool swap = _swapBytes; _swapBytes = true;
_swapBytes = true;
w = (w+1) & 0xFFFE; // if this is a sprite, w will already be even; this does no harm.
bool splitFirst = (dx & 0x01) != 0; // split first means we have to push a single px from the left of the sprite / image
@@ -1464,35 +1480,24 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
}
else // Must be 1bpp
{
bool swap = _swapBytes; _swapBytes = false;
while (dh--) {
w = (w+7) & 0xFFF8;
_swapBytes = false;
int32_t len = dw;
uint8_t* ptr = data;
uint32_t ww = (w+7)>>3; // Width of source image line in bytes
for (int32_t yp = dy; yp < dy + dh; yp++)
{
uint8_t* linePtr = (uint8_t*)lineBuf;
uint8_t bits = 8;
while(len>0) {
if (len < 8) bits = len;
uint32_t xp = dx;
for (uint16_t i = 0; i < bits; i++) {
uint8_t col = (ptr[(xp + dy * w)>>3] << (xp & 0x7)) & 0x80;
if (col) {*linePtr++ = bitmap_fg>>8; *linePtr++ = (uint8_t) bitmap_fg;}
else {*linePtr++ = bitmap_bg>>8; *linePtr++ = (uint8_t) bitmap_bg;}
//if (col) drawPixel((dw-len)+xp,h-dh,bitmap_fg);
//else drawPixel((dw-len)+xp,h-dh,bitmap_bg);
xp++;
}
ptr++;
len -= 8;
for (int32_t xp = dx; xp < dx + dw; xp++)
{
uint16_t col = (data[(xp>>3)] & (0x80 >> (xp & 0x7)) );
if (col) {*linePtr++ = bitmap_fg>>8; *linePtr++ = (uint8_t) bitmap_fg;}
else {*linePtr++ = bitmap_bg>>8; *linePtr++ = (uint8_t) bitmap_bg;}
}
data += ww;
pushPixels(lineBuf, dw);
dy++;
}
_swapBytes = swap; // Restore old value
}
_swapBytes = swap; // Restore old value
inTransaction = false;
end_tft_write();
}
@@ -1508,6 +1513,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
begin_tft_write();
inTransaction = true;
bool swap = _swapBytes;
int32_t xe = x + dw - 1, ye = y + dh - 1;
@@ -1515,7 +1521,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
uint16_t lineBuf[dw];
if (bpp8) { // 8 bits per pixel
bool swap = _swapBytes; _swapBytes = false;
_swapBytes = false;
data += dx + dy * w;
@@ -1527,8 +1533,6 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
uint8_t msbColor = 0;
uint8_t lsbColor = 0;
//int32_t spx = x, spy = y;
while (dh--) {
int32_t len = dw;
uint8_t* ptr = data;
@@ -1571,11 +1575,10 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
y++;
data += w;
}
_swapBytes = swap; // Restore old value
}
else if (cmap != nullptr) // 4bpp with color map
{
bool swap = _swapBytes; _swapBytes = true;
_swapBytes = true;
w = (w+1) & 0xFFFE; // here we try to recreate iwidth from dwidth.
bool splitFirst = ((dx & 0x01) != 0);
@@ -1662,52 +1665,41 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
data += (w>>1);
y++;
}
_swapBytes = swap; // Restore old value
}
else { // 1 bit per pixel
bool swap = _swapBytes; _swapBytes = false;
w = (w+7) & 0xFFF8;
while (dh--) {
_swapBytes = false;
uint32_t ww = (w+7)>>3; // Width of source image line in bytes
uint16_t np = 0;
for (int32_t yp = dy; yp < dy + dh; yp++)
{
int32_t px = x;
bool move = true;
uint16_t np = 0;
int32_t len = dw;
uint8_t* ptr = data;
uint8_t bits = 8;
while(len>0) {
if (len < 8) bits = len;
uint32_t xp = dx;
uint32_t yp = (dy * w)>>3;
for (uint16_t i = 0; i < bits; i++) {
//uint8_t col = (ptr[(xp + dy * w)>>3] << (xp & 0x7)) & 0x80;
if ((ptr[(xp>>3) + yp] << (xp & 0x7)) & 0x80) {
if (move) {
move = false;
setWindow(px, y, xe, ye);
}
np++;
for (int32_t xp = dx; xp < dx + dw; xp++)
{
if (data[(xp>>3)] & (0x80 >> (xp & 0x7))) {
if (move) {
move = false;
setWindow(px, y, xe, ye);
}
else {
if (np) {
pushBlock(bitmap_fg, np);
np = 0;
move = true;
}
}
px++;
xp++;
np++;
}
ptr++;
len -= 8;
else {
if (np) {
pushBlock(bitmap_fg, np);
np = 0;
move = true;
}
}
px++;
}
if (np) pushBlock(bitmap_fg, np);
y++;
dy++;
data += ww;
if (np) { pushBlock(bitmap_fg, np); np = 0; }
}
_swapBytes = swap; // Restore old value
}
_swapBytes = swap; // Restore old value
inTransaction = false;
end_tft_write();
}
@@ -2427,8 +2419,8 @@ void TFT_eSPI::setTextColor(uint16_t c, uint16_t b)
*************************************************************************************x*/
void TFT_eSPI::setPivot(int16_t x, int16_t y)
{
_xpivot = x;
_ypivot = y;
_xPivot = x;
_yPivot = y;
}
@@ -2438,7 +2430,7 @@ void TFT_eSPI::setPivot(int16_t x, int16_t y)
***************************************************************************************/
int16_t TFT_eSPI::getPivotX(void)
{
return _xpivot;
return _xPivot;
}
@@ -2448,7 +2440,7 @@ int16_t TFT_eSPI::getPivotX(void)
***************************************************************************************/
int16_t TFT_eSPI::getPivotY(void)
{
return _ypivot;
return _yPivot;
}
@@ -2529,7 +2521,8 @@ uint8_t TFT_eSPI::getTextDatum(void)
// Return the size of the display (per current rotation)
int16_t TFT_eSPI::width(void)
{
return _xWidth;
if (_vpDatum) return _xWidth;
return _width;
}
@@ -2539,7 +2532,8 @@ int16_t TFT_eSPI::width(void)
***************************************************************************************/
int16_t TFT_eSPI::height(void)
{
return _yHeight;
if (_vpDatum) return _yHeight;
return _height;
}
@@ -2846,6 +2840,32 @@ void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t w, int32_t h)
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 defined (ILI9225_DRIVER)
if (rotation & 0x01) { swap_coord(x0, y0); swap_coord(x1, y1); }
addr_row = 0xFFFF;
addr_col = 0xFFFF;
DC_C; tft_Write_8(TFT_CASET1);
DC_D; tft_Write_16(x0);
DC_C; tft_Write_8(TFT_CASET2);
DC_D; tft_Write_16(x1);
DC_C; tft_Write_8(TFT_PASET1);
DC_D; tft_Write_16(y0);
DC_C; tft_Write_8(TFT_PASET2);
DC_D; tft_Write_16(y1);
DC_C; tft_Write_8(TFT_RAM_ADDR1);
DC_D; tft_Write_16(x0);
DC_C; tft_Write_8(TFT_RAM_ADDR2);
DC_D; tft_Write_16(y0);
// write to RAM
DC_C; tft_Write_8(TFT_RAMWR);
DC_D;
#else
#if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x0, y0); swap_coord(x1, y1); }
@@ -2869,6 +2889,7 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
DC_D;
//end_tft_write(); // Must be called after setWindow
#endif
}
@@ -2925,7 +2946,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
x+= _xDatum;
y+= _yDatum;
// Range checking
// Range checking
if ((x < _vpX) || (y < _vpY) ||(x >= _vpW) || (y >= _vpH)) return;
#ifdef CGRAM_OFFSET
@@ -2933,12 +2954,42 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
y+=rowstart;
#endif
begin_tft_write();
#if defined (ILI9225_DRIVER)
if (rotation & 0x01) { swap_coord(x, y); }
// Set window to full screen to optimise sequential pixel rendering
if (addr_row != 0x9225) {
addr_row = 0x9225; // addr_row used for flag
DC_C; tft_Write_8(TFT_CASET1);
DC_D; tft_Write_16(0);
DC_C; tft_Write_8(TFT_CASET2);
DC_D; tft_Write_16(175);
DC_C; tft_Write_8(TFT_PASET1);
DC_D; tft_Write_16(0);
DC_C; tft_Write_8(TFT_PASET2);
DC_D; tft_Write_16(219);
}
// Define pixel coordinate
DC_C; tft_Write_8(TFT_RAM_ADDR1);
DC_D; tft_Write_16(x);
DC_C; tft_Write_8(TFT_RAM_ADDR2);
DC_D; tft_Write_16(y);
// write to RAM
DC_C; tft_Write_8(TFT_RAMWR);
DC_D; tft_Write_16(color);
#else
#if defined (SSD1963_DRIVER)
if ((rotation & 0x1) == 0) { swap_coord(x, y); }
#endif
begin_tft_write();
#ifdef MULTI_TFT_SUPPORT
// No optimisation
DC_C; tft_Write_8(TFT_CASET);
@@ -2960,9 +3011,9 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color)
addr_row = (y<<16 | y);
}
#endif
DC_C; tft_Write_8(TFT_RAMWR);
DC_D; tft_Write_16(color);
#endif
end_tft_write();
}
@@ -3064,9 +3115,14 @@ void TFT_eSPI::pushColors(uint16_t *data, uint32_t len, bool swap)
// an efficient FastH/V Line draw routine for line segments of 2 pixels or more
void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color)
{
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
if (_vpOoB) return;
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction = true;
//x+= _xDatum; // Not added here, added by drawPixel & drawFastXLine
//y+= _yDatum;
bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
swap_coord(x0, y0);
@@ -3507,30 +3563,20 @@ uint32_t TFT_eSPI::alphaBlend24(uint8_t alpha, uint32_t fgc, uint32_t bgc, uint8
***************************************************************************************/
size_t TFT_eSPI::write(uint8_t utf8)
{
if (_vpOoB) return 1;
uint16_t uniCode = decodeUTF8(utf8);
if (!uniCode) return 1;
if (utf8 == '\r') return 1;
uint16_t uniCode = utf8;
if (_utf8) uniCode = decodeUTF8(utf8);
if (uniCode == 0) return 1;
#ifdef SMOOTH_FONT
if(fontLoaded) {
//Serial.print("UniCode="); Serial.println(uniCode);
//Serial.print("UTF8 ="); Serial.println(utf8);
//fontFile = SPIFFS.open( _gFontFilename, "r" );
//if(!fontFile)
//{
// fontLoaded = false;
// return 1;
//}
if (uniCode < 32 && utf8 != '\n') return 1;
drawGlyph(uniCode);
//fontFile.close();
return 1;
}
#endif
@@ -3538,8 +3584,8 @@ size_t TFT_eSPI::write(uint8_t utf8)
if (uniCode == '\n') uniCode+=22; // Make it a valid space character to stop errors
else if (uniCode < 32) return 1;
uint16_t width = 0;
uint16_t height = 0;
uint16_t cwidth = 0;
uint16_t cheight = 0;
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv DEBUG vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//Serial.print((uint8_t) uniCode); // Debug line sends all printed TFT text to serial port
@@ -3557,11 +3603,11 @@ size_t TFT_eSPI::write(uint8_t utf8)
if (textfont == 2) {
if (uniCode > 127) return 1;
width = pgm_read_byte(widtbl_f16 + uniCode-32);
height = chr_hgt_f16;
cwidth = pgm_read_byte(widtbl_f16 + uniCode-32);
cheight = chr_hgt_f16;
// Font 2 is rendered in whole byte widths so we must allow for this
width = (width + 6) / 8; // Width in whole bytes for font 2, should be + 7 but must allow for font width change
width = width * 8; // Width converted back to pixels
cwidth = (cwidth + 6) / 8; // Width in whole bytes for font 2, should be + 7 but must allow for font width change
cwidth = cwidth * 8; // Width converted back to pixels
}
#ifdef LOAD_RLE
else
@@ -3573,33 +3619,33 @@ size_t TFT_eSPI::write(uint8_t utf8)
if ((textfont>2) && (textfont<9)) {
if (uniCode > 127) return 1;
// Uses the fontinfo struct array to avoid lots of 'if' or 'switch' statements
width = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[textfont].widthtbl ) ) + uniCode-32 );
height= pgm_read_byte( &fontdata[textfont].height );
cwidth = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[textfont].widthtbl ) ) + uniCode-32 );
cheight= pgm_read_byte( &fontdata[textfont].height );
}
}
#endif
#ifdef LOAD_GLCD
if (textfont==1) {
width = 6;
height = 8;
cwidth = 6;
cheight = 8;
}
#else
if (textfont==1) return 1;
#endif
height = height * textsize;
cheight = cheight * textsize;
if (utf8 == '\n') {
cursor_y += height;
cursor_y += cheight;
cursor_x = 0;
}
else {
if (textwrapX && (cursor_x + width * textsize > this->width())) {
cursor_y += height;
if (textwrapX && (cursor_x + cwidth * textsize > width())) {
cursor_y += cheight;
cursor_x = 0;
}
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
if (textwrapY && (cursor_y >= (int32_t) height())) cursor_y = 0;
cursor_x += drawChar(uniCode, cursor_x, cursor_y, textfont);
}
@@ -3609,10 +3655,8 @@ size_t TFT_eSPI::write(uint8_t utf8)
else {
if(utf8 == '\n') {
cursor_x = 0;
cursor_y += (int16_t)textsize *
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
}
else {
cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
} else {
if (uniCode > pgm_read_word(&gfxFont->last )) return 1;
if (uniCode < pgm_read_word(&gfxFont->first)) return 1;
@@ -3622,13 +3666,12 @@ size_t TFT_eSPI::write(uint8_t utf8)
h = pgm_read_byte(&glyph->height);
if((w > 0) && (h > 0)) { // Is there an associated bitmap?
int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset);
if(textwrapX && ((cursor_x + textsize * (xo + w)) > this->width())) {
if(textwrapX && ((cursor_x + textsize * (xo + w)) > width())) {
// Drawing character would go off right edge; wrap to new line
cursor_x = 0;
cursor_y += (int16_t)textsize *
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
}
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
if (textwrapY && (cursor_y >= (int32_t) height())) cursor_y = 0;
drawChar(cursor_x, cursor_y, uniCode, textcolor, textbgcolor, textsize);
}
cursor_x += pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize;
@@ -3645,6 +3688,7 @@ size_t TFT_eSPI::write(uint8_t utf8)
** Function name: drawChar
** Description: draw a Unicode glyph onto the screen
***************************************************************************************/
// TODO: Rationalise with TFT_eSprite
// Any UTF-8 decoding must be done before calling drawChar()
int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y)
{
@@ -4087,11 +4131,11 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
/*
// 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())) {
if (textwrapX && (cursor_x + width * textsize > width())) {
cursor_y += height;
cursor_x = 0;
}
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
if (textwrapY && (cursor_y >= (int32_t)height())) cursor_y = 0;
cursor_x += drawChar(uniCode, cursor_x, cursor_y, textfont);
*/
setCursor(poX, poY);