diff --git a/scripts/font_converter.py b/scripts/font_converter.py index f2ba0e49b..0293c6232 100644 --- a/scripts/font_converter.py +++ b/scripts/font_converter.py @@ -9,6 +9,7 @@ def convert(input, output): dic = {} for part in parts: + print parts, part key, value = part.split('=') try: @@ -19,8 +20,26 @@ def convert(input, output): return dic def get_entry(line): + while line[-1] == "\r" or line[-1] == "\n": + line = line[0:-1] + parts = [] + + quote = 0 + part = "" + + for c in line: + if c == "\"": + quote = 1-quote + elif c == " " and not quote: + if part: + parts.append(part) + part = "" + else: + part += c + + if part: + parts.append(part) - parts = line.split() type = parts[0] dic = build_dic(parts[1:]) @@ -80,7 +99,8 @@ def convert(input, output): kernings.append(None) def save_char(dic): - chars[dic["id"]] = dic + if dic["id"] < 256: + chars[dic["id"]] = dic def save_kerning(dic): kernings[dic["first"] + dic["second"]*256] = dic diff --git a/src/engine/client/ec_font.c b/src/engine/client/ec_font.c new file mode 100644 index 000000000..71a26cd55 --- /dev/null +++ b/src/engine/client/ec_font.c @@ -0,0 +1,190 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#include +#include +#include +#include "ec_font.h" + +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 = 1.0f/font_data.size; + float scale_factor_y = 1.0f/font_data.size; + 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>>6)*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 gfx_load_texture(const char *filename); + +int font_set_load(FONT_SET *font_set, const char *font_filename, const char *texture_filename, int fonts, ...) +{ + int i; + va_list va; + + font_set->font_count = fonts; + + va_start(va, fonts); + for (i = 0; i < fonts; i++) + { + int size; + char composed_font_filename[256]; + char composed_texture_filename[256]; + FONT *font = &font_set->fonts[i]; + + size = va_arg(va, int); + sprintf(composed_font_filename, font_filename, size); + sprintf(composed_texture_filename, texture_filename, size); + + if (font_load(font, composed_font_filename)) + { + va_end(va); + return -1; + } + + font->size = size; + font->texture = gfx_load_texture(composed_texture_filename); + + dbg_msg("font_set/loading", "filename: %s", composed_font_filename); + } + + va_end(va); + return 0; +} + +float font_set_string_width(FONT_SET *font_set, const char *string, float size) +{ + float width = 0.0f; + + const unsigned char *c = (unsigned char *)string; + + FONT *font = &font_set->fonts[0]; + + 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; +} + +float font_kerning(FONT *font, unsigned char c1, unsigned char c2) +{ + return font->kerning[c1 + c2*256]; +} + +FONT *font_set_pick(FONT_SET *font_set, float size) +{ + int i; + FONT *picked_font = 0x0; + + for (i = font_set->font_count-1; i >= 0; i--) + { + FONT *font = &font_set->fonts[i]; + + if (font->size >= size) + picked_font = font; + } + + if (!picked_font) + picked_font = &font_set->fonts[font_set->font_count-1]; + + return picked_font; +} diff --git a/src/engine/client/ec_font.h b/src/engine/client/ec_font.h new file mode 100644 index 000000000..6b4d5910f --- /dev/null +++ b/src/engine/client/ec_font.h @@ -0,0 +1,40 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#ifndef _FONT_H +#define _FONT_H + +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; + int size; + CHARACTER characters[256]; + float kerning[256*256]; +} FONT; + +typedef struct +{ + int font_count; + FONT fonts[8]; +} FONT_SET; + +int font_load(FONT *font, const char *filename); +int font_set_load(FONT_SET *font_set, const char *font_filename, const char *texture_filename, int fonts, ...); +float font_string_width(FONT_SET *font_set, 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); +float font_kerning(FONT *font, unsigned char c1, unsigned char c2); +FONT *font_set_pick(FONT_SET *font_set, float size); + +#endif diff --git a/src/engine/client/ec_gfx.c b/src/engine/client/ec_gfx.c index d93d07df7..106226a43 100644 --- a/src/engine/client/ec_gfx.c +++ b/src/engine/client/ec_gfx.c @@ -12,6 +12,8 @@ #include #include +#include "ec_font.h" + /* compressed textures */ #define GL_COMPRESSED_RGB_ARB 0x84ED #define GL_COMPRESSED_RGBA_ARB 0x84EE @@ -882,13 +884,47 @@ static int word_length(const char *text) } } - - static float pretty_r=1; static float pretty_g=1; static float pretty_b=1; static float pretty_a=1; +void gfx_text(void *font_set_v, float x, float y, const char *text, float size) +{ + const unsigned char *c = (unsigned char *)text; + + FONT_SET *font_set = font_set_v; + FONT *font = font_set_pick(font_set, size); + + gfx_texture_set(font->texture); + + gfx_quads_begin(); + gfx_setcolor(pretty_r, pretty_g, pretty_b, pretty_a); + + while (*c) + { + float tex_x0, tex_y0, tex_x1, tex_y1; + float width, height; + float x_offset, y_offset, x_advance; + + float 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); + + advance = x_advance + font_kerning(font, *c, *(c+1)); + + x += advance*size; + + c++; + } + + gfx_quads_end(); +} + void gfx_pretty_text_color(float r, float g, float b, float a) { pretty_r = r; diff --git a/src/engine/client/ec_ui.c b/src/engine/client/ec_ui.c index b0e088a04..50234a6bc 100644 --- a/src/engine/client/ec_ui.c +++ b/src/engine/client/ec_ui.c @@ -276,160 +276,3 @@ void ui_margin(const struct rect *original, int pixels, struct rect *other_rect) 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(); -} diff --git a/src/engine/client/ec_ui.h b/src/engine/client/ec_ui.h index 3464a2e61..15c63b901 100644 --- a/src/engine/client/ec_ui.h +++ b/src/engine/client/ec_ui.h @@ -29,33 +29,6 @@ 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 diff --git a/src/engine/e_interface.h b/src/engine/e_interface.h index 111d5e54e..9f86d4c87 100644 --- a/src/engine/e_interface.h +++ b/src/engine/e_interface.h @@ -856,6 +856,7 @@ void client_serverbrowse_update(); /* undocumented graphics stuff */ +void gfx_text(void *font, float x, float y, const char *text, float size); void gfx_pretty_text_color(float r, float g, float b, float a); void gfx_pretty_text(float x, float y, float size, const char *text, int max_width); float gfx_pretty_text_width(float size, const char *text, int length); diff --git a/src/game/client/gc_menu.cpp b/src/game/client/gc_menu.cpp index 449004d95..a45b065cc 100644 --- a/src/game/client/gc_menu.cpp +++ b/src/game/client/gc_menu.cpp @@ -12,6 +12,7 @@ extern "C" { #include #include #include + #include } #include "../g_mapres.h" @@ -1875,6 +1876,34 @@ int menu2_render() RECT screen = *ui2_screen(); gfx_mapscreen(screen.x, screen.y, screen.w, screen.h); + + if (1) + { + static FONT_SET font_set; + static bool first = true; + + if (first) + { + font_set_load(&font_set, "fonts/vera%d.tfnt", "fonts/vera%d.png", 4, 8, 10, 12, 14); + first = false; + } + + gfx_clear(0.65f,0.78f,0.9f); + //gfx_pretty_text_color(0.0f, 0.0f, 0.0f, 1.0f); + //gfx_pretty_text_color(0.0f, 0.0f, 0.0f, 1.0f); + + for (int i = 0; i < 24; i++) + { + float size = i * 0.5 + 8; + char temp[64]; + sprintf(temp, "%f: Ingen tomte i jul", size); + gfx_pretty_text(50, 10 + i*int(size), size, temp, -1); + gfx_text(&font_set, 400, 10 + i*int(size), temp, size); + } + + + return 0; + } static bool first = true; if(first)