Просмотр исходного кода

add:lvgl添加外部加载bin字体文件

Dozingfiretruck 3 месяцев назад
Родитель
Сommit
72d2940c77

+ 3 - 0
components/lvgl/binding/luat_lib_lvgl.c

@@ -1339,6 +1339,9 @@ LUAT_LV_EX_RLT
 {"font_load", ROREG_FUNC(luat_lv_font_load)},
 {"font_free", ROREG_FUNC(luat_lv_font_free)},
 
+{"font_load_ex", ROREG_FUNC(luat_lv_font_load_ex)},
+{"font_free_ex", ROREG_FUNC(luat_lv_font_free_ex)},
+
 // 结构体
 #if LV_USE_ANIMATION
 {"anim_t", ROREG_FUNC(luat_lv_struct_anim_t)},

+ 32 - 1
components/lvgl/binding/luat_lib_lvgl_font.c

@@ -9,7 +9,7 @@
 #include "luat_lvgl.h"
 #include "lvgl.h"
 #include "luat_mem.h"
-
+#include "luat_fs.h"
 #include "luat_lvgl_fonts.h"
 #include "luat_spi.h"
 
@@ -175,3 +175,34 @@ int luat_lv_font_free(lua_State *L) {
     }
     return 0;
 }
+
+int luat_lv_font_load_ex(lua_State *L) {
+    lv_font_t *font = NULL;
+    if (lua_isstring(L, 1)) {
+        const char* font_path = luaL_checkstring(L, 1);
+        FILE* font_file = luat_fs_fopen(font_path, "rb");
+        if (font_file == NULL) {
+            LLOGE("open font file fail %s", font_path);
+            return 0;
+        }
+        extern lv_font_t* custom_get_font(FILE* font_file);
+        font = custom_get_font(font_file);
+        if (!font) {
+            LLOGE("从文件加载lvgl字体 %s 失败", font_path);
+        }
+    }
+    if (font) {
+        lua_pushlightuserdata(L, font);
+        return 1;
+    }
+    return 0;
+}
+
+int luat_lv_font_free_ex(lua_State *L) {
+    lv_font_t* font = lua_touserdata(L, 1);
+    if (font) {
+        extern void custom_free_font(lv_font_t* custom_font);
+        custom_free_font(font);
+    }
+    return 0;
+}

+ 3 - 0
components/lvgl/binding/luat_lvgl_font.h

@@ -6,5 +6,8 @@ int luat_lv_font_get(lua_State *L);
 int luat_lv_font_load(lua_State *L);
 int luat_lv_font_free(lua_State *L);
 
+int luat_lv_font_load_ex(lua_State *L);
+int luat_lv_font_free_ex(lua_State *L);
+
 #define LUAT_LV_FONT_EX_RLT 
 

+ 162 - 0
components/lvgl/font/lv_font_ex.c

@@ -0,0 +1,162 @@
+
+/*******************************************************************************
+ * tool: lvgl_conv_tool V1.0.1
+ * author: Dozingfiretruck
+ * author_github_url: https://github.com/Dozingfiretruck
+ * author_gitee_url: https://gitee.com/Dozingfiretruck
+ * qq: 1041390013
+ ******************************************************************************/
+
+#ifdef __has_include
+    #if __has_include("lvgl.h")
+        #ifndef LV_LVGL_H_INCLUDE_SIMPLE
+            #define LV_LVGL_H_INCLUDE_SIMPLE
+        #endif
+    #endif
+#endif
+
+#ifdef LV_LVGL_H_INCLUDE_SIMPLE
+    #include "lvgl.h"
+#else
+    #include "lvgl/lvgl.h"
+#endif
+
+#include "luat_mem.h"
+#include "luat_fs.h"
+
+/*-----------------
+ *    STRUCT
+ *----------------*/
+
+typedef struct{
+    char head[5];
+    uint8_t bpp;
+    int8_t underline_position;
+    int8_t underline_thickness;
+    int16_t line_height;
+    int16_t base_line;
+    uint16_t codes_min;
+    uint16_t codes_max;
+}custom_font_header_t;
+
+typedef struct{
+    uint32_t adv_w;
+    uint16_t box_w;
+    uint16_t box_h;
+    int16_t ofs_x;
+    int16_t ofs_y;
+    uint32_t glyph_data_len;
+}custom_glyph_dsc_t;
+
+typedef struct{
+    custom_font_header_t custom_font_header;
+    FILE* font_file;
+    uint8_t glyph_data[2048];
+}custom_font_data_t;
+
+static void *custom_font_getdata(const lv_font_t * font, uint32_t offset, uint32_t size){
+    custom_font_data_t* custom_font_data = font->dsc;
+    FILE* font_file = custom_font_data->font_file;
+    uint8_t* glyph_data = custom_font_data->glyph_data;
+    memset(glyph_data, 0, sizeof(custom_font_data->glyph_data));
+    luat_fs_fseek(font_file, offset, SEEK_SET);
+    luat_fs_fread(glyph_data, 1, size, font_file);
+    return glyph_data;
+}
+
+/*-----------------
+ *  GET DSC
+ *----------------*/
+
+static bool custom_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) {
+    custom_font_data_t* custom_font_data = font->dsc;
+    custom_font_header_t* custom_font_header = &custom_font_data->custom_font_header;
+    bool is_tab = false;
+    if(unicode_letter == '\t') {
+        unicode_letter = ' ';
+        is_tab = true;
+    }
+    if( unicode_letter>custom_font_header->codes_max || unicode_letter<custom_font_header->codes_min ) {
+        return false;
+    }
+    uint32_t unicode_offset = sizeof(custom_font_header_t)+(unicode_letter-custom_font_header->codes_min)*sizeof(uint32_t);
+    uint32_t *p_pos = (uint32_t *)custom_font_getdata(font, unicode_offset, sizeof(uint32_t));
+    if(*p_pos) {
+        custom_glyph_dsc_t * gdsc = (custom_glyph_dsc_t*)custom_font_getdata(font, *p_pos, sizeof(custom_glyph_dsc_t));
+        dsc_out->box_h = gdsc->box_h;
+        dsc_out->box_w = gdsc->box_w;
+        dsc_out->ofs_x = gdsc->ofs_x;
+        dsc_out->ofs_y = gdsc->ofs_y;
+        dsc_out->bpp   = custom_font_header->bpp;
+
+        uint32_t adv_w = gdsc->adv_w;
+        if(is_tab) adv_w *= 2;
+        dsc_out->adv_w  = (adv_w + (1 << 3)) >> 4;
+        if(is_tab) dsc_out->box_w = dsc_out->box_w * 2;
+        return true;
+    }
+    return false;
+}
+
+/*-----------------
+ *  GET BITMAP
+ *----------------*/
+
+static const uint8_t* custom_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unicode_letter) {
+    custom_font_data_t* custom_font_data = font->dsc;
+    custom_font_header_t* custom_font_header = &custom_font_data->custom_font_header;
+    if(unicode_letter == '\t') unicode_letter = ' ';
+    if( unicode_letter>custom_font_header->codes_max || unicode_letter<custom_font_header->codes_min ) {
+        return NULL;
+    }
+    uint32_t unicode_offset = sizeof(custom_font_header_t )+(unicode_letter-custom_font_header->codes_min)*sizeof(uint32_t);
+    uint32_t *p_pos = (uint32_t *)custom_font_getdata(font, unicode_offset, sizeof(uint32_t));
+    uint32_t dsc_offset = p_pos[0];
+    if(dsc_offset) {
+        custom_glyph_dsc_t* gdsc = (custom_glyph_dsc_t*)custom_font_getdata(font, dsc_offset, sizeof(custom_glyph_dsc_t));
+        return custom_font_getdata(font, dsc_offset + sizeof(custom_glyph_dsc_t), gdsc->glyph_data_len);
+    }
+    return NULL;
+}
+
+/*-----------------
+ *  PUBLIC FONT
+ *----------------*/
+
+lv_font_t* custom_get_font(FILE* font_file){
+    lv_font_t* custom_font = luat_heap_malloc(sizeof(lv_font_t));
+    if (custom_font == NULL){
+        return NULL;
+    }
+    
+    memset(custom_font, 0, sizeof(lv_font_t));
+    custom_font->get_glyph_dsc = custom_font_get_glyph_dsc_fmt_txt;
+    custom_font->get_glyph_bitmap = custom_font_get_bitmap_fmt_txt;
+
+    custom_font_data_t* custom_font_data = luat_heap_malloc(sizeof(custom_font_data_t));
+    memset(custom_font_data, 0, sizeof(custom_font_data_t));
+    custom_font_data->font_file = font_file;
+    custom_font->dsc = custom_font_data;
+
+    uint32_t *p_pos = (uint32_t *)custom_font_getdata(custom_font, 0, sizeof(custom_font_header_t));
+    memcpy(&custom_font_data->custom_font_header, p_pos, sizeof(custom_font_header_t));
+    if (strncmp(custom_font_data->custom_font_header.head, "head", 4)){
+        luat_heap_free(custom_font);
+        return NULL;
+    }
+
+    custom_font->base_line = custom_font_data->custom_font_header.base_line;
+    custom_font->line_height = custom_font_data->custom_font_header.line_height;
+#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8
+    custom_font->underline_position = custom_font_data->custom_font_header.underline_position;
+    custom_font->underline_thickness = custom_font_data->custom_font_header.underline_thickness;
+#endif
+    return custom_font;
+}
+
+void custom_free_font(lv_font_t* custom_font){
+    if (custom_font){
+        luat_heap_free(custom_font->dsc);
+        luat_heap_free(custom_font);
+    }
+}