Adding a New Font Engine¶
Overview¶
Fonts have a format property. It describes how the glyph data is stored. At the time of writing, there are several possible values that this field can take, and those values fall into 2 categories:
Bitmap based: 1, 2, 4 or 8-bpp and image format, and
Vector based vector, SVG; for the latter, the user provides the rendering logic.
For simple formats:
the font is stored as an array of bitmaps, one bitmap per glyph;
the value stored for each pixel determines the pixel's opacity, enabling edges to be smoother — higher bpp values result in smoother edges.
For advanced formats, the font information is stored in its respective format.
The format property also affects the amount of memory needed to store a
font. For example, format = LV_FONT_GLYPH_FORMAT_A4 makes a font nearly four
times larger compared to format = LV_FONT_GLYPH_FORMAT_A1.
Example¶
LVGL's font interface is designed to be very flexible but, even so, you can add your own font engine in place of LVGL's internal one. For example, you can use FreeType to real-time render glyphs from TTF fonts or use an external flash to store the font's bitmap and read them when the library needs them. FreeType can be used in LVGL as described in Freetype.
To add a new font engine, a custom lv_font_t variable needs to be created:
/* Describe the properties of a font */
lv_font_t my_font;
my_font.get_glyph_dsc = my_get_glyph_dsc_cb; /* Set a callback to get info about glyphs */
my_font.get_glyph_bitmap = my_get_glyph_bitmap_cb; /* Set a callback to get bitmap of a glyph */
my_font.line_height = height; /* The real line height where any text fits */
my_font.base_line = base_line; /* Base line measured from the top of line_height */
my_font.dsc = something_required; /* Store any implementation specific data here */
my_font.user_data = user_data; /* Optionally some extra user data */
...
/* Get info about glyph of `unicode_letter` in `font` font.
* Store the result in `dsc_out`.
* The next letter (`unicode_letter_next`) might be used to calculate the width required by this glyph (kerning)
*/
bool my_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next)
{
/* Your code here */
/* Store the result.
* For example ...
*/
dsc_out->adv_w = 12; /* Horizontal space required by the glyph in [px] */
dsc_out->box_h = 8; /* Height of the bitmap in [px] */
dsc_out->box_w = 6; /* Width of the bitmap in [px] */
dsc_out->ofs_x = 0; /* X offset of the bitmap in [px] */
dsc_out->ofs_y = 3; /* Y offset of the bitmap measured from the as line */
dsc_out->format= LV_FONT_GLYPH_FORMAT_A2;
return true; /* true: glyph found; false: glyph was not found */
}
/* Get the bitmap of `unicode_letter` from `font`. */
const uint8_t * my_get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter)
{
/* Your code here */
/* The bitmap should be a continuous bitstream where
* each pixel is represented by `bpp` bits */
return bitmap; /* Or NULL if not found */
}