From 621ab97deaf0adc18de0322d34c9ca3e491fdf44 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 5 Jul 2021 18:51:55 +0200 Subject: [PATCH] lv_freetype patch #10 --- .../lv_lib_freetype/lv_freetype.c | 582 +++++++++--------- .../lv_lib_freetype/lv_freetype.h | 49 +- 2 files changed, 303 insertions(+), 328 deletions(-) diff --git a/lib/libesp32_lvgl/lv_lib_freetype/lv_freetype.c b/lib/libesp32_lvgl/lv_lib_freetype/lv_freetype.c index 3c00d8b65..1eba378d1 100644 --- a/lib/libesp32_lvgl/lv_lib_freetype/lv_freetype.c +++ b/lib/libesp32_lvgl/lv_lib_freetype/lv_freetype.c @@ -6,43 +6,12 @@ /********************* * INCLUDES *********************/ - #include "lv_freetype.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "freertos/task.h" - -#if CONFIG_FREERTOS_UNICORE -#define ARDUINO_RUNNING_CORE 0 -#else -#define ARDUINO_RUNNING_CORE 1 -#endif - -/* - * FreeType requires up to 32KB of stack to run, which overflows the stack of 8KB. - * - * We delegate to a FreeRTOS sub-task with a bigger stack. - * - * Parameters are passed via a RequestQueue, and response back via ResponseQueue - * - * The function that uses this scheme is `get_glyph_dsc_cb()`` - * - */ - -QueueHandle_t FTRequestQueue; -QueueHandle_t FTResponseQueue; -TaskHandle_t FTTaskHandle; -void FT_loop_task(void *pvParameters); - -typedef struct FT_glyph_dsc_request { - const lv_font_t * font; - lv_font_glyph_dsc_t * dsc_out; - uint32_t unicode_letter; - uint32_t unicode_letter_next; -} FT_glyph_dsc_request; - -typedef bool FT_glyph_dsc_response; - +#include "ft2build.h" +#include FT_FREETYPE_H +#include FT_GLYPH_H +#include FT_CACHE_H +#include FT_SIZES_H /********************* * DEFINES @@ -51,38 +20,58 @@ typedef bool FT_glyph_dsc_response; /********************** * TYPEDEFS **********************/ +typedef struct { + char * name; +} lv_face_info_t; + +typedef struct { + lv_ll_t face_ll; +} lv_faces_control_t; + +typedef struct { +#if LV_USE_FT_CACHE_MANAGER + void * face_id; +#else + FT_Size size; +#endif + lv_font_t * font; + uint16_t style; + uint16_t height; +} lv_font_fmt_ft_dsc_t; /********************** * STATIC PROTOTYPES **********************/ -static FT_Face face_find_in_list(lv_ft_info_t *info); -static void face_add_to_list(FT_Face face); -static void face_remove_from_list(FT_Face face); - -static void face_generic_finalizer(void* object); -static bool get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, - uint32_t unicode_letter, uint32_t unicode_letter_next); -static const uint8_t * get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter); - #if LV_USE_FT_CACHE_MANAGER static FT_Error font_face_requester(FTC_FaceID face_id, - FT_Library library_is,FT_Pointer req_data,FT_Face* aface); + FT_Library library_is, FT_Pointer req_data, FT_Face * aface); +static bool lv_ft_font_init_cache(lv_ft_info_t * info); +static void lv_ft_font_destroy_cache(lv_font_t * font); +static bool lv_ft_font_init_cache(lv_ft_info_t * info); +static void lv_ft_font_destroy_cache(lv_font_t * font); +#else +static FT_Face face_find_in_list(lv_ft_info_t * info); +static void face_add_to_list(FT_Face face); +static void face_remove_from_list(FT_Face face); +static void face_generic_finalizer(void * object); +static bool lv_ft_font_init_nocache(lv_ft_info_t * info); +static void lv_ft_font_destroy_nocache(lv_font_t * font); #endif - /********************** - * STATIC VARIABLES - **********************/ +/********************** +* STATIC VARIABLES +**********************/ static FT_Library library; #if LV_USE_FT_CACHE_MANAGER -static FTC_Manager cache_manager; -static FTC_CMapCache cmap_cache; -static FTC_SBitCache sbit_cache; -static FTC_SBit sbit; + static FTC_Manager cache_manager; + static FTC_CMapCache cmap_cache; + static FTC_SBitCache sbit_cache; + static FTC_SBit sbit; +#else + static lv_faces_control_t face_control; #endif -static lv_faces_control_t face_control; - /********************** * MACROS **********************/ @@ -90,22 +79,18 @@ static lv_faces_control_t face_control; /********************** * GLOBAL FUNCTIONS **********************/ -bool lv_freetype_init(FT_UInt max_faces, FT_UInt max_sizes, FT_ULong max_bytes) +bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes) { - face_control.cnt = 0; - face_control.num = max_faces; - _lv_ll_init(&face_control.face_ll, sizeof(FT_Face *)); - FT_Error error = FT_Init_FreeType(&library); - if (error) { + if(error) { LV_LOG_ERROR("init freeType error(%d)", error); return false; } #if LV_USE_FT_CACHE_MANAGER error = FTC_Manager_New(library, max_faces, max_sizes, - max_bytes, font_face_requester, NULL, &cache_manager); - if (error) { + max_bytes, font_face_requester, NULL, &cache_manager); + if(error) { FT_Done_FreeType(library); LV_LOG_ERROR("Failed to open cache manager"); return false; @@ -118,27 +103,21 @@ bool lv_freetype_init(FT_UInt max_faces, FT_UInt max_sizes, FT_ULong max_bytes) } error = FTC_SBitCache_New(cache_manager, &sbit_cache); - if(error){ + if(error) { LV_LOG_ERROR("Failed to open sbit cache"); goto Fail; } - // initialize the queues to send request and receive response - FTRequestQueue = xQueueCreate(1, sizeof(FT_glyph_dsc_request)); - FTResponseQueue = xQueueCreate(1, sizeof(FT_glyph_dsc_response)); - - xTaskCreatePinnedToCore(FT_loop_task, "FreeType_task", LV_USE_FT_STACK_SIZE, NULL, 1, &FTTaskHandle, ARDUINO_RUNNING_CORE); - - if (FTRequestQueue && FTResponseQueue) { - return true; - } + return true; Fail: FTC_Manager_Done(cache_manager); FT_Done_FreeType(library); return false; #else + LV_UNUSED(max_faces); LV_UNUSED(max_sizes); LV_UNUSED(max_bytes); + _lv_ll_init(&face_control.face_ll, sizeof(FT_Face *)); return true; #endif/* LV_USE_FT_CACHE_MANAGER */ } @@ -151,168 +130,46 @@ void lv_freetype_destroy(void) FT_Done_FreeType(library); } -bool lv_ft_font_init(lv_ft_info_t *info) +bool lv_ft_font_init(lv_ft_info_t * info) { - lv_font_fmt_ft_dsc_t * dsc = lv_mem_alloc(sizeof(lv_font_fmt_ft_dsc_t)); - if(dsc == NULL) return false; - - dsc->font = lv_mem_alloc(sizeof(lv_font_t)); - if(dsc->font == NULL) { - lv_mem_free(dsc); - return false; - } - - lv_face_info_t *face_info = NULL; - FT_Face face = face_find_in_list(info); - if (face == NULL) { - if (face_control.cnt == face_control.num - 1) { - LV_LOG_WARN("face full"); - goto Fail; - } - face_info = lv_mem_alloc(sizeof(lv_face_info_t) + strlen(info->name) + 1); - if(face_info == NULL) { - goto Fail; - } - FT_Error error = FT_New_Face(library, info->name, 0, &face); - if(error){ - lv_mem_free(face_info); - LV_LOG_WARN("create face error(%d)", error); - goto Fail; - } - - face_info->name = ((char *)face_info) + sizeof(lv_face_info_t); - strcpy(face_info->name, info->name); - face_info->cnt = 1; - face->generic.data = face_info; - face->generic.finalizer = face_generic_finalizer; - face_add_to_list(face); - } - else { -#if LV_USE_FT_CACHE_MANAGER == 0 - FT_Size size; - FT_Error error = FT_New_Size(face, &size); - if (error) { - goto Fail; - } - FT_Activate_Size(size); - FT_Reference_Face(face); +#if LV_USE_FT_CACHE_MANAGER + return lv_ft_font_init_cache(info); #else - face_info = (lv_face_info_t *)face->generic.data; - face_info->cnt++; + return lv_ft_font_init_nocache(info); #endif - } - FT_Set_Pixel_Sizes(face, 0, info->weight); - - dsc->face = face; - dsc->size = face->size; - dsc->weight = info->weight; - dsc->style = info->style; - lv_font_t *font = dsc->font; - font->user_data = dsc; - font->get_glyph_dsc = get_glyph_dsc_cb; - font->get_glyph_bitmap = get_glyph_bitmap_cb; - font->line_height = (dsc->face->size->metrics.height >> 6); - font->base_line = -(dsc->face->size->metrics.descender >> 6); - font->subpx = LV_FONT_SUBPX_NONE; - font->underline_position = dsc->face->underline_position; - font->underline_thickness = dsc->face->underline_thickness; - font->dsc = NULL; - info->font = font; - return true; - -Fail: - lv_mem_free(dsc->font); - lv_mem_free(dsc); - return false; } -void lv_ft_font_destroy(lv_font_t* font) +void lv_ft_font_destroy(lv_font_t * font) { - if (font == NULL) { - return; - } - - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->user_data); - if (dsc) { -#if LV_USE_FT_CACHE_MANAGER == 0 - FT_Done_Size(dsc->size); - FT_Done_Face(dsc->face); +#if LV_USE_FT_CACHE_MANAGER + lv_ft_font_destroy_cache(font); #else - lv_face_info_t *face_info = (lv_face_info_t *)dsc->face->generic.data; - face_info->cnt--; - if(face_info->cnt == 0){ - FTC_Manager_RemoveFaceID(cache_manager, (FTC_FaceID)dsc->face); - } + lv_ft_font_destroy_nocache(font); #endif - lv_mem_free(dsc->font); - lv_mem_free(dsc); - } } /********************** * STATIC FUNCTIONS **********************/ -static void face_generic_finalizer(void* object) -{ - FT_Face face = (FT_Face)object; - face_remove_from_list(face); - if(face->generic.data){ - lv_face_info_t *face_info = (lv_face_info_t *)face->generic.data; - lv_mem_free(face_info); - } - LV_LOG_INFO("face finalizer(%p)\n", face); -} - -static FT_Face face_find_in_list(lv_ft_info_t *info) -{ - lv_face_info_t *face_info; - FT_Face *pface = _lv_ll_get_head(&face_control.face_ll); - while(pface) { - face_info = (lv_face_info_t *)(*pface)->generic.data; - if (strcmp(face_info->name, info->name) == 0) { - return *pface; - } - pface = _lv_ll_get_next(&face_control.face_ll, pface); - } - - return NULL; -} - -static void face_add_to_list(FT_Face face) -{ - FT_Face *pface; - pface = (FT_Face *)_lv_ll_ins_tail(&face_control.face_ll); - *pface = face; - face_control.cnt++; -} - -static void face_remove_from_list(FT_Face face) -{ - FT_Face *pface = _lv_ll_get_head(&face_control.face_ll); - while(pface) { - if (*pface == face) { - _lv_ll_remove(&face_control.face_ll, pface); - lv_mem_free(pface); - face_control.cnt--; - break; - } - pface = _lv_ll_get_next(&face_control.face_ll, pface); - } -} - #if LV_USE_FT_CACHE_MANAGER static FT_Error font_face_requester(FTC_FaceID face_id, - FT_Library library_is,FT_Pointer req_data,FT_Face* aface) + FT_Library library_is, FT_Pointer req_data, FT_Face * aface) { LV_UNUSED(library_is); LV_UNUSED(req_data); - *aface = face_id; + + lv_face_info_t * info = (lv_face_info_t *)face_id; + FT_Error error = FT_New_Face(library, info->name, 0, aface); + if(error) { + LV_LOG_ERROR("FT_New_Face error:%d\n", error); + return error; + } return FT_Err_Ok; } -static bool get_glyph_dsc_cb_cache(const lv_font_t * font, - lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) +static bool get_glyph_dsc_cb_cache(const lv_font_t * font, + lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { LV_UNUSED(unicode_letter_next); if(unicode_letter < 0x20) { @@ -325,17 +182,23 @@ static bool get_glyph_dsc_cb_cache(const lv_font_t * font, return true; } - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->user_data); - FT_Face face = dsc->face; + lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); - static FTC_ImageTypeRec desc_sbit_type; - desc_sbit_type.face_id = (FTC_FaceID)face; + FT_Face face; + FTC_ImageTypeRec desc_sbit_type; + FTC_FaceID face_id = (FTC_FaceID)dsc->face_id; + FTC_Manager_LookupFace(cache_manager, face_id, &face); + + desc_sbit_type.face_id = face_id; desc_sbit_type.flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL; - desc_sbit_type.height = dsc->weight; - desc_sbit_type.width = dsc->weight; + desc_sbit_type.height = dsc->height; + desc_sbit_type.width = dsc->height; FT_UInt charmap_index = FT_Get_Charmap_Index(face->charmap); - FT_UInt glyph_index = FTC_CMapCache_Lookup(cmap_cache, (FTC_FaceID)face, charmap_index, unicode_letter); + FT_UInt glyph_index = FTC_CMapCache_Lookup(cmap_cache, face_id, charmap_index, unicode_letter); FT_Error error = FTC_SBitCache_Lookup(sbit_cache, &desc_sbit_type, glyph_index, &sbit, NULL); + if(error) { + LV_LOG_ERROR("SBitCache_Lookup error"); + } dsc_out->adv_w = sbit->xadvance; dsc_out->box_h = sbit->height; /*Height of the bitmap in [px]*/ @@ -354,13 +217,129 @@ static const uint8_t * get_glyph_bitmap_cb_cache(const lv_font_t * font, uint32_ return (const uint8_t *)sbit->buffer; } -#else/* LV_USE_FT_CACHE_MANAGER */ -// extern void berry_log_C(const char * berry_buf, ...); - -static bool get_glyph_dsc_cb_nocache(const lv_font_t * font, - lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) +static bool lv_ft_font_init_cache(lv_ft_info_t * info) +{ + lv_font_fmt_ft_dsc_t * dsc = lv_mem_alloc(sizeof(lv_font_fmt_ft_dsc_t)); + if(dsc == NULL) return false; + + dsc->font = lv_mem_alloc(sizeof(lv_font_t)); + if(dsc->font == NULL) { + lv_mem_free(dsc); + return false; + } + + lv_face_info_t * face_info = NULL; + face_info = lv_mem_alloc(sizeof(lv_face_info_t) + strlen(info->name) + 1); + if(face_info == NULL) { + goto Fail; + } + face_info->name = ((char *)face_info) + sizeof(lv_face_info_t); + strcpy(face_info->name, info->name); + + dsc->face_id = face_info; + dsc->height = info->weight; + dsc->style = info->style; + + /* use to get font info */ + FT_Size face_size; + struct FTC_ScalerRec_ scaler; + scaler.face_id = (FTC_FaceID)dsc->face_id; + scaler.width = info->weight; + scaler.height = info->weight; + scaler.pixel = 1; + FT_Error error = FTC_Manager_LookupSize(cache_manager, &scaler, &face_size); + if(error) { + lv_mem_free(face_info); + LV_LOG_ERROR("Failed to LookupSize"); + goto Fail; + } + + lv_font_t * font = dsc->font; + font->dsc = dsc; + font->get_glyph_dsc = get_glyph_dsc_cb_cache; + font->get_glyph_bitmap = get_glyph_bitmap_cb_cache; + font->subpx = LV_FONT_SUBPX_NONE; + font->line_height = (face_size->face->size->metrics.height >> 6); + font->base_line = -(face_size->face->size->metrics.descender >> 6); + font->underline_position = face_size->face->underline_position; + font->underline_thickness = face_size->face->underline_thickness; + + /* return to user */ + info->font = font; + + return true; + +Fail: + lv_mem_free(dsc->font); + lv_mem_free(dsc); + return false; +} + +void lv_ft_font_destroy_cache(lv_font_t * font) +{ + if(font == NULL) { + return; + } + + lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); + if(dsc) { + lv_mem_free(dsc->face_id); + lv_mem_free(dsc->font); + lv_mem_free(dsc); + } +} + +#else/* LV_USE_FT_CACHE_MANAGER */ + +static FT_Face face_find_in_list(lv_ft_info_t * info) +{ + lv_face_info_t * face_info; + FT_Face * pface = _lv_ll_get_head(&face_control.face_ll); + while(pface) { + face_info = (lv_face_info_t *)(*pface)->generic.data; + if(strcmp(face_info->name, info->name) == 0) { + return *pface; + } + pface = _lv_ll_get_next(&face_control.face_ll, pface); + } + + return NULL; +} + +static void face_add_to_list(FT_Face face) +{ + FT_Face * pface; + pface = (FT_Face *)_lv_ll_ins_tail(&face_control.face_ll); + *pface = face; +} + +static void face_remove_from_list(FT_Face face) +{ + FT_Face * pface = _lv_ll_get_head(&face_control.face_ll); + while(pface) { + if(*pface == face) { + _lv_ll_remove(&face_control.face_ll, pface); + lv_mem_free(pface); + break; + } + pface = _lv_ll_get_next(&face_control.face_ll, pface); + } +} + +static void face_generic_finalizer(void * object) +{ + FT_Face face = (FT_Face)object; + face_remove_from_list(face); + if(face->generic.data) { + lv_face_info_t * face_info = (lv_face_info_t *)face->generic.data; + lv_mem_free(face_info); + } + LV_LOG_INFO("face finalizer(%p)\n", face); +} + +static bool get_glyph_dsc_cb_nocache(const lv_font_t * font, + lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { - // berry_log_C(">> get_glyph_dsc_cb_nocache %i %i", unicode_letter, unicode_letter_next); LV_UNUSED(unicode_letter_next); if(unicode_letter < 0x20) { dsc_out->adv_w = 0; @@ -373,26 +352,22 @@ static bool get_glyph_dsc_cb_nocache(const lv_font_t * font, } FT_Error error; - FT_Face face; - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->user_data); - face = dsc->face; + lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); + FT_Face face = dsc->size->face; - FT_UInt glyph_index = FT_Get_Char_Index( face, unicode_letter ); + FT_UInt glyph_index = FT_Get_Char_Index(face, unicode_letter); - if (face->size != dsc->size) { - // berry_log_C(">> FT_Activate_Size %i", dsc->size); + if(face->size != dsc->size) { FT_Activate_Size(dsc->size); } - error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT ); - // berry_log_C(">> after FT_Load_Glyph error = %i", error); - if (error){ + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); + if(error) { return false; } - error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL); - // berry_log_C(">> after FT_Render_Glyph error = %i", error); - if (error){ + error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); + if(error) { return false; } @@ -400,70 +375,101 @@ static bool get_glyph_dsc_cb_nocache(const lv_font_t * font, dsc_out->box_h = face->glyph->bitmap.rows; /*Height of the bitmap in [px]*/ dsc_out->box_w = face->glyph->bitmap.width; /*Width of the bitmap in [px]*/ dsc_out->ofs_x = face->glyph->bitmap_left; /*X offset of the bitmap in [pf]*/ - dsc_out->ofs_y = face->glyph->bitmap_top - face->glyph->bitmap.rows; /*Y offset of the bitmap measured from the as line*/ + dsc_out->ofs_y = face->glyph->bitmap_top - + face->glyph->bitmap.rows; /*Y offset of the bitmap measured from the as line*/ dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/ - // berry_log_C("+++ adv_w %i, h %i, w %i, x %i, y %i", dsc_out->adv_w, dsc_out->box_h, dsc_out->box_w, dsc_out->ofs_x, dsc_out->ofs_y); - return true; } static const uint8_t * get_glyph_bitmap_cb_nocache(const lv_font_t * font, uint32_t unicode_letter) { LV_UNUSED(unicode_letter); - lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->user_data); - FT_Face face = dsc->face; + lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); + FT_Face face = dsc->size->face; return (const uint8_t *)(face->glyph->bitmap.buffer); } -#endif/* LV_USE_FT_CACHE_MANAGER */ - -static bool get_glyph_dsc_cb(const lv_font_t * font, - lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) +static bool lv_ft_font_init_nocache(lv_ft_info_t * info) { -// #if LV_USE_FT_CACHE_MANAGER -// return get_glyph_dsc_cb_cache(font, dsc_out, unicode_letter, unicode_letter_next); -// #else -// return get_glyph_dsc_cb_nocache(font, dsc_out, unicode_letter, unicode_letter_next); -// #endif - static FT_glyph_dsc_request request; - static FT_glyph_dsc_response response; + lv_font_fmt_ft_dsc_t * dsc = lv_mem_alloc(sizeof(lv_font_fmt_ft_dsc_t)); + if(dsc == NULL) return false; - request.font = font; - request.dsc_out = dsc_out; - request.unicode_letter = unicode_letter; - request.unicode_letter_next = unicode_letter_next; - xQueueSendToBack(FTRequestQueue, &request, portMAX_DELAY); - if (xQueueReceive(FTResponseQueue, &response, portMAX_DELAY)) { - return response; - } else { - return false; // should never happen + dsc->font = lv_mem_alloc(sizeof(lv_font_t)); + if(dsc->font == NULL) { + lv_mem_free(dsc); + return false; } -} -static const uint8_t * get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter) -{ -#if LV_USE_FT_CACHE_MANAGER - return get_glyph_bitmap_cb_cache(font, unicode_letter); -#else - return get_glyph_bitmap_cb_nocache(font, unicode_letter); -#endif -} - -void FT_loop_task(void *pvParameters) { - (void) pvParameters; - - while (1) { - FT_glyph_dsc_request request; - FT_glyph_dsc_response response; - - if (xQueueReceive(FTRequestQueue, &request, portMAX_DELAY)) { - #if LV_USE_FT_CACHE_MANAGER - response = get_glyph_dsc_cb_cache(request.font, request.dsc_out, request.unicode_letter, request.unicode_letter_next); - #else - response = get_glyph_dsc_cb_nocache(request.font, request.dsc_out, request.unicode_letter, request.unicode_letter_next); - #endif - xQueueSendToBack(FTResponseQueue, &response, portMAX_DELAY); // send back response + lv_face_info_t * face_info = NULL; + FT_Face face = face_find_in_list(info); + if(face == NULL) { + face_info = lv_mem_alloc(sizeof(lv_face_info_t) + strlen(info->name) + 1); + if(face_info == NULL) { + goto Fail; } + FT_Error error = FT_New_Face(library, info->name, 0, &face); + if(error) { + lv_mem_free(face_info); + LV_LOG_WARN("create face error(%d)", error); + goto Fail; + } + + /* link face and face info */ + face_info->name = ((char *)face_info) + sizeof(lv_face_info_t); + strcpy(face_info->name, info->name); + face->generic.data = face_info; + face->generic.finalizer = face_generic_finalizer; + face_add_to_list(face); } -} \ No newline at end of file + else { + FT_Size size; + FT_Error error = FT_New_Size(face, &size); + if(error) { + goto Fail; + } + FT_Activate_Size(size); + FT_Reference_Face(face); + } + + FT_Set_Pixel_Sizes(face, 0, info->weight); + dsc->size = face->size; + dsc->height = info->weight; + dsc->style = info->style; + + lv_font_t * font = dsc->font; + font->dsc = dsc; + font->get_glyph_dsc = get_glyph_dsc_cb_nocache; + font->get_glyph_bitmap = get_glyph_bitmap_cb_nocache; + font->line_height = (face->size->metrics.height >> 6); + font->base_line = -(face->size->metrics.descender >> 6); + font->underline_position = face->underline_position; + font->underline_thickness = face->underline_thickness; + font->subpx = LV_FONT_SUBPX_NONE; + + info->font = font; + return true; + +Fail: + lv_mem_free(dsc->font); + lv_mem_free(dsc); + return false; +} + +static void lv_ft_font_destroy_nocache(lv_font_t * font) +{ + if(font == NULL) { + return; + } + + lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); + if(dsc) { + FT_Face face = dsc->size->face; + FT_Done_Size(dsc->size); + FT_Done_Face(face); + lv_mem_free(dsc->font); + lv_mem_free(dsc); + } +} + +#endif/* LV_USE_FT_CACHE_MANAGER */ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lv_lib_freetype/lv_freetype.h b/lib/libesp32_lvgl/lv_lib_freetype/lv_freetype.h index 1b419b99a..b8d147c57 100644 --- a/lib/libesp32_lvgl/lv_lib_freetype/lv_freetype.h +++ b/lib/libesp32_lvgl/lv_lib_freetype/lv_freetype.h @@ -2,8 +2,8 @@ * @file lv_freetype.h * */ -#ifndef _LV_FONT_TTF_H -#define _LV_FONT_TTF_H +#ifndef LV_FONT_FREETYPE_H +#define LV_FONT_FREETYPE_H #ifdef __cplusplus extern "C" { @@ -12,37 +12,16 @@ extern "C" { /********************* * INCLUDES *********************/ -// #include "lvgl/lvgl.h" // TODO #include "lvgl.h" -#include "ft2build.h" -#include FT_FREETYPE_H -#include FT_GLYPH_H -#include FT_CACHE_H -#include FT_SIZES_H /********************* * DEFINES *********************/ -#ifndef LV_USE_FT_CACHE_MANAGER -#define LV_USE_FT_CACHE_MANAGER 0 -#endif - -#define LV_USE_FT_STACK_SIZE 24*1024 // FreeType consumes a large amount of stack +#define LV_USE_FT_CACHE_MANAGER 1 /********************** * TYPEDEFS **********************/ -typedef struct { - uint16_t cnt; - char* name; -} lv_face_info_t; - -typedef struct { - uint16_t num; - uint16_t cnt; - lv_ll_t face_ll; -} lv_faces_control_t; - typedef enum { FT_FONT_STYLE_NORMAL = 0, FT_FONT_STYLE_ITALIC = 1 << 0, @@ -50,22 +29,12 @@ typedef enum { } LV_FT_FONT_STYLE; typedef struct { - const char* name; /* The name of the font file */ - lv_font_t* font; /* point to lvgl font */ + const char * name; /* The name of the font file */ + lv_font_t * font; /* point to lvgl font */ uint16_t weight; /* font size */ uint16_t style; /* font style */ } lv_ft_info_t; -typedef struct { - FT_Face face; - FT_Size size; - lv_font_t* font; - uint16_t style; - uint16_t weight; -} lv_font_fmt_freetype_dsc_t; - -typedef lv_font_fmt_freetype_dsc_t lv_font_fmt_ft_dsc_t; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -78,7 +47,7 @@ typedef lv_font_fmt_freetype_dsc_t lv_font_fmt_ft_dsc_t; * Note that this value does not account for managed FT_Face and FT_Size objects. * @return true on success, otherwise false. */ -bool lv_freetype_init(FT_UInt max_faces, FT_UInt max_sizes, FT_ULong max_bytes); +bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes); /** * Destroy freetype library @@ -91,13 +60,13 @@ void lv_freetype_destroy(void); * when success, lv_ft_info_t->font point to the font you created. * @return true on success, otherwise false. */ -bool lv_ft_font_init(lv_ft_info_t *info); +bool lv_ft_font_init(lv_ft_info_t * info); /** * Destroy a font that has been created. * @param font pointer to font. */ -void lv_ft_font_destroy(lv_font_t* font); +void lv_ft_font_destroy(lv_font_t * font); /********************** * MACROS @@ -107,4 +76,4 @@ void lv_ft_font_destroy(lv_font_t* font); } /* extern "C" */ #endif -#endif +#endif /* LV_FONT_FREETYPE_H */ \ No newline at end of file