mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-21 01:08:25 +00:00
e241843bec
- Mass rename .c to .cpp svn-id: r38227
264 lines
6.3 KiB
C++
264 lines
6.3 KiB
C++
/***************************************************************************
|
|
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]);
|
|
|
|
}
|