mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-08-09 23:54:43 +02:00
Support extended font formats
Adafruit_GFX font support extended to Unidode Basic Multilingual Plane Print stream deocdes UTF-8 Smooth font ascent and descent (affects line spacing) changed to rely on metrics provided by Processing IDE (issue #303) Bug fix for font rendering with no background on RLE native fonts
This commit is contained in:
@@ -97,7 +97,7 @@ void TFT_eSPI::loadFont(String fontName)
|
||||
gFont.ascent = (uint16_t)readInt32(); // top of "d"
|
||||
gFont.descent = (uint16_t)readInt32(); // bottom of "p"
|
||||
|
||||
// These next gFont values will be updated when the Metrics are fetched
|
||||
// These next gFont values might be updated when the Metrics are fetched
|
||||
gFont.maxAscent = gFont.ascent; // Determined from metrics
|
||||
gFont.maxDescent = gFont.descent; // Determined from metrics
|
||||
gFont.yAdvance = gFont.ascent + gFont.descent;
|
||||
@@ -147,11 +147,19 @@ void TFT_eSPI::loadMetrics(uint16_t gCount)
|
||||
gdX[gNum] = (int8_t)readInt32(); // x delta from cursor
|
||||
readInt32(); // ignored
|
||||
|
||||
// Different glyph sets have different ascent values not always based on "d", so get maximum glyph ascent
|
||||
//Serial.print("Unicode = 0x"); Serial.print(gUnicode[gNum], HEX); Serial.print(", gHeight = "); Serial.println(gHeight[gNum]);
|
||||
//Serial.print("Unicode = 0x"); Serial.print(gUnicode[gNum], HEX); Serial.print(", gWidth = "); Serial.println(gWidth[gNum]);
|
||||
//Serial.print("Unicode = 0x"); Serial.print(gUnicode[gNum], HEX); Serial.print(", gxAdvance = "); Serial.println(gxAdvance[gNum]);
|
||||
//Serial.print("Unicode = 0x"); Serial.print(gUnicode[gNum], HEX); Serial.print(", gdY = "); Serial.println(gdY[gNum]);
|
||||
|
||||
// Different glyph sets have different ascent values not always based on "d", so we could get
|
||||
// the maximum glyph ascent by checking all characters. BUT this method can generate bad values
|
||||
// for non-existant glyphs, so we will reply on processing for the value and disable this code for now...
|
||||
/*
|
||||
if (gdY[gNum] > gFont.maxAscent)
|
||||
{
|
||||
// Avoid UTF coding values and characters that tend to give duff values
|
||||
if (((gUnicode[gNum] > 0x20) && (gUnicode[gNum] < 0xA0) && (gUnicode[gNum] != 0x7F)) || (gUnicode[gNum] > 0xFF))
|
||||
// Try to avoid UTF coding values and characters that tend to give duff values
|
||||
if (((gUnicode[gNum] > 0x20) && (gUnicode[gNum] < 0x7F)) || (gUnicode[gNum] > 0xA0))
|
||||
{
|
||||
gFont.maxAscent = gdY[gNum];
|
||||
#ifdef SHOW_ASCENT_DESCENT
|
||||
@@ -159,6 +167,7 @@ void TFT_eSPI::loadMetrics(uint16_t gCount)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Different glyph sets have different descent values not always based on "p", so get maximum glyph descent
|
||||
if (((int16_t)gHeight[gNum] - (int16_t)gdY[gNum]) > gFont.maxDescent)
|
||||
|
@@ -8,9 +8,6 @@
|
||||
void unloadFont( void );
|
||||
bool getUnicodeIndex(uint16_t unicode, uint16_t *index);
|
||||
|
||||
uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining);
|
||||
uint16_t decodeUTF8(uint8_t c);
|
||||
|
||||
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
|
||||
|
||||
virtual void drawGlyph(uint16_t code);
|
||||
@@ -44,9 +41,6 @@ fontMetrics gFont = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
String _gFontFilename;
|
||||
|
||||
uint8_t decoderState = 0; // UTF8 decoder state
|
||||
uint16_t decoderBuffer; // Unicode code-point buffer
|
||||
|
||||
bool fontLoaded = false; // Flags when a anti-aliased font is loaded
|
||||
|
||||
private:
|
||||
|
@@ -1312,13 +1312,16 @@ void TFT_eSprite::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t
|
||||
*************************************************************************************x*/
|
||||
size_t TFT_eSprite::write(uint8_t utf8)
|
||||
{
|
||||
uint16_t uniCode = decodeUTF8(utf8);
|
||||
|
||||
if (!uniCode) return 1;
|
||||
|
||||
if (utf8 == '\r') return 1;
|
||||
|
||||
#ifdef SMOOTH_FONT
|
||||
if(this->fontLoaded)
|
||||
{
|
||||
uint16_t unicode = decodeUTF8(utf8);
|
||||
if (unicode < 32 && utf8 != '\n') return 1;
|
||||
if (uniCode < 32 && utf8 != '\n') return 1;
|
||||
|
||||
//fontFile = SPIFFS.open( _gFontFilename, "r" );
|
||||
//fontFile = SPIFFS.open( this->_gFontFilename, "r" );
|
||||
@@ -1330,7 +1333,8 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
//}
|
||||
//Serial.print("Decoded Unicode = 0x");Serial.println(unicode,HEX);
|
||||
|
||||
drawGlyph(unicode);
|
||||
drawGlyph(uniCode);
|
||||
|
||||
//fontFile.close();
|
||||
return 1;
|
||||
}
|
||||
@@ -1338,10 +1342,8 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
|
||||
if (!_created ) return 1;
|
||||
|
||||
|
||||
uint8_t uniCode = utf8; // Work with a copy
|
||||
if (utf8 == '\n') uniCode+=22; // Make it a valid space character to stop errors
|
||||
else if (utf8 < 32) return 1;
|
||||
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;
|
||||
@@ -1362,7 +1364,7 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
if (textfont == 2)
|
||||
{
|
||||
if (utf8 > 127) return 1;
|
||||
// This is 20us faster than using the fontdata structure (0.443ms per character instead of 0.465ms)
|
||||
|
||||
width = pgm_read_byte(widtbl_f16 + uniCode-32);
|
||||
height = chr_hgt_f16;
|
||||
// Font 2 is rendered in whole byte widths so we must allow for this
|
||||
@@ -1380,7 +1382,6 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
{
|
||||
if (utf8 > 127) return 1;
|
||||
// Uses the fontinfo struct array to avoid lots of 'if' or 'switch' statements
|
||||
// A tad slower than above but this is not significant and is more convenient for the RLE fonts
|
||||
width = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[textfont].widthtbl ) ) + uniCode-32 );
|
||||
height= pgm_read_byte( &fontdata[textfont].height );
|
||||
}
|
||||
@@ -1420,15 +1421,14 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
} // Custom GFX font
|
||||
else
|
||||
{
|
||||
|
||||
if(utf8 == '\n') {
|
||||
this->cursor_x = 0;
|
||||
this->cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||
} else {
|
||||
if (uniCode > (uint8_t)pgm_read_byte(&gfxFont->last )) return 1;
|
||||
if (uniCode < (uint8_t)pgm_read_byte(&gfxFont->first)) return 1;
|
||||
if (uniCode > pgm_read_word(&gfxFont->last )) return 1;
|
||||
if (uniCode < pgm_read_word(&gfxFont->first)) return 1;
|
||||
|
||||
uint8_t c2 = uniCode - pgm_read_byte(&gfxFont->first);
|
||||
uint8_t c2 = uniCode - pgm_read_word(&gfxFont->first);
|
||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||
uint8_t w = pgm_read_byte(&glyph->width),
|
||||
h = pgm_read_byte(&glyph->height);
|
||||
@@ -1456,7 +1456,7 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
** Function name: drawChar
|
||||
** Description: draw a single character in the Adafruit GLCD or freefont
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSprite::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, uint32_t bg, uint8_t size)
|
||||
void TFT_eSprite::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size)
|
||||
{
|
||||
if (!_created ) return;
|
||||
|
||||
@@ -1466,6 +1466,7 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color
|
||||
((y + 8 * size - 1) < 0)) // Clip top
|
||||
return;
|
||||
|
||||
if (c < 32) return;
|
||||
#ifdef LOAD_GLCD
|
||||
//>>>>>>>>>>>>>>>>>>
|
||||
#ifdef LOAD_GFXFF
|
||||
@@ -1534,15 +1535,15 @@ void TFT_eSprite::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color
|
||||
|
||||
#ifdef LOAD_GFXFF
|
||||
// Filter out bad characters not present in font
|
||||
if ((c >= (uint8_t)pgm_read_byte(&gfxFont->first)) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last )))
|
||||
if ((c >= pgm_read_word(&gfxFont->first)) && (c <= pgm_read_word(&gfxFont->last )))
|
||||
{
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
c -= pgm_read_byte(&gfxFont->first);
|
||||
c -= pgm_read_word(&gfxFont->first);
|
||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]);
|
||||
uint8_t *bitmap = (uint8_t *)pgm_read_dword(&gfxFont->bitmap);
|
||||
|
||||
uint16_t bo = pgm_read_word(&glyph->bitmapOffset);
|
||||
uint32_t bo = pgm_read_word(&glyph->bitmapOffset);
|
||||
uint8_t w = pgm_read_byte(&glyph->width),
|
||||
h = pgm_read_byte(&glyph->height);
|
||||
//xa = pgm_read_byte(&glyph->xAdvance);
|
||||
@@ -1597,15 +1598,19 @@ 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*/
|
||||
// Any UTF-8 decoding must be done before calling drawChar()
|
||||
int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y)
|
||||
{
|
||||
return drawChar(uniCode, x, y, textfont);
|
||||
}
|
||||
|
||||
// Any UTF-8 decoding must be done before calling drawChar()
|
||||
int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||
{
|
||||
if (!_created ) return 0;
|
||||
|
||||
if (!uniCode) return 0;
|
||||
|
||||
if (font==1)
|
||||
{
|
||||
#ifdef LOAD_GLCD
|
||||
@@ -1630,9 +1635,9 @@ int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t fo
|
||||
}
|
||||
else
|
||||
{
|
||||
if((uniCode >= pgm_read_byte(&gfxFont->first)) && (uniCode <= pgm_read_byte(&gfxFont->last) ))
|
||||
if((uniCode >= pgm_read_word(&gfxFont->first)) && (uniCode <= pgm_read_word(&gfxFont->last) ))
|
||||
{
|
||||
uint8_t c2 = uniCode - pgm_read_byte(&gfxFont->first);
|
||||
uint16_t c2 = uniCode - pgm_read_word(&gfxFont->first);
|
||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||
return pgm_read_byte(&glyph->xAdvance) * textsize;
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ class TFT_eSprite : public TFT_eSPI {
|
||||
|
||||
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),
|
||||
void drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size),
|
||||
|
||||
fillSprite(uint32_t color),
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
#ifdef LOAD_GFXFF
|
||||
|
||||
typedef struct { // Data stored PER GLYPH
|
||||
uint16_t bitmapOffset; // Pointer into GFXfont->bitmap
|
||||
uint32_t bitmapOffset; // Pointer into GFXfont->bitmap
|
||||
uint8_t width, height; // Bitmap dimensions in pixels
|
||||
uint8_t xAdvance; // Distance to advance cursor (x axis)
|
||||
int8_t xOffset, yOffset; // Dist from cursor pos to UL corner
|
||||
@@ -21,7 +21,7 @@ typedef struct { // Data stored PER GLYPH
|
||||
typedef struct { // Data stored for FONT AS A WHOLE:
|
||||
uint8_t *bitmap; // Glyph bitmaps, concatenated
|
||||
GFXglyph *glyph; // Glyph array
|
||||
uint8_t first, last; // ASCII extents
|
||||
uint16_t first, last; // ASCII extents
|
||||
uint8_t yAdvance; // Newline distance (y axis)
|
||||
} GFXfont;
|
||||
|
||||
|
111
TFT_eSPI.cpp
111
TFT_eSPI.cpp
@@ -2273,20 +2273,21 @@ int16_t TFT_eSPI::textWidth(const char *string)
|
||||
int16_t TFT_eSPI::textWidth(const char *string, uint8_t font)
|
||||
{
|
||||
int32_t str_width = 0;
|
||||
uint16_t uniCode = 0;
|
||||
|
||||
#ifdef SMOOTH_FONT
|
||||
if(fontLoaded)
|
||||
{
|
||||
while (*string)
|
||||
{
|
||||
uint16_t unicode = decodeUTF8(*string++);
|
||||
if (unicode)
|
||||
uniCode = decodeUTF8(*string++);
|
||||
if (uniCode)
|
||||
{
|
||||
if (unicode == 0x20) str_width += gFont.spaceWidth;
|
||||
if (uniCode == 0x20) str_width += gFont.spaceWidth;
|
||||
else
|
||||
{
|
||||
uint16_t gNum = 0;
|
||||
bool found = getUnicodeIndex(unicode, &gNum);
|
||||
bool found = getUnicodeIndex(uniCode, &gNum);
|
||||
if (found)
|
||||
{
|
||||
if(str_width == 0 && gdX[gNum] < 0) str_width -= gdX[gNum];
|
||||
@@ -2302,18 +2303,15 @@ int16_t TFT_eSPI::textWidth(const char *string, uint8_t font)
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char uniCode;
|
||||
char *widthtable;
|
||||
|
||||
if (font>1 && font<9)
|
||||
{
|
||||
widthtable = (char *)pgm_read_dword( &(fontdata[font].widthtbl ) ) - 32; //subtract the 32 outside the loop
|
||||
char *widthtable = (char *)pgm_read_dword( &(fontdata[font].widthtbl ) ) - 32; //subtract the 32 outside the loop
|
||||
|
||||
while (*string)
|
||||
{
|
||||
uniCode = *(string++);
|
||||
if (uniCode > 31 && uniCode < 128)
|
||||
str_width += pgm_read_byte( widthtable + uniCode); // Normally we need to subract 32 from uniCode
|
||||
str_width += pgm_read_byte( widthtable + uniCode); // Normally we need to subtract 32 from uniCode
|
||||
else str_width += pgm_read_byte( widthtable + 32); // Set illegal character = space width
|
||||
}
|
||||
}
|
||||
@@ -2326,9 +2324,9 @@ int16_t TFT_eSPI::textWidth(const char *string, uint8_t font)
|
||||
while (*string)
|
||||
{
|
||||
uniCode = decodeUTF8(*string++);
|
||||
if ((uniCode >= (uint8_t)pgm_read_byte(&gfxFont->first)) && (uniCode <= (uint8_t)pgm_read_byte(&gfxFont->last )))
|
||||
if ((uniCode >= pgm_read_word(&gfxFont->first)) && (uniCode <= pgm_read_word(&gfxFont->last )))
|
||||
{
|
||||
uniCode -= pgm_read_byte(&gfxFont->first);
|
||||
uniCode -= pgm_read_word(&gfxFont->first);
|
||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[uniCode]);
|
||||
// If this is not the last character or is a digit then use xAdvance
|
||||
if (*string || isDigits) str_width += pgm_read_byte(&glyph->xAdvance);
|
||||
@@ -2393,7 +2391,7 @@ int16_t TFT_eSPI::fontHeight(void)
|
||||
** Function name: drawChar
|
||||
** Description: draw a single character in the Adafruit GLCD font
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, uint32_t bg, uint8_t size)
|
||||
void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size)
|
||||
{
|
||||
if ((x >= _width) || // Clip right
|
||||
(y >= _height) || // Clip bottom
|
||||
@@ -2498,17 +2496,17 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, u
|
||||
|
||||
#ifdef LOAD_GFXFF
|
||||
// Filter out bad characters not present in font
|
||||
if ((c >= (uint8_t)pgm_read_byte(&gfxFont->first)) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last )))
|
||||
if ((c >= pgm_read_word(&gfxFont->first)) && (c <= pgm_read_word(&gfxFont->last )))
|
||||
{
|
||||
spi_begin();
|
||||
inTransaction = true;
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
c -= pgm_read_byte(&gfxFont->first);
|
||||
c -= pgm_read_word(&gfxFont->first);
|
||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]);
|
||||
uint8_t *bitmap = (uint8_t *)pgm_read_dword(&gfxFont->bitmap);
|
||||
|
||||
uint16_t bo = pgm_read_word(&glyph->bitmapOffset);
|
||||
uint32_t bo = pgm_read_word(&glyph->bitmapOffset);
|
||||
uint8_t w = pgm_read_byte(&glyph->width),
|
||||
h = pgm_read_byte(&glyph->height);
|
||||
//xa = pgm_read_byte(&glyph->xAdvance);
|
||||
@@ -3991,18 +3989,18 @@ uint16_t TFT_eSPI::decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining)
|
||||
***************************************************************************************/
|
||||
size_t TFT_eSPI::write(uint8_t utf8)
|
||||
{
|
||||
uint16_t uniCode = decodeUTF8(utf8);
|
||||
|
||||
if (!uniCode) return 1;
|
||||
|
||||
if (utf8 == '\r') return 1;
|
||||
|
||||
#ifdef SMOOTH_FONT
|
||||
if(fontLoaded)
|
||||
{
|
||||
uint16_t unicode = decodeUTF8(utf8);
|
||||
|
||||
//Serial.print("UniCode="); Serial.println(unicode);
|
||||
//Serial.print("UniCode="); Serial.println(uniCode);
|
||||
//Serial.print("UTF8 ="); Serial.println(utf8);
|
||||
|
||||
if (!unicode) return 1;
|
||||
|
||||
//fontFile = SPIFFS.open( _gFontFilename, "r" );
|
||||
|
||||
//if(!fontFile)
|
||||
@@ -4011,16 +4009,15 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
||||
// return 1;
|
||||
//}
|
||||
|
||||
drawGlyph(unicode);
|
||||
drawGlyph(uniCode);
|
||||
|
||||
//fontFile.close();
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t uniCode = utf8; // Work with a copy
|
||||
if (utf8 == '\n') uniCode+=22; // Make it a valid space character to stop errors
|
||||
else if (utf8 < 32) return 1;
|
||||
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;
|
||||
@@ -4040,8 +4037,8 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
||||
#ifdef LOAD_FONT2
|
||||
if (textfont == 2)
|
||||
{
|
||||
if (utf8 > 127) return 1;
|
||||
// This is 20us faster than using the fontdata structure (0.443ms per character instead of 0.465ms)
|
||||
if (uniCode > 127) return 1;
|
||||
|
||||
width = pgm_read_byte(widtbl_f16 + uniCode-32);
|
||||
height = chr_hgt_f16;
|
||||
// Font 2 is rendered in whole byte widths so we must allow for this
|
||||
@@ -4057,9 +4054,8 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
||||
{
|
||||
if ((textfont>2) && (textfont<9))
|
||||
{
|
||||
if (utf8 > 127) return 1;
|
||||
if (uniCode > 127) return 1;
|
||||
// Uses the fontinfo struct array to avoid lots of 'if' or 'switch' statements
|
||||
// A tad slower than above but this is not significant and is more convenient for the RLE fonts
|
||||
width = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[textfont].widthtbl ) ) + uniCode-32 );
|
||||
height= pgm_read_byte( &fontdata[textfont].height );
|
||||
}
|
||||
@@ -4098,18 +4094,15 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
||||
} // Custom GFX font
|
||||
else
|
||||
{
|
||||
uniCode = (uint8_t)decodeUTF8(utf8);
|
||||
if (!uniCode) return 1;
|
||||
|
||||
if(utf8 == '\n') {
|
||||
cursor_x = 0;
|
||||
cursor_y += (int16_t)textsize *
|
||||
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||
} else {
|
||||
if (uniCode > (uint8_t)pgm_read_byte(&gfxFont->last )) return 1;
|
||||
if (uniCode < (uint8_t)pgm_read_byte(&gfxFont->first)) return 1;
|
||||
if (uniCode > pgm_read_word(&gfxFont->last )) return 1;
|
||||
if (uniCode < pgm_read_word(&gfxFont->first)) return 1;
|
||||
|
||||
uint8_t c2 = uniCode - pgm_read_byte(&gfxFont->first);
|
||||
uint16_t c2 = uniCode - pgm_read_word(&gfxFont->first);
|
||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||
uint8_t w = pgm_read_byte(&glyph->width),
|
||||
h = pgm_read_byte(&glyph->height);
|
||||
@@ -4136,17 +4129,17 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: drawChar
|
||||
** Description: draw a Unicode onto the screen
|
||||
** Description: draw a Unicode glyph onto the screen
|
||||
***************************************************************************************/
|
||||
int16_t TFT_eSPI::drawChar(uint16_t utf8, 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)
|
||||
{
|
||||
return drawChar(utf8, x, y, textfont);
|
||||
return drawChar(uniCode, x, y, textfont);
|
||||
}
|
||||
|
||||
int16_t TFT_eSPI::drawChar(uint16_t utf8, int32_t x, int32_t y, uint8_t font)
|
||||
// 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)
|
||||
{
|
||||
|
||||
uint16_t uniCode = decodeUTF8(utf8);
|
||||
if (!uniCode) return 0;
|
||||
|
||||
if (font==1)
|
||||
@@ -4173,9 +4166,9 @@ int16_t TFT_eSPI::drawChar(uint16_t utf8, int32_t x, int32_t y, uint8_t font)
|
||||
}
|
||||
else
|
||||
{
|
||||
if((uniCode >= pgm_read_byte(&gfxFont->first)) && (uniCode <= pgm_read_byte(&gfxFont->last) ))
|
||||
if((uniCode >= pgm_read_word(&gfxFont->first)) && (uniCode <= pgm_read_word(&gfxFont->last) ))
|
||||
{
|
||||
uint8_t c2 = uniCode - pgm_read_byte(&gfxFont->first);
|
||||
uint16_t c2 = uniCode - pgm_read_word(&gfxFont->first);
|
||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||
return pgm_read_byte(&glyph->xAdvance) * textsize;
|
||||
}
|
||||
@@ -4197,7 +4190,6 @@ int16_t TFT_eSPI::drawChar(uint16_t utf8, int32_t x, int32_t y, uint8_t font)
|
||||
#ifdef LOAD_FONT2
|
||||
if (font == 2)
|
||||
{
|
||||
// This is faster than using the fontdata structure
|
||||
flash_address = pgm_read_dword(&chrtbl_f16[uniCode]);
|
||||
width = pgm_read_byte(widtbl_f16 + uniCode);
|
||||
height = chr_hgt_f16;
|
||||
@@ -4211,7 +4203,6 @@ int16_t TFT_eSPI::drawChar(uint16_t utf8, int32_t x, int32_t y, uint8_t font)
|
||||
{
|
||||
if ((font>2) && (font<9))
|
||||
{
|
||||
// This is slower than above but is more convenient for the RLE fonts
|
||||
flash_address = pgm_read_dword( pgm_read_dword( &(fontdata[font].chartbl ) ) + uniCode*sizeof(void *) );
|
||||
width = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[font].widthtbl ) ) + uniCode );
|
||||
height= pgm_read_byte( &fontdata[font].height );
|
||||
@@ -4309,6 +4300,7 @@ int16_t TFT_eSPI::drawChar(uint16_t utf8, int32_t x, int32_t y, uint8_t font)
|
||||
// Font is not 2 and hence is RLE encoded
|
||||
{
|
||||
spi_begin();
|
||||
inTransaction = true;
|
||||
|
||||
w *= height; // Now w is total number of pixels in the character
|
||||
if ((textsize != 1) || (textcolor == textbgcolor)) {
|
||||
@@ -4360,6 +4352,7 @@ int16_t TFT_eSPI::drawChar(uint16_t utf8, int32_t x, int32_t y, uint8_t font)
|
||||
}
|
||||
}
|
||||
|
||||
inTransaction = false;
|
||||
spi_end();
|
||||
}
|
||||
else // Text colour != background && textsize = 1
|
||||
@@ -4442,7 +4435,7 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY)
|
||||
return drawString(string, poX, poY, textfont);
|
||||
}
|
||||
|
||||
// With font number
|
||||
// With font number. Note: font number is over-ridden if a smooth font is loaded
|
||||
int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8_t font)
|
||||
{
|
||||
int16_t sumX = 0;
|
||||
@@ -4553,15 +4546,15 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
||||
{
|
||||
cheight = (glyph_ab + glyph_bb) * textsize;
|
||||
// Get the offset for the first character only to allow for negative offsets
|
||||
uint8_t c2 = 0;
|
||||
uint16_t c2 = 0;
|
||||
uint16_t len = strlen(string);
|
||||
uint16_t n = 0;
|
||||
|
||||
while (n < len && c2 == 0) c2 = decodeUTF8((uint8_t*)string, &n, len - n);
|
||||
|
||||
if((c2 >= pgm_read_byte(&gfxFont->first)) && (c2 <= pgm_read_byte(&gfxFont->last) ))
|
||||
if((c2 >= pgm_read_word(&gfxFont->first)) && (c2 <= pgm_read_word(&gfxFont->last) ))
|
||||
{
|
||||
c2 -= pgm_read_byte(&gfxFont->first);
|
||||
c2 -= pgm_read_word(&gfxFont->first);
|
||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||
xo = pgm_read_byte(&glyph->xOffset) * textsize;
|
||||
// Adjust for negative xOffset
|
||||
@@ -4576,6 +4569,9 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t len = strlen(string);
|
||||
uint16_t n = 0;
|
||||
|
||||
#ifdef SMOOTH_FONT
|
||||
if(fontLoaded)
|
||||
{
|
||||
@@ -4584,14 +4580,13 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
||||
//drawLine(poX, poY - 5, poX, poY + 5, TFT_GREEN);
|
||||
//fontFile = SPIFFS.open( _gFontFilename, "r");
|
||||
if(!fontFile) return 0;
|
||||
uint16_t len = strlen(string);
|
||||
uint16_t n = 0;
|
||||
|
||||
setCursor(poX, poY);
|
||||
|
||||
while (n < len)
|
||||
{
|
||||
uint16_t unicode = decodeUTF8((uint8_t*)string, &n, len - n);
|
||||
drawGlyph(unicode);
|
||||
uint16_t uniCode = decodeUTF8((uint8_t*)string, &n, len - n);
|
||||
drawGlyph(uniCode);
|
||||
}
|
||||
sumX += cwidth;
|
||||
//fontFile.close();
|
||||
@@ -4599,7 +4594,11 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while (*string) sumX += drawChar(*(string++), poX+sumX, poY, font);
|
||||
while (n < len)
|
||||
{
|
||||
uint16_t uniCode = decodeUTF8((uint8_t*)string, &n, len - n);
|
||||
sumX += drawChar(uniCode, poX+sumX, poY, font);
|
||||
}
|
||||
}
|
||||
|
||||
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv DEBUG vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
@@ -4669,7 +4668,7 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
||||
#endif
|
||||
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DEBUG ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
return sumX;
|
||||
return sumX + poX;
|
||||
}
|
||||
|
||||
|
||||
@@ -4782,7 +4781,7 @@ int16_t TFT_eSPI::drawFloat(float floatNumber, uint8_t dp, int32_t poX, int32_t
|
||||
// No chance of overflow from here on
|
||||
|
||||
// Get integer part
|
||||
unsigned long temp = (unsigned long)floatNumber;
|
||||
uint32_t temp = (uint32_t)floatNumber;
|
||||
|
||||
// Put integer part into array
|
||||
ltoa(temp, str + ptr, 10);
|
||||
@@ -4830,7 +4829,7 @@ void TFT_eSPI::setFreeFont(const GFXfont *f)
|
||||
|
||||
glyph_ab = 0;
|
||||
glyph_bb = 0;
|
||||
uint8_t numChars = pgm_read_byte(&gfxFont->last) - pgm_read_byte(&gfxFont->first);
|
||||
uint16_t numChars = pgm_read_word(&gfxFont->last) - pgm_read_word(&gfxFont->first);
|
||||
|
||||
// Find the biggest above and below baseline offsets
|
||||
for (uint8_t c = 0; c < numChars; c++)
|
||||
|
@@ -668,7 +668,7 @@ class TFT_eSPI : public Print {
|
||||
|
||||
// These are virtual so the TFT_eSprite class can override them with sprite specific functions
|
||||
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),
|
||||
drawChar(int32_t x, int32_t y, uint16_t 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),
|
||||
@@ -813,6 +813,8 @@ class TFT_eSPI : public Print {
|
||||
void writeColor(uint16_t color, uint32_t len); // Write colours without transaction overhead
|
||||
void endWrite(void); // End SPI transaction
|
||||
|
||||
uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining);
|
||||
uint16_t decodeUTF8(uint8_t c);
|
||||
size_t write(uint8_t);
|
||||
|
||||
#ifdef TFT_SDA_READ
|
||||
@@ -838,6 +840,9 @@ class TFT_eSPI : public Print {
|
||||
int16_t _xpivot; // x pivot point coordinate
|
||||
int16_t _ypivot; // x pivot point coordinate
|
||||
|
||||
uint8_t decoderState = 0; // UTF8 decoder state
|
||||
uint16_t decoderBuffer; // Unicode code-point buffer
|
||||
|
||||
private:
|
||||
|
||||
inline void spi_begin() __attribute__((always_inline));
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// This is a Processing sketch, see https://processing.org/ to download the IDE
|
||||
|
||||
// Select the character range in the user configure section starting at line 100
|
||||
// Select the font, size and character ranges in the user configuration section
|
||||
// of this sketch, which starts at line 120. Instructions start at line 50.
|
||||
|
||||
|
||||
/*
|
||||
Software License Agreement (FreeBSD License)
|
||||
@@ -36,44 +38,58 @@ Software License Agreement (FreeBSD License)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// This is a processing sketch to create font files for the TFT_eSPI library:
|
||||
|
||||
// https://github.com/Bodmer/TFT_eSPI
|
||||
|
||||
// Coded by Bodmer January 2018
|
||||
// Coded by Bodmer January 2018, updated 10/2/19
|
||||
// Version 0.8
|
||||
|
||||
// See comments below in code for specifying the font parameters
|
||||
// (point size, unicode blocks to include etc). Ranges of characers or
|
||||
// specific individual unicodes can be included in the created font file/
|
||||
// >>>>>>>>>>>>>>>>>>>> INSTRUCTIONS <<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// See comments below in code for specifying the font parameters (point size,
|
||||
// unicode blocks to include etc). Ranges of characters (glyphs) and specific
|
||||
// individual glyphs can be included in the created "*.vlw" font file.
|
||||
|
||||
// Created fonts are saved in the sketches "FontFiles" folder. Press Ctrl+K to
|
||||
// see that folder.
|
||||
// see that folder location.
|
||||
|
||||
// 16 bit unicodes in the range 0x0000 - 0xFFFF are supported.
|
||||
// 16 bit Unicode point codes in the range 0x0000 - 0xFFFF are supported.
|
||||
// Codes 0-31 are control codes such as "tab" and "carraige return" etc.
|
||||
// and 32 is a "space", these should NOT be included.
|
||||
|
||||
// The sketch will convert True Type (a .ttf or .otf file) file stored in the
|
||||
// sketches "Data" folder as well as your computers system fonts.
|
||||
// sketches "Data" folder as well as your computers' system fonts.
|
||||
|
||||
// To maximise rendering performance only include the characters you will use.
|
||||
// Characters at the start of the file will render faster than those at the end.
|
||||
// To maximise rendering performance and the memory consumed only include the characters
|
||||
// you will use. Characters at the start of the file will render faster than those at
|
||||
// the end due to the buffering and file seeking overhead.
|
||||
|
||||
// The inclusion of "non-existant" characters in a font may give unpredicatable results
|
||||
// when rendering with the TFT_eSPI library. The Processing sketch window that pops up
|
||||
// to show the font characters will print "boxes" (also known as Tofu!) for non existant
|
||||
// characters.
|
||||
|
||||
// Once created the files must be loaded into the ESP32 or ESP8266 SPIFFS memory
|
||||
// using the Arduino IDE plugin detailed here:
|
||||
// https://github.com/esp8266/arduino-esp8266fs-plugin
|
||||
// https://github.com/me-no-dev/arduino-esp32fs-plugin
|
||||
|
||||
// The sketch list all the available PC fonts to the console, you may need to increase
|
||||
// console line count (in preferences.txt) to stop some fonts scrolling out of view.
|
||||
// When the sketch is run it will generate a file called "System_Font_List.txt" in the
|
||||
// sketch "FontFiles" folder, press Ctrl+K to see it. Open the file in a text editor to
|
||||
// view it. This list provides the font reference number needed below to locate that
|
||||
// font on your system.
|
||||
|
||||
// The sketch also lists all the available system fonts to the console, you can increase
|
||||
// the console line count (in preferences.txt) to stop some fonts scrolling out of view.
|
||||
// See link in File>Preferences to locate "preferences.txt" file. You must close
|
||||
// Processing then edit the file lines. If Processing is not closed first then the
|
||||
// edits will be overwritten by defaults! Edit "preferences.txt" as follows for
|
||||
// 1000 lines, then save, then run Processing again:
|
||||
// 3000 lines, then save, then run Processing again:
|
||||
|
||||
// console.length=3000; // Line 4 in file
|
||||
// console.scrollback.lines=3000; // Line 7 in file
|
||||
|
||||
/*
|
||||
console.length=1000 // Line 4 in file
|
||||
console.scrollback.lines=1000 // Line 7 in file
|
||||
*/
|
||||
|
||||
// Useful links:
|
||||
/*
|
||||
@@ -91,28 +107,34 @@ Software License Agreement (FreeBSD License)
|
||||
https://github.com/esp8266/arduino-esp8266fs-plugin
|
||||
https://github.com/me-no-dev/arduino-esp32fs-plugin
|
||||
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
>>>>>>>>>>>>>>>>>>>> END OF INSTRUCTIONS <<<<<<<<<<<<<<<<<<<< */
|
||||
|
||||
import java.awt.Desktop;
|
||||
|
||||
import java.awt.Desktop; // Required to allow sketch to open file windows
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// >>>>>>>>>> USER CONFIGURED PARAMETERS START HERE <<<<<<<<<<
|
||||
|
||||
// Use font number or name, -1 for fontNumber means use fontName below, a value >=0 means use system font number from list.
|
||||
// When the sketch is run it will generate a file called "systemFontList.txt" in the sketch folder, press Ctrl+K to see it.
|
||||
// Open the "systemFontList.txt" in a text editor to view the font files and reference numbers for your system.
|
||||
|
||||
// Use font name for ttf files placed in the "Data" folder or the font number seen in IDE Console for system fonts
|
||||
int fontNumber = -1; // << Use [Number] in brackets from the fonts listed.
|
||||
|
||||
// OR use font name for ttf files placed in the "Data" folder or the font number seen in IDE Console for system fonts
|
||||
// the font numbers are listed when the sketch is run.
|
||||
// | 1 2 | Maximum filename size for SPIFFS is 32 including leading /
|
||||
// | 1 2 | Maximum filename size for SPIFFS is 31 including leading /
|
||||
// 1234567890123456789012345 and added point size and .vlw extension, so max is 25
|
||||
String fontName = "Final-Frontier"; // Manually crop the filename length later after creation if needed
|
||||
|
||||
String fontType = ".ttf"; //SPIFFS does not accept underscore in filename!
|
||||
// Note: SPIFFS does NOT accept underscore in a filename!
|
||||
String fontType = ".ttf";
|
||||
//String fontType = ".otf";
|
||||
|
||||
// Use font number instead of name, -1 means use name above, or a value >=0 means use system font number from list.
|
||||
int fontNumber = -1; // << Use [Number] in brackets from the fonts listed in console window
|
||||
|
||||
// Define the font size in points for the created font file
|
||||
int fontSize = 28;
|
||||
// Define the font size in points for the TFT_eSPI font file
|
||||
int fontSize = 20;
|
||||
|
||||
// Font size to use in the Processing sketch display window that pops up (can be different to above)
|
||||
int displayFontSize = 28;
|
||||
@@ -125,7 +147,7 @@ int displayFontSize = 28;
|
||||
static final int[] unicodeBlocks = {
|
||||
// The list below has been created from the table here: https://en.wikipedia.org/wiki/Unicode_block
|
||||
// Remove // at start of lines below to include that unicode block, different code ranges can also be specified by
|
||||
// editting the start and end of range values. Multiple lines from the list below can be included, limited only by
|
||||
// editting the start and end-of-range values. Multiple lines from the list below can be included, limited only by
|
||||
// the final font file size!
|
||||
|
||||
// Block range, //Block name, Code points, Assigned characters, Scripts
|
||||
@@ -298,7 +320,7 @@ static final int[] unicodeBlocks = {
|
||||
//0x0061, 0x007A, //Example custom range (Lower case a-z)
|
||||
};
|
||||
|
||||
// Here we specify specific individual Unicodes to be included (appended at end of selected range)
|
||||
// Here we specify particular individual Unicodes to be included (appended at end of selected range)
|
||||
static final int[] specificUnicodes = {
|
||||
|
||||
// Commonly used codes, add or remove // in next line
|
||||
@@ -311,7 +333,7 @@ static final int[] specificUnicodes = {
|
||||
0x0070, // p
|
||||
//*/
|
||||
|
||||
// More characters, change next line to //* to use
|
||||
// More characters for TFT_eSPI test sketches, change next line to //* to use
|
||||
/*
|
||||
0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x010C, 0x010D,
|
||||
0x010E, 0x010F, 0x0110, 0x0111, 0x0118, 0x0119, 0x011A, 0x011B,
|
||||
@@ -337,8 +359,8 @@ static final int[] specificUnicodes = {
|
||||
//*/
|
||||
};
|
||||
|
||||
|
||||
// >>>>>>>>>> USER CONFIGURED PARAMETERS END HERE <<<<<<<<<<
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Variable to hold the inclusive Unicode range (16 bit values only for this sketch)
|
||||
@@ -347,7 +369,10 @@ int lastUnicode = 0;
|
||||
|
||||
PFont myFont;
|
||||
|
||||
PrintWriter logOutput;
|
||||
|
||||
void setup() {
|
||||
logOutput = createWriter("FontFiles/System_Font_List.txt");
|
||||
|
||||
size(1000, 800);
|
||||
|
||||
@@ -355,6 +380,15 @@ void setup() {
|
||||
String[] fontList = PFont.list();
|
||||
printArray(fontList);
|
||||
|
||||
// Save font list to file
|
||||
for (int x = 0; x < fontList.length; x++)
|
||||
{
|
||||
logOutput.print("[" + x + "] ");
|
||||
logOutput.println(fontList[x]);
|
||||
}
|
||||
logOutput.flush(); // Writes the remaining data to the file
|
||||
logOutput.close(); // Finishes the file
|
||||
|
||||
// Set the fontName from the array number or the defined fontName
|
||||
if (fontNumber >= 0)
|
||||
{
|
||||
@@ -410,19 +444,19 @@ void setup() {
|
||||
}
|
||||
}
|
||||
|
||||
// loading the range specified
|
||||
// loading the specific point codes
|
||||
for (int i = 0; i < specificUnicodes.length; i++) {
|
||||
charset[index] = Character.toChars(specificUnicodes[i])[0];
|
||||
index++;
|
||||
}
|
||||
|
||||
// Make font smooth
|
||||
// Make font smooth (anti-aliased)
|
||||
boolean smooth = true;
|
||||
|
||||
// Create the font in memory
|
||||
myFont = createFont(fontName+fontType, displayFontSize, smooth, charset);
|
||||
|
||||
// Print a few characters to the sketch window
|
||||
// Print characters to the sketch window
|
||||
fill(0, 0, 0);
|
||||
textFont(myFont);
|
||||
|
||||
@@ -445,7 +479,7 @@ void setup() {
|
||||
float cwidth = textWidth((char)unicode) + 2;
|
||||
if ( (x + cwidth) > (width - gapx) ) break;
|
||||
|
||||
// Draw the letter to the screen
|
||||
// Draw the glyph to the screen
|
||||
text(new String(Character.toChars(unicode)), x, y);
|
||||
|
||||
// Move cursor
|
||||
@@ -458,7 +492,7 @@ void setup() {
|
||||
}
|
||||
|
||||
|
||||
// creating font
|
||||
// creating font to save as a file
|
||||
PFont font;
|
||||
|
||||
font = createFont(fontName+fontType, fontSize, smooth, charset);
|
||||
|
@@ -41,8 +41,8 @@ void loop(void) {
|
||||
tft.getSetup(user); //
|
||||
|
||||
Serial.printf("\n[code]\n");
|
||||
String ver = user.version;
|
||||
Serial.println("TFT_eSPI ver = " + ver +"\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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TFT_eSPI",
|
||||
"version": "1.4.3",
|
||||
"version": "1.4.4",
|
||||
"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":
|
||||
|
@@ -1,5 +1,5 @@
|
||||
name=TFT_eSPI
|
||||
version=1.4.3
|
||||
version=1.4.4
|
||||
author=Bodmer
|
||||
maintainer=Bodmer
|
||||
sentence=A fast TFT graphics library for ESP8266 and ESP32 processors for the Arduino IDE
|
||||
|
Reference in New Issue
Block a user