Own font usage questions

Description of problem

I have a question about creating own font in lv-mpy. I know about lv.font_t class, I know documentation about own fonts in C (https://docs.littlevgl.com/en/html/overview/font.html#add-new-font), but I am not sure about usage in mpy.

I am using my font structure (description in my repo: https://gitlab.com/mhepp63/ili934x-micropython),

What I want:

using own font in lv-micropython. Please, how to properly use lv.font_t to make own font?

Platform

ESP32

Code:

mvfont = b'...data'

def get_font_char(font, c):
    return glyph_data_with_header

def get_glyph_dsc_cb(self, dsc_out, unicode_letter, unicode_letter_next):

    ch = get_font_char(mvfont, unicode_letter) 
    if not ch:
        return False

    dsc_out.adv_w = ch[5]   #/*Horizontal space required by the glyph in [px]*/
    dsc_out.box_h = ch[3]   #/*Height of the bitmap in [px]*/
    dsc_out.box_w = ch[2]   #/*Width of the bitmap in [px]*/
    dsc_out.ofs_x = ch[4]   #/*X offset of the bitmap in [pf]*/
    dsc_out.ofs_y = ch[1]   #/*Y offset of the bitmap measured from the as line*/
    dsc_out.bpp   = 1       #/*Bits per pixel: 1/2/4/8*/
 
    return True

def get_glyph_bitmap_cb(self, unicode_letter):

    ch = get_font_char(mvfont, unicode_letter)

    y_offset, width, height, x_offset, x_delta = struct.unpack('>5B', ch[1:6])

    d,m = divmod(width*height, 8)
    chr_size = d+1 if m else d
 
    return ch[5: 5+chr_size]
 
 
 rcl56 = lv.font_t()
 rcl56.get_glyph_dsc =       get_glyph_dsc_cb    #/*Set a callback to get info about gylphs*/
 rcl56.get_glyph_bitmap =    get_glyph_bitmap_cb #/*Set a callback to get bitmap of a glyp*/
 rcl56.line_height =         58                  #/*The real line height where any text fits*/
 rcl56.base_line =           47                  #/*Base line measured from the top of line_height*/
 rcl56.dsc =                 None                #/*Store any implementation specific data here*/
 rcl56.user_data =           None

And usage of this code:

>>> style = label.get_style(lv.label.STYLE.MAIN)
>>> style.text.font = rcl56
>>> label.set_style(lv.label.STYLE.MAIN, style)
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x400e0dfe  PS      : 0x00060d30  A0      : 0x800e2da8  A1      : 0x3ffdb400
A2      : 0x00000004  A3      : 0x0000241e  A4      : 0x00000000  A5      : 0x00000001
A6      : 0x3f874d30  A7      : 0x0000241e  A8      : 0x800d280c  A9      : 0x3ffdb3f0
A10     : 0x3f887320  A11     : 0x00000000  A12     : 0x00009e4f  A13     : 0x3ffc2530
A14     : 0x00006fbe  A15     : 0x00009e4e  SAR     : 0x0000001c  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000004  LBEG    : 0x40099c0c  LEND    : 0x40099c17  LCOUNT  : 0x00000000

ELF file SHA256: 0000000000000000000000000000000000000000000000000000000000000000

Backtrace: 0x400e0dfb:0x3ffdb400 0x400e2da5:0x3ffdb430 0x40135db0:0x3ffdb450 0x402151d1:0x3ffdb480 0x4010774e:0x3ffdb4a0 0x4010a462:0x3ffdb4d0 0x4010a656:0x3ffdb550 0x4011b8a1:0x3ffdb580 0x4011bdd1:0x3ffdb5e0 0x400ff908:0x3ffdb600 0x400ff9ab:0x3ffdb620 0x40137695:0x3ffdb640 0x4013770d:0x3ffdb660 0x401356ca:0x3ffdb680 0x400df855:0x3ffdb6a0 0x400df8d9:0x3ffdb6c0 0x400ed9c1:0x3ffdb6e0 0x400e3c3c:0x3ffdb780 0x400df855:0x3ffdb7f0 0x400df882:0x3ffdb810 0x4014f4c4:0x3ffdb830 0x4014f744:0x3ffdb8d0 0x400f6a84:0x3ffdb910 0x400953bd:0x3ffdb940

Rebooting...

Hi @mhepp!

I never tried adding a new font format, I only used lvgl fonts created with LittlevGL font converter.

Any reason you don’t want to use lvgl font system? They put a lot of work in it, it supports advanced features such as compression, kerning etc. and you can convert any TTF font to lvgl font using the font converter tool.

Regarding your crash, I suggest you try to debugging it. The backtrace you got is a good starting point:

Backtrace: 0x400e0dfb:0x3ffdb400 0x400e2da5:0x3ffdb430 0x40135db0:0x3ffdb450 0x402151d1:0x3ffdb480 0x4010774e:0x3ffdb4a0 0x4010a462:0x3ffdb4d0 0x4010a656:0x3ffdb550 0x4011b8a1:0x3ffdb580 0x4011bdd1:0x3ffdb5e0 0x400ff908:0x3ffdb600 0x400ff9ab:0x3ffdb620 0x40137695:0x3ffdb640 0x4013770d:0x3ffdb660 0x401356ca:0x3ffdb680 0x400df855:0x3ffdb6a0 0x400df8d9:0x3ffdb6c0 0x400ed9c1:0x3ffdb6e0 0x400e3c3c:0x3ffdb780 0x400df855:0x3ffdb7f0 0x400df882:0x3ffdb810 0x4014f4c4:0x3ffdb830 0x4014f744:0x3ffdb8d0 0x400f6a84:0x3ffdb910 0x400953bd:0x3ffdb940

What you need to do is:

  • Make sure you build your project in DEBUG mode, with debug symbols
  • Parse this line with addr2line

Hi amirgon,

thanks for reply. I have no problem to use lvgl font system, I have converted font etc… BUT if I understand this process well, I must compile my font as a part of lv-mpy. This means, I must recompile and reflash mpy each time I need some change in fonts. This means keep changes in repo for future updates and this is not so simply…

My font format is able to handle kerning too, is probably very similar to format used in lvgl, but uses python structures.

My goal is rewrite existing application to use lvgl. I have very simple lib for display (ili9341), which is written in mpy and is very slow (to redraw all things on screen it needs more then 2s, so it is not usable to print time with seconds, and no, I am not redrawing whole screen each time change :wink: ). I want to use lvgl for faster drawing… and add some interactivity in future… My question is “Is there some mpy example of using own font? Or, what I am doing wrong?”

But, if recommended way is use of build-in fonts, I can live with this…

Currently you must compile and reflash after updating or adding font.
We plan to support dynamic font loading in the future, which would allow loading the font on runtime from a file.
I’m not sure when I’ll have time to work on this, but I’ve opened a github issue for tracking it.

I’m not aware of any micropython example (or C example) that implements a new font. As far as I know, the only implementation is lvgl’s font system.
I’m not sure what you are doing wrong, if you want to find out I suggest you try debugging it.

Our ili9341 driver allows more than 30FPS, even when the whole screen is redrawn. It’s using DMA, double buffering, critical part are written in C, etc.

I also recommend using the built-in font system. I think it will cost you a lot less time to use it than to integrate your own font format, especially since you are using MicroPython and not C (although, with all the effort @amirgon has put into making the MicroPython binding so stable, maybe the difference is irrelevant.)

Amirgon:

thank you, this answered all my questions.

Dynamic font loading will be VERY NICE feature.

I started with Loboris mpy, which uses parts written in C, DMA, etc… too, but is very buggy and no more developed, so I switched to clear mpy and written my display driver. I optimized them for memory usage (I had ESP32 without psram), but it is very slow. Then I found lvgl, it looks like good solution for my speed troubles :wink: (and as bonus, this is the first system, where is working touch layer).

Embeddedt:

I undrestand and it looks like way which I will go. For now :wink:

BTW. I have build-in my fonts now and I must say, this fonts looks much more better…