ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
10 мая
347468 Топик полностью
SciFi (16.08.2012 09:52, просмотров: 220) ответил Blackbird_sunday на Чем сделать точечные фонты из *.ttf . Проблема не простая - в общем мне нужно будет загонять в плисину фонт чтоб на дисплюй выводить . Как там чо описать это не та проблема - проблема сначала бинарник сделать со шрифтом . Видел пару прог которые
Я использую 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; }
ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้