Skip to content

Generate new fonts

The commercial edition allows to generate new fonts, to be used as header files or uploaded to an external SPI Flash.

Configure

$ sudo apt install php php-cli php-gd php-mbstring

The command installs PHP and other dependencies.

$ git clone  https://github.com/lvgl/lv_utils 
$ cd lv_utils/
$ git reset --hard ec7d2676b36a27fa13b21162aca1476ad8456ec5

The commands download and install the utility from this repository and select this specific version.

Use

$ php font_conv_core.php "name=DejaVuSans28&font=DejaVuSans.ttf&height=28&bpp=1&uni_first=32&uni_last=255"

font_conv_core generates the font.

The parameters are

  • name sets the name of the generated C file;
  • font sets the name of the TTF font;
  • height selects the height in pixels;
  • bpp should be set to 1;
  • uni_first is set to 32 for space;
  • uni_last could be set to 127 or to 255 to include extended characters.

Rename the Font_DejaVuSans28.c file as Font_DejaVuSans28.cpp

$ mv DejaVuSans28.c DejaVuSans28.cpp

Create the corresponding header file Font_DejaVuSans28.h

// Configuration
#include "hV_Configuration.h"

// The Arduino IDE doesn't allow to select the libraries, hence this condition.
#if (FONT_MODE == USE_FONT_HEADER)

#ifndef DEJAVUSANS28FONT_RELEASE
#define DEJAVUSANS28FONT_RELEASE 507

#include "hV_Font.h"

#if (hV_FONT_HEADER_STRUCTURE_RELEASE < 507)

#error Required hV_FONT_HEADER_STRUCTURE_RELEASE 507

#endif // hV_FONT_HEADER_STRUCTURE_RELEASE

extern const font_s Font_DejaVuSans28;

#endif // DEJAVUSANS28FONT_RELEASE

#endif // FONT_MODE 

Edit the Font_DejaVuSans28.cpp file and add at the beginning

// Configuration
#include "hV_Configuration.h"

// The Arduino IDE doesn't allow to select the libraries, hence this condition.
#if (FONT_MODE == USE_FONT_HEADER)

// Font_DejaVuSans28.h
#include "Font_DejaVuSans28.h"

Replace

static const uint8_t DejaVuSans28_glyph_bitmap[]

by

static const width_s Width_DejaVuSans28[] PLACE_IN_FRAM

The PLACE_IN_FRAM macro tells the compiler to locate the array in a specific region of memory, here upper-FRAM for the MSP430FR5994.

Replace

static const lv_font_glyph_dsc_t DejaVuSans28_glyph_dsc[]

by

static const width_s Width_Barcode128[] =

Replace w_px and glyph_index on each entry

  {.w_px = 8,   .glyph_index = 0},  /*Unicode: U+0020 ( )*/

by pixel and index

  {.pixel = 8, .index = 0}, /*Unicode: U+0020 ( )*/

Finally, replace

lv_font_t DejaVuSans28 = 
{
    .unicode_first = 32, /*First Unicode letter in this font*/
    .unicode_last = 255, /*Last Unicode letter in this font*/
    .h_px = 28, /*Font height in pixels*/
    .glyph_bitmap = DejaVuSans28_glyph_bitmap, /*Bitmap of glyphs*/
    .glyph_dsc = DejaVuSans28_glyph_dsc, /*Description of glyphs*/
    .glyph_cnt = 224, /*Number of glyphs in the font*/
    .unicode_list = NULL, /*Every character in the font from 'unicode_first' to 'unicode_last'*/
    .get_bitmap = lv_font_get_bitmap_continuous /*Function pointer to get glyph's bitmap*/
    .get_width = lv_font_get_width_continuous, /*Function pointer to get glyph's width*/
    .bpp = 1, /*Bit per pixel*/
    .monospace = 0, /*Fix width (0: if not used)*/
    .next_page = NULL, /*Pointer to a font extension*/
};

by

const font_s Font_DejaVuSans28 =
{
    .kind = 0x20, // kind of font: Sans Serif
    .height = 28, // reference size, from source font
    .maxWidth = 23,
    .first = 32, // number of first character, usually 32
    .number = 224, // number of characters, usually 96 or 224
    .width = Width_DejaVuSans28, // characters widths and relative addresses
    .table = Table_DejaVuSans28 // characters definitions
};

with

  • kind: kind of font, to be set according to the table below;
  • height: height, set during font generation, set from h_px;
  • maxWidth: maximum width, to be calculated from the *width array;
  • first: first character, usually 32, set from h_px;
  • number: number of characters, usually 96 or 224, set from glyph_cnt or unicode_last - unicode_first + 1;
  • width: characters index and length in bytes, see * width array;
  • table: character definition, see * table array.

The kind of font is coded on 8 bits according to

Bit Value Content
7 0x80 High definition, 2 bits per pixel
6 0x40 Fixed Mono font
5 0x20 Proportional font, Sans Serif
4 0x10 Proportional font, Serif
3 0x08 Italic
2 0x04 Bold
1..0 0x00..0x03 Variant number

Example: 0x20 refers to a proportional Sans Serif font.

Add at the end

#endif // FONT_MODE

Example

Header file Font_DejaVuSans28.h

// SDK
#include "hV_HAL_Peripherals.h"

// Configuration
#include "hV_Configuration.h"

#ifndef hV_FONT_HEADER_STRUCTURE_RELEASE
#define hV_FONT_HEADER_STRUCTURE_RELEASE 507

// The Arduino IDE doesn't allow to select the libraries, hence this condition.
#if (FONT_MODE == USE_FONT_HEADER)

struct width_s
{
    uint16_t pixel; ///< width in pixel
    uint16_t index; ///< relative address
};

struct font_s
{
    uint8_t kind; ///< font description
    uint8_t height; ///< general height in pixels
    uint8_t maxWidth; ///< maximum width in pixels from *width array
    uint8_t first; ///< number of first character, usually 32
    uint8_t number; ///< number of characters, usually 96 or 224
    const width_s * width; ///< characters widths and relative addresses
    const uint8_t * table; ///< characters definitions
};

#endif // USE_FONT_HEADER

#endif // hV_FONT_HEADER_STRUCTURE_RELEASE

Code file Font_DejaVuSans28.cpp

// Configuration
#include "hV_Configuration.h"

// The Arduino IDE doesn't allow to select the libraries, hence this condition.
#if (FONT_MODE == USE_FONT_HEADER)

// Font_DejaVuSans28.h
#include "Font_DejaVuSans28.h"

static const uint8_t Table_DejaVuSans28[] PLACE_IN_FRAM =
{
    /*Unicode: U+0020 ( ) , Width: 8 */
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........
    0x00,  //........

    /*Unicode: U+0021 (!) , Width: 2 */
    0x00,  //..
    0x00,  //..
    0x00,  //..
    0x00,  //..
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0x00,  //..
    0x00,  //..
    0x00,  //..
    0xc0,  //%%
    0xc0,  //%%
    0xc0,  //%%
    0x00,  //..
    0x00,  //..
    0x00,  //..
    0x00,  //..
    0x00,  //..
    0x00,  //..

    // ...

    /*Unicode: U+00ff (ÿ) , Width: 13 */
    0x00, 0x00,  //.............
    0x00, 0x00,  //.............
    0x00, 0x00,  //.............
    0x00, 0x00,  //.............
    0x0d, 0x80,  //....%%.%%....
    0x0d, 0x80,  //....%%.%%....
    0x00, 0x00,  //.............
    0x00, 0x00,  //.............
    0x00, 0x00,  //.............
    0xc0, 0x18,  //%%.........%%
    0x60, 0x30,  //.%%.......%%.
    0x60, 0x30,  //.%%.......%%.
    0x70, 0x70,  //.%%%.....%%%.
    0x30, 0x60,  //..%%.....%%..
    0x30, 0xe0,  //..%%....%%%..
    0x18, 0xc0,  //...%%...%%...
    0x18, 0xc0,  //...%%...%%...
    0x0d, 0x80,  //....%%.%%....
    0x0d, 0x80,  //....%%.%%....
    0x0f, 0x80,  //....%%%%%....
    0x07, 0x00,  //.....%%%.....
    0x07, 0x00,  //.....%%%.....
    0x06, 0x00,  //.....%%......
    0x06, 0x00,  //.....%%......
    0x0c, 0x00,  //....%%.......
    0x7c, 0x00,  //.%%%%%.......
    0x78, 0x00,  //.%%%%........
    0x00, 0x00,  //.............

};

static const width_s Width_DejaVuSans28[] PLACE_IN_FRAM =
{
    { .pixel = 8, .index = 0 }, /*Unicode: U+0020 ( )*/
    { .pixel = 2, .index = 28 }, /*Unicode: U+0021 (!)*/
    // ...
    { .pixel = 13, .index = 11592 }, /*Unicode: U+00ff (ÿ)*/
};

const font_s Font_DejaVuSans28 =
{
    .kind = 0x20, // kind of font: Sans Serif
    .height = 28, // reference size, from source font
    .maxWidth = 23,
    .first = 32, // number of first character, usually 32
    .number = 224, // number of characters, usually 96 or 224
    .width = Width_DejaVuSans28, // characters widths and relative addresses
    .table = Table_DejaVuSans28 // characters definitions
};

#endif // FONT_MODE