Dados de fontes de bitmap como array em C

5

Eu preciso converter algumas fontes bitmap X11 em um array em C para um display OLED de 128x64.

Eu vi algumas fontes como /usr/share/fonts/X11/misc/9x15-ISO8859-1.pcf.gz

O resultado deve parecer

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

As ferramentas para converter uma fonte pcf em uma matriz de caracteres em C? Onde estão os bons recursos para fontes de bitmap?

Há mais alguma coisa que eu tenha perdido?

    
por WhiteHotLoveTiger 12.03.2014 / 01:43

2 respostas

7

Você pode usar convert conforme mostrado aqui: arquivo de cabeçalho C com fontes de bitmap

Provavelmente, há muitos comandos para converter fontes em bitmap, mas a API freetype é fácil o suficiente para escrever o seu próprio código sem muito código.

Usando o exemplo do freetype , escrevi algo que você pode usar como ponto de partida. .xbm file (é um arquivo c , mas você pode usar programas gráficos como gimp para visualizar / editar).

Observe que gimp também suporta exportação para .xbm com bytes diferentes por pixel.

O .xbm exportado pelo exemplo é um formato de 1 bit por pixel (1 preto, 0 branco), você precisa editar o código para manipular mais cores (o freetype normalmente usa um buffer de bitmap de escala de cinza de 8 bits para renderizar, se o modo de renderização for FT_RENDER_MODE_NORMAL , talvez seja necessário remover a etapa com o bitmap temporário usado para alinhar o buffer FT a 1 byte.

A função to_bitmap é onde a conversão do buffer FT para o bitmap de destino é feita,

Para construir o exemplo, o pacote freetype dev é necessário, em Debian (talvez também Ubuntu ) use:

sudo apt-get install libfreetype6-dev

Simplesmente make para criá-lo.

Use o comando com o caminho da fonte como argumento, a saída está em 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;

}
    
por 02.06.2014 / 23:13
4

É muito fácil converter a fonte PSF (console) para C, incluindo PCF (X11). Eu acho que ele vai fazer o truque para você, se você estiver procurando por fonte bitmap monoespaçada para aplicativos embarcados simples.

Tudo o que você precisa é de psf2inc de psftools package:

$ psf2inc --psf1 font.psf font.inc

Agora font.inc mantendo todos os 256 caracteres 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 */

E assim por diante. Depois de algumas edições, você terá um bom cabeçalho com fonte monoespaçada.

    
por 30.12.2014 / 18:46