213 lines
6.4 KiB
C++
213 lines
6.4 KiB
C++
// Coded by Bodmer 10/2/18, see license in root directory.
|
|
// This is part of the TFT_eSPI class and is associated with anti-aliased font functions
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
// New anti-aliased (smoothed) font functions added below
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/***************************************************************************************
|
|
** Function name: loadFont
|
|
** Description: loads parameters from a font vlw array in memory
|
|
*************************************************************************************x*/
|
|
void TFT_eSPI::loadFont(const uint8_t array[])
|
|
{
|
|
loadFont("", false);
|
|
}
|
|
|
|
#ifdef FONT_FS_AVAILABLE
|
|
/***************************************************************************************
|
|
** Function name: loadFont
|
|
** Description: loads parameters from a font vlw file
|
|
*************************************************************************************x*/
|
|
void TFT_eSPI::loadFont(String fontName, fs::FS &ffs)
|
|
{
|
|
loadFont(fontName, false);
|
|
}
|
|
#endif
|
|
|
|
/***************************************************************************************
|
|
** Function name: loadFont
|
|
** Description: loads parameters from a font vlw file
|
|
*************************************************************************************x*/
|
|
void TFT_eSPI::loadFont(String fontName, bool flash)
|
|
{
|
|
sf->loadFont(fontName, flash);
|
|
fontLoaded = true;
|
|
}
|
|
|
|
|
|
/***************************************************************************************
|
|
** Function name: deleteMetrics
|
|
** Description: Delete the old glyph metrics and free up the memory
|
|
*************************************************************************************x*/
|
|
void TFT_eSPI::unloadFont( void )
|
|
{
|
|
fontLoaded = false;
|
|
}
|
|
|
|
/***************************************************************************************
|
|
** Function name: drawGlyph
|
|
** Description: Write a character to the TFT cursor position
|
|
*************************************************************************************x*/
|
|
// Expects file to be open
|
|
void TFT_eSPI::drawGlyph(uint16_t code)
|
|
{
|
|
if (code < 0x21)
|
|
{
|
|
if (code == 0x20) {
|
|
cursor_x += sf->gFont.spaceWidth;
|
|
return;
|
|
}
|
|
|
|
if (code == '\n') {
|
|
cursor_x = 0;
|
|
cursor_y += sf->gFont.yAdvance;
|
|
if (cursor_y >= _height) cursor_y = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
uint16_t gNum = 0;
|
|
bool found = sf->getUnicodeIndex(code, &gNum);
|
|
|
|
uint16_t fg = textcolor;
|
|
uint16_t bg = textbgcolor;
|
|
|
|
if (found)
|
|
{
|
|
|
|
if (textwrapX && (cursor_x + sf->gWidth[gNum] + sf->gdX[gNum] > _width))
|
|
{
|
|
cursor_y += sf->gFont.yAdvance;
|
|
cursor_x = 0;
|
|
}
|
|
if (textwrapY && ((cursor_y + sf->gFont.yAdvance) >= _height)) cursor_y = 0;
|
|
if (cursor_x == 0) cursor_x -= sf->gdX[gNum];
|
|
|
|
uint8_t* pbuffer = nullptr;
|
|
const uint8_t* gPtr = (const uint8_t*) sf->gFont.gArray;
|
|
|
|
#ifdef FONT_FS_AVAILABLE
|
|
if (sf->fs_font)
|
|
{
|
|
sf->fontFile.seek(sf->gBitmap[gNum], fs::SeekSet); // This is taking >30ms for a significant position shift
|
|
pbuffer = (uint8_t*)malloc(sf->gWidth[gNum]);
|
|
}
|
|
#endif
|
|
|
|
int16_t xs = 0;
|
|
uint32_t dl = 0;
|
|
uint8_t pixel;
|
|
|
|
int16_t cy = cursor_y + sf->gFont.maxAscent - sf->gdY[gNum];
|
|
int16_t cx = cursor_x + sf->gdX[gNum];
|
|
|
|
startWrite(); // Avoid slow ESP32 transaction overhead for every pixel
|
|
|
|
for (int y = 0; y < sf->gHeight[gNum]; y++)
|
|
{
|
|
#ifdef FONT_FS_AVAILABLE
|
|
if (sf->fs_font) {
|
|
if (sf->spiffs)
|
|
{
|
|
sf->fontFile.read(pbuffer, sf->gWidth[gNum]);
|
|
//Serial.println("SPIFFS");
|
|
}
|
|
else
|
|
{
|
|
endWrite(); // Release SPI for SD card transaction
|
|
sf->fontFile.read(pbuffer,sf-> gWidth[gNum]);
|
|
startWrite(); // Re-start SPI for TFT transaction
|
|
//Serial.println("Not SPIFFS");
|
|
}
|
|
}
|
|
#endif
|
|
for (int x = 0; x < sf->gWidth[gNum]; x++)
|
|
{
|
|
#ifdef FONT_FS_AVAILABLE
|
|
if (sf->fs_font) pixel = pbuffer[x];
|
|
else
|
|
#endif
|
|
pixel = pgm_read_byte(gPtr + sf->gBitmap[gNum] + x + sf->gWidth[gNum] * y);
|
|
|
|
if (pixel)
|
|
{
|
|
if (pixel != 0xFF)
|
|
{
|
|
if (dl) {
|
|
if (dl==1) drawPixel(xs, y + cy, fg);
|
|
else drawFastHLine( xs, y + cy, dl, fg);
|
|
dl = 0;
|
|
}
|
|
if (getColor) bg = getColor(x + cx, y + cy);
|
|
drawPixel(x + cx, y + cy, alphaBlend(pixel, fg, bg));
|
|
}
|
|
else
|
|
{
|
|
if (dl==0) xs = x + cx;
|
|
dl++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dl) { drawFastHLine( xs, y + cy, dl, fg); dl = 0; }
|
|
}
|
|
}
|
|
if (dl) { drawFastHLine( xs, y + cy, dl, fg); dl = 0; }
|
|
}
|
|
|
|
if (pbuffer) free(pbuffer);
|
|
cursor_x += sf->gxAdvance[gNum];
|
|
endWrite();
|
|
}
|
|
else
|
|
{
|
|
// Not a Unicode in font so draw a rectangle and move on cursor
|
|
drawRect(cursor_x, cursor_y + sf->gFont.maxAscent - sf->gFont.ascent, sf->gFont.spaceWidth, sf->gFont.ascent, fg);
|
|
cursor_x += sf->gFont.spaceWidth + 1;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************************
|
|
** Function name: showFont
|
|
** Description: Page through all characters in font, td ms between screens
|
|
*************************************************************************************x*/
|
|
void TFT_eSPI::showFont(uint32_t td)
|
|
{
|
|
if( !fontLoaded || sf == nullptr) return;
|
|
|
|
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
|
|
|
|
fillScreen(textbgcolor);
|
|
|
|
for (uint16_t i = 0; i < sf->gFont.gCount; i++)
|
|
{
|
|
// Check if this will need a new screen
|
|
if (cursorX + sf->gdX[i] + sf->gWidth[i] >= width()) {
|
|
cursorX = -sf->gdX[i];
|
|
|
|
cursorY += sf->gFont.yAdvance;
|
|
if (cursorY + sf->gFont.maxAscent + sf->gFont.descent >= height()) {
|
|
cursorX = -sf->gdX[i];
|
|
cursorY = 0;
|
|
delay(timeDelay);
|
|
timeDelay = td;
|
|
fillScreen(textbgcolor);
|
|
}
|
|
}
|
|
|
|
setCursor(cursorX, cursorY);
|
|
drawGlyph(sf->gUnicode[i]);
|
|
cursorX += sf->gxAdvance[i];
|
|
//cursorX += printToSprite( cursorX, cursorY, i );
|
|
yield();
|
|
}
|
|
|
|
delay(timeDelay);
|
|
fillScreen(textbgcolor);
|
|
//fontFile.close();
|
|
}
|