How to use TTF font, not bitmap font for each font size

Hi All,

How can I use TTF font for every size.
At now, lvgl is using bitmap font, and it take many memory for each font size.
For ex, one Roboto font, but if the size just is different, corresponding size font c array is generated, Roboto_12, Roboto_14, Roboto_16,…

Below site talked about custom font, and it is released in v5.1, but I cann’t find any example or function like get_ttf_bitmap in lvgl library.

I can imagine that,

  • Save TTF into flash
  • When need to draw a font size, read TTF and generate font size bitmap in RAM
  • Use generated bitmap, then delete after drawn.
    My imagine may not be impossible, but please help if you have any idea + example code.

You can use lv_lib_freetype for this.

It sounds great!, but freetype is built on linux.
I’m using MCUPresso on windows for rtos application.
Could you guide me how to use freetype on windows and port lib into rtos?

@kisvegabor
LVGL is good for small hardware which ttf is saved on its memory (not file like linux or windows)
Could you create a library that can read head memory and generate bitmap font?
( refer to FT_New_Memory_Face )

I’m sure it’s possible to build FreeType with a managed build system too but it definitely needs some work. It might be useful: FreeType ported to STM32 microcontroller to support vector fonts - Programmer Sought

1 Like

I ported Freetype into my project in my way.
But when run FT_Load_Glyph(), I got an error called “Out Of Memory” :frowning:
Maybe not enough RAM for generate bitmap.

Hi @kisvegabor

I passed “out of memory”, showed “Hello” string, but result is strange.
image

I am using lvgl v7.10.0
I added ttf font binary into flash, I changed a line in lv_freetype.c

#define LV_USE_FT_CACHE_MANAGER  0
//FT_Error error = FT_New_Face(library, info->name, 0, &face);
FT_Error error = FT_New_Memory_Face(library, ttfData, 308628, 0, &face);

Could you give me some suggestions to solve this problem??

My code as below.

/* init freetype library */
lv_freetype_init(64, 1, 0);

/*Create a font*/
lv_ft_info_t info;
info.name = "font";
info.weight = 50;
info.style = FT_FONT_STYLE_NORMAL;
lv_ft_font_init(&info);

/*Create style with the new font*/
static lv_style_t style;
lv_style_init(&style);
lv_style_set_text_font(&style, LV_STATE_DEFAULT, info.font);

/*Add style to lable_1*/
lv_obj_add_style(guider_ui.screen_label_1, LV_LABEL_PART_MAIN, &style);
lv_label_set_text(guider_ui.screen_label_1, "Hello");

I change pixel_width of FT_Set_Pixel_Sizes in lv_freetype and result is OK.

//FT_Set_Pixel_Sizes(face, 2, info->weight);
FT_Set_Pixel_Sizes(face, 50, info->weight);

How to calculate pixel_width to match pixel_height as default?

I’m not an expert of FreeType, but the docs says do not use FT_Set_Pixel_Sizes if the cache API is used.
Base Interface - FreeType-2.11.0 API Reference

What if you don’t call this function at all?

What if you don’t call this function at all?

I don’t use cache, so if don’t call FT_Set_Pixel_Sizes(), lcd shows nothing.
In lv_ft_font_init_nocache(), I fixed pixel_width as below:

FT_Set_Pixel_Sizes(face, info->weight, info->weight);

result is the width of text created by freetype is equal to the bitmap created on lvgl web.