From 1335e8a897e4a3fa8e3bf80a98100ac1b800d753 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Mon, 22 Nov 2021 17:32:57 +0100 Subject: [PATCH] Add font parser and dynamic font loader #249 --- include/hasp_mem.h | 5 +- src/hasp/hasp.cpp | 49 ++++++++------- src/hasp/hasp_attribute.cpp | 47 ++++++++------- src/hasp/hasp_font.cpp | 115 ++++++++++++++++++++++++++++++++++++ src/hasp/hasp_font.h | 10 ++++ src/hasp_gui.cpp | 3 +- src/hasplib.h | 1 + 7 files changed, 185 insertions(+), 45 deletions(-) create mode 100644 src/hasp/hasp_font.cpp create mode 100644 src/hasp/hasp_font.h diff --git a/include/hasp_mem.h b/include/hasp_mem.h index 696702cf..7cb8cfe9 100644 --- a/include/hasp_mem.h +++ b/include/hasp_mem.h @@ -12,14 +12,14 @@ extern "C" { #endif #ifdef LODEPNG_NO_COMPILE_ALLOCATORS -void* lodepng_calloc(size_t num,size_t size); +void* lodepng_calloc(size_t num, size_t size); void* lodepng_malloc(size_t size); void* lodepng_realloc(void* ptr, size_t new_size); void lodepng_free(void* ptr); #endif // LODEPNG_NO_COMPILE_ALLOCATORS bool hasp_use_psram(); -void* hasp_calloc(size_t num,size_t size); +void* hasp_calloc(size_t num, size_t size); void* hasp_malloc(size_t size); void* hasp_realloc(void* ptr, size_t new_size); void hasp_free(void* ptr); @@ -28,5 +28,4 @@ void hasp_free(void* ptr); } #endif - #endif // HASP_MEM_H \ No newline at end of file diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index 045beacc..6695c740 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -496,33 +496,42 @@ void haspSetup(void) if(haspFonts[2] == nullptr) haspFonts[2] = LV_THEME_DEFAULT_FONT_SUBTITLE; if(haspFonts[3] == nullptr) haspFonts[3] = LV_THEME_DEFAULT_FONT_TITLE; - // haspFonts[0] = lv_font_load("E:/font_1.fnt"); - // haspFonts[2] = lv_font_load("E:/font_2.fnt"); + // haspFonts[0] = lv_font_load("E:/font_1.fnt"); + // haspFonts[2] = lv_font_load("E:/font_2.fnt"); + /* #if defined(ARDUINO_ARCH_ESP32) - lv_ft_info_t info1; - info1.name = "L:/arial.ttf"; - info1.weight = 48; - info1.style = FT_FONT_STYLE_NORMAL; - lv_ft_font_init(&info1); - haspFonts[4] = info1.font; + // lv_ft_info_t info1; + // info1.name = "L:/arial.ttf"; + // info1.weight = 48; + // info1.style = FT_FONT_STYLE_NORMAL; + // lv_ft_font_init(&info1); + // haspFonts[4] = info1.font; + haspFonts[4] = get_font("arial"); // "L:/arial.ttf", 45, FT_FONT_STYLE_NORMAL); + LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, haspFonts[4]); - lv_ft_info_t info2; - info2.name = "L:/mdi.ttf"; - info2.weight = 32; - info2.style = FT_FONT_STYLE_NORMAL; - lv_ft_font_init(&info2); - haspFonts[5] = info2.font; + // lv_ft_info_t info2; + // info2.name = "L:/mdi.ttf"; + // info2.weight = 92; + // info2.style = FT_FONT_STYLE_NORMAL; + // lv_ft_font_init(&info2); + // haspFonts[5] = info2.font; + haspFonts[5] = get_font("mdi"); // "L:/mdi.ttf", 80, FT_FONT_STYLE_NORMAL); + LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, haspFonts[5]); - lv_ft_info_t info3; - info3.name = "L:/robotocondensed.ttf"; - info3.weight = 32; - info3.style = FT_FONT_STYLE_NORMAL; - lv_ft_font_init(&info3); - haspFonts[6] = info3.font; + // lv_ft_info_t info3; + // info3.name = "L:/robotocondensed.ttf"; + // info3.weight = 48; + // info3.style = FT_FONT_STYLE_NORMAL; + // lv_ft_font_init(&info3); + // haspFonts[6] = info3.font; + haspFonts[6] = get_font("robotocondensed"); // "L:/robotocondensed.ttf", 48, FT_FONT_STYLE_NORMAL); + LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, haspFonts[6]); haspFonts[7] = hasp_font_load("L:/RobotoCondensedRegular.bin"); + LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, haspFonts[7]); #endif +*/ hasp_set_theme(haspThemeId); diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp index 74905946..e4c6a0bb 100644 --- a/src/hasp/hasp_attribute.cpp +++ b/src/hasp/hasp_attribute.cpp @@ -228,46 +228,51 @@ static bool my_line_set_points(lv_obj_t* obj, const char* payload) static lv_font_t* haspPayloadToFont(const char* payload) { - uint8_t var = atoi(payload); + if(Parser::is_only_digits(payload)) { + uint8_t var = atoi(payload); - switch(var) { - case 0 ... 7: - // LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, robotocondensed_regular_12); - return hasp_get_font(var); + switch(var) { + case 0 ... 7: + return hasp_get_font(var); - case 8: - return &unscii_8_icon; + case 8: + return &unscii_8_icon; #ifndef ARDUINO_ARCH_ESP8266 #ifdef HASP_FONT_1 - case HASP_FONT_SIZE_1: - return &HASP_FONT_1; + case HASP_FONT_SIZE_1: + return &HASP_FONT_1; #endif #ifdef HASP_FONT_2 - case HASP_FONT_SIZE_2: - LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_2); - return &HASP_FONT_2; + case HASP_FONT_SIZE_2: + LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_2); + return &HASP_FONT_2; #endif #ifdef HASP_FONT_3 - case HASP_FONT_SIZE_3: - LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_3); - return &HASP_FONT_3; + case HASP_FONT_SIZE_3: + LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_3); + return &HASP_FONT_3; #endif #ifdef HASP_FONT_4 - case HASP_FONT_SIZE_4: - LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_4); - return &HASP_FONT_4; + case HASP_FONT_SIZE_4: + LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, HASP_FONT_4); + return &HASP_FONT_4; #endif #endif - default: - return nullptr; + default: + return nullptr; + } + } else { + return get_font(payload); } + + return nullptr; } static hasp_attribute_type_t hasp_process_label_long_mode(lv_obj_t* obj, const char* payload, char** text, bool update) @@ -611,7 +616,7 @@ static hasp_attribute_type_t hasp_local_style_attr(lv_obj_t* obj, const char* at case ATTR_TEXT_FONT: { lv_font_t* font = haspPayloadToFont(payload); if(font) { - LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, *font); + LOG_WARNING(TAG_ATTR, "%s %d %x", __FILE__, __LINE__, font); uint8_t count = 3; if(obj_check_type(obj, LV_HASP_ROLLER)) count = my_roller_get_visible_row_count(obj); lv_obj_set_style_local_text_font(obj, part, state, font); diff --git a/src/hasp/hasp_font.cpp b/src/hasp/hasp_font.cpp new file mode 100644 index 00000000..df67fb53 --- /dev/null +++ b/src/hasp/hasp_font.cpp @@ -0,0 +1,115 @@ +#include + +#include "hasplib.h" +#include "lv_freetype.h" + +#include "hasp_mem.h" +#include "font/hasp_font_loader.h" + +static lv_ll_t hasp_fonts_ll; + +typedef struct +{ + const char* name; /* The name of the font file */ + lv_font_t* font; /* point to lvgl font */ +} hasp_font_info_t; + +void font_setup() +{ + _lv_ll_init(&hasp_fonts_ll, sizeof(lv_ft_info_t)); +} + +size_t font_split_payload(const char* payload) +{ + size_t pos = 0; + while(*(payload + pos) != '\0') { + if(Parser::is_only_digits(payload + pos)) return pos; + pos++; + } + return 0; +} + +static lv_font_t* font_find_in_list(const char* payload) +{ + hasp_font_info_t* font_p = (hasp_font_info_t*)_lv_ll_get_head(&hasp_fonts_ll); + while(font_p) { + if(strcmp(font_p->name, payload) == 0) { + return font_p->font; + } + font_p = (hasp_font_info_t*)_lv_ll_get_next(&hasp_fonts_ll, font_p); + } + + return NULL; +} + +static lv_font_t* font_add_to_list(const char* payload) +{ + char filename[64]; + + // Try .bin file + snprintf_P(filename, sizeof(filename), PSTR("L:\\%s.bin"), payload); + lv_font_t* font = hasp_font_load(filename); + char* name_p = NULL; + + if(!font) { + // Try .ttf file + + size_t pos = font_split_payload(payload); + if(pos > 0 && pos < 56) { + uint16_t size = atoi(payload + pos); + + char fontname[64]; + memset(fontname, 0, sizeof(fontname)); + strncpy(fontname, payload, pos); + snprintf_P(filename, sizeof(filename), PSTR("L:\\%s.ttf"), fontname); + + lv_ft_info_t info; + info.name = filename; + info.weight = size; + info.style = FT_FONT_STYLE_NORMAL; + if(lv_ft_font_init(&info)) { + font = info.font; + } + } + } + + if(!font) { + // Try .otf file + snprintf_P(filename, sizeof(filename), PSTR("L:\\%s.otf"), payload); + + lv_ft_info_t info; + info.name = filename; + info.weight = 56; + info.style = FT_FONT_STYLE_NORMAL; + if(lv_ft_font_init(&info)) { + font = info.font; + } + } + + if(!font) return NULL; + LOG_VERBOSE(TAG_FONT, F("Loaded font %s size %d"), filename, font->line_height); + + size_t len = strlen(payload); + name_p = (char*)calloc(sizeof(char), len + 1); + if(!name_p) return NULL; + strncpy(name_p, payload, len); + + hasp_font_info_t info; + info.name = name_p; + info.font = font; + + hasp_font_info_t* info_p; + info_p = (hasp_font_info_t*)_lv_ll_ins_tail(&hasp_fonts_ll); + *info_p = info; + + return info.font; +} + +// Convert the payload to a font pointer +lv_font_t* get_font(const char* payload) +{ + lv_font_t* font = font_find_in_list(payload); + if(font) return font; + + return font_add_to_list(payload); +} diff --git a/src/hasp/hasp_font.h b/src/hasp/hasp_font.h new file mode 100644 index 00000000..015944e2 --- /dev/null +++ b/src/hasp/hasp_font.h @@ -0,0 +1,10 @@ +/* MIT License - Copyright (c) 2019-2021 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifndef HASP_FONT_H +#define HASP_FONT_H + +void font_setup(); +lv_font_t* get_font(const char* payload); + +#endif \ No newline at end of file diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index ea72bb8a..fb68e1a8 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -298,8 +298,9 @@ void guiSetup() LOG_TRACE(TAG_LVGL, F(D_SERVICE_STARTING)); gui_init_lvgl(); gui_init_images(); - gui_init_freetype(); gui_init_filesystems(); + gui_init_freetype(); + font_setup(); /* Initialize the LVGL display driver with correct orientation */ #if(TOUCH_DRIVER == 0x2046) || defined(LGFX_USE_V1) // Use native display driver to rotate display and touch diff --git a/src/hasplib.h b/src/hasplib.h index 793ea762..4bcd3aea 100644 --- a/src/hasplib.h +++ b/src/hasplib.h @@ -20,6 +20,7 @@ #include "hasp/hasp_attribute.h" #include "hasp/hasp_dispatch.h" #include "hasp/hasp_event.h" +#include "hasp/hasp_font.h" #include "hasp/hasp_object.h" #include "hasp/hasp_page.h" #include "hasp/hasp_parser.h"