1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

refactor(font): refactor font glyph data acquire method (#5884)

This commit is contained in:
Benign X 2024-03-22 18:51:08 +08:00 committed by GitHub
parent 213cb5971e
commit 48416d7dae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 42 additions and 62 deletions

View File

@ -421,7 +421,7 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc,
} }
} }
dsc->glyph_data = (void *)lv_font_get_glyph_bitmap(&g, letter, draw_buf); dsc->glyph_data = (void *) lv_font_get_glyph_bitmap(&g, draw_buf);
dsc->format = dsc->glyph_data ? g.format : LV_FONT_GLYPH_FORMAT_NONE; dsc->format = dsc->glyph_data ? g.format : LV_FONT_GLYPH_FORMAT_NONE;
} }
else { else {

View File

@ -42,12 +42,11 @@
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t letter, const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
lv_draw_buf_t * draw_buf)
{ {
const lv_font_t * font_p = g_dsc->resolved_font; const lv_font_t * font_p = g_dsc->resolved_font;
LV_ASSERT_NULL(font_p); LV_ASSERT_NULL(font_p);
return font_p->get_glyph_bitmap(g_dsc, letter, draw_buf); return font_p->get_glyph_bitmap(g_dsc, draw_buf);
} }
bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter,

View File

@ -60,16 +60,19 @@ typedef uint8_t lv_font_glyph_format_t;
/** Describes the properties of a glyph.*/ /** Describes the properties of a glyph.*/
typedef struct { typedef struct {
const lv_font_t * const lv_font_t *
resolved_font; /**< Pointer to a font where the glyph was actually found after handling fallbacks*/ resolved_font; /**< Pointer to a font where the glyph was actually found after handling fallbacks*/
uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width.*/ uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width.*/
uint16_t box_w; /**< Width of the glyph's bounding box*/ uint16_t box_w; /**< Width of the glyph's bounding box*/
uint16_t box_h; /**< Height of the glyph's bounding box*/ uint16_t box_h; /**< Height of the glyph's bounding box*/
int16_t ofs_x; /**< x offset of the bounding box*/ int16_t ofs_x; /**< x offset of the bounding box*/
int16_t ofs_y; /**< y offset of the bounding box*/ int16_t ofs_y; /**< y offset of the bounding box*/
lv_font_glyph_format_t format; /**< Font format of the glyph see @lv_font_glyph_format_t*/ lv_font_glyph_format_t format; /**< Font format of the glyph see @lv_font_glyph_format_t*/
uint8_t is_placeholder: 1; /**< Glyph is missing. But placeholder will still be displayed*/ uint8_t is_placeholder: 1; /**< Glyph is missing. But placeholder will still be displayed*/
uint32_t glyph_index; /**< The index of the glyph in the font file. Used by the font cache*/ union {
uint32_t index; /**< Unicode code point*/
const void * src; /**< Pointer to the source data used by image fonts*/
} gid; /**< The index of the glyph in the font file. Used by the font cache*/
lv_cache_entry_t * entry; /**< The cache entry of the glyph draw data. Used by the font cache*/ lv_cache_entry_t * entry; /**< The cache entry of the glyph draw data. Used by the font cache*/
} lv_font_glyph_dsc_t; } lv_font_glyph_dsc_t;
@ -105,7 +108,7 @@ struct _lv_font_t {
bool (*get_glyph_dsc)(const lv_font_t *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next); bool (*get_glyph_dsc)(const lv_font_t *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next);
/** Get a glyph's bitmap from a font*/ /** Get a glyph's bitmap from a font*/
const void * (*get_glyph_bitmap)(lv_font_glyph_dsc_t *, uint32_t, lv_draw_buf_t *); const void * (*get_glyph_bitmap)(lv_font_glyph_dsc_t *, lv_draw_buf_t *);
/** Release a glyph*/ /** Release a glyph*/
void (*release_glyph)(const lv_font_t *, lv_font_glyph_dsc_t *); void (*release_glyph)(const lv_font_t *, lv_font_glyph_dsc_t *);
@ -130,13 +133,12 @@ struct _lv_font_t {
/** /**
* Return with the bitmap of a font. * Return with the bitmap of a font.
* @param g_dsc the glyph descriptor including which font to use etc. * @note You must call @lv_font_get_glyph_dsc to get @g_dsc (@lv_font_glyph_dsc_t) before you can call this function.
* @param letter a UNICODE character code * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and the format.
* @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it. * @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it.
* @return pointer to the glyph's data. It can be a draw buffer for bitmap fonts or an image source for imgfonts. * @return pointer to the glyph's data. It can be a draw buffer for bitmap fonts or an image source for imgfonts.
*/ */
const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t letter, const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf);
lv_draw_buf_t * draw_buf);
/** /**
* Get the descriptor of a glyph * Get the descriptor of a glyph

View File

@ -75,16 +75,13 @@ static const uint8_t opa2_table[4] = {0, 85, 170, 255};
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, uint32_t unicode_letter, const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
lv_draw_buf_t * draw_buf)
{ {
const lv_font_t * font = g_dsc->resolved_font; const lv_font_t * font = g_dsc->resolved_font;
uint8_t * bitmap_out = draw_buf->data; uint8_t * bitmap_out = draw_buf->data;
if(unicode_letter == '\t') unicode_letter = ' ';
lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc; lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc;
uint32_t gid = get_glyph_dsc_id(font, unicode_letter); uint32_t gid = g_dsc->gid.index;
if(!gid) return NULL; if(!gid) return NULL;
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid]; const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
@ -206,6 +203,7 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t *
dsc_out->ofs_y = gdsc->ofs_y; dsc_out->ofs_y = gdsc->ofs_y;
dsc_out->format = (uint8_t)fdsc->bpp; dsc_out->format = (uint8_t)fdsc->bpp;
dsc_out->is_placeholder = false; dsc_out->is_placeholder = false;
dsc_out->gid.index = gid;
if(is_tab) dsc_out->box_w = dsc_out->box_w * 2; if(is_tab) dsc_out->box_w = dsc_out->box_w * 2;

View File

@ -214,13 +214,11 @@ typedef struct {
/** /**
* Used as `get_glyph_bitmap` callback in lvgl's native font format if the font is uncompressed. * Used as `get_glyph_bitmap` callback in lvgl's native font format if the font is uncompressed.
* @param g_dsc the glyph descriptor including which font to use etc. * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and format.
* @param letter a UNICODE character code
* @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it. * @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it.
* @return pointer to an A8 bitmap (not necessarily bitmap_out) or NULL if `unicode_letter` not found * @return pointer to an A8 bitmap (not necessarily bitmap_out) or NULL if `unicode_letter` not found
*/ */
const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, uint32_t unicode_letter, const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf);
lv_draw_buf_t * draw_buf);
/** /**
* Used as `get_glyph_dsc` callback in lvgl's native font format if the font is uncompressed. * Used as `get_glyph_dsc` callback in lvgl's native font format if the font is uncompressed.

View File

@ -170,7 +170,7 @@ static bool freetype_glyph_create_cb(lv_freetype_glyph_cache_data_t * data, void
} }
dsc_out->is_placeholder = glyph_index == 0; dsc_out->is_placeholder = glyph_index == 0;
dsc_out->glyph_index = glyph_index; dsc_out->gid.index = (uint32_t)glyph_index;
return true; return true;
} }

View File

@ -30,9 +30,7 @@ typedef struct _lv_freetype_image_cache_data_t {
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf);
uint32_t unicode_letter,
lv_draw_buf_t * draw_buf);
static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void * user_data); static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void * user_data);
static void freetype_image_free_cb(lv_freetype_image_cache_data_t * node, void * user_data); static void freetype_image_free_cb(lv_freetype_image_cache_data_t * node, void * user_data);
@ -77,18 +75,14 @@ void lv_freetype_set_cbs_image_font(lv_freetype_font_dsc_t * dsc)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
uint32_t unicode_letter,
lv_draw_buf_t * draw_buf)
{ {
LV_UNUSED(unicode_letter);
LV_UNUSED(draw_buf); LV_UNUSED(draw_buf);
const lv_font_t * font = g_dsc->resolved_font; const lv_font_t * font = g_dsc->resolved_font;
lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc; lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc;
LV_ASSERT_FREETYPE_FONT_DSC(dsc); LV_ASSERT_FREETYPE_FONT_DSC(dsc);
FT_Face face = dsc->cache_node->face; FT_UInt glyph_index = (FT_UInt)g_dsc->gid.index;
FT_UInt glyph_index = FT_Get_Char_Index(face, unicode_letter);
lv_cache_t * cache = dsc->cache_node->draw_data_cache; lv_cache_t * cache = dsc->cache_node->draw_data_cache;

View File

@ -32,12 +32,10 @@ typedef struct _lv_freetype_outline_node_t {
static lv_freetype_outline_t outline_create(lv_freetype_context_t * ctx, FT_Face face, FT_UInt glyph_index, static lv_freetype_outline_t outline_create(lv_freetype_context_t * ctx, FT_Face face, FT_UInt glyph_index,
uint32_t size, uint32_t strength); uint32_t size, uint32_t strength);
static lv_result_t outline_delete(lv_freetype_context_t * ctx, lv_freetype_outline_t outline); static lv_result_t outline_delete(lv_freetype_context_t * ctx, lv_freetype_outline_t outline);
static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf);
uint32_t unicode_letter,
lv_draw_buf_t * draw_buf);
static void freetype_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc); static void freetype_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc);
static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, uint32_t unicode_letter); static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, FT_UInt glyph_index);
/*glyph dsc cache lru callbacks*/ /*glyph dsc cache lru callbacks*/
static bool freetype_glyph_outline_create_cb(lv_freetype_outline_node_t * node, lv_freetype_font_dsc_t * dsc); static bool freetype_glyph_outline_create_cb(lv_freetype_outline_node_t * node, lv_freetype_font_dsc_t * dsc);
@ -153,15 +151,14 @@ static lv_cache_compare_res_t freetype_glyph_outline_cmp_cb(const lv_freetype_ou
return node_a->glyph_index > node_b->glyph_index ? 1 : -1; return node_a->glyph_index > node_b->glyph_index ? 1 : -1;
} }
static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
uint32_t unicode_letter,
lv_draw_buf_t * draw_buf)
{ {
LV_UNUSED(draw_buf); LV_UNUSED(draw_buf);
const lv_font_t * font = g_dsc->resolved_font; const lv_font_t * font = g_dsc->resolved_font;
lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc; lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc;
LV_ASSERT_FREETYPE_FONT_DSC(dsc); LV_ASSERT_FREETYPE_FONT_DSC(dsc);
lv_cache_entry_t * entry = lv_freetype_outline_lookup(dsc, unicode_letter); lv_cache_entry_t * entry = lv_freetype_outline_lookup(dsc, (FT_UInt)g_dsc->gid.index);
if(entry == NULL) { if(entry == NULL) {
return NULL; return NULL;
} }
@ -184,13 +181,10 @@ static void freetype_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_
g_dsc->entry = NULL; g_dsc->entry = NULL;
} }
static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, uint32_t unicode_letter) static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, FT_UInt glyph_index)
{ {
lv_freetype_cache_node_t * cache_node = dsc->cache_node; lv_freetype_cache_node_t * cache_node = dsc->cache_node;
FT_Face face = cache_node->face;
FT_UInt glyph_index = FT_Get_Char_Index(face, unicode_letter);
lv_freetype_outline_node_t tmp_node; lv_freetype_outline_node_t tmp_node;
tmp_node.glyph_index = glyph_index; tmp_node.glyph_index = glyph_index;

View File

@ -63,7 +63,7 @@ typedef struct ttf_font_desc {
typedef struct _tiny_ttf_cache_data_t { typedef struct _tiny_ttf_cache_data_t {
lv_font_t * font; lv_font_t * font;
uint32_t unicode; uint32_t glyph_index;
uint32_t size; uint32_t size;
lv_draw_buf_t * draw_buf; lv_draw_buf_t * draw_buf;
} tiny_ttf_cache_data_t; } tiny_ttf_cache_data_t;
@ -72,8 +72,7 @@ typedef struct _tiny_ttf_cache_data_t {
**********************/ **********************/
static bool ttf_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, static bool ttf_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); uint32_t unicode_letter_next);
static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf);
uint32_t unicode_letter, lv_draw_buf_t * draw_buf);
static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc); static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc);
static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size_t data_size, static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size_t data_size,
int32_t font_size, int32_t font_size,
@ -222,17 +221,18 @@ static bool ttf_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * d
dsc_out->ofs_y = -y2; /*Y offset of the bitmap measured from the as line*/ dsc_out->ofs_y = -y2; /*Y offset of the bitmap measured from the as line*/
dsc_out->format = LV_FONT_GLYPH_FORMAT_A8; dsc_out->format = LV_FONT_GLYPH_FORMAT_A8;
dsc_out->is_placeholder = false; dsc_out->is_placeholder = false;
dsc_out->gid.index = (uint32_t)g1;
return true; /*true: glyph found; false: glyph was not found*/ return true; /*true: glyph found; false: glyph was not found*/
} }
static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
uint32_t unicode_letter, lv_draw_buf_t * draw_buf)
{ {
LV_UNUSED(draw_buf); LV_UNUSED(draw_buf);
uint32_t glyph_index = g_dsc->gid.index;
const lv_font_t * font = g_dsc->resolved_font; const lv_font_t * font = g_dsc->resolved_font;
tiny_ttf_cache_data_t search_key = { tiny_ttf_cache_data_t search_key = {
.font = (lv_font_t *)font, .font = (lv_font_t *)font,
.unicode = unicode_letter, .glyph_index = glyph_index,
.size = font->line_height, .size = font->line_height,
}; };
@ -340,10 +340,9 @@ static bool tiny_ttf_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_d
{ {
ttf_font_desc_t * dsc = (ttf_font_desc_t *)user_data; ttf_font_desc_t * dsc = (ttf_font_desc_t *)user_data;
uint32_t unicode_letter = node->unicode;
const stbtt_fontinfo * info = (const stbtt_fontinfo *)&dsc->info; const stbtt_fontinfo * info = (const stbtt_fontinfo *)&dsc->info;
int g1 = stbtt_FindGlyphIndex(info, (int)unicode_letter); int g1 = (int)node->glyph_index;
if(g1 == 0) { if(g1 == 0) {
/* Glyph not found */ /* Glyph not found */
return false; return false;
@ -382,8 +381,8 @@ static lv_cache_compare_res_t tiny_ttf_cache_compare_cb(const tiny_ttf_cache_dat
return lhs->font > rhs->font ? 1 : -1; return lhs->font > rhs->font ? 1 : -1;
} }
if(lhs->unicode != rhs->unicode) { if(lhs->glyph_index != rhs->glyph_index) {
return lhs->unicode > rhs->unicode ? 1 : -1; return lhs->glyph_index > rhs->glyph_index ? 1 : -1;
} }
if(lhs->size != rhs->size) { if(lhs->size != rhs->size) {

View File

@ -26,8 +26,7 @@ typedef struct {
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static const void * imgfont_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t unicode, static const void * imgfont_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf);
lv_draw_buf_t * draw_buf);
static bool imgfont_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, static bool imgfont_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out,
uint32_t unicode, uint32_t unicode_next); uint32_t unicode, uint32_t unicode_next);
@ -80,15 +79,11 @@ void lv_imgfont_destroy(lv_font_t * font)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static const void * imgfont_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, uint32_t unicode, static const void * imgfont_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
lv_draw_buf_t * draw_buf)
{ {
LV_UNUSED(draw_buf); LV_UNUSED(draw_buf);
const lv_font_t * font = g_dsc->resolved_font;
imgfont_dsc_t * dsc = (imgfont_dsc_t *)font->dsc; const void * img_src = g_dsc->gid.src;
int32_t offset_y = 0;
const void * img_src = dsc->path_cb(font, unicode, 0, &offset_y, dsc->user_data);
return img_src; return img_src;
} }
@ -118,6 +113,7 @@ static bool imgfont_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t *
dsc_out->ofs_x = 0; dsc_out->ofs_x = 0;
dsc_out->ofs_y = offset_y; dsc_out->ofs_y = offset_y;
dsc_out->format = LV_FONT_GLYPH_FORMAT_IMAGE; /* is image identifier */ dsc_out->format = LV_FONT_GLYPH_FORMAT_IMAGE; /* is image identifier */
dsc_out->gid.src = img_src;
return true; return true;
} }

View File

@ -479,7 +479,7 @@ void test_freetype_outline_rendering_test(void)
lv_font_get_glyph_dsc(font_italic, &g, 0x9F98, '\0'); lv_font_get_glyph_dsc(font_italic, &g, 0x9F98, '\0');
const lv_ll_t * outline_data; const lv_ll_t * outline_data;
outline_data = (lv_ll_t *)lv_font_get_glyph_bitmap(&g, 0x9F98, NULL); outline_data = (lv_ll_t *) lv_font_get_glyph_bitmap(&g, NULL);
uint32_t i = 0; uint32_t i = 0;
lv_freetype_outline_event_param_t * param; lv_freetype_outline_event_param_t * param;