I need to convert some X11 bitmap fonts to an array in C for a 128x64 OLED Display.

I saw some fonts like /usr/share/fonts/X11/misc/9x15-ISO8859-1.pcf.gz

The result should look like

/* Standard ASCII 6x8 font */
const char PROGMEM font6x8[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
  0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
  0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "

Are the tools for converting a pcf font to an array of chars in C? Where are good resources for bitmap fonts?

Is there anything else I have missed?

  • 1
    I'm interested in this myself. If you do come across an answer, please share your solution here. Apr 21 '14 at 17:44
  • Why need to convert. Do you want to store the file in an array?
    – totti
    May 31 '14 at 14:24
  • You have *.pcf.gz file and you want to create array in C, right? You should try to open the file, read it and convert bytes to hexadecimal format.
    – Cockootec
    Jun 2 '14 at 19:00
  • @totti: the why is already included in the Q: for a 128x64 OLED Display.
    – user55518
    Jun 4 '14 at 18:52

You can use convert as shown here: C header file with bitmapped fonts

Probably there are a lot of commands to convert fonts to bitmap, but the freetype API is easy enough to write your own with not much code.

Using the freetype example I wrote something you can use as a start, it output an .xbm file (is a c file but you can use graphics programs like gimp to view/edit it).

Notiche that gimp also support export to .xbm with different bytes per pixel.

The .xbm exported by the example is a 1 bit per pixel format (1 black, 0 white), you need to edit the code in order to handle more colors (the freetype normally use a 8 bit gray scale bitmap buffer to render, if render mode is FT_RENDER_MODE_NORMAL, you may also need to remove the step with the temporary bitmap used to align the FT buffer to 1 byte).

The to_bitmap function is where the conversion from the FT buffer to the destination bitmap is done,

To build the example the freetype dev package is needed, on Debian (maybe also Ubuntu) use:

sudo apt-get install libfreetype6-dev

Simply make to build it.

Use the command with the font path as argument, the output is on stdout

./font2c /usr/share/fonts/X11/misc/9x15-ISO8859-1.pcf.gz >c-bmp-font.xbm


CFLAGS += -O2 -Wall 
CFLAGS += $(shell freetype-config --cflags)
LIBS += $(shell freetype-config --libs)

font2c: font2c.c
    $(CC) $(CFLAGS) -o $@ $^ $(LIBS)

    -rm -f font2c


#include <stdio.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include <ftbitmap.h>

#define WIDTH   640
#define HEIGHT  480

static unsigned char image[HEIGHT][BYTEWIDTH];

static FT_Library library;
static FT_Face face;
static FT_Error err;
static FT_Bitmap tempbitmap;

static void to_bitmap( FT_Bitmap*  bitmap, FT_Int x, FT_Int y) {

    FT_Int  i, j, p, q;
    FT_Int  x_max = x + bitmap->width;
    FT_Int  y_max = y + bitmap->rows;

    for ( i = x, p = 0; i < x_max; i++, p++ ) {
        for ( j = y, q = 0; j < y_max; j++, q++ ) {
            if ( (i < 0) || (j < 0) || (i >= WIDTH || j >= HEIGHT) )
            image[j][i >> 3] |= (bitmap->buffer[q * bitmap->width + p]) << (i & 7);

static void draw_glyph(unsigned char glyph, int *x, int *y) {
    FT_UInt  glyph_index;
    FT_GlyphSlot  slot = face->glyph;

    glyph_index = FT_Get_Char_Index( face, glyph );

    if ((err = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ))) {
        fprintf( stderr, "warning: failed FT_Load_Glyph 0x%x %d\n", glyph, err);

    if ((err = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_MONO ))) {
        fprintf( stderr, "warning: failed FT_Render_Glyph 0x%x %d\n", glyph, err);

    FT_Bitmap_Convert( library, &slot->bitmap, &tempbitmap, 1);

    to_bitmap( &tempbitmap, *x, *y );

    FT_Bitmap_Done( library, &tempbitmap );

    *x += slot->advance.x >> 6;

static void out_xbm(int w, int h) {
    int x, y;
    printf("#define BMP_width %d\n", WIDTH);
    printf("#define BMP_height %d\n", h);
    printf("static char BMP_bits[] = {\n");
    for (y=0; y < h; y++) {
        for (x=0; x < w; x++) {
            printf("0x%x, ", image[y][x]);

int main(int argc, char **argv) {
    char *filename;
    int x = 0, y = 0;
    int g;

    memset (image, 0, BYTEWIDTH*HEIGHT);

    if (argc < 2) {
        fprintf( stderr, "usage: font2c [font]\n");
    filename = argv[1];

    if ((err = FT_Init_FreeType( &library ))) {
        fprintf( stderr, "error: Init_Freetype failed %d\n", err);
    if ((err = FT_New_Face( library, filename, 0, &face ))) {
        fprintf( stderr, "error: FT_New_Face failed %d\n", err);

    for (g = 0; g < 256; g++) {
        if (x+8 >= WIDTH) {
                x = 0;
                y += 15; // FIXME get ascender
        draw_glyph(g, &x, &y);

    out_xbm(BYTEWIDTH, HEIGHT);

    FT_Done_Face( face );
    FT_Done_FreeType( library );

    return 0;

  • 1
    You're welcome. Added to github with autotools support and facilities to generate the .deb package, maybe I'll make some improvement in the future (having enough free time)
    – Alex
    Jun 4 '14 at 19:03

It's quite easy to convert PSF (console) font to C include rather PCF (X11). I think it will do the trick for you if you're looking for monospace bitmap font for simple embedded applications.

All you need is psf2inc from psftools package:

$ psf2inc --psf1 font.psf font.inc

Now font.inc holding all 256 ASCII characters:

0x36, 0x04,   /* Magic */
0x02,   /* Type */
0x0e,   /* Char size */
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe,
0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00,   /* 0 */
0x00, 0x00, 0xfc, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6,
0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00,   /* 1 */
0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6,
0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00,   /* 2 */

And so on. After some editing you will get a nice header with monospace font.


xxd is your best option :

xxd -i <myfile> > header.h

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy