diff options
Diffstat (limited to 'engines/sci/tools/fonttoc.cpp')
-rw-r--r-- | engines/sci/tools/fonttoc.cpp | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/engines/sci/tools/fonttoc.cpp b/engines/sci/tools/fonttoc.cpp new file mode 100644 index 0000000000..f39f2601e5 --- /dev/null +++ b/engines/sci/tools/fonttoc.cpp @@ -0,0 +1,263 @@ +/*************************************************************************** + bdftofont.c Copyright (C) 2003 Christoph Reichenbach + + + This program may be modified and copied freely according to the terms of + the GNU general public license (GPL), as long as the above copyright + notice and the licensing information contained herein are preserved. + + Please refer to www.gnu.org for licensing details. + + This work is provided AS IS, without warranty of any kind, expressed or + implied, including but not limited to the warranties of merchantibility, + noninfringement, and fitness for a specific purpose. The author will not + be held liable for any damage caused by this work or derivatives of it. + + By using this source code, you agree to the licensing terms as stated + above. + + + Please contact the maintainer for bug reports or inquiries. + + Current Maintainer: + + Christoph Reichenbach (CR) <jameson@linuxgames.com> + +***************************************************************************/ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + + +#define GLYPH(n) glyphs[n] + + +int max_width = 0; + +char inbuf[256]; + +typedef struct { + int bytes; + int width; + unsigned char *bitmap; +} glyph_t; + + +unsigned int +invert_bits(unsigned int s, int bits) +{ + unsigned int rv = 0; + int i; + for (i = 0; i < bits; i++) + if (s & (1 << i)) + rv |= (1 << (bits - 1 - i)); + + return rv; +} + +void +read_single_glyph(FILE *in_file, glyph_t *dest, int index, int char_height) +{ + int width = -1; + int bytes = 0; + int i; + unsigned char *data + = dest->bitmap = (unsigned char *) malloc(char_height * 4); /* Let's waste memory */ + + do { + unsigned int d = 0; + + fgets(inbuf, 255, in_file); + + if (char_height-- == -1) { + fprintf(stderr, "Char 0x%02x is too long!\n", index); + exit(1); + } + + if (inbuf[0] == '.' || inbuf[0] == '#') { + int cw; + + if (width == -1) + width = strlen(inbuf) - 1; + else if (strlen(inbuf) - 1 != width) { + fprintf(stderr, "Char 0x%02x uses inconsistent width\n", index); + exit(1); + } + + for (i = 0; i < width; i++) + if (inbuf[i] == '#') + d |= (1 << i); + + d = invert_bits(d, ((width + 7) / 8) * 8); + + cw = width; + do { + *data = d & 0xff; + d >>= 8; + data++; + cw -= 8; + ++bytes; + } while (cw > 0); + } + + } while (inbuf[0] == '.' || inbuf[0] == '#'); + + if (char_height >= 0) { + fprintf(stderr, "Char 0x%02x is too short (by %d)!\n", index, char_height); + exit(1); + } + + dest->width = width; + if (width > max_width) + max_width = width; + + dest->bytes = bytes; +} + +glyph_t * +read_glyphs(FILE *in_file, int nr, int char_height) +{ + int i; + glyph_t *glyphs = (glyph_t *) calloc(sizeof(glyph_t), nr); + + for (i = 0; i < nr; i++) + read_single_glyph(in_file, glyphs + i, i, char_height); + + return glyphs; +} + +void +convert_font(FILE *in_file, char *structname, FILE *out_file) +{ + int chars_nr; + glyph_t *glyphs; + int bytes_per_row; + int line_height; + int char_height = 0; + int char_byte_size; + int i; + + fscanf(in_file, "# %d %d\n", &chars_nr, &char_height); + printf("Parsing %d characters at height %d\n", chars_nr, char_height); + glyphs = read_glyphs(in_file, chars_nr, char_height); + + bytes_per_row = (max_width + 7) >> 3; + line_height = char_height + 1; + fclose(in_file); + + char_byte_size = bytes_per_row * char_height; + + fprintf(out_file, "/* Auto-generated by bdftofont.c */\n\n"); + + fprintf(out_file, "#include <gfx_system.h>\n\n"); + + fprintf(out_file, "static int %s_widths[] = {\n", structname); + for (i = 0; i < chars_nr; i++) { + int rw = GLYPH(i).width; + fprintf(out_file, "\t%d%s\t/* 0x%02x */\n", rw, + (i < (chars_nr-1))? ",":"", i); + } + fprintf(out_file, "};\n\n"); + + fprintf(out_file, "static unsigned char %s_data[] = {\n", structname); + for (i = 0; i < chars_nr; i++) { + int rh = char_height; + int rw = GLYPH(i).width; + int xoff = 0; + int yoff = 0; + int j, k; + + int top_pad = yoff; + int bot_pad = (char_height - rh) - top_pad; + int bytes_to_read = (GLYPH(i).bytes) / rh; + unsigned char *data = GLYPH(i).bitmap; + + if (bytes_to_read <= 0) { + fprintf(stderr, "No bytes per row: bytes=%d, w=%d, h=%d\n", + GLYPH(i).bytes, rw, rh); + exit(1); + } + + if (bot_pad < 0) { + fprintf(stderr, "Bottom padding <0: height=%d/%d, top_pad=%d\n", + rh, char_height, yoff); + exit(1); + } + + fprintf(out_file,"\t/* 0x%02x ('%c') */\n", i, ((i>31)&&(i<0x7f))?i:'.'); + /* First, pad everything */ + for (j = 0; j < top_pad; j++) { + fprintf(out_file, "\t"); + for (k = 0; k < bytes_per_row; k++) + fprintf(out_file, "0x00, "); + fprintf(out_file, "\n"); + } + + /* Write char data */ + for (j = 0; j < rh; j++) { + unsigned int b = 0; + unsigned int oldb; + fprintf(out_file, "\t"); + for (k = 0; k < bytes_to_read; k++) { + int shift_offset = 8 * (bytes_to_read - 1 - k); + b |= (*data++ << shift_offset); + } + + oldb = b; + + for (k = 0; k < bytes_per_row; k++) { + fprintf(out_file, "0x%02x%s", (b & 0xff), (bot_pad || (i+1 < chars_nr) || (j+1 < rh) || (k+1 < bytes_per_row))?", ":""); + b >>= 8; + } + fprintf(out_file, "\t/* "); + for (k = 0; k < rw; k++) + fprintf(out_file, (oldb & (1 << ((bytes_per_row * 8) - 1 - k)))? "##":".."); + fprintf(out_file, " */"); + + fprintf(out_file, "\n"); + } + + /* Pad bottom */ + for (j = 0; j < bot_pad; j++) { + fprintf(out_file, "\t"); + for (k = 0; k < bytes_per_row; k++) + fprintf(out_file, "0x00%s", ((i+1 < chars_nr) || (j+1 < bot_pad) || (k+1 < bytes_per_row))?", ":""); + fprintf(out_file, "\n"); + } + } + fprintf(out_file, "};\n\n"); + + fprintf(out_file, "gfx_bitmap_font_t %s = {\n", structname); + fprintf(out_file, "\t-1, /* resource ID */\n"); + fprintf(out_file, "\t%d, /* # of characters */\n", chars_nr); + fprintf(out_file, "\t%s_widths, /* Widths */\n", structname); + fprintf(out_file, "\t%d, /* Bytes per row */\n", bytes_per_row); + fprintf(out_file, "\t%d, /* Line height */\n", line_height); + fprintf(out_file, "\t%d, /* Char height */\n", char_height); + fprintf(out_file, "\t%d, /* Char size (occupied, in bytes) */\n", char_byte_size); + fprintf(out_file, "\t%s_data /* Bulk data */\n", structname); + fprintf(out_file, "};\n"); + + fclose(out_file); +} + + +int +main(int argc, char **argv) +{ + FILE *f = NULL; + + if (argc < 4) { + fprintf(stderr, "Usage: %s <font.font> <structname> <outfile.c>\n ", argv[0]); + exit(1); + } + + f = fopen(argv[1], "r"); + if (f) + convert_font(f, argv[2], fopen(argv[3], "w")); + else + perror(argv[1]); + +} |