mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-08-07 06:34:44 +02:00
Add smooth fonts in program memory for ESP32/8266
The 4 new smooth font "Font_Demo_1/2/3/4_Array" examples now work on ESP32 and ESP8266.
This commit is contained in:
@@ -12,12 +12,12 @@
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSPI::loadFont(const uint8_t array[])
|
||||
{
|
||||
if(array == nullptr) return;
|
||||
if (array == nullptr) return;
|
||||
fontPtr = (uint8_t*) array;
|
||||
loadFont("", false);
|
||||
}
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
/***************************************************************************************
|
||||
** Function name: loadFont
|
||||
** Description: loads parameters from a font vlw file
|
||||
@@ -96,23 +96,27 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
|
||||
|
||||
if (fontLoaded) unloadFont();
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (fontName == "") fs_font = false;
|
||||
else { fontPtr = nullptr; fs_font = true; }
|
||||
|
||||
spiffs = flash; // true if font is in SPIFFS
|
||||
if (fs_font) {
|
||||
spiffs = flash; // true if font is in SPIFFS
|
||||
|
||||
if(spiffs) fontFS = SPIFFS;
|
||||
if(spiffs) fontFS = SPIFFS;
|
||||
|
||||
// Avoid a crash on the ESP32 if the file does not exist
|
||||
if (fontFS.exists("/" + fontName + ".vlw") == false) {
|
||||
Serial.println("Font file " + fontName + " not found!");
|
||||
return;
|
||||
// Avoid a crash on the ESP32 if the file does not exist
|
||||
if (fontFS.exists("/" + fontName + ".vlw") == false) {
|
||||
Serial.println("Font file " + fontName + " not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
fontFile = fontFS.open( "/" + fontName + ".vlw", "r");
|
||||
|
||||
if(!fontFile) return;
|
||||
|
||||
fontFile.seek(0, fs::SeekSet);
|
||||
}
|
||||
|
||||
fontFile = fontFS.open( "/" + fontName + ".vlw", "r");
|
||||
|
||||
if(!fontFile) return;
|
||||
|
||||
fontFile.seek(0, fs::SeekSet);
|
||||
#endif
|
||||
|
||||
gFont.gArray = (const uint8_t*)fontPtr;
|
||||
@@ -145,7 +149,7 @@ void TFT_eSPI::loadFont(String fontName, bool flash)
|
||||
void TFT_eSPI::loadMetrics(void)
|
||||
{
|
||||
uint32_t headerPtr = 24;
|
||||
uint32_t bitmapPtr = 24 + gFont.gCount * 28;
|
||||
uint32_t bitmapPtr = headerPtr + gFont.gCount * 28;
|
||||
|
||||
#if defined (ESP32) && defined (CONFIG_SPIRAM_SUPPORT)
|
||||
if ( psramFound() )
|
||||
@@ -175,8 +179,8 @@ void TFT_eSPI::loadMetrics(void)
|
||||
Serial.print("descent = "); Serial.println(gFont.descent);
|
||||
#endif
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
fontFile.seek(headerPtr, fs::SeekSet);
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (fs_font) fontFile.seek(headerPtr, fs::SeekSet);
|
||||
#endif
|
||||
|
||||
uint16_t gNum = 0;
|
||||
@@ -228,8 +232,6 @@ void TFT_eSPI::loadMetrics(void)
|
||||
|
||||
gBitmap[gNum] = bitmapPtr;
|
||||
|
||||
//headerPtr += 28;
|
||||
|
||||
bitmapPtr += gWidth[gNum] * gHeight[gNum];
|
||||
|
||||
gNum++;
|
||||
@@ -292,8 +294,8 @@ void TFT_eSPI::unloadFont( void )
|
||||
|
||||
gFont.gArray = nullptr;
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
if(fontFile) fontFile.close();
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (fs_font && fontFile) fontFile.close();
|
||||
#endif
|
||||
|
||||
fontLoaded = false;
|
||||
@@ -308,17 +310,22 @@ uint32_t TFT_eSPI::readInt32(void)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
val |= fontFile.read() << 24;
|
||||
val |= fontFile.read() << 16;
|
||||
val |= fontFile.read() << 8;
|
||||
val |= fontFile.read();
|
||||
#else
|
||||
val |= (*fontPtr++) << 24;
|
||||
val |= (*fontPtr++) << 16;
|
||||
val |= (*fontPtr++) << 8;
|
||||
val |= (*fontPtr++);
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (fs_font) {
|
||||
val |= fontFile.read() << 24;
|
||||
val |= fontFile.read() << 16;
|
||||
val |= fontFile.read() << 8;
|
||||
val |= fontFile.read();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
val |= pgm_read_byte(fontPtr++) << 24;
|
||||
val |= pgm_read_byte(fontPtr++) << 16;
|
||||
val |= pgm_read_byte(fontPtr++) << 8;
|
||||
val |= pgm_read_byte(fontPtr++);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -380,15 +387,20 @@ void TFT_eSPI::drawGlyph(uint16_t code)
|
||||
if (textwrapY && ((cursor_y + gFont.yAdvance) >= _height)) cursor_y = 0;
|
||||
if (cursor_x == 0) cursor_x -= gdX[gNum];
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
fontFile.seek(gBitmap[gNum], fs::SeekSet); // This is taking >30ms for a significant position shift
|
||||
uint8_t pbuffer[gWidth[gNum]];
|
||||
#else
|
||||
uint8_t* pbuffer = nullptr;
|
||||
const uint8_t* gPtr = (const uint8_t*) gFont.gArray;
|
||||
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (fs_font)
|
||||
{
|
||||
fontFile.seek(gBitmap[gNum], fs::SeekSet); // This is taking >30ms for a significant position shift
|
||||
pbuffer = (uint8_t*)malloc(gWidth[gNum]);
|
||||
}
|
||||
#endif
|
||||
|
||||
int16_t xs = 0;
|
||||
uint32_t dl = 0;
|
||||
uint8_t pixel;
|
||||
|
||||
int16_t cy = cursor_y + gFont.maxAscent - gdY[gNum];
|
||||
int16_t cx = cursor_x + gdX[gNum];
|
||||
@@ -397,27 +409,30 @@ void TFT_eSPI::drawGlyph(uint16_t code)
|
||||
|
||||
for (int y = 0; y < gHeight[gNum]; y++)
|
||||
{
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
if (spiffs)
|
||||
{
|
||||
fontFile.read(pbuffer, gWidth[gNum]);
|
||||
//Serial.println("SPIFFS");
|
||||
}
|
||||
else
|
||||
{
|
||||
endWrite(); // Release SPI for SD card transaction
|
||||
fontFile.read(pbuffer, gWidth[gNum]);
|
||||
startWrite(); // Re-start SPI for TFT transaction
|
||||
//Serial.println("Not SPIFFS");
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (fs_font) {
|
||||
if (spiffs)
|
||||
{
|
||||
fontFile.read(pbuffer, gWidth[gNum]);
|
||||
//Serial.println("SPIFFS");
|
||||
}
|
||||
else
|
||||
{
|
||||
endWrite(); // Release SPI for SD card transaction
|
||||
fontFile.read(pbuffer, gWidth[gNum]);
|
||||
startWrite(); // Re-start SPI for TFT transaction
|
||||
//Serial.println("Not SPIFFS");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (int x = 0; x < gWidth[gNum]; x++)
|
||||
{
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
uint8_t pixel = pbuffer[x];
|
||||
#else
|
||||
uint8_t pixel = gPtr[gBitmap[gNum] + x + gWidth[gNum] * y];
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (fs_font) pixel = pbuffer[x];
|
||||
else
|
||||
#endif
|
||||
pixel = pgm_read_byte(gPtr + gBitmap[gNum] + x + gWidth[gNum] * y);
|
||||
|
||||
if (pixel)
|
||||
{
|
||||
if (pixel != 0xFF)
|
||||
@@ -444,6 +459,7 @@ void TFT_eSPI::drawGlyph(uint16_t code)
|
||||
if (dl) { drawFastHLine( xs, y + cy, dl, fg); dl = 0; }
|
||||
}
|
||||
|
||||
if (pbuffer) free(pbuffer);
|
||||
cursor_x += gxAdvance[gNum];
|
||||
endWrite();
|
||||
}
|
||||
@@ -463,14 +479,6 @@ void TFT_eSPI::showFont(uint32_t td)
|
||||
{
|
||||
if(!fontLoaded) return;
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
if(!fontFile)
|
||||
{
|
||||
fontLoaded = false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int16_t cursorX = width(); // Force start of new page to initialise cursor
|
||||
int16_t cursorY = height();// for the first character
|
||||
uint32_t timeDelay = 0; // No delay before first page
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
// These are for the new antialiased fonts
|
||||
void loadFont(const uint8_t array[]);
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
void loadFont(String fontName, fs::FS &ffs);
|
||||
#endif
|
||||
void loadFont(String fontName, bool flash = true);
|
||||
@@ -42,10 +42,12 @@ fontMetrics gFont = { nullptr, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
bool fontLoaded = false; // Flags when a anti-aliased font is loaded
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
fs::File fontFile;
|
||||
fs::FS &fontFS = SPIFFS;
|
||||
bool spiffs = true;
|
||||
fs::FS &fontFS = SPIFFS;
|
||||
bool spiffs = true;
|
||||
bool fs_font = false; // For ESP32/8266 use smooth font file or FLASH (PROGMEM) array
|
||||
|
||||
#else
|
||||
bool fontFile = true;
|
||||
#endif
|
||||
|
@@ -1840,19 +1840,10 @@ size_t TFT_eSprite::write(uint8_t utf8)
|
||||
{
|
||||
if (uniCode < 32 && utf8 != '\n') return 1;
|
||||
|
||||
//fontFile = SPIFFS.open( _gFontFilename, "r" );
|
||||
//fontFile = SPIFFS.open( this->_gFontFilename, "r" );
|
||||
|
||||
//if(!fontFile)
|
||||
//{
|
||||
// fontLoaded = false;
|
||||
// return 1;
|
||||
//}
|
||||
//Serial.print("Decoded Unicode = 0x");Serial.println(unicode,HEX);
|
||||
|
||||
drawGlyph(uniCode);
|
||||
|
||||
//fontFile.close();
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -2359,28 +2350,37 @@ void TFT_eSprite::drawGlyph(uint16_t code)
|
||||
this->cursor_y = 0;
|
||||
}
|
||||
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
this->fontFile.seek(this->gBitmap[gNum], fs::SeekSet); // This is slow for a significant position shift!
|
||||
uint8_t pbuffer[this->gWidth[gNum]];
|
||||
#else
|
||||
uint8_t* pbuffer = nullptr;
|
||||
const uint8_t* gPtr = (const uint8_t*) this->gFont.gArray;
|
||||
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (this->fs_font) {
|
||||
this->fontFile.seek(this->gBitmap[gNum], fs::SeekSet); // This is slow for a significant position shift!
|
||||
pbuffer = (uint8_t*)malloc(this->gWidth[gNum]);
|
||||
}
|
||||
#endif
|
||||
|
||||
int16_t xs = 0;
|
||||
uint16_t dl = 0;
|
||||
uint8_t pixel = 0;
|
||||
|
||||
for (int32_t y = 0; y < this->gHeight[gNum]; y++)
|
||||
{
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
this->fontFile.read(pbuffer, this->gWidth[gNum]);
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (this->fs_font) {
|
||||
this->fontFile.read(pbuffer, this->gWidth[gNum]);
|
||||
}
|
||||
#endif
|
||||
for (int32_t x = 0; x < this->gWidth[gNum]; x++)
|
||||
{
|
||||
#if defined (ESP32) || defined (ESP8266)
|
||||
uint8_t pixel = pbuffer[x];
|
||||
#else
|
||||
uint8_t pixel = gPtr[gBitmap[gNum] + x + gWidth[gNum] * y];
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
if (this->fs_font) {
|
||||
pixel = pbuffer[x];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
pixel = pgm_read_byte(gPtr + this->gBitmap[gNum] + x + this->gWidth[gNum] * y);
|
||||
|
||||
if (pixel)
|
||||
{
|
||||
if (pixel != 0xFF)
|
||||
@@ -2403,6 +2403,8 @@ void TFT_eSprite::drawGlyph(uint16_t code)
|
||||
if (dl) { drawFastHLine( xs, y + this->cursor_y + this->gFont.maxAscent - this->gdY[gNum], dl, fg); dl = 0; }
|
||||
}
|
||||
|
||||
if (pbuffer) free(pbuffer);
|
||||
|
||||
if (newSprite)
|
||||
{
|
||||
pushSprite(this->cursor_x + this->gdX[gNum], this->cursor_y, bg);
|
||||
@@ -2442,14 +2444,6 @@ void TFT_eSprite::printToSprite(String string)
|
||||
void TFT_eSprite::printToSprite(char *cbuffer, uint16_t len) //String string)
|
||||
{
|
||||
if(!this->fontLoaded) return;
|
||||
|
||||
//fontFile = SPIFFS.open( this->_gFontFilename, "r" );
|
||||
|
||||
if(!this->fontFile)
|
||||
{
|
||||
this->fontLoaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t n = 0;
|
||||
bool newSprite = !_created;
|
||||
@@ -2491,8 +2485,6 @@ void TFT_eSprite::printToSprite(char *cbuffer, uint16_t len) //String string)
|
||||
pushSprite(_tft->cursor_x, _tft->cursor_y);
|
||||
deleteSprite();
|
||||
}
|
||||
|
||||
//fontFile.close();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#define FS_NO_GLOBALS
|
||||
#include <FS.h>
|
||||
#include "SPIFFS.h" // ESP32 only
|
||||
#define FONT_FS_AVAILABLE
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -33,6 +33,7 @@
|
||||
// Call up the SPIFFS FLASH filing system for the anti-aliased fonts
|
||||
#define FS_NO_GLOBALS
|
||||
#include <FS.h>
|
||||
#define FONT_FS_AVAILABLE
|
||||
#endif
|
||||
|
||||
// Do not allow parallel mode for ESP8266
|
||||
|
10
TFT_eSPI.cpp
10
TFT_eSPI.cpp
@@ -194,10 +194,14 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
|
||||
locked = true; // Transaction mutex lock flags
|
||||
inTransaction = false;
|
||||
|
||||
_booted = true;
|
||||
_booted = true; // Default attributes
|
||||
_cp437 = true;
|
||||
_utf8 = true;
|
||||
|
||||
#ifdef FONT_FS_AVAILABLE
|
||||
fs_font = true; // Smooth font filing system or array (fs_font = false) flag
|
||||
#endif
|
||||
|
||||
#if defined (ESP32) && defined (CONFIG_SPIRAM_SUPPORT)
|
||||
if (psramFound()) _psram_enable = true; // Enable the use of PSRAM (if available)
|
||||
else
|
||||
@@ -3734,10 +3738,6 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
|
||||
#ifdef SMOOTH_FONT
|
||||
if(fontLoaded) {
|
||||
if (textcolor!=textbgcolor) fillRect(poX, poY, cwidth, cheight, textbgcolor);
|
||||
//drawLine(poX - 5, poY, poX + 5, poY, TFT_GREEN);
|
||||
//drawLine(poX, poY - 5, poX, poY + 5, TFT_GREEN);
|
||||
//fontFile = SPIFFS.open( _gFontFilename, "r");
|
||||
if(!fontFile) return 0;
|
||||
|
||||
setCursor(poX, poY);
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#ifndef _TFT_eSPIH_
|
||||
#define _TFT_eSPIH_
|
||||
|
||||
#define TFT_ESPI_VERSION "2.1.0"
|
||||
#define TFT_ESPI_VERSION "2.1.1"
|
||||
|
||||
/***************************************************************************************
|
||||
** Section 1: Load required header files
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TFT_eSPI",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.1",
|
||||
"keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140",
|
||||
"description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32",
|
||||
"repository":
|
||||
|
@@ -1,5 +1,5 @@
|
||||
name=TFT_eSPI
|
||||
version=2.1.0
|
||||
version=2.1.1
|
||||
author=Bodmer
|
||||
maintainer=Bodmer
|
||||
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32
|
||||
|
Reference in New Issue
Block a user