add new font stuff

This commit is contained in:
Jakob Fries 2007-12-22 02:55:19 +00:00
parent 87b89138f4
commit 1ddfbba366
5 changed files with 309 additions and 0 deletions

121
scripts/font_converter.py Normal file
View file

@ -0,0 +1,121 @@
from __future__ import with_statement
import struct
import sys
def convert(input, output):
with open(input, "r") as in_file:
with open(output, "w") as out_file:
def build_dic(parts):
dic = {}
for part in parts:
key, value = part.split('=')
try:
dic[key] = int(value)
except:
dic[key] = value
return dic
def get_entry(line):
parts = line.split()
type = parts[0]
dic = build_dic(parts[1:])
return type, dic
def write_int16(val):
out_file.write(struct.pack('<h', val))
def write_info(dic):
write_int16(dic["size"])
def write_common(dic):
write_int16(dic["scaleW"])
write_int16(dic["scaleH"])
write_int16(dic["lineHeight"])
write_int16(dic["base"])
def write_page(dic):
pass
def write_chars(dic):
pass
def write_char(dic):
write_int16(dic["x"])
write_int16(dic["y"])
write_int16(dic["width"])
write_int16(dic["height"])
write_int16(dic["xoffset"])
write_int16(dic["yoffset"])
write_int16(dic["xadvance"])
def write_default_char():
write_int16(0)
write_int16(0)
write_int16(0)
write_int16(0)
write_int16(0)
write_int16(0)
write_int16(0)
def write_kernings(dic):
pass
def write_kerning(dic):
write_int16(dic["amount"])
def write_default_kerning():
write_int16(0)
chars = []
kernings = []
for i in range(256):
chars.append(None)
for i in range(256*256):
kernings.append(None)
def save_char(dic):
chars[dic["id"]] = dic
def save_kerning(dic):
kernings[dic["first"] + dic["second"]*256] = dic
write_table = {
"info": write_info,
"common": write_common,
"page": write_page,
"chars": write_chars,
"char": save_char,
"kernings": write_kernings,
"kerning": save_kerning
}
for line in in_file:
type, dic = get_entry(line)
write_table[type](dic)
for i in range(256):
if chars[i]:
write_char(chars[i])
else:
write_default_char()
for i in range(256*256):
if kernings[i]:
write_kerning(kernings[i])
else:
write_default_kerning()
if len(sys.argv) != 3:
print "font converter! converts .fnt files to teewars .tfnt"
print "usage: font_converter <input> <output>"
else:
print "converting..."
convert(sys.argv[1], sys.argv[2])
print "done!"

View file

@ -554,6 +554,7 @@ int gfx_load_png(IMAGE_INFO *img, const char *filename)
{
dbg_msg("game/png", "invalid format. filename='%s'", filename);
png_close_file(&png);
return 0;
}
buffer = (unsigned char *)mem_alloc(png.width * png.height * png.bpp, 1);

View file

@ -275,3 +275,161 @@ void ui_margin(const struct rect *original, int pixels, struct rect *other_rect)
other_rect->w = r.w - 2*pixels;
other_rect->h = r.h - 2*pixels;
}
typedef struct
{
short x, y;
short width, height;
short x_offset, y_offset;
short x_advance;
} FONT_CHARACTER;
typedef struct
{
short size;
short width, height;
short line_height;
short base;
FONT_CHARACTER characters[256];
short kerning[256*256];
} FONT_DATA;
int font_load(FONT *font, const char *filename)
{
FONT_DATA font_data;
IOHANDLE file;
dbg_msg("font/load", "loading %s", filename);
file = io_open(filename, IOFLAG_READ);
if(file)
{
int i;
io_read(file, &font_data, sizeof(FONT_DATA));
io_close(file);
#if defined(CONF_ARCH_ENDIAN_BIG)
swap_endian(&font_data, 2, sizeof(FONT_DATA)/2);
#endif
dbg_msg("font/load", "width: %d, height: %d, sizeof(FONT_DATA): %d", font_data.width, font_data.height, sizeof(FONT_DATA));
{
float scale_factor_x = ((float)font_data.size)/font_data.width;
float scale_factor_y = ((float)font_data.size)/font_data.height;
float scale_factor_tex_x = 1.0f/font_data.width;
float scale_factor_tex_y = 1.0f/font_data.height;
for (i = 0; i < 256; i++)
{
float tex_x0 = font_data.characters[i].x*scale_factor_tex_x;
float tex_y0 = font_data.characters[i].y*scale_factor_tex_y;
float tex_x1 = (font_data.characters[i].x+font_data.characters[i].width)*scale_factor_tex_x;
float tex_y1 = (font_data.characters[i].y+font_data.characters[i].height)*scale_factor_tex_y;
float width = font_data.characters[i].width*scale_factor_x;
float height = font_data.characters[i].height*scale_factor_y;
float x_offset = font_data.characters[i].x_offset*scale_factor_x;
float y_offset = font_data.characters[i].y_offset*scale_factor_y;
float x_advance = font_data.characters[i].x_advance*scale_factor_x;
font->characters[i].tex_x0 = tex_x0;
font->characters[i].tex_y0 = tex_y0;
font->characters[i].tex_x1 = tex_x1;
font->characters[i].tex_y1 = tex_y1;
font->characters[i].width = width;
font->characters[i].height = height;
font->characters[i].x_offset = x_offset;
font->characters[i].y_offset = y_offset;
font->characters[i].x_advance = x_advance;
}
for (i = 0; i < 256*256; i++)
{
font->kerning[i] = font_data.kerning[i]*scale_factor_x;
}
}
return 0;
}
else
return -1;
}
int font_save(FONT *font, const char *filename)
{
return 0;
}
float font_string_width(FONT *font, const char *string, float size)
{
float width = 0.0f;
const unsigned char *c = (unsigned char *)string;
while (*c)
{
float tex_x0, tex_y0, tex_x1, tex_y1;
float char_width, char_height;
float x_offset, y_offset, x_advance;
font_character_info(font, *c, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &char_width, &char_height, &x_offset, &y_offset, &x_advance);
width += x_advance;
c++;
}
return width*size;
}
void font_character_info(FONT *font, unsigned char c, float *tex_x0, float *tex_y0, float *tex_x1, float *tex_y1, float *width, float *height, float *x_offset, float *y_offset, float *x_advance)
{
CHARACTER *character = &font->characters[c];
*tex_x0 = character->tex_x0;
*tex_y0 = character->tex_y0;
*tex_x1 = character->tex_x1;
*tex_y1 = character->tex_y1;
*width = character->width;
*height = character->height;
*x_offset = character->x_offset;
*y_offset = character->y_offset;
*x_advance = character->x_advance;
}
void font_render(FONT *font, const char *string, float x, float y, float size)
{
const unsigned char *c = (unsigned char *)string;
gfx_texture_set(font->texture);
gfx_quads_begin();
gfx_setcolor(1.0f, 1.0f, 1.0f, 1.0f);
while (*c)
{
float tex_x0, tex_y0, tex_x1, tex_y1;
float width, height;
float x_offset, y_offset, x_advance;
font_character_info(font, *c, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &width, &height, &x_offset, &y_offset, &x_advance);
gfx_quads_setsubset(tex_x0, tex_y0, tex_x1, tex_y1);
gfx_quads_drawTL(x+x_offset*size, y+y_offset*size, width*size, height*size);
x += x_advance*size;
c++;
}
gfx_quads_end();
}

View file

@ -29,6 +29,33 @@ void ui_do_image(int texture, float x, float y, float w, float h);
void ui_do_label(float x, float y, const char *text, float size);
int ui_do_button(const void *id, const char *text, int checked, float x, float y, float w, float h, draw_button_callback draw_func, void *extra);
typedef struct
{
float tex_x0;
float tex_y0;
float tex_x1;
float tex_y1;
float width;
float height;
float x_offset;
float y_offset;
float x_advance;
}
CHARACTER;
typedef struct
{
int texture;
CHARACTER characters[256];
float kerning[256*256];
} FONT;
int font_load(FONT *font, const char *filename);
int font_save(FONT *font, const char *filename);
float font_string_width(FONT *font, const char *string, float size);
void font_character_info(FONT *font, unsigned char c, float *tex_x0, float *tex_y0, float *tex_x1, float *tex_y1, float *width, float *height, float *x_offset, float *y_offset, float *x_advance);
void font_render(FONT *font, const char *string, float x, float y, float size);
#ifdef __cplusplus
}
#endif

View file

@ -1831,6 +1831,8 @@ void menu_do_connected()
void menu_init()
{
int i;
if(config.cl_show_welcome)
popup = POPUP_FIRST_LAUNCH;
config.cl_show_welcome = 0;