Merge pull request #13114 from arendst/revert-12569-lv_freetype_patch_10

Revert "lv_freetype patch #10"
This commit is contained in:
s-hadinger 2021-09-12 22:14:46 +02:00 committed by GitHub
commit 77857fd40c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 327 additions and 302 deletions

View File

@ -6,12 +6,43 @@
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
#include "lv_freetype.h" #include "lv_freetype.h"
#include "ft2build.h" #include "freertos/FreeRTOS.h"
#include FT_FREETYPE_H #include "freertos/queue.h"
#include FT_GLYPH_H #include "freertos/task.h"
#include FT_CACHE_H
#include FT_SIZES_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;
/********************* /*********************
* DEFINES * DEFINES
@ -20,42 +51,22 @@
/********************** /**********************
* TYPEDEFS * 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 PROTOTYPES
**********************/ **********************/
#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);
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 FT_Face face_find_in_list(lv_ft_info_t *info);
static void face_add_to_list(FT_Face face); static void face_add_to_list(FT_Face face);
static void face_remove_from_list(FT_Face face); static void face_remove_from_list(FT_Face face);
static void face_generic_finalizer(void* object); static void face_generic_finalizer(void* object);
static bool lv_ft_font_init_nocache(lv_ft_info_t * info); static bool get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out,
static void lv_ft_font_destroy_nocache(lv_font_t * font); 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);
#endif #endif
/********************** /**********************
@ -68,10 +79,10 @@ static FT_Library library;
static FTC_CMapCache cmap_cache; static FTC_CMapCache cmap_cache;
static FTC_SBitCache sbit_cache; static FTC_SBitCache sbit_cache;
static FTC_SBit sbit; static FTC_SBit sbit;
#else
static lv_faces_control_t face_control;
#endif #endif
static lv_faces_control_t face_control;
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/
@ -79,8 +90,12 @@ static FT_Library library;
/********************** /**********************
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes) bool lv_freetype_init(FT_UInt max_faces, FT_UInt max_sizes, FT_ULong 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); FT_Error error = FT_Init_FreeType(&library);
if (error) { if (error) {
LV_LOG_ERROR("init freeType error(%d)", error); LV_LOG_ERROR("init freeType error(%d)", error);
@ -108,16 +123,22 @@ bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes
goto Fail; 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: Fail:
FTC_Manager_Done(cache_manager); FTC_Manager_Done(cache_manager);
FT_Done_FreeType(library); FT_Done_FreeType(library);
return false; return false;
#else #else
LV_UNUSED(max_faces);
LV_UNUSED(max_sizes); LV_UNUSED(max_sizes);
LV_UNUSED(max_bytes); LV_UNUSED(max_bytes);
_lv_ll_init(&face_control.face_ll, sizeof(FT_Face *));
return true; return true;
#endif/* LV_USE_FT_CACHE_MANAGER */ #endif/* LV_USE_FT_CACHE_MANAGER */
} }
@ -131,93 +152,6 @@ void lv_freetype_destroy(void)
} }
bool lv_ft_font_init(lv_ft_info_t *info) bool lv_ft_font_init(lv_ft_info_t *info)
{
#if LV_USE_FT_CACHE_MANAGER
return lv_ft_font_init_cache(info);
#else
return lv_ft_font_init_nocache(info);
#endif
}
void lv_ft_font_destroy(lv_font_t * font)
{
#if LV_USE_FT_CACHE_MANAGER
lv_ft_font_destroy_cache(font);
#else
lv_ft_font_destroy_nocache(font);
#endif
}
/**********************
* STATIC FUNCTIONS
**********************/
#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)
{
LV_UNUSED(library_is);
LV_UNUSED(req_data);
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)
{
LV_UNUSED(unicode_letter_next);
if(unicode_letter < 0x20) {
dsc_out->adv_w = 0;
dsc_out->box_h = 0;
dsc_out->box_w = 0;
dsc_out->ofs_x = 0;
dsc_out->ofs_y = 0;
dsc_out->bpp = 0;
return true;
}
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc);
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->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, 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]*/
dsc_out->box_w = sbit->width; /*Width of the bitmap in [px]*/
dsc_out->ofs_x = sbit->left; /*X offset of the bitmap in [pf]*/
dsc_out->ofs_y = sbit->top - sbit->height; /*Y offset of the bitmap measured from the as line*/
dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/
return true;
}
static const uint8_t * get_glyph_bitmap_cb_cache(const lv_font_t * font, uint32_t unicode_letter)
{
LV_UNUSED(font);
LV_UNUSED(unicode_letter);
return (const uint8_t *)sbit->buffer;
}
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)); lv_font_fmt_ft_dsc_t * dsc = lv_mem_alloc(sizeof(lv_font_fmt_ft_dsc_t));
if(dsc == NULL) return false; if(dsc == NULL) return false;
@ -229,44 +163,61 @@ static bool lv_ft_font_init_cache(lv_ft_info_t * info)
} }
lv_face_info_t *face_info = NULL; 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); face_info = lv_mem_alloc(sizeof(lv_face_info_t) + strlen(info->name) + 1);
if(face_info == NULL) { if(face_info == NULL) {
goto Fail; goto Fail;
} }
face_info->name = ((char *)face_info) + sizeof(lv_face_info_t); FT_Error error = FT_New_Face(library, info->name, 0, &face);
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){ if(error){
lv_mem_free(face_info); lv_mem_free(face_info);
LV_LOG_ERROR("Failed to LookupSize"); LV_LOG_WARN("create face error(%d)", error);
goto Fail; 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);
#else
face_info = (lv_face_info_t *)face->generic.data;
face_info->cnt++;
#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; lv_font_t *font = dsc->font;
font->dsc = dsc; font->user_data = dsc;
font->get_glyph_dsc = get_glyph_dsc_cb_cache; font->get_glyph_dsc = get_glyph_dsc_cb;
font->get_glyph_bitmap = get_glyph_bitmap_cb_cache; 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->subpx = LV_FONT_SUBPX_NONE;
font->line_height = (face_size->face->size->metrics.height >> 6); font->underline_position = dsc->face->underline_position;
font->base_line = -(face_size->face->size->metrics.descender >> 6); font->underline_thickness = dsc->face->underline_thickness;
font->underline_position = face_size->face->underline_position; font->dsc = NULL;
font->underline_thickness = face_size->face->underline_thickness;
/* return to user */
info->font = font; info->font = font;
return true; return true;
Fail: Fail:
@ -275,21 +226,42 @@ Fail:
return false; return false;
} }
void lv_ft_font_destroy_cache(lv_font_t * font) void lv_ft_font_destroy(lv_font_t* font)
{ {
if (font == NULL) { if (font == NULL) {
return; return;
} }
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->user_data);
if (dsc) { if (dsc) {
lv_mem_free(dsc->face_id); #if LV_USE_FT_CACHE_MANAGER == 0
FT_Done_Size(dsc->size);
FT_Done_Face(dsc->face);
#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);
}
#endif
lv_mem_free(dsc->font); lv_mem_free(dsc->font);
lv_mem_free(dsc); lv_mem_free(dsc);
} }
} }
#else/* LV_USE_FT_CACHE_MANAGER */ /**********************
* 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) static FT_Face face_find_in_list(lv_ft_info_t *info)
{ {
@ -311,6 +283,7 @@ static void face_add_to_list(FT_Face face)
FT_Face *pface; FT_Face *pface;
pface = (FT_Face *)_lv_ll_ins_tail(&face_control.face_ll); pface = (FT_Face *)_lv_ll_ins_tail(&face_control.face_ll);
*pface = face; *pface = face;
face_control.cnt++;
} }
static void face_remove_from_list(FT_Face face) static void face_remove_from_list(FT_Face face)
@ -320,24 +293,25 @@ static void face_remove_from_list(FT_Face face)
if (*pface == face) { if (*pface == face) {
_lv_ll_remove(&face_control.face_ll, pface); _lv_ll_remove(&face_control.face_ll, pface);
lv_mem_free(pface); lv_mem_free(pface);
face_control.cnt--;
break; break;
} }
pface = _lv_ll_get_next(&face_control.face_ll, pface); pface = _lv_ll_get_next(&face_control.face_ll, pface);
} }
} }
static void face_generic_finalizer(void * object) #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_Face face = (FT_Face)object; LV_UNUSED(library_is);
face_remove_from_list(face); LV_UNUSED(req_data);
if(face->generic.data) { *aface = face_id;
lv_face_info_t * face_info = (lv_face_info_t *)face->generic.data; return FT_Err_Ok;
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, 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_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next)
{ {
LV_UNUSED(unicode_letter_next); LV_UNUSED(unicode_letter_next);
@ -351,22 +325,73 @@ static bool get_glyph_dsc_cb_nocache(const lv_font_t * font,
return true; return true;
} }
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->user_data);
FT_Face face = dsc->face;
static FTC_ImageTypeRec desc_sbit_type;
desc_sbit_type.face_id = (FTC_FaceID)face;
desc_sbit_type.flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL;
desc_sbit_type.height = dsc->weight;
desc_sbit_type.width = dsc->weight;
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_Error error = FTC_SBitCache_Lookup(sbit_cache, &desc_sbit_type, glyph_index, &sbit, NULL);
dsc_out->adv_w = sbit->xadvance;
dsc_out->box_h = sbit->height; /*Height of the bitmap in [px]*/
dsc_out->box_w = sbit->width; /*Width of the bitmap in [px]*/
dsc_out->ofs_x = sbit->left; /*X offset of the bitmap in [pf]*/
dsc_out->ofs_y = sbit->top - sbit->height; /*Y offset of the bitmap measured from the as line*/
dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/
return true;
}
static const uint8_t * get_glyph_bitmap_cb_cache(const lv_font_t * font, uint32_t unicode_letter)
{
LV_UNUSED(font);
LV_UNUSED(unicode_letter);
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)
{
// 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;
dsc_out->box_h = 0;
dsc_out->box_w = 0;
dsc_out->ofs_x = 0;
dsc_out->ofs_y = 0;
dsc_out->bpp = 0;
return true;
}
FT_Error error; FT_Error error;
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); FT_Face face;
FT_Face face = dsc->size->face; lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->user_data);
face = dsc->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) { if (face->size != dsc->size) {
// berry_log_C(">> FT_Activate_Size %i", dsc->size);
FT_Activate_Size(dsc->size); FT_Activate_Size(dsc->size);
} }
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT ); error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT );
// berry_log_C(">> after FT_Load_Glyph error = %i", error);
if (error){ if (error){
return false; return false;
} }
error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL); error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL);
// berry_log_C(">> after FT_Render_Glyph error = %i", error);
if (error){ if (error){
return false; return false;
} }
@ -375,101 +400,70 @@ 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_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->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_x = face->glyph->bitmap_left; /*X offset of the bitmap in [pf]*/
dsc_out->ofs_y = face->glyph->bitmap_top - dsc_out->ofs_y = face->glyph->bitmap_top - face->glyph->bitmap.rows; /*Y offset of the bitmap measured from the as line*/
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*/ 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; return true;
} }
static const uint8_t * get_glyph_bitmap_cb_nocache(const lv_font_t * font, uint32_t unicode_letter) static const uint8_t * get_glyph_bitmap_cb_nocache(const lv_font_t * font, uint32_t unicode_letter)
{ {
LV_UNUSED(unicode_letter); LV_UNUSED(unicode_letter);
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->user_data);
FT_Face face = dsc->size->face; FT_Face face = dsc->face;
return (const uint8_t *)(face->glyph->bitmap.buffer); return (const uint8_t *)(face->glyph->bitmap.buffer);
} }
static bool lv_ft_font_init_nocache(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) {
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);
}
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 */ #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)
{
// #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;
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
}
}
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
}
}
}

View File

@ -2,8 +2,8 @@
* @file lv_freetype.h * @file lv_freetype.h
* *
*/ */
#ifndef LV_FONT_FREETYPE_H #ifndef _LV_FONT_TTF_H
#define LV_FONT_FREETYPE_H #define _LV_FONT_TTF_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -12,16 +12,37 @@ extern "C" {
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
// #include "lvgl/lvgl.h" // TODO
#include "lvgl.h" #include "lvgl.h"
#include "ft2build.h"
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_CACHE_H
#include FT_SIZES_H
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define LV_USE_FT_CACHE_MANAGER 1 #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
/********************** /**********************
* TYPEDEFS * 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 { typedef enum {
FT_FONT_STYLE_NORMAL = 0, FT_FONT_STYLE_NORMAL = 0,
FT_FONT_STYLE_ITALIC = 1 << 0, FT_FONT_STYLE_ITALIC = 1 << 0,
@ -35,6 +56,16 @@ typedef struct {
uint16_t style; /* font style */ uint16_t style; /* font style */
} lv_ft_info_t; } 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 * GLOBAL PROTOTYPES
**********************/ **********************/
@ -47,7 +78,7 @@ typedef struct {
* Note that this value does not account for managed FT_Face and FT_Size objects. * Note that this value does not account for managed FT_Face and FT_Size objects.
* @return true on success, otherwise false. * @return true on success, otherwise false.
*/ */
bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes); bool lv_freetype_init(FT_UInt max_faces, FT_UInt max_sizes, FT_ULong max_bytes);
/** /**
* Destroy freetype library * Destroy freetype library
@ -76,4 +107,4 @@ void lv_ft_font_destroy(lv_font_t * font);
} /* extern "C" */ } /* extern "C" */
#endif #endif
#endif /* LV_FONT_FREETYPE_H */ #endif