Problems using lv_font_conv conversion?

I use lv_font_conv to convert the TTF font file into a binary file, and I get the wrong display in the simulator. The specific commands and results are as follows:

lewis@ubuntu:~$ env DEBUG=* lv_font_conv --font BenMoJingYuan/BenMoJingYuan.ttf -r
0x20-0x7F --size 48 --format bin --bpp 3 --no-compress -o output.font
  font last_id: 96 +0ms
  font minY: -13 +1ms
  font maxY: 44 +0ms
  font glyphIdFormat: 0 +1ms
  font kerningScale: 1 +0ms
  font advanceWidthFormat: 0 +0ms
  font xy_bits: 6 +0ms
  font wh_bits: 6 +0ms
  font advanceWidthBits: 7 +0ms
  font monospaced: false +0ms
  font indexToLocFormat: 0 +11ms
  font subpixels_mode: 0 +0ms
  font.table.head table size = 48 +0ms
  font.table.cmap 1 subtable(s): 0 "format 0", 1 "sparse" +0ms
  font.table.cmap table size = 28 +0ms
  font.table.loca table size = 204 +0ms
  font.table.glyf table size = 31692 +0ms
  font font size: 31972 +4ms

The test code used in the simulator is:

    lv_obj_t *src = lv_scr_act();

    lv_obj_t *label = lv_label_create(src, NULL);
    lv_label_set_text(label, "ABCDEFG");
    lv_font_t *font = lv_font_load("~/output.font");
    if (font) {
        lv_obj_set_style_local_text_font(label, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, font);
        lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
    } else {
        printf("load font failed\n");
    }

The display is like this.

Snipaste

I have made sure that the file has been opened normally, but the display result is wrong!

In order to verify that my file system is correct, I also tested the image, and the result is normal. Below is the code and display effect.

    lv_obj_t *src = lv_scr_act();

    lv_obj_t *img = lv_img_create(src, NULL);
    lv_img_set_src(img, "~/image.bin");
    lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 0);


    lv_obj_t *label = lv_label_create(src, NULL);
    lv_label_set_text(label, "ABCDEFG");
    lv_font_t   *font = lv_font_load("~/output.font");
    if (font) {
        lv_obj_set_style_local_text_font(label, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, font);
        lv_obj_align(label, img, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
    } else {
        printf("load font failed\n");
    }

Snipaste1

Maybe you can try to create a c-file from your ttf file and try this.
Or try to use --bpp1 -bpp2, just to see if there is a difference.

Strange thing, when I use --bpp 3 for creating a c-file lv_font_conv outputs a

LittlevGL supports "--bpp 3" with compression only

whereas if I create the binary file, no error is issued.

Ok . Setting --bpp to 1 can display normally, but it is strange that bpp=3 should also be normal.

I think this warning message might also apply to binary files being loaded by LVGL, but since the binary format is intended to be generic, it does not display the warning.

@puzrin Is this an oversight?

Another problem is that if I choose to generate font binary files in a wide range, then Segmentation fault (core dumped) will appear directly in the simulator. Here are the steps to perform.

 env DEBUG=* lv_font_conv --font BenMoJingYuan/BenMoJingYuan.ttf -r 0x20-0x7F -r 0x4E00-0x9FA5 --size 48 --format bin --bpp 1
--no-compress -o myfont.font
  font last_id: 4617 +0ms
  font minY: -13 +2ms
  font maxY: 45 +0ms
  font glyphIdFormat: 1 +1ms
  font kerningScale: 1 +1ms
  font advanceWidthFormat: 0 +0ms
  font xy_bits: 6 +2ms
  font wh_bits: 6 +1ms
  font advanceWidthBits: 7 +1ms
  font monospaced: false +0ms
  font indexToLocFormat: 1 +149ms
  font subpixels_mode: 0 +0ms
  font.table.head table size = 48 +0ms
  font.table.cmap 10 subtable(s): 4 "format 0", 6 "sparse" +0ms
  font.table.cmap table size = 9044 +19ms
  font.table.loca table size = 18480 +0ms
  font.table.glyf table size = 1074052 +0ms
  font font size: 1101624 +117ms

Run in the terminal:

lewis@ubuntu:~/pc_simulator_sdl_eclipse$ ./demo
Segmentation fault (core dumped)

But if it generates a smaller range of binary files then it can run normally, for example:

env DEBUG=* lv_font_conv --font BenMoJingYuan/BenMoJingYuan.ttf -r 0x20-0x7F -r 0x4E00-0x4E66 --size 48 --format bin --bpp 1
--no-compress -o myfont.font

Maybe you can check if you run out of heap memory.
You need a lot of heap memory for loading the font file.

The last time I’ve taken a look into the lv_font_load there has been almost no checking whether lv_mem_alloc returns NULL or not.

So if you get out of heap memory an exception is the consequence.

Oh my god, it really is!
It takes too much memory to read large-capacity font files. It is completely different from what I used before.

When using bare metal directly, the file offset is calculated using the font used, but the encoding is different. Using UTF8 encoding, the actual offset address cannot be obtained from the text to be used.

Is there any way to reduce the heap memory used? I can only think of a compromise, to split a large file into multiple small files and traverse all the files. .

My idea was to load only the top font information, and the starting block number of the binary information (on SDCard or eMMC), and read the real glyph data when it is needed. But that would need some rewriting of lv_font_load.

I have a STM32H743 board and reading all the binary data from file into heap took a lot of time (trying to load chinese font, with a lot of glyphs), and needed a lot of memory.

So reading the glyphs on the fly would be the only reasonable thing to do.
Reading a block from SDCard needs about 1 ms (on my board).

If you have fixed text only, you can only included the needed glyphs into binary font.

I may not understand the lvgl font structure, what you said is correct. Although what I said is feasible, it is not very practical because it cannot return all the given characters.

I will study it carefully. Thank you for your reply!

lvgl (text) format is restricted subset of bin due language limitations.

It should, but current bin support is temporary kludge. Instead of direct load, bin is converted to “lvgl” in memory. I guess, current code does not take into account lvgl format limitations.

It was suggested by volunteer to support dynamic fonts loa (from file system), and merged as “better than nothing” to motivate rewrite.