Skip to content

Custom Characters Guide

Microesque edited this page Dec 13, 2024 · 4 revisions

The library provides the ability to define and display custom characters.

Custom characters allow you to display unique characters, or characters that don't exist in your font. Like font characters, they are printed at the current cursor location and automatically advance it as they are printed. They are also affected by the font scaling the same way, so they behave exactly like font characters.

Note that, setting up a font is not required to display custom characters. Meaning, you could print any text just by using custom characters.

Creating and displaying a custom character is straightforward. The only real hurdle is creating the bitmap and the glyph for the character. Below is an example walkthrough of the process.


Imagine that you're trying to display a smiley face like below:

img

The ssd1306_custom_char structure is used to represent custom characters, so we'll need to define one for our smiley character. The structure members are:

struct ssd1306_custom_char {
    uint8_t *bitmap;    /* Pointer to the bitmap of the character */
    uint8_t width;      /* Width of the bitmap */
    uint8_t height;     /* Height of the bitmap */
    int8_t x_offset;    /* x offset of the bitmap */
    int8_t y_offset;    /* y offset of the bitmap */
    uint8_t x_advance;  /* Cursor advance amount after printing */
};

First, imagine the same characters on a grid and mark the smallest possible rectangle that covers your custom character. Here it's marked with a yellow rectangle:

img

The bitmap is obtained by iterating over the pixels within the yellow rectangle. Start from the top left pixel and work your way down to the bottom right like shown below and mark down their values. White pixels are marked as 1, while black pixels are marked as 0.

After completing the iteration, group these values into bytes (8-bits) from left to right. If the last byte can't be completed, pad it with zeroes. These bytes make up the bitmap array in order, which we'll name smiley_bitmap[]:

img

To find the rest of the structure members, mark the position of:

  • red : The current cursor location (after the character Y in this case)
  • pink : Where you want the cursor to be after printing
  • blue : The top left pixel of the yellow rectangle

The ssd1306_custom_char structure values are found as:

  • width and height are the width and height of the yellow rectangle.
  • x_offset is the horizontal offset from red to blue.
  • y_offset is the vertical offset from red to blue.
  • x_advance is the horizontal offset from red to pink.
img

The final custom character definition is:

const uint8_t smiley_bitmap[] = {
    0b01010010, 0b10000001, 0b00010111, 0b00000000
};
const struct ssd1306_custom_char smiley_char = {
    smiley_bitmap, 5, 5, 0, -4, 6
};

Custom characters are printed by passing the address of the ssd1306_custom_char structure to the ssd1306_draw_char_custom() function:

ssd1306_draw_char_custom(&display, &smiley_char);

The final source code to display the text at the beginning is:

Assuming a font is set up for ssd1306_draw_str().

/* Custom smiley char definition */
const uint8_t smiley_bitmap[] = {
    0b01010010, 0b10000001, 0b00010111, 0b00000000
};
const struct ssd1306_custom_char smiley_char = {
    smiley_bitmap, 5, 5, 0, -4, 6
};

/* Magnify chars by 3 so we can properly see them */
ssd1306_set_font_scale(&display, 3);

/* Draw the characters */
ssd1306_draw_str(&display, "HEY");
ssd1306_draw_char_custom(&display, &smiley_char);
ssd1306_display_update(&display);
img