Я использую ttf2pcx, потом парсю pcx -> http://www.allegro.cc/resource/Tools/Fonts/ttf2pcx
Вот парсилка, можно приспособить под свои нужды:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned long uint32_t;
typedef signed long int32_t;
#pragma pack(push, 1)
struct pcx_header
{
uint8_t manufacturer;
uint8_t version;
uint8_t encoding;
uint8_t bpp;
uint16_t xmin;
uint16_t ymin;
uint16_t xmax;
uint16_t ymax;
uint16_t hdpi;
uint16_t vdpi;
uint8_t palette[48];
uint8_t reserved;
uint8_t nplanes;
uint16_t bytesperline;
uint16_t paletteinfo;
uint16_t hscreensize;
uint16_t vscreensize;
uint8_t padding[54];
};
#pragma pack(pop)
struct bitmap_structure
{
uint16_t width;
uint16_t x0, y0;
uint16_t dx, dy;
uint8_t height;
uint8_t nrows;
uint8_t ncols;
uint8_t trim_top;
uint8_t trim_bottom;
};
struct character
{
uint32_t width : 8;
uint32_t index : 24;
};
static int
validate_header(const struct pcx_header* header)
{
if (header->manufacturer != 10)
{
fprintf(stderr, "Wrong manufacturer code.\n");
return 1;
}
if (header->version > 5)
{
fprintf(stderr, "Unexpected version.\n");
return 1;
}
if (header->encoding != 1)
{
fprintf(stderr, "Wrong encoding code.\n");
return 1;
}
if (header->bpp != 8)
{
fprintf(stderr, "Unexpected number of bits per pixel.\n");
return 1;
}
if (header->xmin != 0)
{
fprintf(stderr, "Unexpected Xmin.\n");
return 1;
}
if (header->ymin != 0)
{
fprintf(stderr, "Unexpected Ymin.\n");
return 1;
}
if (header->hscreensize != (header->xmax + 1))
{
fprintf(stderr, "Horizontal screen size inconsistent with Xmax.\n");
return 1;
}
if (header->vscreensize != (header->ymax + 1))
{
fprintf(stderr, "Vertical screen size inconsistent with Ymax.\n");
return 1;
}
if (header->reserved != 0)
{
fprintf(stderr, "Reserved byte not zero.\n");
return 1;
}
if (header->nplanes != 1)
{
fprintf(stderr, "Unexpected number of planes.\n");
return 1;
}
if (header->bytesperline < header->hscreensize)
{
fprintf(stderr, "Unexpected number of bytes per line.\n");
return 1;
}
if (header->paletteinfo != 1)
{
fprintf(stderr, "Unexpected PaletteInfo code.\n");
return 1;
}
return 0;
}
static int
read_byte(FILE* f, uint8_t* c)
{
if (fread(c, 1, 1, f) != 1)
{
fprintf(stderr, "Could not load bitmap data.\n");
return 1;
}
return 0;
}
static int
load_bitmap(FILE* f, const struct pcx_header* header, uint8_t* bitmap)
{
uint8_t c;
int16_t n;
uint16_t nline = 0;
int32_t left = (int32_t)header->hscreensize * header->vscreensize;
do
{
if (read_byte(f, &c) != 0)
{
return 1;
}
if ((c & 0xC0) == 0xC0)
{
n = c & 0x3F;
if (read_byte(f, &c) != 0)
{
return 1;
}
}
else
{
n = 1;
}
nline += n;
if (nline == header->bytesperline)
{
n -= header->bytesperline - header->hscreensize;
nline = 0;
}
else if (nline > header->bytesperline)
{
fprintf(stderr, "Too much data in scan line.\n");
return 1;
}
left -= n;
if (left < 0)
{
fprintf(stderr, "Too much data in bitmap.\n");
return 1;
}
memset(bitmap, c, n);
bitmap += n;
}
while (left > 0);
return 0;
}
static int
analyze_bitmap(const struct pcx_header* header,
const uint8_t* bitmap,
struct bitmap_structure* bms)
{
uint16_t x, y, row;
bms->width = header->hscreensize;
for (y = 0; y < header->vscreensize; y++)
{
for (x = 0; x < header->hscreensize; x++)
{
if (bitmap[x + y * header->hscreensize] != 0xFF)
{
bms->x0 = x;
bms->y0 = y;
goto next;
}
}
}
fprintf(stderr, "Could not find first character.\n");
return 1;
next:
while (bitmap[x + bms->y0 * header->hscreensize] != 0xFF)
{
x++;
if (x >= header->hscreensize)
{
fprintf(stderr, "Could not find first character width.\n");
return 1;
}
}
while (bitmap[x + bms->y0 * header->hscreensize] == 0xFF)
{
x++;
if (x >= header->hscreensize)
{
fprintf(stderr, "Could not find second column.\n");
return 1;
}
}
bms->dx = x - bms->x0;
while (bitmap[bms->x0 + y * header->hscreensize] != 0xFF)
{
y++;
if (y >= header->vscreensize)
{
fprintf(stderr, "Could not find first character height.\n");
return 1;
}
}
bms->height = y - bms->y0;
while (bitmap[bms->x0 + y * header->hscreensize] == 0xFF)
{
y++;
if (y >= header->vscreensize)
{
fprintf(stderr, "Could not find second row.\n");
return 1;
}
}
bms->dy = y - bms->y0;
bms->ncols = 0;
for (x = bms->x0; x < header->hscreensize; x += bms->dx)
{
if (bitmap[x + bms->y0 * header->hscreensize] != 0xFF)
{
bms->ncols++;
}
}
bms->nrows = 0;
for (y = bms->y0; y < header->vscreensize; y += bms->dy)
{
if (bitmap[bms->x0 + y * header->hscreensize] != 0xFF)
{
bms->nrows++;
}
}
if (bms->y0 + bms->dy * (bms->nrows - 1) + bms->height > header->vscreensize)
{
fprintf(stderr, "Rows don't fit into bitmap.\n");
return 1;
}
bms->trim_top = 255;
bms->trim_bottom = 255;
for (row = 0; row < bms->nrows; row++)
{
for (y = 0; y < bms->height; y++)
{
for (x = 0; x < bms->width; x++)
{
uint8_t byte;
byte = bitmap[x + (bms->y0 + y + row * bms->dy) * bms->width];
if ((byte > 0) && (byte < 0xFF))
{
goto found_top;
}
}
}
found_top:
if (y < bms->trim_top)
{
bms->trim_top = y;
}
for (y = bms->height - 1; y >= 0; y--)
{
for (x = 0; x < bms->width; x++)
{
uint8_t byte;
byte = bitmap[x + (bms->y0 + y + row * bms->dy) * bms->width];
if ((byte > 0) && (byte < 0xFF))
{
goto found_bottom;
}
}
}
found_bottom:
y = bms->height - 1 - y;
if (y < bms->trim_bottom)
{
bms->trim_bottom = y;
}
}
return 0;
}
static void
emit_nibble(uint32_t* bitstream, uint32_t* index, uint8_t data)
{
bitstream[*index >> 3] &= ~(0xF << ((7 & *index) * 4));
bitstream[*index >> 3] |= (data << ((7 & *index) * 4));
++*index;
}
static void
emit_bitstream(uint32_t* bitstream, uint32_t* index, uint8_t c, uint16_t n)
{
while (n > 1)
{
uint8_t dn = (n > 16) ? 16 : n;
emit_nibble(bitstream, index, c | 8);
emit_nibble(bitstream, index, dn - 1);
n -= dn;
}
if (n == 1)
{
emit_nibble(bitstream, index, c);
}
}
static int
extract_char(const uint8_t* bitmap,
const struct bitmap_structure* bms,
struct character* ch,
uint32_t* bitstream,
uint32_t* index,
uint32_t* bitstream_top)
{
uint16_t x, y, runlen = 0;
uint8_t runchar;
ch->index = *index;
for (x = 0; bitmap[x] != 0xFF; x++)
{
}
ch->width = x;
for (y = bms->trim_top; y < bms->height - bms->trim_bottom; y++)
{
for (x = 0; x < ch->width; x++)
{
uint8_t c;
c = bitmap[x + y * bms->width];
if (c >= 8)
{
fprintf(stderr, "Unexpected pixel within character.\n");
return 1;
}
if (runlen == 0)
{
runchar = c;
runlen = 1;
}
else if (c == runchar)
{
runlen++;
}
else
{
emit_bitstream(bitstream, index, runchar, runlen);
if (bitstream >= bitstream_top)
{
fprintf(stderr, "Font bitstream over 64Kbytes.\n");
return 1;
}
runchar = c;
runlen = 1;
}
}
}
emit_bitstream(bitstream, index, runchar, runlen);
if (bitstream >= bitstream_top)
{
fprintf(stderr, "Font bitstream over 64Kbytes.\n");
return 1;
}
return 0;
}
static int
extract_font(const uint8_t* bitmap,
const struct bitmap_structure* bms,
struct character chars[256],
uint32_t* bitstream,
uint32_t* index)
{
uint16_t col, row, i = 0;
for (row = 0; row < bms->nrows; row++)
{
for (col = 0; col < bms->ncols; col++)
{
uint16_t x, y;
x = bms->x0 + col * bms->dx;
y = bms->y0 + row * bms->dy;
if (bitmap[x + y * bms->width] != 0xFF)
{
if (extract_char(&bitmap[x + y * bms->width],
bms,
&chars[i],
bitstream,
index,
bitstream
+ sizeof(bitstream)
/ sizeof(bitstream[0])) != 0)
{
return 1;
}
i++;
}
}
}
return 0;
}
static void
dump_source(struct character chars[256],
const uint32_t* bitstream,
uint32_t index,
const char* name,
uint8_t height)
{
uint16_t i;
printf("#include \"lcd.h\"\n\n");
printf("static const uint32_t bitstream[] = {\n");
for (i = 0; i < (index + 7) / 8; i++)
{
if (i % 4 == 0)
{
if (i > 0)
{
printf(",\n");
}
printf(" ");
}
else
{
printf(", ");
}
printf("0x%08X", (int)bitstream[i]);
}
printf("\n};\n\n");
printf("static const struct font_char chars[] = {\n");
for (i = 0; i < 256; i++)
{
if (chars[i].width == 0)
{
break;
}
else
{
if (i > 0)
{
printf(",\n");
}
printf(" { %2d, %5d }",
(int)chars[i].width,
(int)chars[i].index);
}
}
printf("\n};\n\n");
printf("const struct font %s = {\n", name);
printf(" %d,\n", height);
printf(" 32,\n"
" chars,\n"
" bitstream\n"
"};\n");
}
int
main(int argc, char* argv[])
{
FILE* f;
struct pcx_header header;
uint8_t* bitmap;
static struct character chars[256];
static uint32_t bitstream[8192];
struct bitmap_structure bms;
uint32_t index = 0;
if (argc < 3)
{
fprintf(stderr, "Usage: ttf2font3bpp filename fontname\n");
return 1;
}
f = fopen(argv[1], "rb");
if (f == 0)
{
fprintf(stderr, "Could not open file %s.\n", argv[1]);
return 1;
}
if (fread(&header, sizeof(header), 1, f) < 1)
{
fprintf(stderr, "Could not load PCX header.\n");
return 1;
}
header.hscreensize = header.xmax + 1;
header.vscreensize = header.ymax + 1;
if (validate_header(&header) != 0)
{
return 1;
}
bitmap = (uint8_t*)malloc(1 + (uint32_t)header.hscreensize * header.vscreensize);
if (bitmap == 0)
{
fprintf(stderr, "Could not allocate memory for bitmap.\n");
return 1;
}
if (load_bitmap(f, &header, bitmap) != 0)
{
return 1;
}
if (analyze_bitmap(&header, bitmap, &bms) != 0)
{
return 1;
}
if (extract_font(bitmap, &bms, chars, bitstream, &index) != 0)
{
return 1;
}
dump_source(chars, bitstream, index, argv[2],
bms.height - bms.trim_top - bms.trim_bottom);
return 0;
}
ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้
Вот парсилка, можно приспособить под свои нужды:
-
- хм скачал ttf2pcx а русские буквы она не берет - а они нужны . И еще под чем парсилка компиляется то ? - Blackbird_sunday(21.08.2012 08:13, )
- Русские буквы есть: 0x410-0x44F (уникод рулит). А компилятор - по сцылке (копипастим код в окошко и вуаля) -> SciFi(266 знак., 21.08.2012 09:35 - 09:45, ссылка)
- хм скачал ttf2pcx а русские буквы она не берет - а они нужны . И еще под чем парсилка компиляется то ? - Blackbird_sunday(21.08.2012 08:13, )