Dynamically doubling font size

Hi,

I suggest using Tiny_TTF.

Thanks.
I tested Tiny_TTF. It’s a great feature, but it may not meet my requirements. The main reasons are as follows:

  1. The commonly used Simplified Chinese character set GB2312 has 6763 characters, with the most frequently used ones being 3755. The TTF font file is too large,several hundred KB or several MB.
  2. If created using lv.tiny_ttf_create_file, the rendering on ESP32S3 is too slow. It takes several seconds to render 10 Chinese characters.
  3. If created using lv.tiny_ttf_create_data, ESP32S3 doesn’t have enough memory for such a large font.
  4. Therefore, using Bitmap for scaling might be a way to save both ROM and RAM simultaneously. Of course, the font won’t be as detailed as TrueType.

Do you have any good suggestions, thanks?

@kisvegabor
Perhaps embedding the TTF file into the program as a C array and then using Tiny_TTF in MicroPython could significantly improve the speed.
Now the question is, how can embedded resource files into the program as a C array and be called by MicroPython?

What about using the cache of TinyTTF? See here and here. To test it you can try rendering a single letter (e.g. "a"), and compare its speed with rendering the same letter many times. E.g. "aaaaaaaaaaaaaaaaaaaaaaaaaaa"

06a8036d-8005-4171-bb3c-6aa339363165
When I use lv.tiny_ttf_create_file_ex, speed is slow. But when I use lv.tiny_ttf_create_data, the speed is ok.
It seems that when reading font data from a file and rendering it, the speed is not fast enough.

import lvgl as lv
import time
# from ubuntu_font import ubuntu_font
scr = lv.obj()
lv.scr_load(scr)
time.sleep(5)
label2 = lv.label(scr)
label2.set_text("start")
label2.align(lv.ALIGN.CENTER, 0, 0)

myfont_cn = lv.tiny_ttf_create_file_ex("S:/user/AlibabaPuHuiTi-3-35-Thin.ttf", 40,20*1024)

label1 = lv.label(scr)
label1.set_style_text_font(myfont_cn,0)
label1.set_text("力力力力力力力力力力")
label1.align(lv.ALIGN.CENTER, 0, -25)


label2 = lv.label(scr)
label2.set_style_text_font(myfont_cn,0)
label2.set_text("力")
label2.align(lv.ALIGN.CENTER, 0, 50)

label2 = lv.label(scr)
label2.set_style_text_font(myfont_cn,0)
label2.set_text("力力力力")
label2.align(lv.ALIGN.CENTER, 0, 90)

By the way, I am using the ESP32 S3 micropython platform. The ttf file is stored in the flash vfs or sdcard sdmmc 1-wire file system, but the speed of displaying Chinese fonts is not enough. Is it a bug in the reading and writing of the micropython file system?

I think the slow speed is a result of you using:

  1. micropython, check out this video for example: https://www.youtube.com/watch?v=u9UfKTOcYNs
    it seems micropython is ridiculously slow!!
  2. An SD card. The first bit of text “start” is not read from your SD card, but your Chinese text is, I am not sure about the speed of your SD card but it will most likely be (much) slower than reading from internal memory.

I advice trying this out without using Micropython and see if that makes a difference in speed.

I think the problem is that only the bitmap is cached by Tiny_TTF, but LVGL needs to read some information about the gylphs too (width, height, etc) in ttf_get_glyph_dsc_cb.

I think the correct solution would be to cache the glyph metadata too.

As an experiment, you can modify ttf_get_glyph_dsc_cb to just set some fixed values for dsc_out and return. The text will be messed up, but you should see how fast the scrambled characters were drawn. If it was fast we will know for sure that the bottleneck is there.

@kisvegabor I just enabled the log of dsc_out in ttf_get_glyph_dsc_cb. If the same Chinese character is displayed, the parameters of dsc_out are exactly the same.
As shown in the gif I sent, the refreshing of the same Chinese character is still very slow.
So maybe the problem is not “cache the glyph metadata”?

I also think it may be a problem with the reading and rendering from the micropython SD card, because when multiple images were placed on the SD card, such as img1.set_src(“S:img1.png”), img2.set_src(“S:img2.png”), there was also a slow display speed.

By default there is no caching at all. So if the same character’s metadata is queried 100 times, it will read it 100 times from the SD card. That why I suggested to hard code some values to see how it affects speed.

Ok, I understand what you mean. I just tested it and it’s really fast.
So, what should we do now? :laughing:

tiny_ttf_test
@kisvegabor This is the new gif after " modify ttf_get_glyph_dsc_cb to just set some fixed values for dsc_out and return"

Nice!

Good question :smiley: I don’t what File System you use but you can set cache for these here too. Setting it to 256 bytes. should be a good start.

I’m using lvgl micropython, esp32 s3. The default setting for the file system is 500, but I changed it to 4096, but it didn’t have any effect.

How fast it is with cache_size=0? Will it be very very very slow?

Anyway it seems we have no other option than caching the glyph_dsc’s too. We shouldn’t do it in v8, but rather in v9.

Sorry, but I have no good idea now for an immediate solution. :frowning:

when set cache_size=0, the display speed of poweron.gif is very slow, but tiny_ttf load speed is no change.
Currently, I am using the LVGL V9 micropython version.
I will try to store the font in the PROGMEM flash area.
But flash size is limited.
If the loading speed of the SD card can be improved, it will definitely be the best choice.