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.ascent = (uint16_t)readInt32(); // top of "d"
|
||||||
gFont.descent = (uint16_t)readInt32(); // bottom of "p"
|
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.maxAscent = gFont.ascent; // Determined from metrics
|
||||||
gFont.maxDescent = gFont.descent; // Determined from metrics
|
gFont.maxDescent = gFont.descent; // Determined from metrics
|
||||||
gFont.yAdvance = gFont.ascent + gFont.descent;
|
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
|
gdX[gNum] = (int8_t)readInt32(); // x delta from cursor
|
||||||
readInt32(); // ignored
|
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)
|
if (gdY[gNum] > gFont.maxAscent)
|
||||||
{
|
{
|
||||||
// Avoid UTF coding values and characters that tend to give duff values
|
// Try to 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))
|
if (((gUnicode[gNum] > 0x20) && (gUnicode[gNum] < 0x7F)) || (gUnicode[gNum] > 0xA0))
|
||||||
{
|
{
|
||||||
gFont.maxAscent = gdY[gNum];
|
gFont.maxAscent = gdY[gNum];
|
||||||
#ifdef SHOW_ASCENT_DESCENT
|
#ifdef SHOW_ASCENT_DESCENT
|
||||||
@@ -159,6 +167,7 @@ void TFT_eSPI::loadMetrics(uint16_t gCount)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Different glyph sets have different descent values not always based on "p", so get maximum glyph descent
|
// 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)
|
if (((int16_t)gHeight[gNum] - (int16_t)gdY[gNum]) > gFont.maxDescent)
|
||||||
|
@@ -8,9 +8,6 @@
|
|||||||
void unloadFont( void );
|
void unloadFont( void );
|
||||||
bool getUnicodeIndex(uint16_t unicode, uint16_t *index);
|
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);
|
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
|
||||||
|
|
||||||
virtual void drawGlyph(uint16_t code);
|
virtual void drawGlyph(uint16_t code);
|
||||||
@@ -44,9 +41,6 @@ fontMetrics gFont = { 0, 0, 0, 0, 0, 0, 0 };
|
|||||||
|
|
||||||
String _gFontFilename;
|
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
|
bool fontLoaded = false; // Flags when a anti-aliased font is loaded
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -1312,13 +1312,16 @@ void TFT_eSprite::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t
|
|||||||
*************************************************************************************x*/
|
*************************************************************************************x*/
|
||||||
size_t TFT_eSprite::write(uint8_t utf8)
|
size_t TFT_eSprite::write(uint8_t utf8)
|
||||||
{
|
{
|
||||||
|
uint16_t uniCode = decodeUTF8(utf8);
|
||||||
|
|
||||||
|
if (!uniCode) return 1;
|
||||||
|
|
||||||
if (utf8 == '\r') return 1;
|
if (utf8 == '\r') return 1;
|
||||||
|
|
||||||
#ifdef SMOOTH_FONT
|
#ifdef SMOOTH_FONT
|
||||||
if(this->fontLoaded)
|
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( _gFontFilename, "r" );
|
||||||
//fontFile = SPIFFS.open( this->_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);
|
//Serial.print("Decoded Unicode = 0x");Serial.println(unicode,HEX);
|
||||||
|
|
||||||
drawGlyph(unicode);
|
drawGlyph(uniCode);
|
||||||
|
|
||||||
//fontFile.close();
|
//fontFile.close();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1338,10 +1342,8 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
|||||||
|
|
||||||
if (!_created ) return 1;
|
if (!_created ) return 1;
|
||||||
|
|
||||||
|
if (uniCode == '\n') uniCode+=22; // Make it a valid space character to stop errors
|
||||||
uint8_t uniCode = utf8; // Work with a copy
|
else if (uniCode < 32) return 1;
|
||||||
if (utf8 == '\n') uniCode+=22; // Make it a valid space character to stop errors
|
|
||||||
else if (utf8 < 32) return 1;
|
|
||||||
|
|
||||||
uint16_t width = 0;
|
uint16_t width = 0;
|
||||||
uint16_t height = 0;
|
uint16_t height = 0;
|
||||||
@@ -1362,7 +1364,7 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
|||||||
if (textfont == 2)
|
if (textfont == 2)
|
||||||
{
|
{
|
||||||
if (utf8 > 127) return 1;
|
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);
|
width = pgm_read_byte(widtbl_f16 + uniCode-32);
|
||||||
height = chr_hgt_f16;
|
height = chr_hgt_f16;
|
||||||
// Font 2 is rendered in whole byte widths so we must allow for this
|
// 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;
|
if (utf8 > 127) return 1;
|
||||||
// Uses the fontinfo struct array to avoid lots of 'if' or 'switch' statements
|
// 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 );
|
width = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[textfont].widthtbl ) ) + uniCode-32 );
|
||||||
height= pgm_read_byte( &fontdata[textfont].height );
|
height= pgm_read_byte( &fontdata[textfont].height );
|
||||||
}
|
}
|
||||||
@@ -1420,15 +1421,14 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
|||||||
} // Custom GFX font
|
} // Custom GFX font
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if(utf8 == '\n') {
|
if(utf8 == '\n') {
|
||||||
this->cursor_x = 0;
|
this->cursor_x = 0;
|
||||||
this->cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
this->cursor_y += (int16_t)textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||||
} else {
|
} else {
|
||||||
if (uniCode > (uint8_t)pgm_read_byte(&gfxFont->last )) return 1;
|
if (uniCode > pgm_read_word(&gfxFont->last )) return 1;
|
||||||
if (uniCode < (uint8_t)pgm_read_byte(&gfxFont->first)) 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]);
|
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||||
uint8_t w = pgm_read_byte(&glyph->width),
|
uint8_t w = pgm_read_byte(&glyph->width),
|
||||||
h = pgm_read_byte(&glyph->height);
|
h = pgm_read_byte(&glyph->height);
|
||||||
@@ -1456,7 +1456,7 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
|||||||
** Function name: drawChar
|
** Function name: drawChar
|
||||||
** Description: draw a single character in the Adafruit GLCD or freefont
|
** Description: draw a single character in the Adafruit GLCD or freefont
|
||||||
*************************************************************************************x*/
|
*************************************************************************************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;
|
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
|
((y + 8 * size - 1) < 0)) // Clip top
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (c < 32) return;
|
||||||
#ifdef LOAD_GLCD
|
#ifdef LOAD_GLCD
|
||||||
//>>>>>>>>>>>>>>>>>>
|
//>>>>>>>>>>>>>>>>>>
|
||||||
#ifdef LOAD_GFXFF
|
#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
|
#ifdef LOAD_GFXFF
|
||||||
// Filter out bad characters not present in font
|
// 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]);
|
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]);
|
||||||
uint8_t *bitmap = (uint8_t *)pgm_read_dword(&gfxFont->bitmap);
|
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),
|
uint8_t w = pgm_read_byte(&glyph->width),
|
||||||
h = pgm_read_byte(&glyph->height);
|
h = pgm_read_byte(&glyph->height);
|
||||||
//xa = pgm_read_byte(&glyph->xAdvance);
|
//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
|
** Function name: drawChar
|
||||||
** Description: draw a unicode onto the screen
|
** Description: draw a unicode onto the screen
|
||||||
*************************************************************************************x*/
|
*************************************************************************************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)
|
int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y)
|
||||||
{
|
{
|
||||||
return drawChar(uniCode, x, y, textfont);
|
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)
|
int16_t TFT_eSprite::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
|
||||||
{
|
{
|
||||||
if (!_created ) return 0;
|
if (!_created ) return 0;
|
||||||
|
|
||||||
|
if (!uniCode) return 0;
|
||||||
|
|
||||||
if (font==1)
|
if (font==1)
|
||||||
{
|
{
|
||||||
#ifdef LOAD_GLCD
|
#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
|
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]);
|
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||||
return pgm_read_byte(&glyph->xAdvance) * textsize;
|
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 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),
|
fillSprite(uint32_t color),
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
#ifdef LOAD_GFXFF
|
#ifdef LOAD_GFXFF
|
||||||
|
|
||||||
typedef struct { // Data stored PER GLYPH
|
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 width, height; // Bitmap dimensions in pixels
|
||||||
uint8_t xAdvance; // Distance to advance cursor (x axis)
|
uint8_t xAdvance; // Distance to advance cursor (x axis)
|
||||||
int8_t xOffset, yOffset; // Dist from cursor pos to UL corner
|
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:
|
typedef struct { // Data stored for FONT AS A WHOLE:
|
||||||
uint8_t *bitmap; // Glyph bitmaps, concatenated
|
uint8_t *bitmap; // Glyph bitmaps, concatenated
|
||||||
GFXglyph *glyph; // Glyph array
|
GFXglyph *glyph; // Glyph array
|
||||||
uint8_t first, last; // ASCII extents
|
uint16_t first, last; // ASCII extents
|
||||||
uint8_t yAdvance; // Newline distance (y axis)
|
uint8_t yAdvance; // Newline distance (y axis)
|
||||||
} GFXfont;
|
} GFXfont;
|
||||||
|
|
||||||
|
113
TFT_eSPI.cpp
113
TFT_eSPI.cpp
@@ -2272,21 +2272,22 @@ int16_t TFT_eSPI::textWidth(const char *string)
|
|||||||
|
|
||||||
int16_t TFT_eSPI::textWidth(const char *string, uint8_t font)
|
int16_t TFT_eSPI::textWidth(const char *string, uint8_t font)
|
||||||
{
|
{
|
||||||
int32_t str_width = 0;
|
int32_t str_width = 0;
|
||||||
|
uint16_t uniCode = 0;
|
||||||
|
|
||||||
#ifdef SMOOTH_FONT
|
#ifdef SMOOTH_FONT
|
||||||
if(fontLoaded)
|
if(fontLoaded)
|
||||||
{
|
{
|
||||||
while (*string)
|
while (*string)
|
||||||
{
|
{
|
||||||
uint16_t unicode = decodeUTF8(*string++);
|
uniCode = decodeUTF8(*string++);
|
||||||
if (unicode)
|
if (uniCode)
|
||||||
{
|
{
|
||||||
if (unicode == 0x20) str_width += gFont.spaceWidth;
|
if (uniCode == 0x20) str_width += gFont.spaceWidth;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint16_t gNum = 0;
|
uint16_t gNum = 0;
|
||||||
bool found = getUnicodeIndex(unicode, &gNum);
|
bool found = getUnicodeIndex(uniCode, &gNum);
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
if(str_width == 0 && gdX[gNum] < 0) str_width -= gdX[gNum];
|
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
|
#endif
|
||||||
|
|
||||||
unsigned char uniCode;
|
|
||||||
char *widthtable;
|
|
||||||
|
|
||||||
if (font>1 && font<9)
|
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)
|
while (*string)
|
||||||
{
|
{
|
||||||
uniCode = *(string++);
|
uniCode = *(string++);
|
||||||
if (uniCode > 31 && uniCode < 128)
|
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
|
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)
|
while (*string)
|
||||||
{
|
{
|
||||||
uniCode = decodeUTF8(*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]);
|
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[uniCode]);
|
||||||
// If this is not the last character or is a digit then use xAdvance
|
// If this is not the last character or is a digit then use xAdvance
|
||||||
if (*string || isDigits) str_width += pgm_read_byte(&glyph->xAdvance);
|
if (*string || isDigits) str_width += pgm_read_byte(&glyph->xAdvance);
|
||||||
@@ -2393,7 +2391,7 @@ int16_t TFT_eSPI::fontHeight(void)
|
|||||||
** Function name: drawChar
|
** Function name: drawChar
|
||||||
** Description: draw a single character in the Adafruit GLCD font
|
** 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
|
if ((x >= _width) || // Clip right
|
||||||
(y >= _height) || // Clip bottom
|
(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
|
#ifdef LOAD_GFXFF
|
||||||
// Filter out bad characters not present in font
|
// 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();
|
spi_begin();
|
||||||
inTransaction = true;
|
inTransaction = true;
|
||||||
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
|
||||||
c -= pgm_read_byte(&gfxFont->first);
|
c -= pgm_read_word(&gfxFont->first);
|
||||||
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]);
|
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]);
|
||||||
uint8_t *bitmap = (uint8_t *)pgm_read_dword(&gfxFont->bitmap);
|
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),
|
uint8_t w = pgm_read_byte(&glyph->width),
|
||||||
h = pgm_read_byte(&glyph->height);
|
h = pgm_read_byte(&glyph->height);
|
||||||
//xa = pgm_read_byte(&glyph->xAdvance);
|
//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)
|
size_t TFT_eSPI::write(uint8_t utf8)
|
||||||
{
|
{
|
||||||
|
uint16_t uniCode = decodeUTF8(utf8);
|
||||||
|
|
||||||
|
if (!uniCode) return 1;
|
||||||
|
|
||||||
if (utf8 == '\r') return 1;
|
if (utf8 == '\r') return 1;
|
||||||
|
|
||||||
#ifdef SMOOTH_FONT
|
#ifdef SMOOTH_FONT
|
||||||
if(fontLoaded)
|
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);
|
//Serial.print("UTF8 ="); Serial.println(utf8);
|
||||||
|
|
||||||
if (!unicode) return 1;
|
|
||||||
|
|
||||||
//fontFile = SPIFFS.open( _gFontFilename, "r" );
|
//fontFile = SPIFFS.open( _gFontFilename, "r" );
|
||||||
|
|
||||||
//if(!fontFile)
|
//if(!fontFile)
|
||||||
@@ -4011,16 +4009,15 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
|||||||
// return 1;
|
// return 1;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
drawGlyph(unicode);
|
drawGlyph(uniCode);
|
||||||
|
|
||||||
//fontFile.close();
|
//fontFile.close();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t uniCode = utf8; // Work with a copy
|
if (uniCode == '\n') uniCode+=22; // Make it a valid space character to stop errors
|
||||||
if (utf8 == '\n') uniCode+=22; // Make it a valid space character to stop errors
|
else if (uniCode < 32) return 1;
|
||||||
else if (utf8 < 32) return 1;
|
|
||||||
|
|
||||||
uint16_t width = 0;
|
uint16_t width = 0;
|
||||||
uint16_t height = 0;
|
uint16_t height = 0;
|
||||||
@@ -4040,8 +4037,8 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
|||||||
#ifdef LOAD_FONT2
|
#ifdef LOAD_FONT2
|
||||||
if (textfont == 2)
|
if (textfont == 2)
|
||||||
{
|
{
|
||||||
if (utf8 > 127) return 1;
|
if (uniCode > 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);
|
width = pgm_read_byte(widtbl_f16 + uniCode-32);
|
||||||
height = chr_hgt_f16;
|
height = chr_hgt_f16;
|
||||||
// Font 2 is rendered in whole byte widths so we must allow for this
|
// 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 ((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
|
// 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 );
|
width = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[textfont].widthtbl ) ) + uniCode-32 );
|
||||||
height= pgm_read_byte( &fontdata[textfont].height );
|
height= pgm_read_byte( &fontdata[textfont].height );
|
||||||
}
|
}
|
||||||
@@ -4098,18 +4094,15 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
|||||||
} // Custom GFX font
|
} // Custom GFX font
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uniCode = (uint8_t)decodeUTF8(utf8);
|
|
||||||
if (!uniCode) return 1;
|
|
||||||
|
|
||||||
if(utf8 == '\n') {
|
if(utf8 == '\n') {
|
||||||
cursor_x = 0;
|
cursor_x = 0;
|
||||||
cursor_y += (int16_t)textsize *
|
cursor_y += (int16_t)textsize *
|
||||||
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
(uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
||||||
} else {
|
} else {
|
||||||
if (uniCode > (uint8_t)pgm_read_byte(&gfxFont->last )) return 1;
|
if (uniCode > pgm_read_word(&gfxFont->last )) return 1;
|
||||||
if (uniCode < (uint8_t)pgm_read_byte(&gfxFont->first)) 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]);
|
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||||
uint8_t w = pgm_read_byte(&glyph->width),
|
uint8_t w = pgm_read_byte(&glyph->width),
|
||||||
h = pgm_read_byte(&glyph->height);
|
h = pgm_read_byte(&glyph->height);
|
||||||
@@ -4136,17 +4129,17 @@ size_t TFT_eSPI::write(uint8_t utf8)
|
|||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
** Function name: drawChar
|
** 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 (!uniCode) return 0;
|
||||||
|
|
||||||
if (font==1)
|
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
|
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]);
|
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||||
return pgm_read_byte(&glyph->xAdvance) * textsize;
|
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
|
#ifdef LOAD_FONT2
|
||||||
if (font == 2)
|
if (font == 2)
|
||||||
{
|
{
|
||||||
// This is faster than using the fontdata structure
|
|
||||||
flash_address = pgm_read_dword(&chrtbl_f16[uniCode]);
|
flash_address = pgm_read_dword(&chrtbl_f16[uniCode]);
|
||||||
width = pgm_read_byte(widtbl_f16 + uniCode);
|
width = pgm_read_byte(widtbl_f16 + uniCode);
|
||||||
height = chr_hgt_f16;
|
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))
|
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 *) );
|
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 );
|
width = pgm_read_byte( (uint8_t *)pgm_read_dword( &(fontdata[font].widthtbl ) ) + uniCode );
|
||||||
height= pgm_read_byte( &fontdata[font].height );
|
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
|
// Font is not 2 and hence is RLE encoded
|
||||||
{
|
{
|
||||||
spi_begin();
|
spi_begin();
|
||||||
|
inTransaction = true;
|
||||||
|
|
||||||
w *= height; // Now w is total number of pixels in the character
|
w *= height; // Now w is total number of pixels in the character
|
||||||
if ((textsize != 1) || (textcolor == textbgcolor)) {
|
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();
|
spi_end();
|
||||||
}
|
}
|
||||||
else // Text colour != background && textsize = 1
|
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);
|
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 TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8_t font)
|
||||||
{
|
{
|
||||||
int16_t sumX = 0;
|
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;
|
cheight = (glyph_ab + glyph_bb) * textsize;
|
||||||
// Get the offset for the first character only to allow for negative offsets
|
// 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 len = strlen(string);
|
||||||
uint16_t n = 0;
|
uint16_t n = 0;
|
||||||
|
|
||||||
while (n < len && c2 == 0) c2 = decodeUTF8((uint8_t*)string, &n, len - n);
|
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]);
|
GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c2]);
|
||||||
xo = pgm_read_byte(&glyph->xOffset) * textsize;
|
xo = pgm_read_byte(&glyph->xOffset) * textsize;
|
||||||
// Adjust for negative xOffset
|
// Adjust for negative xOffset
|
||||||
@@ -4576,6 +4569,9 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint16_t len = strlen(string);
|
||||||
|
uint16_t n = 0;
|
||||||
|
|
||||||
#ifdef SMOOTH_FONT
|
#ifdef SMOOTH_FONT
|
||||||
if(fontLoaded)
|
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);
|
//drawLine(poX, poY - 5, poX, poY + 5, TFT_GREEN);
|
||||||
//fontFile = SPIFFS.open( _gFontFilename, "r");
|
//fontFile = SPIFFS.open( _gFontFilename, "r");
|
||||||
if(!fontFile) return 0;
|
if(!fontFile) return 0;
|
||||||
uint16_t len = strlen(string);
|
|
||||||
uint16_t n = 0;
|
|
||||||
setCursor(poX, poY);
|
setCursor(poX, poY);
|
||||||
|
|
||||||
while (n < len)
|
while (n < len)
|
||||||
{
|
{
|
||||||
uint16_t unicode = decodeUTF8((uint8_t*)string, &n, len - n);
|
uint16_t uniCode = decodeUTF8((uint8_t*)string, &n, len - n);
|
||||||
drawGlyph(unicode);
|
drawGlyph(uniCode);
|
||||||
}
|
}
|
||||||
sumX += cwidth;
|
sumX += cwidth;
|
||||||
//fontFile.close();
|
//fontFile.close();
|
||||||
@@ -4599,7 +4594,11 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
|||||||
else
|
else
|
||||||
#endif
|
#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
|
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv DEBUG vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||||
@@ -4669,7 +4668,7 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
|||||||
#endif
|
#endif
|
||||||
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DEBUG ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
// No chance of overflow from here on
|
||||||
|
|
||||||
// Get integer part
|
// Get integer part
|
||||||
unsigned long temp = (unsigned long)floatNumber;
|
uint32_t temp = (uint32_t)floatNumber;
|
||||||
|
|
||||||
// Put integer part into array
|
// Put integer part into array
|
||||||
ltoa(temp, str + ptr, 10);
|
ltoa(temp, str + ptr, 10);
|
||||||
@@ -4830,7 +4829,7 @@ void TFT_eSPI::setFreeFont(const GFXfont *f)
|
|||||||
|
|
||||||
glyph_ab = 0;
|
glyph_ab = 0;
|
||||||
glyph_bb = 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
|
// Find the biggest above and below baseline offsets
|
||||||
for (uint8_t c = 0; c < numChars; c++)
|
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
|
// 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),
|
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),
|
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),
|
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),
|
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 writeColor(uint16_t color, uint32_t len); // Write colours without transaction overhead
|
||||||
void endWrite(void); // End SPI transaction
|
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);
|
size_t write(uint8_t);
|
||||||
|
|
||||||
#ifdef TFT_SDA_READ
|
#ifdef TFT_SDA_READ
|
||||||
@@ -838,6 +840,9 @@ class TFT_eSPI : public Print {
|
|||||||
int16_t _xpivot; // x pivot point coordinate
|
int16_t _xpivot; // x pivot point coordinate
|
||||||
int16_t _ypivot; // 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:
|
private:
|
||||||
|
|
||||||
inline void spi_begin() __attribute__((always_inline));
|
inline void spi_begin() __attribute__((always_inline));
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
// This is a Processing sketch, see https://processing.org/ to download the IDE
|
// 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)
|
Software License Agreement (FreeBSD License)
|
||||||
@@ -36,47 +38,61 @@ Software License Agreement (FreeBSD License)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
// This is a processing sketch to create font files for the TFT_eSPI library:
|
// This is a processing sketch to create font files for the TFT_eSPI library:
|
||||||
|
|
||||||
// https://github.com/Bodmer/TFT_eSPI
|
// 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
|
// >>>>>>>>>>>>>>>>>>>> INSTRUCTIONS <<<<<<<<<<<<<<<<<<<<
|
||||||
// (point size, unicode blocks to include etc). Ranges of characers or
|
|
||||||
// specific individual unicodes can be included in the created font file/
|
// 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
|
// 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
|
// 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.
|
// To maximise rendering performance and the memory consumed only include the characters
|
||||||
// Characters at the start of the file will render faster than those at the end.
|
// 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
|
// Once created the files must be loaded into the ESP32 or ESP8266 SPIFFS memory
|
||||||
// using the Arduino IDE plugin detailed here:
|
// using the Arduino IDE plugin detailed here:
|
||||||
// https://github.com/esp8266/arduino-esp8266fs-plugin
|
// https://github.com/esp8266/arduino-esp8266fs-plugin
|
||||||
// https://github.com/me-no-dev/arduino-esp32fs-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
|
// When the sketch is run it will generate a file called "System_Font_List.txt" in the
|
||||||
// console line count (in preferences.txt) to stop some fonts scrolling out of view.
|
// 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
|
// 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
|
// 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
|
// 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:
|
// Useful links:
|
||||||
/*
|
/*
|
||||||
|
|
||||||
https://en.wikipedia.org/wiki/Unicode_font
|
https://en.wikipedia.org/wiki/Unicode_font
|
||||||
|
|
||||||
@@ -86,33 +102,39 @@ Software License Agreement (FreeBSD License)
|
|||||||
http://savannah.gnu.org/projects/freefont/
|
http://savannah.gnu.org/projects/freefont/
|
||||||
|
|
||||||
http://www.google.com/get/noto/
|
http://www.google.com/get/noto/
|
||||||
|
|
||||||
https://github.com/Bodmer/TFT_eSPI
|
https://github.com/Bodmer/TFT_eSPI
|
||||||
https://github.com/esp8266/arduino-esp8266fs-plugin
|
https://github.com/esp8266/arduino-esp8266fs-plugin
|
||||||
https://github.com/me-no-dev/arduino-esp32fs-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 <<<<<<<<<<
|
// >>>>>>>>>> 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.
|
// 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
|
// 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 fontName = "Final-Frontier"; // Manually crop the filename length later after creation if needed
|
||||||
|
// Note: SPIFFS does NOT accept underscore in a filename!
|
||||||
String fontType = ".ttf"; //SPIFFS does not accept underscore in filename!
|
String fontType = ".ttf";
|
||||||
//String fontType = ".otf";
|
//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
|
// Define the font size in points for the TFT_eSPI font file
|
||||||
int fontSize = 28;
|
int fontSize = 20;
|
||||||
|
|
||||||
// Font size to use in the Processing sketch display window that pops up (can be different to above)
|
// Font size to use in the Processing sketch display window that pops up (can be different to above)
|
||||||
int displayFontSize = 28;
|
int displayFontSize = 28;
|
||||||
@@ -125,7 +147,7 @@ int displayFontSize = 28;
|
|||||||
static final int[] unicodeBlocks = {
|
static final int[] unicodeBlocks = {
|
||||||
// The list below has been created from the table here: https://en.wikipedia.org/wiki/Unicode_block
|
// 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
|
// 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!
|
// the final font file size!
|
||||||
|
|
||||||
// Block range, //Block name, Code points, Assigned characters, Scripts
|
// Block range, //Block name, Code points, Assigned characters, Scripts
|
||||||
@@ -298,20 +320,20 @@ static final int[] unicodeBlocks = {
|
|||||||
//0x0061, 0x007A, //Example custom range (Lower case a-z)
|
//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 = {
|
static final int[] specificUnicodes = {
|
||||||
|
|
||||||
// Commonly used codes, add or remove // in next line
|
// Commonly used codes, add or remove // in next line
|
||||||
// 0x00A3, 0x00B0, 0x00B5, 0x03A9, 0x20AC, // £ ° µ Ω €
|
// 0x00A3, 0x00B0, 0x00B5, 0x03A9, 0x20AC, // £ ° µ Ω €
|
||||||
|
|
||||||
// Numbers and characters for showing time, change next line to //* to use
|
// Numbers and characters for showing time, change next line to //* to use
|
||||||
/*
|
/*
|
||||||
0x002B, 0x002D, 0x002E, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, // - + . 0 1 2 3 4
|
0x002B, 0x002D, 0x002E, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, // - + . 0 1 2 3 4
|
||||||
0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x0061, 0x006D, // 5 6 7 8 9 : a m
|
0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x0061, 0x006D, // 5 6 7 8 9 : a m
|
||||||
0x0070, // p
|
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,
|
0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x010C, 0x010D,
|
||||||
0x010E, 0x010F, 0x0110, 0x0111, 0x0118, 0x0119, 0x011A, 0x011B,
|
0x010E, 0x010F, 0x0110, 0x0111, 0x0118, 0x0119, 0x011A, 0x011B,
|
||||||
@@ -337,8 +359,8 @@ static final int[] specificUnicodes = {
|
|||||||
//*/
|
//*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// >>>>>>>>>> USER CONFIGURED PARAMETERS END HERE <<<<<<<<<<
|
// >>>>>>>>>> USER CONFIGURED PARAMETERS END HERE <<<<<<<<<<
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Variable to hold the inclusive Unicode range (16 bit values only for this sketch)
|
// Variable to hold the inclusive Unicode range (16 bit values only for this sketch)
|
||||||
@@ -347,7 +369,10 @@ int lastUnicode = 0;
|
|||||||
|
|
||||||
PFont myFont;
|
PFont myFont;
|
||||||
|
|
||||||
|
PrintWriter logOutput;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
logOutput = createWriter("FontFiles/System_Font_List.txt");
|
||||||
|
|
||||||
size(1000, 800);
|
size(1000, 800);
|
||||||
|
|
||||||
@@ -355,6 +380,15 @@ void setup() {
|
|||||||
String[] fontList = PFont.list();
|
String[] fontList = PFont.list();
|
||||||
printArray(fontList);
|
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
|
// Set the fontName from the array number or the defined fontName
|
||||||
if (fontNumber >= 0)
|
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++) {
|
for (int i = 0; i < specificUnicodes.length; i++) {
|
||||||
charset[index] = Character.toChars(specificUnicodes[i])[0];
|
charset[index] = Character.toChars(specificUnicodes[i])[0];
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make font smooth
|
// Make font smooth (anti-aliased)
|
||||||
boolean smooth = true;
|
boolean smooth = true;
|
||||||
|
|
||||||
// Create the font in memory
|
// Create the font in memory
|
||||||
myFont = createFont(fontName+fontType, displayFontSize, smooth, charset);
|
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);
|
fill(0, 0, 0);
|
||||||
textFont(myFont);
|
textFont(myFont);
|
||||||
|
|
||||||
@@ -444,10 +478,10 @@ void setup() {
|
|||||||
int unicode = charset[index];
|
int unicode = charset[index];
|
||||||
float cwidth = textWidth((char)unicode) + 2;
|
float cwidth = textWidth((char)unicode) + 2;
|
||||||
if ( (x + cwidth) > (width - gapx) ) break;
|
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);
|
text(new String(Character.toChars(unicode)), x, y);
|
||||||
|
|
||||||
// Move cursor
|
// Move cursor
|
||||||
x += cwidth;
|
x += cwidth;
|
||||||
// Increment the counter
|
// Increment the counter
|
||||||
@@ -458,12 +492,12 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// creating font
|
// creating font to save as a file
|
||||||
PFont font;
|
PFont font;
|
||||||
|
|
||||||
font = createFont(fontName+fontType, fontSize, smooth, charset);
|
font = createFont(fontName+fontType, fontSize, smooth, charset);
|
||||||
|
|
||||||
println("Created font " + fontName + str(fontSize) + ".vlw");
|
println("Created font " + fontName + str(fontSize) + ".vlw");
|
||||||
|
|
||||||
// creating file
|
// creating file
|
||||||
try {
|
try {
|
||||||
@@ -486,4 +520,4 @@ void setup() {
|
|||||||
catch(IOException e) {
|
catch(IOException e) {
|
||||||
println("Doh! Failed to create the file");
|
println("Doh! Failed to create the file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,8 +41,8 @@ void loop(void) {
|
|||||||
tft.getSetup(user); //
|
tft.getSetup(user); //
|
||||||
|
|
||||||
Serial.printf("\n[code]\n");
|
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("Processor = ESP%i\n", user.esp, HEX);
|
||||||
Serial.printf("Frequency = %i MHz\n", ESP.getCpuFreqMHz());
|
Serial.printf("Frequency = %i MHz\n", ESP.getCpuFreqMHz());
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "TFT_eSPI",
|
"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",
|
"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",
|
"description": "A TFT and ePaper SPI graphics library for ESP8266 and ESP32",
|
||||||
"repository":
|
"repository":
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
name=TFT_eSPI
|
name=TFT_eSPI
|
||||||
version=1.4.3
|
version=1.4.4
|
||||||
author=Bodmer
|
author=Bodmer
|
||||||
maintainer=Bodmer
|
maintainer=Bodmer
|
||||||
sentence=A fast TFT graphics library for ESP8266 and ESP32 processors for the Arduino IDE
|
sentence=A fast TFT graphics library for ESP8266 and ESP32 processors for the Arduino IDE
|
||||||
|
Reference in New Issue
Block a user