web-dev-qa-db-ja.com

Cの配列としてのビットマップフォントデータ

128x64 OLEDディスプレイ用に、いくつかのX11ビットマップフォントをCの配列に変換する必要があります。

/usr/share/fonts/X11/misc/9x15-ISO8859-1.pcf.gzのようなフォントをいくつか見ました

結果は次のようになります

/* 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,// "

PcfフォントをCの文字配列に変換するツールはありますか?ビットマップフォントの良いリソースはどこにありますか?

他に見逃したことはありますか?

5
user55518

次のようにconvertを使用できます。 ビットマップフォントを含むCヘッダーファイル

フォントをビットマップに変換するコマンドはたくさんありますが、 freetype API は、それほど多くのコードを含まない独自のコマンドを書くのに十分簡単です。

freetypeの例 を使用して、最初に使用できるものを書き、.xbmファイルを出力します(cファイルですが、gimpで表示/編集します)。

gimpは、ピクセルあたりのバイト数が異なる.xbmへのエクスポートもサポートしていることに注意してください。

この例でエクスポートされる.xbmは、1ビット/ピクセル形式(1黒、0白)です。より多くの色を処理するには、コードを編集する必要があります(freetypeは通常、8ビットのグレースケールビットマップバッファーを使用してレンダー、レンダーモードがFT_RENDER_MODE_NORMALの場合、FTバッファーを1バイトに整列するために使用される一時ビットマップを使用してステップを削除する必要がある場合もあります)。

to_bitmap関数は、FTバッファーから宛先ビットマップへの変換が行われる場所です。

例をビルドするには、freetype devパッケージが必要です。Debian(おそらくUbuntu)を使用します。

Sudo apt-get install libfreetype6-dev

単にmakeを作成してください。

引数としてフォントパスを指定してコマンドを使用します。出力は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;

}
7
Alex

PSF(コンソール)フォントをCインクルードPCF(X11)に変換するのは非常に簡単です。単純な組み込みアプリケーション用のモノスペースビットマップフォントを探している場合は、これでうまくいくと思います。

あなたに必要なのは psf2incpsftoolsパッケージから:

$ psf2inc --psf1 font.psf font.inc

font.inc 256文字すべてを保持ASCII文字:

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 */

等々。少し編集すると、等幅フォントのNiceヘッダーが表示されます。

4
andele

xxdが最善のオプションです。

xxd -i <myfile> > header.h
0
ScottHamilton