Last active
August 3, 2022 14:20
-
-
Save chaosgoo/c94cf1d2d4f703301208f3d0a6eaed1b to your computer and use it in GitHub Desktop.
lvgl动态字体字重修改
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "../../lv_examples.h" | |
#if LV_USE_FREETYPE && LV_BUILD_EXAMPLES | |
/** | |
* Load a font with FreeType | |
*/ | |
void lv_example_freetype_1(void) | |
{ | |
/*Create a font*/ | |
static lv_ft_info_t info; | |
/*FreeType uses C standard file system, so no driver letter is required.*/ | |
info.name = "./lvgl/examples/libs/freetype/Archivo-VF.ttf"; | |
info.height = 24; | |
info.weight = 900; | |
info.style = FT_FONT_STYLE_NORMAL; | |
info.mem = NULL; | |
if(!lv_ft_font_init(&info)) { | |
LV_LOG_ERROR("create failed."); | |
} | |
/*Create style with the new font*/ | |
static lv_style_t style; | |
lv_style_init(&style); | |
lv_style_set_text_font(&style, info.font); | |
lv_style_set_text_align(&style, LV_TEXT_ALIGN_CENTER); | |
/*Create a label with the new style*/ | |
lv_obj_t * label = lv_label_create(lv_scr_act()); | |
lv_obj_add_style(label, &style, 0); | |
lv_label_set_text(label, "Hello world\nI'm a font created with FreeType"); | |
lv_obj_center(label); | |
} | |
#else | |
void lv_example_freetype_1(void) | |
{ | |
/*TODO | |
*fallback for online examples*/ | |
lv_obj_t * label = lv_label_create(lv_scr_act()); | |
lv_label_set_text(label, "FreeType is not installed"); | |
lv_obj_center(label); | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file lv_freetype.c | |
* | |
*/ | |
/********************* | |
* INCLUDES | |
*********************/ | |
#include "lv_freetype.h" | |
#if LV_USE_FREETYPE | |
#include "ft2build.h" | |
#include FT_FREETYPE_H | |
#include FT_GLYPH_H | |
#include FT_CACHE_H | |
#include FT_SIZES_H | |
#include FT_IMAGE_H | |
#include FT_OUTLINE_H | |
#include FT_MULTIPLE_MASTERS_H | |
/********************* | |
* DEFINES | |
*********************/ | |
/********************** | |
* TYPEDEFS | |
**********************/ | |
typedef struct { | |
const void * mem; | |
long size; | |
char * name; | |
} lv_face_info_t; | |
typedef struct { | |
lv_ll_t face_ll; | |
} lv_faces_control_t; | |
typedef struct { | |
#if LV_FREETYPE_CACHE_SIZE >= 0 | |
void * face_id; | |
#else | |
FT_Size size; | |
#endif | |
lv_font_t * font; | |
uint16_t style; | |
uint16_t height; | |
uint16_t weight; | |
} lv_font_fmt_ft_dsc_t; | |
/********************** | |
* STATIC PROTOTYPES | |
**********************/ | |
#if LV_FREETYPE_CACHE_SIZE >= 0 | |
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); | |
#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 FT_Library library; | |
#if LV_FREETYPE_CACHE_SIZE >= 0 | |
static FTC_Manager cache_manager; | |
static FTC_CMapCache cmap_cache; | |
static FT_Face current_face = NULL; | |
#if LV_FREETYPE_SBIT_CACHE | |
static FTC_SBitCache sbit_cache; | |
static FTC_SBit sbit; | |
#else | |
static FTC_ImageCache image_cache; | |
static FT_Glyph image_glyph; | |
#endif | |
#else | |
static lv_faces_control_t face_control; | |
#endif | |
/********************** | |
* MACROS | |
**********************/ | |
/********************** | |
* GLOBAL FUNCTIONS | |
**********************/ | |
bool lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes) | |
{ | |
FT_Error error = FT_Init_FreeType(&library); | |
if(error) { | |
LV_LOG_ERROR("init freeType error(%d)", error); | |
return false; | |
} | |
#if LV_FREETYPE_CACHE_SIZE >= 0 | |
error = FTC_Manager_New(library, max_faces, max_sizes, | |
max_bytes, font_face_requester, NULL, &cache_manager); | |
if(error) { | |
FT_Done_FreeType(library); | |
LV_LOG_ERROR("Failed to open cache manager"); | |
return false; | |
} | |
error = FTC_CMapCache_New(cache_manager, &cmap_cache); | |
if(error) { | |
LV_LOG_ERROR("Failed to open Cmap Cache"); | |
goto Fail; | |
} | |
#if LV_FREETYPE_SBIT_CACHE | |
error = FTC_SBitCache_New(cache_manager, &sbit_cache); | |
if(error) { | |
LV_LOG_ERROR("Failed to open sbit cache"); | |
goto Fail; | |
} | |
#else | |
error = FTC_ImageCache_New(cache_manager, &image_cache); | |
if(error) { | |
LV_LOG_ERROR("Failed to open image cache"); | |
goto Fail; | |
} | |
#endif | |
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_FREETYPE_CACHE_SIZE */ | |
} | |
void lv_freetype_destroy(void) | |
{ | |
#if LV_FREETYPE_CACHE_SIZE >= 0 | |
FTC_Manager_Done(cache_manager); | |
#endif | |
FT_Done_FreeType(library); | |
} | |
bool lv_ft_font_init(lv_ft_info_t * info) | |
{ | |
#if LV_FREETYPE_CACHE_SIZE >= 0 | |
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_FREETYPE_CACHE_SIZE >= 0 | |
lv_ft_font_destroy_cache(font); | |
#else | |
lv_ft_font_destroy_nocache(font); | |
#endif | |
} | |
/********************** | |
* STATIC FUNCTIONS | |
**********************/ | |
#if LV_FREETYPE_CACHE_SIZE >= 0 | |
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; | |
if(info->mem) { | |
error = FT_New_Memory_Face(library, info->mem, info->size, 0, aface); | |
} | |
else { | |
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_bold_glyph(const lv_font_t * font, FT_Face face, | |
FT_UInt glyph_index, lv_font_glyph_dsc_t * dsc_out) | |
{ | |
if(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT)) { | |
return false; | |
} | |
lv_font_fmt_ft_dsc_t * dsc = (lv_font_fmt_ft_dsc_t *)(font->dsc); | |
if(face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { | |
if(dsc->style & FT_FONT_STYLE_BOLD) { | |
int strength = 1 << 6; | |
FT_Outline_Embolden(&face->glyph->outline, strength); | |
} | |
} | |
if(FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL)) { | |
return false; | |
} | |
dsc_out->adv_w = (face->glyph->metrics.horiAdvance >> 6); | |
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->bpp = 8; /*Bit per pixel: 1/2/4/8*/ | |
return true; | |
} | |
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); | |
FTC_FaceID face_id = (FTC_FaceID)dsc->face_id; | |
FT_Size face_size; | |
struct FTC_ScalerRec_ scaler; | |
scaler.face_id = face_id; | |
scaler.width = dsc->height; | |
scaler.height = dsc->height; | |
scaler.pixel = 1; | |
if(FTC_Manager_LookupSize(cache_manager, &scaler, &face_size) != 0) { | |
return false; | |
} | |
FT_Face face = face_size->face; | |
FT_MM_Var* amaster = NULL; | |
FT_Error err = FT_Get_MM_Var(face, &amaster); | |
if (err) { | |
LV_LOG_ERROR("FT_Get_MM_Var error:%d\n", err); | |
return err; | |
} | |
FT_Fixed coords[1] = { dsc->weight<<16 }; | |
err = FT_Set_Var_Design_Coordinates(face, 1, coords); | |
if (err) { | |
LV_LOG_ERROR("FT_Set_Var_Design_Coordinates error:%d\n", err); | |
return err; | |
} | |
FT_Done_MM_Var(library, amaster); | |
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); | |
dsc_out->is_placeholder = glyph_index == 0; | |
if(dsc->style & FT_FONT_STYLE_ITALIC) { | |
FT_Matrix italic_matrix; | |
italic_matrix.xx = 1 << 16; | |
italic_matrix.xy = 0x5800; | |
italic_matrix.yx = 0; | |
italic_matrix.yy = 1 << 16; | |
FT_Set_Transform(face, &italic_matrix, NULL); | |
} | |
if(dsc->style & FT_FONT_STYLE_BOLD) { | |
current_face = face; | |
if(!get_bold_glyph(font, face, glyph_index, dsc_out)) { | |
current_face = NULL; | |
return false; | |
} | |
goto end; | |
} | |
FTC_ImageTypeRec desc_type; | |
desc_type.face_id = face_id; | |
desc_type.flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL; | |
desc_type.height = dsc->height; | |
desc_type.width = dsc->height; | |
#if LV_FREETYPE_SBIT_CACHE | |
FT_Error error = FTC_SBitCache_Lookup(sbit_cache, &desc_type, glyph_index, &sbit, NULL); | |
if(error) { | |
LV_LOG_ERROR("SBitCache_Lookup error"); | |
return false; | |
} | |
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*/ | |
#else | |
FT_Error error = FTC_ImageCache_Lookup(image_cache, &desc_type, glyph_index, &image_glyph, NULL); | |
if(error) { | |
LV_LOG_ERROR("ImageCache_Lookup error"); | |
return false; | |
} | |
if(image_glyph->format != FT_GLYPH_FORMAT_BITMAP) { | |
LV_LOG_ERROR("Glyph_To_Bitmap error"); | |
return false; | |
} | |
FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)image_glyph; | |
dsc_out->adv_w = (glyph_bitmap->root.advance.x >> 16); | |
dsc_out->box_h = glyph_bitmap->bitmap.rows; /*Height of the bitmap in [px]*/ | |
dsc_out->box_w = glyph_bitmap->bitmap.width; /*Width of the bitmap in [px]*/ | |
dsc_out->ofs_x = glyph_bitmap->left; /*X offset of the bitmap in [pf]*/ | |
dsc_out->ofs_y = glyph_bitmap->top - | |
glyph_bitmap->bitmap.rows; /*Y offset of the bitmap measured from the as line*/ | |
dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/ | |
#endif | |
end: | |
if((dsc->style & FT_FONT_STYLE_ITALIC) && (unicode_letter_next == '\0')) { | |
dsc_out->adv_w = dsc_out->box_w + dsc_out->ofs_x; | |
} | |
return true; | |
} | |
static const uint8_t * get_glyph_bitmap_cb_cache(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->dsc); | |
if(dsc->style & FT_FONT_STYLE_BOLD) { | |
if(current_face && current_face->glyph->format == FT_GLYPH_FORMAT_BITMAP) { | |
return (const uint8_t *)(current_face->glyph->bitmap.buffer); | |
} | |
return NULL; | |
} | |
#if LV_FREETYPE_SBIT_CACHE | |
return (const uint8_t *)sbit->buffer; | |
#else | |
FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)image_glyph; | |
return (const uint8_t *)glyph_bitmap->bitmap.buffer; | |
#endif | |
} | |
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_memset_00(dsc->font, sizeof(lv_font_t)); | |
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->mem = info->mem; | |
face_info->size = info->mem_size; | |
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->height; | |
dsc->weight = 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->height; | |
scaler.height = info->height; | |
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); | |
FT_Fixed scale = face_size->face->size->metrics.y_scale; | |
int8_t thickness = FT_MulFix(scale, face_size->face->underline_thickness) >> 6; | |
font->underline_position = FT_MulFix(scale, face_size->face->underline_position) >> 6; | |
font->underline_thickness = thickness < 1 ? 1 : 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) { | |
FTC_Manager_RemoveFaceID(cache_manager, (FTC_FaceID)dsc->face_id); | |
lv_mem_free(dsc->face_id); | |
lv_mem_free(dsc->font); | |
lv_mem_free(dsc); | |
} | |
} | |
#else/* LV_FREETYPE_CACHE_SIZE */ | |
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) | |
{ | |
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; | |
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); | |
if(face->size != dsc->size) { | |
FT_Activate_Size(dsc->size); | |
} | |
dsc_out->is_placeholder = glyph_index == 0; | |
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); | |
if(error) { | |
return false; | |
} | |
if(face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { | |
if(dsc->style & FT_FONT_STYLE_BOLD) { | |
int strength = 1 << 6; | |
FT_Outline_Embolden(&face->glyph->outline, strength); | |
} | |
if(dsc->style & FT_FONT_STYLE_ITALIC) { | |
FT_Matrix italic_matrix; | |
italic_matrix.xx = 1 << 16; | |
italic_matrix.xy = 0x5800; | |
italic_matrix.yx = 0; | |
italic_matrix.yy = 1 << 16; | |
FT_Outline_Transform(&face->glyph->outline, &italic_matrix); | |
} | |
} | |
error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); | |
if(error) { | |
return false; | |
} | |
dsc_out->adv_w = (face->glyph->metrics.horiAdvance >> 6); | |
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->bpp = 8; /*Bit per pixel: 1/2/4/8*/ | |
if((dsc->style & FT_FONT_STYLE_ITALIC) && (unicode_letter_next == '\0')) { | |
dsc_out->adv_w = dsc_out->box_w + dsc_out->ofs_x; | |
} | |
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->dsc); | |
FT_Face face = dsc->size->face; | |
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_memset_00(dsc->font, sizeof(lv_font_t)); | |
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; | |
if(info->mem) { | |
error = FT_New_Memory_Face(library, info->mem, (FT_Long) info->mem_size, 0, &face); | |
} | |
else { | |
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->mem = info->mem; | |
face_info->size = (long) info->mem_size; | |
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->height); | |
dsc->size = face->size; | |
dsc->height = info->height; | |
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->subpx = LV_FONT_SUBPX_NONE; | |
FT_Fixed scale = face->size->metrics.y_scale; | |
int8_t thickness = FT_MulFix(scale, face->underline_thickness) >> 6; | |
font->underline_position = FT_MulFix(scale, face->underline_position) >> 6; | |
font->underline_thickness = thickness < 1 ? 1 : thickness; | |
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_FREETYPE_CACHE_SIZE */ | |
#endif /*LV_USE_FREETYPE*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file lv_freetype.h | |
* | |
*/ | |
#ifndef LV_FREETYPE_H | |
#define LV_FREETYPE_H | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/********************* | |
* INCLUDES | |
*********************/ | |
#include "../../../lvgl.h" | |
#if LV_USE_FREETYPE | |
/********************* | |
* DEFINES | |
*********************/ | |
/********************** | |
* TYPEDEFS | |
**********************/ | |
typedef enum { | |
FT_FONT_STYLE_NORMAL = 0, | |
FT_FONT_STYLE_ITALIC = 1 << 0, | |
FT_FONT_STYLE_BOLD = 1 << 1 | |
} LV_FT_FONT_STYLE; | |
typedef struct { | |
const char * name; /* The name of the font file */ | |
const void * mem; /* The pointer of the font file */ | |
size_t mem_size; /* The size of the memory */ | |
lv_font_t * font; /* point to lvgl font */ | |
uint16_t weight; /* font size */ | |
uint16_t height; /* font size */ | |
uint16_t style; /* font style */ | |
} lv_ft_info_t; | |
/********************** | |
* GLOBAL PROTOTYPES | |
**********************/ | |
/** | |
* init freetype library | |
* @param max_faces Maximum number of opened FT_Face objects managed by this cache instance. Use 0 for defaults. | |
* @param max_sizes Maximum number of opened FT_Size objects managed by this cache instance. Use 0 for defaults. | |
* @param max_bytes Maximum number of bytes to use for cached data nodes. Use 0 for defaults. | |
* 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(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes); | |
/** | |
* Destroy freetype library | |
*/ | |
void lv_freetype_destroy(void); | |
/** | |
* Creates a font with info parameter specified. | |
* @param info See lv_ft_info_t for details. | |
* 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); | |
/** | |
* Destroy a font that has been created. | |
* @param font pointer to font. | |
*/ | |
void lv_ft_font_destroy(lv_font_t * font); | |
/********************** | |
* MACROS | |
**********************/ | |
#endif /*LV_USE_FREETYPE*/ | |
#ifdef __cplusplus | |
} /* extern "C" */ | |
#endif | |
#endif /* LV_FREETYPE_H */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment