Bitmap Font data as array in C

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

Makefile:

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

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

clean:
    -rm -f font2c

font2c.c:

#include <stdio.h>

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

#define WIDTH   640
#define BYTEWIDTH (WIDTH)/8
#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) )
                continue;
            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);
        return;
    }

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

    FT_Bitmap_New(&tempbitmap);
    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++) {
        printf("\t");
        for (x=0; x < w; x++) {
            printf("0x%x, ", image[y][x]);
        }
        printf("\n");
    }
    printf("\n}\n");
}

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");
        exit(1);
    }
    filename = argv[1];

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

    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;

}

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.