XuNeo / luavgl

lua + lvgl = luavgl An optimized lvgl Lua binding
MIT License
57 stars 13 forks source link

lv_font_load() from file system #33

Closed jonsmirl closed 3 months ago

jonsmirl commented 3 months ago

Introduce the problem

Could I please get support for lv_font_load()? LVGL should be able to load fonts from SPIFFS, right?

Custom fonts added at build time are working fine, I already added one to my app.

Proposal

No response

XuNeo commented 3 months ago

Hi, This needs a bit C code to expose available font to lua. There's a callback function to create/delete font no matter it's a freetype font or lvgl bin font. I have tested the logic with freetype but not lv_font_load. It should be similar.

https://github.com/XuNeo/luavgl/blob/c19d631226bc2015c1d4b18b3442e1b83f8a5ea2/simulator/main.c#L21-L25

typedef const lv_font_t *(*make_font_cb)(const char *name, int size,
                                         int weight);

For example lvgl.Font("MiSansW medium, montserrat", 24) will call make_font_cb. The name will be misansw medium which is converted to lowercase. size is 24 and weight is the default 400.

https://github.com/XuNeo/luavgl/blob/c19d631226bc2015c1d4b18b3442e1b83f8a5ea2/src/font.c#L10-L31

jonsmirl commented 3 months ago

That is much more general than lv_font_load() since it supports making multiple fonts (face, point, weight). lv_font_load() just takes the filename and a string and loads the single font contained in the file (no options). I only have one font file in the system - the device uses a different LVGL font file for the different regions (Chinese, Korean, Japanese, Latin, Cyrillic, etc). I only put the glyphs needed by the labels into the font file in order to make it small. I do use subpixel rendered LVGL fonts since that makes a large difference on my 240x320 LCD.

lv_font_t * my_font;
my_font = lv_font_load(X/path/to/my_font.bin);

/*Use the font*/

/*Free the font if not required anymore*/
lv_font_free(my_font);
XuNeo commented 3 months ago

I see. Then you can still use the make_font_cb, simply call my_font = lv_font_load(X/path/to/my_font.bin); and return my_font. If more fonts are needed, it can be done by map the local font filename with call back parameter name.

jonsmirl commented 3 months ago

I wanted to pass in the file name.

XuNeo commented 3 months ago

Yes, you can do it by calling lvgl.Font("my_font") from lua. And make_font_cb will get name as "my_font".

jonsmirl commented 3 months ago

I will code this up tomorrow, it is midnight here in Boston.

jonsmirl commented 3 months ago

I have this working now using your API