Ihr Ingenieurbüro für

Elektronik- und Softwareentwicklung

Library for Graphics Displays with Font Generator

Veröffentlicht:   |   Weitere Einträge über eadogm baremetal LCD cortex-m3 libopencm3

After having the first assembled cordi prototyping board on my desk I started thinking about writing some software to bring the board to life. I decided to use the libopencm3 library which is much better designed than the usual vendor provided libraries.

The controller bringup was pretty straightforward. I only needed to provide the proper memory layout to the linkerscript and configure the correct processor lib to link against. The libopencm3 provides a separate repository with many example configurations you can choose as a basis for your own board.

Then when the board was up and running the missing piece was the EADOGM132 display. When you look around in the internet you will find some libraries but most of them are GPL or AVR specific both of which I don't like.

So I started to roll our own graphics library with the following goals:

  • MIT Licensed
  • Font support
  • UTF-8 support
  • Display abstraction to be able to plugin whatever display you may need

Display Layer

The display interface is defined in glib.h like this:

struct glib_lcd {
    /* Write the driver's frame buffer to the display */
    void (*flush)(struct glib_lcd *dev);

    /* Draw a bitmap to the driver's framebuffer */
    void (*draw_bitmap)(struct glib_lcd *dev, int x, int y,
                        const struct glib_bitmap *bitmap);

    /* Set/Clear a pixel in the driver's frame buffer*/
    void (*setpix)(struct glib_lcd *dev, int x, int y);
    void (*clrpix)(struct glib_lcd *dev, int x, int y);

    /* The displays resolution */
    uint16_t xres;
    uint16_t yres;

For our initial cordi use case there is a eadogm driver implemented in eadog.c which is written in a way to also support the other eadog* variants in the future. By now there is only rudimentary support for the eadogm132.

Graphics Lib

The graphics library is implemented in glib.c and provides all common hardware independent display directives like drawing rects, lines, circles, fonts etc.

By now the library is in a pretty early state and only supports the following directives defined in glib.h:

void glib_init(struct glib_dev *dev, struct glib_lcd *lcd);
void glib_flush(struct glib_dev *dev);
void glib_font_set(struct glib_dev *dev, const struct glib_font *font);
void glib_print(struct glib_dev *dev, int x, int y, const char *utf8);

Usually your application will use only the functions it provides for interacting with displays.

Font Generator

The graphics lib depends on proper defined font sets to be able to draw glyphs to the display. The font definition is based on one bitmap for each glyph. To save flash space the font bitmaps are only defined for the rectangle in which they actually have 'ink'. That's why an additional offset is required for each glyph. Together with the offset the 'inky' rect can be drawn to the correct position.

By now there is only support for monochrome displays so the bitmaps are defined with one bit per pixel (bpp) without any padding.

The definitions are in glib.h as follows:

struct glib_bitmap {
    int width;
    int height;
    const uint8_t data[];

struct glib_glyph {
    uint32_t utf8;
    int x;
    int y;
    const struct glib_bitmap *bitmap;

struct glib_font {
    int charcount;
    const struct glib_glyph glyphs[];

Defining font sets based on these definitions would be a bit too work expensive to do it by hand. That's why I've written a simple cross platform font generator which can export your PC's system fonts to the format described above. You simply define the characters you want included into the font set and the program renders them to 1 bpp bitmaps and exports them to regular c files for compiling and linking against your application.

Supported are pretty much all character sets you can imagine because the character lookup is based on utf-8 unicode.

UVC liblcd Font Converter

To write unicode to the display simply embed your text into your source file:

/* ---8<--- */

glib_font_set(&gdev, &font_ubuntu12);
glib_print(&gdev, 0, 12, "Hello World!");
glib_print(&gdev, 0, 24, "Привет мир!");

/* --->8--- */
cordi stm32f100 eadogm132 utf-8 example


The repository is hosted on GitHub: https://github.com/uvc-ingenieure/liblcd

Tthere is also precompiled Win32 version of the converter: Download

On the other platforms you have to build the converter yourself.


Be aware that the library is in a pretty early state and not very usable yet. It was just written as a reference and will be completed when we have a need of that funcionallity.

You're welcome to contribute and fork on GitHub!

Comments powered by Disqus