Dynamic font loading in LVGL 9

,

Hi all, I’m trying to load fonts in bin format (converted from ttf using the online converter). The interface appears to have changed from V8 for which I found examples. Does someone has an example? Thank you!

Is there no one in the know?

Hello!
Here is a code snippet to load (and unload) .bin font:

# Load bin font:
font = lv.binfont_create("S:test-font.bin")
label.set_style_text_font(font, 0)
...

# Dispose font resource (after label is deleted, so no more reference to font):
lv.binfont_destroy(font)

Load/unload TTF fonts (slower):

# Load TTF:
size = 16   
font = lv.tiny_ttf_create_file("S:test-font.ttf", size)
label.set_style_text_font(font, 0)
...

# Unload TTF
lv.tiny_ttf_destroy(font)

Font convert tool: https://github.com/lvgl/lv_font_conv/

To convert any font:

  1. Install lv_font_conv:
    npm i lv_font_conv -g
  2. Download any free font which you prefer (and has glyphs for your special characters).
  3. You can check the font (glyphs, supported characters) in online tool:
    https://www.glyphrstudio.com/online/
  4. Run command to convert downloaded font:
    lv_font_conv --font customfont.ttf --output customfont-20.bin --bpp 1 --size 20 --format bin --range 0x20-0x7F --no-compress
    You should of course change the value of --font, --output, --size and --range arguments to your needs. It is recommended to create different sizes of same font to see runtime, which font size is better in your project.
  5. Upload your converted .bin font to your device, and use it:
    https://docs.lvgl.io/latest/en/html/overview/font.html#load-font-in-run-time

Download free fonts:

1 Like

Here is a font_helper.py file I use:
(logging module: micropython-lib/python-stdlib/logging/logging.py at master · micropython/micropython-lib · GitHub)

import lvgl as lv
import logging

FONTS_LVGL_PATH = "S:fonts"

_log = logging.getLogger("LVGL_FONT")


def load(path: str, lvgl_path: str = FONTS_LVGL_PATH, raise_exception=False):
    full_path = f"{lvgl_path}/{path}"
    try:
        return lv.binfont_create(full_path)
    except Exception as e:
        if raise_exception:
            raise e
        else:
            _log.exc(e, f"Failed loading font: {full_path}")

    return None

def dispose(font: lv.font_t):
    if font:
        lv.binfont_destroy(font)

def load_ttf(path: str, size: int, lvgl_path: str = FONTS_LVGL_PATH, raise_exception=False):
    full_path = f"{lvgl_path}/{path}"
    try:
        return lv.tiny_ttf_create_file(full_path, size)
    except Exception as e:
        if raise_exception:
            raise e
        else:
            _log.exc(e, f"Failed loading font: {full_path}")

    return None

def dispose_ttf(font: lv.font_t):
    if font:
        lv.tiny_ttf_destroy(font)

def set_label_font(label: lv.label, path: str):
    font = load(path, raise_exception=False)
    if font:
        label.set_style_text_font(font, 0)
    return font
1 Like