mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-27 05:06:44 +00:00
Add Multiple Font Support
This commit is contained in:
parent
3bded8bfc3
commit
d6f0025f68
@ -71,9 +71,11 @@ uint32_t charInBuffer = 0; // Last Character ID in the Bitmap Buffer
|
|||||||
static lv_zifont_char_t lastCharInfo; // Holds the last Glyph DSC
|
static lv_zifont_char_t lastCharInfo; // Holds the last Glyph DSC
|
||||||
|
|
||||||
#if ESP32
|
#if ESP32
|
||||||
static lv_zifont_char_t charCache[256 - 32]; // glyphID DSC cache
|
// static lv_zifont_char_t charCache[256 - 32]; // glyphID DSC cache
|
||||||
|
#define CHAR_CACHE_SIZE 224
|
||||||
#else
|
#else
|
||||||
static lv_zifont_char_t charCache[256 - 32]; // glyphID DSC cache
|
#define CHAR_CACHE_SIZE 1
|
||||||
|
// static lv_zifont_char_t charCache[256 - 32]; // glyphID DSC cache
|
||||||
#endif
|
#endif
|
||||||
static uint8_t * charBitmap_p;
|
static uint8_t * charBitmap_p;
|
||||||
|
|
||||||
@ -95,12 +97,27 @@ int lv_zifont_init(void)
|
|||||||
return LV_RES_OK; // OK
|
return LV_RES_OK; // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool openFont(File & file, const char * filename)
|
||||||
|
{
|
||||||
|
file = SPIFFS.open(filename, "r");
|
||||||
|
if(!file) {
|
||||||
|
errorPrintln(String(F("FONT: %sOpening font: ")) + String(filename));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int lv_zifont_font_init(lv_font_t * font, const char * font_path, uint16_t size)
|
int lv_zifont_font_init(lv_font_t * font, const char * font_path, uint16_t size)
|
||||||
{
|
{
|
||||||
charInBuffer = 0; // invalidate any previous cache
|
charInBuffer = 0; // invalidate any previous cache
|
||||||
|
|
||||||
lv_font_fmt_zifont_dsc_t * dsc = (lv_font_fmt_zifont_dsc_t *)lv_mem_alloc(sizeof(lv_font_fmt_zifont_dsc_t));
|
lv_font_fmt_zifont_dsc_t * dsc;
|
||||||
LV_ASSERT_MEM(dsc);
|
if(!font->dsc) {
|
||||||
|
dsc = (lv_font_fmt_zifont_dsc_t *)lv_mem_alloc(sizeof(lv_font_fmt_zifont_dsc_t));
|
||||||
|
LV_ASSERT_MEM(dsc);
|
||||||
|
} else {
|
||||||
|
dsc = (lv_font_fmt_zifont_dsc_t *)font->dsc;
|
||||||
|
}
|
||||||
if(dsc == NULL) return ZIFONT_ERROR_OUT_OF_MEMORY;
|
if(dsc == NULL) return ZIFONT_ERROR_OUT_OF_MEMORY;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
@ -111,47 +128,63 @@ int lv_zifont_font_init(lv_font_t * font, const char * font_path, uint16_t size)
|
|||||||
dsc->last_glyph_id = 0;
|
dsc->last_glyph_id = 0;
|
||||||
|
|
||||||
/* Open the font for reading */
|
/* Open the font for reading */
|
||||||
File file = SPIFFS.open(font_path, "r");
|
File file;
|
||||||
if(!file) {
|
if(!openFont(file, font_path)) return ZIFONT_ERROR_OPENING_FILE;
|
||||||
char msg[64];
|
|
||||||
sprintf(msg, PSTR("FONT: Error %d while opening font: %s\n"), error, font_path);
|
|
||||||
debugPrintln(msg);
|
|
||||||
return ZIFONT_ERROR_OPENING_FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read file header as dsc */
|
/* Read file header as dsc */
|
||||||
size_t readSize = file.readBytes((char *)dsc, sizeof(lv_font_fmt_zifont_dsc_t));
|
zi_font_header_t header;
|
||||||
|
size_t readSize = file.readBytes((char *)&header, sizeof(zi_font_header_t));
|
||||||
|
|
||||||
/* Check that we read the correct size */
|
/* Check that we read the correct size */
|
||||||
if(readSize != sizeof(lv_font_fmt_zifont_dsc_t)) {
|
if(readSize != sizeof(zi_font_header_t)) {
|
||||||
debugPrintln(PSTR("FONT: Error reading ziFont Header"));
|
debugPrintln(PSTR("FONT: Error reading ziFont Header"));
|
||||||
|
file.close();
|
||||||
return ZIFONT_ERROR_READING_DATA;
|
return ZIFONT_ERROR_READING_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check ziFile Header Format */
|
/* Check ziFile Header Format */
|
||||||
if(dsc->Password != 4 || dsc->Version != 5) {
|
if(header.Password != 4 || header.Version != 5) {
|
||||||
debugPrintln(PSTR("FONT: Unknown font file format"));
|
debugPrintln(PSTR("FONT: Unknown font file format"));
|
||||||
|
file.close();
|
||||||
return ZIFONT_ERROR_UNKNOWN_HEADER;
|
return ZIFONT_ERROR_UNKNOWN_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dsc->CharHeight = header.CharHeight;
|
||||||
|
dsc->CharWidth = header.CharWidth;
|
||||||
|
dsc->Maximumnumchars = header.Maximumnumchars;
|
||||||
|
dsc->Actualnumchars = header.Actualnumchars;
|
||||||
|
dsc->Totaldatalength = header.Totaldatalength;
|
||||||
|
dsc->Startdataaddress = header.Startdataaddress + header.Descriptionlength;
|
||||||
|
dsc->Fontdataadd8byte = header.Fontdataadd8byte;
|
||||||
|
|
||||||
|
if(!dsc->ascii_glyph_dsc) {
|
||||||
|
dsc->ascii_glyph_dsc = (lv_zifont_char_t *)lv_mem_alloc(sizeof(lv_zifont_char_t) * CHAR_CACHE_SIZE);
|
||||||
|
LV_ASSERT_MEM(dsc->ascii_glyph_dsc);
|
||||||
|
}
|
||||||
|
if(dsc->ascii_glyph_dsc == NULL) {
|
||||||
|
file.close();
|
||||||
|
return ZIFONT_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
/* read charmap into cache */
|
/* read charmap into cache */
|
||||||
file.seek(0 * sizeof(lv_zifont_char_t) + dsc->Descriptionlength + sizeof(lv_font_fmt_zifont_dsc_t), SeekSet);
|
file.seek(0 * sizeof(zi_font_header_t) + dsc->Startdataaddress, SeekSet);
|
||||||
//* read and fill charmap cache
|
//* read and fill charmap cache
|
||||||
readSize = file.readBytes((char *)charCache, sizeof(charCache));
|
readSize = file.readBytes((char *)dsc->ascii_glyph_dsc, sizeof(lv_zifont_char_t) * CHAR_CACHE_SIZE);
|
||||||
|
|
||||||
//* Check that we read the correct size
|
//* Check that we read the correct size
|
||||||
if(readSize != sizeof(charCache)) {
|
if(readSize != sizeof(lv_zifont_char_t) * CHAR_CACHE_SIZE) {
|
||||||
debugPrintln(PSTR("FONT: Error reading ziFont character map"));
|
debugPrintln(PSTR("FONT: Error reading ziFont character map"));
|
||||||
|
file.close();
|
||||||
return ZIFONT_ERROR_READING_DATA;
|
return ZIFONT_ERROR_READING_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
char msg[128];
|
char msg[128];
|
||||||
sprintf_P(msg, PSTR("FONT: Loaded V%d Font File: %s containing %d characters"), dsc->Version, font_path,
|
sprintf_P(msg, PSTR("FONT: Loaded V%d Font File: %s containing %d characters"), header.Version, font_path,
|
||||||
dsc->Maximumnumchars);
|
header.Maximumnumchars);
|
||||||
debugPrintln(msg);
|
debugPrintln(msg);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
sprintf_P(msg, PSTR("password: %u - skipL0: %u - skipLH: %u - state: %u\n"), dsc->Password, dsc->SkipL0,
|
sprintf_P(msg, PSTR("password: %u - skipL0: %u - skipLH: %u - state: %u\n"), dsc->Password, dsc->SkipL0,
|
||||||
dsc->SkipLH, dsc->State);
|
dsc->SkipLH, dsc->State);
|
||||||
@ -162,12 +195,10 @@ int lv_zifont_font_init(lv_font_t * font, const char * font_path, uint16_t size)
|
|||||||
sprintf_P(msg, PSTR("CodepageStart0: %u - CodepageEnd0: %u - CodepageStart1: %u - CodepageEnd1: %u\n"),
|
sprintf_P(msg, PSTR("CodepageStart0: %u - CodepageEnd0: %u - CodepageStart1: %u - CodepageEnd1: %u\n"),
|
||||||
dsc->SecondByteStart, dsc->SecondByteEnd, dsc->FirstByteStart, dsc->FirstByteEnd);
|
dsc->SecondByteStart, dsc->SecondByteEnd, dsc->FirstByteStart, dsc->FirstByteEnd);
|
||||||
Serial.printf(msg);
|
Serial.printf(msg);
|
||||||
sprintf_P(msg, PSTR("CharCount: %u - FileVersion: %u - FontnameLength: %u - tbd: %u\n"), dsc->Maximumnumchars, ,
|
sprintf_P(msg, PSTR("CharCount: %u - FileVersion: %u - FontnameLength: %u - tbd: %u\n"),
|
||||||
dsc->Descriptionlength, dsc->Zimobinbeg);
|
dsc->Maximumnumchars, , dsc->Descriptionlength, dsc->Zimobinbeg); Serial.printf(msg); sprintf_P(msg,
|
||||||
Serial.printf(msg);
|
PSTR("FontnameAndCmapLength: %u - FontnameStartAddr: %u - temp0: %u - temp1: %u\n"), dsc->Totaldatalength,
|
||||||
sprintf_P(msg, PSTR("FontnameAndCmapLength: %u - FontnameStartAddr: %u - temp0: %u - temp1: %u\n"),
|
dsc->Startdataaddress, dsc->CodeT0, dsc->CodeDec); Serial.printf(msg);*/
|
||||||
dsc->Totaldatalength, dsc->Startdataaddress, dsc->CodeT0, dsc->CodeDec);
|
|
||||||
Serial.printf(msg);*/
|
|
||||||
|
|
||||||
/* Init Glyph Cache */
|
/* Init Glyph Cache */
|
||||||
dsc->last_glyph_dsc = NULL;
|
dsc->last_glyph_dsc = NULL;
|
||||||
@ -180,7 +211,10 @@ int lv_zifont_font_init(lv_font_t * font, const char * font_path, uint16_t size)
|
|||||||
font->dsc = dsc; /* header data struct */ /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
|
font->dsc = dsc; /* header data struct */ /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
|
||||||
font->subpx = 0;
|
font->subpx = 0;
|
||||||
|
|
||||||
font->user_data = (char *)font_path;
|
if(font->user_data != (char *)font_path) {
|
||||||
|
if(font->user_data) free(font->user_data);
|
||||||
|
font->user_data = (char *)font_path;
|
||||||
|
}
|
||||||
return ZIFONT_NO_ERROR;
|
return ZIFONT_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,20 +246,15 @@ static const uint8_t * lv_font_get_bitmap_fmt_zifont(const lv_font_t * font, uin
|
|||||||
uint16_t charmap_position;
|
uint16_t charmap_position;
|
||||||
if(unicode_letter >= 0xF000) {
|
if(unicode_letter >= 0xF000) {
|
||||||
sprintf_P(filename, PSTR("/fontawesome%u.zi"), fdsc->CharHeight);
|
sprintf_P(filename, PSTR("/fontawesome%u.zi"), fdsc->CharHeight);
|
||||||
charmap_position = 25 + sizeof(lv_font_fmt_zifont_dsc_t);
|
charmap_position = 25 + sizeof(zi_font_header_t);
|
||||||
glyphID = unicode_letter - 0xf000; // start of fontawesome
|
glyphID = unicode_letter - 0xf000; // start of fontawesome
|
||||||
} else {
|
} else {
|
||||||
strcpy(filename, (char *)font->user_data);
|
strcpy(filename, (char *)font->user_data);
|
||||||
charmap_position = fdsc->Descriptionlength + sizeof(lv_font_fmt_zifont_dsc_t);
|
charmap_position = fdsc->Startdataaddress;
|
||||||
glyphID = unicode_letter - 0x20; // simple unicode to ascii - space is charNum=0
|
glyphID = unicode_letter - 0x20; // simple unicode to ascii - space is charNum=0
|
||||||
}
|
}
|
||||||
|
|
||||||
file = SPIFFS.open(filename, "r");
|
if(!openFont(file, filename)) return NULL;
|
||||||
if(!file) {
|
|
||||||
debugPrintln(String(F("FONT: [ERROR] while opening font:")) + String(filename));
|
|
||||||
// debugPrintln((char *)font->user_data);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_zifont_char_t * charInfo;
|
lv_zifont_char_t * charInfo;
|
||||||
/* Check Last Glyph in chache is valid and Matches currentGlyphID */
|
/* Check Last Glyph in chache is valid and Matches currentGlyphID */
|
||||||
@ -233,7 +262,7 @@ static const uint8_t * lv_font_get_bitmap_fmt_zifont(const lv_font_t * font, uin
|
|||||||
// Serial.print("@");
|
// Serial.print("@");
|
||||||
charInfo = fdsc->last_glyph_dsc;
|
charInfo = fdsc->last_glyph_dsc;
|
||||||
} else {
|
} else {
|
||||||
Serial.print("-");
|
Serial.print("%");
|
||||||
/* Read Character Table */
|
/* Read Character Table */
|
||||||
charInfo = (lv_zifont_char_t *)lv_mem_alloc(sizeof(lv_zifont_char_t));
|
charInfo = (lv_zifont_char_t *)lv_mem_alloc(sizeof(lv_zifont_char_t));
|
||||||
uint32_t char_position = glyphID * sizeof(lv_zifont_char_t) + charmap_position;
|
uint32_t char_position = glyphID * sizeof(lv_zifont_char_t) + charmap_position;
|
||||||
@ -389,41 +418,42 @@ static bool lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t * font, lv_font_gly
|
|||||||
uint8_t charmap_position;
|
uint8_t charmap_position;
|
||||||
uint8_t charwidth;
|
uint8_t charwidth;
|
||||||
if(unicode_letter >= 0xF000) {
|
if(unicode_letter >= 0xF000) {
|
||||||
charmap_position = 25 + sizeof(lv_font_fmt_zifont_dsc_t);
|
charmap_position = 25 + sizeof(zi_font_header_t);
|
||||||
glyphID = unicode_letter - 0xf000; // start of fontawesome
|
glyphID = unicode_letter - 0xf000; // start of fontawesome
|
||||||
charwidth = 0;
|
charwidth = 0;
|
||||||
} else {
|
} else {
|
||||||
charmap_position = fdsc->Descriptionlength + sizeof(lv_font_fmt_zifont_dsc_t);
|
charmap_position = fdsc->Startdataaddress; // Descriptionlength + sizeof(lv_font_fmt_zifont_dsc_t);
|
||||||
glyphID = unicode_letter - 0x20; // simple unicode to ascii - space is charNum=0
|
glyphID = unicode_letter - 0x20; // simple unicode to ascii - space is charNum=0
|
||||||
if(glyphID < sizeof(charCache) / sizeof(charCache[0]))
|
// if(glyphID < sizeof(fdsc->ascii_glyph_dsc) / sizeof(lv_zifont_char_t))
|
||||||
charwidth = charCache[glyphID].width;
|
if(glyphID < CHAR_CACHE_SIZE)
|
||||||
|
charwidth = fdsc->ascii_glyph_dsc[glyphID].width;
|
||||||
else
|
else
|
||||||
charwidth = 0;
|
charwidth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(charwidth == 0 || glyphID >= sizeof(charCache) / sizeof(charCache[0])) {
|
// if(charwidth == 0 || glyphID >= sizeof(fdsc->ascii_glyph_dsc) / sizeof(lv_zifont_char_t)) {
|
||||||
|
if(charwidth == 0 || glyphID >= CHAR_CACHE_SIZE) {
|
||||||
|
|
||||||
/* Open the font for reading */
|
/* Open the font for reading */
|
||||||
if(unicode_letter >= 0xF000) {
|
if(unicode_letter >= 0xF000) {
|
||||||
file = SPIFFS.open("/fontawesome24.zi", "r");
|
char filename[32];
|
||||||
|
sprintf_P(filename, PSTR("/fontawesome%u.zi"), fdsc->CharHeight);
|
||||||
|
if(!openFont(file, filename)) return false;
|
||||||
} else {
|
} else {
|
||||||
file = SPIFFS.open((char *)font->user_data, "r");
|
if(!openFont(file, (char *)font->user_data)) return false;
|
||||||
}
|
|
||||||
if(!file) {
|
|
||||||
Serial.printf("Error %d in opening file: %s\n", error, (char *)font->user_data);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read 10 bytes charmap */
|
/* read 10 bytes charmap */
|
||||||
lv_zifont_char_t * myCharIndex = (lv_zifont_char_t *)lv_mem_alloc(sizeof(lv_zifont_char_t));
|
// lv_zifont_char_t * myCharIndex = (lv_zifont_char_t *)lv_mem_alloc(sizeof(lv_zifont_char_t));
|
||||||
uint32_t char_position = glyphID * sizeof(lv_zifont_char_t) + charmap_position;
|
lv_zifont_char_t myCharIndex;
|
||||||
|
uint32_t char_position = glyphID * sizeof(lv_zifont_char_t) + charmap_position;
|
||||||
file.seek(char_position, SeekSet);
|
file.seek(char_position, SeekSet);
|
||||||
size_t readSize = file.readBytes((char *)myCharIndex, sizeof(lv_zifont_char_t));
|
size_t readSize = file.readBytes((char *)&myCharIndex, sizeof(lv_zifont_char_t));
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
/* Check that we read the correct size */
|
/* Check that we read the correct size */
|
||||||
if(readSize != sizeof(lv_zifont_char_t)) {
|
if(readSize != sizeof(lv_zifont_char_t)) {
|
||||||
lv_mem_free(myCharIndex);
|
// lv_mem_free(myCharIndex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,13 +463,12 @@ static bool lv_font_get_glyph_dsc_fmt_zifont(const lv_font_t * font, lv_font_gly
|
|||||||
// return false;
|
// return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unicode_letter <= 0xff && glyphID < sizeof(charCache) / sizeof(charCache[0]))
|
if(unicode_letter <= 0xff && glyphID < CHAR_CACHE_SIZE) fdsc->ascii_glyph_dsc[glyphID] = myCharIndex;
|
||||||
charCache[glyphID] = *myCharIndex;
|
lastCharInfo = myCharIndex;
|
||||||
lastCharInfo = *myCharIndex;
|
// lv_mem_free(myCharIndex);
|
||||||
lv_mem_free(myCharIndex);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
lastCharInfo = charCache[glyphID];
|
lastCharInfo = fdsc->ascii_glyph_dsc[glyphID];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t w = lastCharInfo.width + lastCharInfo.kerningL + lastCharInfo.kerningR;
|
uint8_t w = lastCharInfo.width + lastCharInfo.kerningL + lastCharInfo.kerningR;
|
||||||
|
@ -62,9 +62,24 @@ typedef struct
|
|||||||
uint8_t Variablewidth;
|
uint8_t Variablewidth;
|
||||||
uint8_t Namelength;
|
uint8_t Namelength;
|
||||||
uint8_t Fontdataadd8byte;
|
uint8_t Fontdataadd8byte;
|
||||||
uint16_t last_glyph_id; // Reserved 1
|
uint16_t reserved1; // Reserved 1
|
||||||
uint32_t Actualnumchars;
|
uint32_t Actualnumchars;
|
||||||
lv_zifont_char_t * last_glyph_dsc; // Reserved 3
|
uint32_t * reserved3; // Reserved 3
|
||||||
|
} zi_font_header_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t Codepageid;
|
||||||
|
uint8_t CharWidth;
|
||||||
|
uint8_t CharHeight;
|
||||||
|
uint32_t Maximumnumchars;
|
||||||
|
uint32_t Actualnumchars;
|
||||||
|
uint32_t Totaldatalength;
|
||||||
|
uint32_t Startdataaddress;
|
||||||
|
uint8_t Fontdataadd8byte;
|
||||||
|
uint16_t last_glyph_id;
|
||||||
|
lv_zifont_char_t * last_glyph_dsc;
|
||||||
|
lv_zifont_char_t * ascii_glyph_dsc;
|
||||||
} lv_font_fmt_zifont_dsc_t;
|
} lv_font_fmt_zifont_dsc_t;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
Loading…
x
Reference in New Issue
Block a user