Fonts

點陣圖字型數據作為C中的數組

  • November 2, 2019

我需要將一些 X11 點陣圖字型轉換為 C 中的數組以用於 128x64 OLED 顯示器。

我看到一些字型像/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中的字元數組的工具是什麼?點陣圖字型的好資源在哪裡?

還有什麼我錯過的嗎?

您可以使用convert如下所示:C header file with bitmapped fonts

可能有很多命令可以將字型轉換為點陣圖,但是freetype API很容易編寫您自己的 API,而無需太多程式碼。

使用freetype 範例我寫了一些你可以用作開始的東西,它輸出一個.xbm文件(是一個c文件,但你可以使用圖形程序gimp來查看/編輯它)。

Notichegimp也支持導出到.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;

}

引用自:https://unix.stackexchange.com/questions/119236