about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2009-06-07 14:36:54 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2009-06-07 14:36:54 +0000
commitcdc5f26900dc10e10679ba76a30f195e8b3f5505 (patch)
tree415b28219072589b09031c145d34def8e0f8956b /src
parent4bb1df318905f491740f4298c69cda317fb53fcb (diff)
downloadzcatch-cdc5f26900dc10e10679ba76a30f195e8b3f5505.tar.gz
zcatch-cdc5f26900dc10e10679ba76a30f195e8b3f5505.zip
new font rendering system using freetype2. only compiles under linux for now
Diffstat (limited to 'src')
-rw-r--r--src/engine/client/ec_font.c199
-rw-r--r--src/engine/client/ec_font.h41
-rw-r--r--src/engine/client/ec_gfx.c34
-rw-r--r--src/engine/client/ec_gfx_text.c448
-rw-r--r--src/engine/e_client_interface.h1
-rw-r--r--src/engine/e_if_gfx.h12
-rw-r--r--src/game/client/components/console.cpp3
-rw-r--r--src/game/client/components/controls.cpp2
-rw-r--r--src/game/client/components/menus.cpp15
-rw-r--r--src/game/client/components/menus_browser.cpp5
-rw-r--r--src/game/client/gameclient.cpp11
-rwxr-xr-xsrc/tools/font_generator/alte_haas_grotesk.ttfbin262372 -> 0 bytes
-rwxr-xr-xsrc/tools/font_generator/alte_haas_grotesk_bold.ttfbin262248 -> 0 bytes
-rwxr-xr-xsrc/tools/font_generator/boris_black_bloxx.ttfbin53152 -> 0 bytes
-rwxr-xr-xsrc/tools/font_generator/build1
-rwxr-xr-xsrc/tools/font_generator/komika_axis.ttfbin53996 -> 0 bytes
-rwxr-xr-xsrc/tools/font_generator/main.cpp191
-rwxr-xr-xsrc/tools/font_generator/tahoma.ttfbin383140 -> 0 bytes
-rw-r--r--src/trackinggenerator/main.cpp110
19 files changed, 457 insertions, 616 deletions
diff --git a/src/engine/client/ec_font.c b/src/engine/client/ec_font.c
deleted file mode 100644
index f8760d41..00000000
--- a/src/engine/client/ec_font.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <base/system.h>
-#include <engine/e_client_interface.h>
-#include <engine/e_engine.h>
-#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;
-
-	file = engine_openfile(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
-
-        {
-            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)*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] = (char)font_data.kerning[i];
-            }
-        }
-
-        return 0;
-    }
-    else
-        return -1;
-}
-
-/*int gfx_load_texture(const char *filename, int store_format, int flags);
-#define IMG_ALPHA 2*/
-
-int font_set_load(FONT_SET *font_set, const char *font_filename, const char *text_texture_filename, const char *outline_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_text_texture_filename[256];
-        char composed_outline_texture_filename[256];
-        FONT *font = &font_set->fonts[i];
-
-        size = va_arg(va, int);
-        str_format(composed_font_filename, sizeof(composed_font_filename), font_filename, size);
-        str_format(composed_text_texture_filename, sizeof(composed_text_texture_filename), text_texture_filename, size);
-        str_format(composed_outline_texture_filename, sizeof(composed_outline_texture_filename), outline_texture_filename, size);
-
-        if (font_load(font, composed_font_filename))
-        {
-            dbg_msg("font/loading", "failed loading font %s.", composed_font_filename);
-            va_end(va);
-            return -1;
-        }
-
-        font->size = size;
-        font->text_texture = gfx_load_texture(composed_text_texture_filename, IMG_ALPHA, TEXLOAD_NORESAMPLE);
-        font->outline_texture = gfx_load_texture(composed_outline_texture_filename, IMG_ALPHA, TEXLOAD_NORESAMPLE);
-    }
-
-    va_end(va);
-    return 0;
-}
-
-float font_text_width(FONT *font, const char *text, float size, int length)
-{
-    float width = 0.0f;
-
-    const unsigned char *c = (unsigned char *)text;
-    int chars_left;
-    if (length == -1)
-        chars_left = strlen(text);
-    else
-        chars_left = length;
-
-    while (chars_left--)
-    {
-        float tex_x0, tex_y0, tex_x1, tex_y1;
-        float char_width, char_height;
-        float x_offset, y_offset, x_advance;
-        float advance;
-
-        font_character_info(font, *c, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &char_width, &char_height, &x_offset, &y_offset, &x_advance);
-
-        advance = x_advance + font_kerning(font, *c, *(c+1));
-
-        width += 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] / (float)font->size;
-}
-
-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
deleted file mode 100644
index e38b11b7..00000000
--- a/src/engine/client/ec_font.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 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 text_texture;
-    int outline_texture;
-    int size;
-    CHARACTER characters[256];
-    char kerning[256*256];
-} FONT;
-
-typedef struct
-{
-    int font_count;
-    FONT fonts[14];
-} FONT_SET;
-
-int font_load(FONT *font, const char *filename);
-int font_set_load(FONT_SET *font_set, const char *font_filename, const char *text_texture_filename, const char *outline_texture_filename, int fonts, ...);
-float font_text_width(FONT *font, const char *text, float size, int width);
-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 97dced87..1ea9f407 100644
--- a/src/engine/client/ec_gfx.c
+++ b/src/engine/client/ec_gfx.c
@@ -29,8 +29,6 @@
 #include <stdio.h>
 #include <math.h>
 
-#include "ec_font.h"
-
 /* compressed textures */
 #define GL_COMPRESSED_RGB_ARB 0x84ED
 #define GL_COMPRESSED_RGBA_ARB 0x84EE
@@ -118,8 +116,8 @@ static void flush()
 	}
 	
 		
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
 	glVertexPointer(3, GL_FLOAT,
 			sizeof(VERTEX),
@@ -210,6 +208,8 @@ static int try_init()
 	return 0;
 }
 
+void gfx_font_init();
+
 static int gfx_init_window()
 {
 	if(try_init() == 0)
@@ -324,8 +324,8 @@ int gfx_init()
 		glDepthMask(0);
 
 		
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 	}
 
 	/* init input */
@@ -333,7 +333,11 @@ int gfx_init()
 	
 	/* create null texture, will get id=0 */
 	invalid_texture = gfx_load_texture_raw(4,4,IMG_RGBA,null_texture_data,IMG_RGBA,TEXLOAD_NORESAMPLE);
+	dbg_msg("", "invalid texture id: %d %d", invalid_texture, textures[invalid_texture].tex);
+
 
+	/* font init */
+	gfx_font_init();
 	/* perform some tests */
 	/* pixeltest_dotesting(); */
 	
@@ -544,7 +548,7 @@ int gfx_load_texture_raw(int w, int h, int format, const void *data, int store_f
 	glGenTextures(1, &textures[tex].tex);
 	glBindTexture(GL_TEXTURE_2D, textures[tex].tex);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
 	gluBuild2DMipmaps(GL_TEXTURE_2D, store_oglformat, w, h, oglformat, GL_UNSIGNED_BYTE, texdata);
 	
 	/* calculate memory usage */
@@ -646,8 +650,24 @@ void gfx_screenshot()
 	do_screenshot = 1;
 }
 
+
+extern int text_render_codepaths_usage[5];
+
 void gfx_swap()
 {
+	/*dbg_msg("", "%d %d %d %d %d",
+		text_render_codepaths_usage[0],
+		text_render_codepaths_usage[1],
+		text_render_codepaths_usage[2],
+		text_render_codepaths_usage[3],
+		text_render_codepaths_usage[4]);
+
+	text_render_codepaths_usage[0] = 0;
+	text_render_codepaths_usage[1] = 0;
+	text_render_codepaths_usage[2] = 0;
+	text_render_codepaths_usage[3] = 0;
+	text_render_codepaths_usage[4] = 0;*/
+
 	if(do_screenshot)
 	{
 		/* find filename */
diff --git a/src/engine/client/ec_gfx_text.c b/src/engine/client/ec_gfx_text.c
index 99e05790..313069c1 100644
--- a/src/engine/client/ec_gfx_text.c
+++ b/src/engine/client/ec_gfx_text.c
@@ -2,6 +2,15 @@
 #include <string.h>
 #include <engine/e_client_interface.h>
 
+
+#ifdef CONF_PLATFORM_MACOSX
+	#include <OpenGL/gl.h>
+	#include <OpenGL/glu.h>
+#else
+	#include <GL/gl.h>
+	#include <GL/glu.h>
+#endif
+
 static int word_length(const char *text)
 {
 	int s = 1;
@@ -21,10 +30,10 @@ static float text_g=1;
 static float text_b=1;
 static float text_a=1;
 
-static FONT_SET *default_font_set = 0;
-void gfx_text_set_default_font(void *font)
+static struct FONT *default_font = 0;
+void gfx_text_set_default_font(struct FONT *font)
 {
-	default_font_set = (FONT_SET *)font;
+	default_font = font;
 }
 
 
@@ -42,14 +51,377 @@ void gfx_text_set_cursor(TEXT_CURSOR *cursor, float x, float y, float font_size,
 	cursor->charcount = 0;
 }
 
+
+void gfx_text(void *font_set_v, float x, float y, float size, const char *text, int max_width)
+{
+	TEXT_CURSOR cursor;
+	gfx_text_set_cursor(&cursor, x, y, size, TEXTFLAG_RENDER);
+	cursor.line_width = max_width;
+	gfx_text_ex(&cursor, text, -1);
+}
+
+float gfx_text_width(void *font_set_v, float size, const char *text, int length)
+{
+	TEXT_CURSOR cursor;
+	gfx_text_set_cursor(&cursor, 0, 0, size, 0);
+	gfx_text_ex(&cursor, text, length);
+	return cursor.x;
+}
+
+void gfx_text_color(float r, float g, float b, float a)
+{
+	text_r = r;
+	text_g = g;
+	text_b = b;
+	text_a = a;
+}
+
+/* ft2 texture */
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+static FT_Library ft_library;
+
+#define MAX_CHARACTERS 64
+
+
+/* GL_LUMINANCE can be good for debugging*/
+static int font_texture_format = GL_ALPHA;
+
+
+static int font_sizes[] = {8,9,10,11,12,13,14,15,16,17,18,19,20,36};
+#define NUM_FONT_SIZES (sizeof(font_sizes)/sizeof(int))
+
+
+typedef struct FONTCHAR
+{
+	int id;
+	
+	/* these values are scaled to the font size */
+	/* width * font_size == real_size */
+	float width;
+	float height;
+	float offset_x;
+	float offset_y;
+	float advance_x;
+	
+	float uvs[4];
+	int64 touch_time;
+} FONTCHAR;
+
+typedef struct FONTSIZEDATA
+{
+	int font_size;
+	FT_Face *face;
+
+	unsigned textures[2];
+	int texture_width;
+	int texture_height;
+	
+	int num_x_chars;
+	int num_y_chars;
+	
+	FONTCHAR characters[MAX_CHARACTERS*MAX_CHARACTERS];
+	
+	int current_character;	
+} FONTSIZEDATA;
+
+typedef struct FONT
+{
+	char filename[128];
+	FT_Face ft_face;
+	FONTSIZEDATA sizes[NUM_FONT_SIZES];
+} FONT;
+
+static int font_get_index(int pixelsize)
+{
+	int i;
+	for(i = 0; i < NUM_FONT_SIZES; i++)
+	{
+		if(font_sizes[i] >= pixelsize)
+			return i;
+	}
+	
+	return NUM_FONT_SIZES-1;
+}
+
+FONT *gfx_font_load(const char *filename)
+{
+	int i;
+	FONT *font = mem_alloc(sizeof(FONT), 1);
+	
+	mem_zero(font, sizeof(*font));
+	str_copy(font->filename, filename, sizeof(font->filename));
+	
+	if(FT_New_Face(ft_library, font->filename, 0, &font->ft_face))
+	{
+		mem_free(font);
+		return NULL;
+	}
+
+	for(i = 0; i < NUM_FONT_SIZES; i++)
+		font->sizes[i].font_size = -1;
+		
+	return font;
+};
+
+void gfx_font_destroy(FONT *font)
+{
+	mem_free(font);
+}
+
+void gfx_font_init()
+{
+	FT_Init_FreeType(&ft_library);
+}
+
+static void grow(unsigned char *in, unsigned char *out, int w, int h)
+{
+	int y, x;
+	for(y = 0; y < h; y++) 
+		for(x = 0; x < w; x++) 
+		{ 
+			int c = in[y*w+x]; 
+			int s_y, s_x;
+
+			for(s_y = -1; s_y <= 1; s_y++)
+				for(s_x = -1; s_x <= 1; s_x++)
+				{
+					int get_x = x+s_x;
+					int get_y = y+s_y;
+					if (get_x >= 0 && get_y >= 0 && get_x < w && get_y < h)
+					{
+						int index = get_y*w+get_x;
+						if(in[index] > c)
+							c = in[index]; 
+					}
+				}
+
+			out[y*w+x] = c;
+		} 
+}
+
+static void font_init_texture(FONTSIZEDATA *font, int width, int height)
+{
+	int i;
+	void *mem = mem_alloc(width*height, 1);
+	mem_zero(mem, width*height);
+	
+	font->texture_width = width;
+	font->texture_height = height;
+	font->num_x_chars = 32;
+	font->num_y_chars = 32;
+	font->current_character = 0;
+	glGenTextures(2, font->textures);
+	
+	for(i = 0; i < 2; i++)
+	{
+		glBindTexture(GL_TEXTURE_2D, font->textures[i]);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		glTexImage2D(GL_TEXTURE_2D, 0, font_texture_format, width, height, 0, font_texture_format, GL_UNSIGNED_BYTE, mem);
+	}
+	
+	mem_free(mem);
+}
+
+static void font_init_index(FONT *font, int index)
+{
+	font->sizes[index].font_size = font_sizes[index];
+	//FT_New_Face(ft_library, "data/fonts/vera.ttf", 0, &font->ft_face);
+	font_init_texture(&font->sizes[index], 1024*2, 1024*2);
+}
+
+static FONTSIZEDATA *font_get_size(FONT *font, int pixelsize)
+{
+	int index = font_get_index(pixelsize);
+	if(font->sizes[index].font_size != font_sizes[index])
+		font_init_index(font, index);
+	return &font->sizes[index];
+}
+
+
+static void font_upload_glyph(FONTSIZEDATA *sizedata, int texnum, int slot_id, int chr, const void *data)
+{
+	int x = (slot_id%sizedata->num_x_chars) * (sizedata->texture_width/sizedata->num_x_chars);
+	int y = (slot_id/sizedata->num_x_chars) * (sizedata->texture_height/sizedata->num_y_chars);
+	
+	glBindTexture(GL_TEXTURE_2D, sizedata->textures[texnum]);
+	glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
+		sizedata->texture_width/sizedata->num_x_chars,
+		sizedata->texture_height/sizedata->num_y_chars,
+		font_texture_format, GL_UNSIGNED_BYTE, data);
+	
+	//dbg_msg("font", "uploaded %d at %d (%d %d)", chr, slot_id, x, y);
+}
+
+/* 8k of data used for rendering glyphs */
+static unsigned char glyphdata[(4096/64) * (4096/64)];
+static unsigned char glyphdata_outlined[(4096/64) * (4096/64)];
+
+static int font_get_slot(FONTSIZEDATA *sizedata)
+{
+	int char_count = sizedata->num_x_chars*sizedata->num_y_chars;
+	if(sizedata->current_character < char_count)
+	{
+		int i = sizedata->current_character;
+		sizedata->current_character++;
+		return i;
+	}
+
+	/* kick out the oldest */
+	/* TODO: remove this linear search */
+	{
+		int oldest = 0;
+		int i;
+		for(i = 1; i < char_count; i++)
+		{
+			if(sizedata->characters[i].touch_time < sizedata->characters[oldest].touch_time)
+				oldest = i;
+		}
+		return oldest;
+	}
+}
+
+static int font_render_glyph(FONT *font, FONTSIZEDATA *sizedata, int chr)
+{
+	FT_Bitmap *bitmap;
+	int slot_id = sizedata->current_character;
+	int slot_w = sizedata->texture_width / sizedata->num_x_chars;
+	int slot_h = sizedata->texture_height / sizedata->num_y_chars;
+	int slot_size = slot_w*slot_h;
+	int outline_thickness = 1;
+	int x = 1;
+	int y = 1;
+	int px, py;
+
+	FT_Set_Pixel_Sizes(font->ft_face, 0, sizedata->font_size);
+	
+	if(FT_Load_Char(font->ft_face, chr, FT_LOAD_RENDER))
+	{
+		dbg_msg("font", "error loading glyph %d", chr);
+		return -1;
+	}
+
+	bitmap = &font->ft_face->glyph->bitmap; 
+	
+	/* fetch slot */
+	slot_id = font_get_slot(sizedata);
+	if(slot_id < 0)
+		return -1;
+	
+	/* adjust spacing */
+	if(sizedata->font_size >= 18)
+		outline_thickness = 2;
+	x += outline_thickness;
+	y += outline_thickness;
+
+	/* prepare glyph data */
+	mem_zero(glyphdata, slot_size);
+
+	for(py = 0; py < bitmap->rows; py++) 
+		for(px = 0; px < bitmap->width; px++) 
+			glyphdata[(py+y)*slot_w+px+x] = bitmap->buffer[py*bitmap->pitch+px];
+
+	if(0) for(py = 0; py < slot_w; py++) 
+		for(px = 0; px < slot_h; px++) 
+			glyphdata[py*slot_w+px] = 255;
+	
+	/* upload the glyph */
+	font_upload_glyph(sizedata, 0, slot_id, chr, glyphdata);
+	
+	if(outline_thickness == 1)
+	{
+		grow(glyphdata, glyphdata_outlined, slot_w, slot_h);
+		font_upload_glyph(sizedata, 1, slot_id, chr, glyphdata_outlined);
+	}
+	else
+	{
+		grow(glyphdata, glyphdata_outlined, slot_w, slot_h);
+		grow(glyphdata_outlined, glyphdata, slot_w, slot_h);
+		font_upload_glyph(sizedata, 1, slot_id, chr, glyphdata);
+	}
+	
+	/* set char info */
+	{
+		FONTCHAR *fontchr = &sizedata->characters[slot_id];
+		float scale = 1.0f/sizedata->font_size;
+		float uscale = 1.0f/sizedata->texture_width;
+		float vscale = 1.0f/sizedata->texture_height;
+		int height = bitmap->rows + outline_thickness*2 + 2;
+		int width = bitmap->width + outline_thickness*2 + 2;
+		
+		fontchr->id = chr;
+		fontchr->height = height * scale;
+		fontchr->width = width * scale;
+		fontchr->offset_x = (font->ft_face->glyph->bitmap_left-1) * scale;
+		fontchr->offset_y = (sizedata->font_size - font->ft_face->glyph->bitmap_top) * scale;
+		fontchr->advance_x = (font->ft_face->glyph->advance.x>>6) * scale;
+		
+		fontchr->uvs[0] = (slot_id%sizedata->num_x_chars) / (float)(sizedata->num_x_chars);
+		fontchr->uvs[1] = (slot_id/sizedata->num_x_chars) / (float)(sizedata->num_y_chars);
+		fontchr->uvs[2] = fontchr->uvs[0] + width*uscale;
+		fontchr->uvs[3] = fontchr->uvs[1] + height*vscale;
+	}
+	
+	return slot_id;
+}
+
+static FONTCHAR *font_get_char(FONT *font, FONTSIZEDATA *sizedata, int chr)
+{
+	FONTCHAR *fontchr = NULL;
+	
+	/* search for the character */
+	/* TODO: remove this linear search */
+	int i;
+	for(i = 0; i < sizedata->current_character; i++)
+	{
+		if(sizedata->characters[i].id == chr)
+		{
+			fontchr = &sizedata->characters[i];
+			break;
+		}
+	}
+	
+	/* check if we need to render the character */
+	if(!fontchr)
+	{
+		int index = font_render_glyph(font, sizedata, chr);
+		if(index >= 0)
+			fontchr = &sizedata->characters[index];
+	}
+	
+	/* touch the character */
+	/* TODO: don't call time_get here */
+	if(fontchr)
+		fontchr->touch_time = time_get();
+		
+	return fontchr;
+}
+
+/* must only be called from the rendering function as the font must be set to the correct size */
+static void font_setsize(FONT *font, int size)
+{
+	FT_Set_Pixel_Sizes(font->ft_face, 0, size);
+}
+
+static float font_kerning(FONT *font, int left, int right)
+{
+	FT_Vector kerning = {0,0};
+	FT_Get_Kerning(font->ft_face, left, right, FT_KERNING_DEFAULT, &kerning );
+	return (kerning.x>>6);
+}
+
+
 void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 {
-	FONT_SET *font_set = cursor->font_set;
+	FONT *font = cursor->font;
+	FONTSIZEDATA *sizedata = NULL;
+
 	float screen_x0, screen_y0, screen_x1, screen_y1;
 	float fake_to_screen_x, fake_to_screen_y;
 	int actual_x, actual_y;
 
-	FONT *font;
 	int actual_size;
 	int i;
 	int got_new_line = 0;
@@ -74,11 +446,17 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 	actual_size = size * fake_to_screen_y;
 	size = actual_size / fake_to_screen_y;
 
-	if(!font_set)
-		font_set = default_font_set;
-
-	font = font_set_pick(font_set, actual_size);
+	/* fetch font data */
+	if(!font)
+		font = default_font;
+	
+	if(!font)
+		return;
 
+	sizedata = font_get_size(font, actual_size);
+	font_setsize(font, actual_size);
+	
+	/* set length */
 	if (length < 0)
 		length = strlen(text);
 		
@@ -98,10 +476,12 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 
 		if(cursor->flags&TEXTFLAG_RENDER)
 		{
+			// TODO: Make this better
+			glEnable(GL_TEXTURE_2D);
 			if (i == 0)
-				gfx_texture_set(font->outline_texture);
+				glBindTexture(GL_TEXTURE_2D, sizedata->textures[1]);
 			else
-				gfx_texture_set(font->text_texture);
+				glBindTexture(GL_TEXTURE_2D, sizedata->textures[0]);
 
 			gfx_quads_begin();
 			if (i == 0)
@@ -157,11 +537,10 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 
 			while(this_batch-- > 0)
 			{
-				float tex_x0, tex_y0, tex_x1, tex_y1;
-				float width, height;
-				float x_offset, y_offset, x_advance;
-				float advance;
+				float advance = 0;
+				FONTCHAR *chr;
 
+				// TODO: UTF-8 decode
 				if(*current == '\n')
 				{
 					draw_x = cursor->start_x;
@@ -172,15 +551,18 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 					continue;
 				}
 
-				font_character_info(font, *current, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &width, &height, &x_offset, &y_offset, &x_advance);
+				chr = font_get_char(font, sizedata, *current);
 
-				if(cursor->flags&TEXTFLAG_RENDER)
+				if(chr)
 				{
-					gfx_quads_setsubset(tex_x0, tex_y0, tex_x1, tex_y1);
-					gfx_quads_drawTL(draw_x+x_offset*size, draw_y+y_offset*size, width*size, height*size);
-				}
+					if(cursor->flags&TEXTFLAG_RENDER)
+					{
+						gfx_quads_setsubset(chr->uvs[0], chr->uvs[1], chr->uvs[2], chr->uvs[3]);
+						gfx_quads_drawTL(draw_x+chr->offset_x*size, draw_y+chr->offset_y*size, chr->width*size, chr->height*size);
+					}
 
-				advance = x_advance + font_kerning(font, *current, *(current+1));
+					advance = chr->advance_x + font_kerning(font, *current, *(current+1));
+				}
 								
 				if(cursor->flags&TEXTFLAG_STOP_AT_END && draw_x+advance*size-cursor->start_x > cursor->line_width)
 				{
@@ -213,27 +595,3 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 	if(got_new_line)
 		cursor->y = draw_y;
 }
-
-void gfx_text(void *font_set_v, float x, float y, float size, const char *text, int max_width)
-{
-	TEXT_CURSOR cursor;
-	gfx_text_set_cursor(&cursor, x, y, size, TEXTFLAG_RENDER);
-	cursor.line_width = max_width;
-	gfx_text_ex(&cursor, text, -1);
-}
-
-float gfx_text_width(void *font_set_v, float size, const char *text, int length)
-{
-	TEXT_CURSOR cursor;
-	gfx_text_set_cursor(&cursor, 0, 0, size, 0);
-	gfx_text_ex(&cursor, text, length);
-	return cursor.x;
-}
-
-void gfx_text_color(float r, float g, float b, float a)
-{
-	text_r = r;
-	text_g = g;
-	text_b = b;
-	text_a = a;
-}
diff --git a/src/engine/e_client_interface.h b/src/engine/e_client_interface.h
index 2cc9e5c7..7ec5c93d 100644
--- a/src/engine/e_client_interface.h
+++ b/src/engine/e_client_interface.h
@@ -16,7 +16,6 @@ extern "C" {
 
 #include "e_console.h"
 #include "e_config.h"
-#include "client/ec_font.h"
 
 #ifdef __cplusplus
 }
diff --git a/src/engine/e_if_gfx.h b/src/engine/e_if_gfx.h
index 8221c81d..61a76bad 100644
--- a/src/engine/e_if_gfx.h
+++ b/src/engine/e_if_gfx.h
@@ -11,6 +11,11 @@
 */
 
 /*
+	Structure: FONT
+*/
+struct FONT;
+
+/*
 	Structure: IMAGE_INFO
 */
 typedef struct
@@ -321,7 +326,7 @@ void gfx_text_color(float r, float g, float b, float a);
 	See Also:
 		<other_func>
 */
-void gfx_text_set_default_font(void *font);
+void gfx_text_set_default_font(struct FONT *font);
 
 /*
 	Group: Other
@@ -654,7 +659,8 @@ typedef struct
 	float start_y;
 	float line_width;
 	float x, y;
-	void *font_set;
+	
+	struct FONT *font;
 	float font_size;
 } TEXT_CURSOR;
 
@@ -662,6 +668,8 @@ void gfx_text_set_cursor(TEXT_CURSOR *cursor, float x, float y, float font_size,
 void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length);
 
 
+struct FONT *gfx_font_load(const char *filename);
+void gfx_font_destroy(struct FONT *font);
 
 
 #endif
diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp
index 53d5637e..7b806b36 100644
--- a/src/game/client/components/console.cpp
+++ b/src/game/client/components/console.cpp
@@ -9,7 +9,6 @@
 
 extern "C" {
 	#include <engine/e_ringbuffer.h>
-	#include <engine/client/ec_font.h>
 }
 
 #include <cstring>
@@ -225,7 +224,7 @@ void CONSOLE::possible_commands_render_callback(const char *str, void *user)
 	
 	if(info->enum_count == info->wanted_completion)
 	{
-		float tw = gfx_text_width(info->cursor.font_set, info->cursor.font_size, str, -1);
+		float tw = gfx_text_width(info->cursor.font, info->cursor.font_size, str, -1);
 		gfx_texture_set(-1);
 		gfx_quads_begin();
 			gfx_setcolor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,0.85f);
diff --git a/src/game/client/components/controls.cpp b/src/game/client/components/controls.cpp
index af114ce2..b48fb198 100644
--- a/src/game/client/components/controls.cpp
+++ b/src/game/client/components/controls.cpp
@@ -170,7 +170,7 @@ int CONTROLS::snapinput(int *data)
 void CONTROLS::on_render()
 {
 	// update target pos
-	if(!(gameclient.snap.gameobj && gameclient.snap.gameobj->paused || gameclient.snap.spectate))
+	if(gameclient.snap.gameobj && !(gameclient.snap.gameobj->paused || gameclient.snap.spectate))
 		target_pos = gameclient.local_character_pos + mouse_pos;
 }
 
diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp
index 54c587ef..53b57e2c 100644
--- a/src/game/client/components/menus.cpp
+++ b/src/game/client/components/menus.cpp
@@ -13,10 +13,6 @@
 
 #include <engine/e_client_interface.h>
 
-extern "C" {
-	#include <engine/client/ec_font.h>
-}
-
 #include <game/version.hpp>
 #include <game/generated/g_protocol.hpp>
 
@@ -603,6 +599,15 @@ int MENUS::render_menubar(RECT r)
 
 void MENUS::render_loading(float percent)
 {
+	static int64 last_load_render = 0;
+
+	// make sure that we don't render for each little thing we load
+	// because that will slow down loading if we have vsync
+	if(time_get()-last_load_render < time_freq()/60)
+		return;
+		
+	last_load_render = time_get();
+	
 	// need up date this here to get correct
 	vec3 rgb = hsl_to_rgb(vec3(config.ui_color_hue/255.0f, config.ui_color_sat/255.0f, config.ui_color_lht/255.0f));
 	gui_color = vec4(rgb.r, rgb.g, rgb.b, config.ui_color_alpha/255.0f);
@@ -994,6 +999,8 @@ void MENUS::on_statechange(int new_state, int old_state)
 	}
 }
 
+extern "C" void font_debug_render();
+
 void MENUS::on_render()
 {
 	if(client_state() != CLIENTSTATE_ONLINE && client_state() != CLIENTSTATE_DEMOPLAYBACK)
diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp
index c26bddba..a7751347 100644
--- a/src/game/client/components/menus_browser.cpp
+++ b/src/game/client/components/menus_browser.cpp
@@ -3,11 +3,6 @@
 #include <stdlib.h> // atoi
 
 #include <engine/e_client_interface.h>
-
-extern "C" {
-	#include <engine/client/ec_font.h>
-}
-
 #include <game/generated/g_protocol.hpp>
 #include <game/generated/gc_data.hpp>
 
diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp
index 8d0e044c..a90cdc49 100644
--- a/src/game/client/gameclient.cpp
+++ b/src/game/client/gameclient.cpp
@@ -193,15 +193,12 @@ void GAMECLIENT::on_init()
 	for(int i = 0; i < NUM_NETOBJTYPES; i++)
 		snap_set_staticsize(i, netobj_get_size(i));
 	
-	// load default font	
-	static FONT_SET default_font;
 	int64 start = time_get();
 	
-	int before = gfx_memory_usage();
-	font_set_load(&default_font, "fonts/default_font%d.tfnt", "fonts/default_font%d.png", "fonts/default_font%d_b.png", 14, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 36);
-	dbg_msg("font", "gfx memory used for font textures: %d", gfx_memory_usage()-before);
-	
-	gfx_text_set_default_font(&default_font);
+	// load default font	
+	static FONT *default_font;
+	default_font = gfx_font_load("data/fonts/vera.ttf");
+	gfx_text_set_default_font(default_font);
 
 	config.cl_threadsoundloading = 0;
 
diff --git a/src/tools/font_generator/alte_haas_grotesk.ttf b/src/tools/font_generator/alte_haas_grotesk.ttf
deleted file mode 100755
index 78756343..00000000
--- a/src/tools/font_generator/alte_haas_grotesk.ttf
+++ /dev/null
Binary files differdiff --git a/src/tools/font_generator/alte_haas_grotesk_bold.ttf b/src/tools/font_generator/alte_haas_grotesk_bold.ttf
deleted file mode 100755
index 1a456e80..00000000
--- a/src/tools/font_generator/alte_haas_grotesk_bold.ttf
+++ /dev/null
Binary files differdiff --git a/src/tools/font_generator/boris_black_bloxx.ttf b/src/tools/font_generator/boris_black_bloxx.ttf
deleted file mode 100755
index fbc38cba..00000000
--- a/src/tools/font_generator/boris_black_bloxx.ttf
+++ /dev/null
Binary files differdiff --git a/src/tools/font_generator/build b/src/tools/font_generator/build
deleted file mode 100755
index ce712f8c..00000000
--- a/src/tools/font_generator/build
+++ /dev/null
@@ -1 +0,0 @@
-g++ main.cpp -Lfreetype-2.3.5/objs/.libs -lfreetype -I freetype-2.3.5/include
diff --git a/src/tools/font_generator/komika_axis.ttf b/src/tools/font_generator/komika_axis.ttf
deleted file mode 100755
index 15bab8eb..00000000
--- a/src/tools/font_generator/komika_axis.ttf
+++ /dev/null
Binary files differdiff --git a/src/tools/font_generator/main.cpp b/src/tools/font_generator/main.cpp
deleted file mode 100755
index 9d4b29e1..00000000
--- a/src/tools/font_generator/main.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-#include <stdio.h> 
-#include <ft2build.h> 
-#include FT_FREETYPE_H 
- 
-FT_Library library; 
-FT_Face face; 
- 
-const int max_width = 512; 
-const int max_height = max_width; 
- 
-const char chars[] = "abcdefghijklmnopqrstuv"; 
- 
-void save(const char *filename, unsigned char *data, int w, int h) 
-{ 
-        char header[18] = {0}; 
-        header[2] = 2; // 2=rgb 3=grayscale 
-        header[12] = w&255; // width 
-        header[13] = w>>8; 
-        header[14] = h&255; // height 
-        header[15] = h>>8; 
-        header[16] = 32; 
-        header[17] = (1<<5) | 8; // org 
- 
-        char tganame[128]; 
-        sprintf(tganame, "%s.tga", filename); 
- 
-        FILE *f = fopen(tganame, "wb"); 
-        fwrite(header, 1, sizeof(header), f); 
- 
-        for(int y = 0; y < h; y++) 
-                for(int x = 0; x < w; x++) 
-                { 
-                        fputc(0xff, f); 
-                        fputc(0xff, f); 
-                        fputc(0xff, f); 
-                        fputc(data[y*w+x], f); 
-                } 
-
-        fclose(f); 
- 
-        char cmd[512]; 
-        sprintf(cmd, "convert %s.tga %s.png; rm %s.tga",filename, filename, filename); 
-        system(cmd); 
-} 
-
-void grow(unsigned char *in, unsigned char *out, int w, int h)
-{
-        for(int y = 0; y < h; y++) 
-                for(int x = 0; x < w; x++) 
-                { 
-                        int c = in[y*w+x]; 
-
-                        for (int s_y = -1; s_y <= 1; s_y++)
-                            for (int s_x = -1; s_x <= 1; s_x++)
-                            {
-                                int get_x = x+s_x;
-                                int get_y = y+s_y;
-                                if (get_x >= 0 && get_y >= 0 && get_x < w && get_y < h)
-                                {
-                                    int index = get_y*w+get_x;
-                                    if(in[index] > c)
-                                        c = in[index]; 
-                                }
-                            }
-
-                        out[y*w+x] = c;
-                } 
-}
- 
-unsigned char alpha_buf[max_width*(max_height*4)] = {0}; 
-unsigned char alpha_buf2[max_width*(max_height*4)] = {0}; 
-unsigned char *alpha = &alpha_buf[max_width*2]; 
-unsigned char *alpha2 = &alpha_buf2[max_width*2]; 
- 
-int gen(const char *filename, const char *output, int size, int border) 
-{ 
-        char buf[256]; 
-
-		int w = 128; 
-		int h = 128; 
- 
-		while (1)
-		{
-			bool continue_now = false;
-			memset(alpha, 0, w*h); 
-
-			sprintf(buf, "trying to generate %dx%d", w, h);
-			puts(buf);
-	 
-			sprintf(buf, "%s%d.fnt", output, size); 
-			FILE *fnt = fopen(buf, "wb"); 
-			sprintf(buf, "%s%d.tga", output, size); 
-			fprintf(fnt, "info face=\"%s\" size=%d bold=0 italic=0 charset=\"\" unicode=1 stretchH=100 smooth=1 aa=4 padding=0,0,0,0 spacing=1,1\n", output, size); 
-			fprintf(fnt, "common lineHeight=%d base=26 scaleW=%d scaleH=%d pages=1 packed=0\n", size, w, h); 
-			fprintf(fnt, "page id=0 file=\"%s\"\n", buf); 
-	 
-			int error = FT_New_Face(library, filename, 0, &face); 
-
-			int outline_thickness = size >= 18 ? 2 : 1;
-	 
-			int spacing = outline_thickness + 1; 
-			error = FT_Set_Pixel_Sizes(face, 0, size); 
-			int x = spacing; 
-			int y = spacing; 
-			for(int i = 32; i < 255; i++) 
-			{ 
-					if((i >= 8*16-1 && i < 10*16) || i == 11*16-1) // remove some strange characters 
-							continue; 
-	 
-					error = FT_Load_Char(face, i, FT_LOAD_RENDER); 
-					if(error) 
-							continue; 
-					FT_Bitmap *bitmap = &face->glyph->bitmap; 
-	 
-					if(x + bitmap->width + spacing*2 >= w) 
-					{ 
-							x = spacing; 
-							y += size+spacing*2; 
-					} 
-	 
-					x += spacing; 
-	 
-					fprintf(fnt, "char id=%d x=%d y=%d width=%d height=%d xoffset=%d yoffset=%d xadvance=%d page=0 chnl=15\n", 
-							i, x-outline_thickness, y-outline_thickness, bitmap->width+2*outline_thickness, bitmap->rows+2*outline_thickness, face->glyph->bitmap_left-1, size-face->glyph->bitmap_top, face->glyph->advance.x>>6); 
-
-					if (x + bitmap->width - 1 >= w || y + bitmap->rows - 1 >= h)
-					{
-						if (w == h)
-							w <<= 1;
-						else
-							h <<= 1;
-
-						continue_now = true;
-
-						break;
-					}
-	 
-					for(int py = 0; py < bitmap->rows; py++) 
-							for(int px = 0; px < bitmap->width; px++) 
-									alpha[(py+y)*w+px+x] = bitmap->buffer[py*bitmap->pitch+px]; 
-					x += spacing; 
-					x += bitmap->width; 
-			} 
-	 
-			fclose(fnt); 
-
-			if (continue_now)
-				continue;
-	 
-			sprintf(buf, "%s%d", output, size); 
-			save(buf, alpha, w, h);
-
-			// generate outline
-			int passes = size >= 18 ? 2 : 1;
-			for (int i = 0; i < passes; i++)
-			{
-				grow(alpha, alpha2, w, h);
-
-				unsigned char *temp = alpha;
-				alpha = alpha2;
-				alpha2 = temp;
-			}
-
-			sprintf(buf, "%s%d_b", output, size); 
-			save(buf, alpha, w, h);
-
-			break;
-		}
-}
-
-void gen_font(char *font_name, char *output, int size_count, int *sizes)
-{
-        for(int i = 0; i < size_count; i++) 
-                gen(font_name, output, sizes[i], 0); 
-}
- 
-int main() 
-{ 
-        int error = FT_Init_FreeType(&library); 
-
-        int tahoma_sizes[] = { 8, 9, 10, 11, 12 }; 
-        gen_font("tahoma.ttf", "default_font", sizeof(tahoma_sizes)/sizeof(*tahoma_sizes), tahoma_sizes);
-
-        int alte_haas_sizes[] = { 13, 14, 15, 16, 17 };
-        gen_font("alte_haas_grotesk.ttf", "default_font", sizeof(alte_haas_sizes)/sizeof(*alte_haas_sizes), alte_haas_sizes);
-
-        int alte_haas_bold_sizes[] = { 18, 19, 20, 36 };
-        gen_font("alte_haas_grotesk_bold.ttf", "default_font", sizeof(alte_haas_bold_sizes)/sizeof(*alte_haas_bold_sizes), alte_haas_bold_sizes);
- 
-        return 0; 
-} 
diff --git a/src/tools/font_generator/tahoma.ttf b/src/tools/font_generator/tahoma.ttf
deleted file mode 100755
index f5a011e9..00000000
--- a/src/tools/font_generator/tahoma.ttf
+++ /dev/null
Binary files differdiff --git a/src/trackinggenerator/main.cpp b/src/trackinggenerator/main.cpp
deleted file mode 100644
index 5ffafea9..00000000
--- a/src/trackinggenerator/main.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
-#include <iostream>
-#include <fstream>
-
-using namespace std;
-
-int main(int argc, char *argv[])
-{
-	if (argc != 2)
-	{
-		cout << "Usage: bla <infile.tga>" << endl;
-		return -1;
-	}
-
-	ifstream file(argv[1]);
-
-	if (!file)
-	{
-		cout << "No such file..." << endl;
-		return -1;
-	}
-
-	unsigned short headers[9];
-
-	file.read((char *)headers, 18);
-
-	int width = headers[6];
-	int height = headers[7];
-
-	const int charsx = 16;
-	const int charsy = 16;
-	const int charWidth = width / charsx;
-	const int charHeight = height / charsy;
-
-	char *data = new char[width * height * 4];
-
-	file.read(data, width * height * 4);
-	
-    int startTable[256] = {0};
-	int endTable[256] = {0};
-
-    for (int i = 0; i < charsy; i++)
-        for (int j = 0; j < charsx; j++)
-        {
-            bool done = false;
-
-            for (int x = 0; x < charWidth && !done; ++x)
-                for (int y = charHeight - 1; y >= 0; --y)
-                {   
-                    // check if alpha is != 0 
-                    int tempX = j * charWidth + x;
-                    int tempY = i * charHeight + y;
-                    
-                    int coordIndex = tempX + tempY * width;
-                    
-                    if (data[4 * coordIndex + 3] != 0)
-                    {   
-                        // if it is, save the x-coord to table and go to next character
-                        startTable[j + i * charsx] = x;
-                        done = true;
-                    }
-                }
-
-
-			done = false;
-            for (int x = charWidth - 1; x >= 0 && !done; --x)
-                for (int y = charHeight - 1; y >= 0; --y)
-                {
-                    // check if alpha is != 0
-                    int tempX = j * charWidth + x;
-                    int tempY = i * charHeight + y;
-
-                    int coordIndex = tempX + tempY * width;
-
-                    if (data[4 * coordIndex + 3] != 0)
-                    {
-                        // if it is, save the x-coord to table and go to next character
-                        endTable[j + i * charsx] = x;
-                        done = true;
-                    }
-                }
-        }
-
-    delete[] data;
-
-    cout << "float CharStartTable[] =" << endl << '{' << endl << '\t';
-
-    for (int i = 0; i < 256; i++)
-    {
-        cout << startTable[i] / float(charWidth) << ", ";
-        if (!((i + 1) % 16))
-            cout << endl << '\t';
-    }
-
-    cout << endl << "};" << endl;
-
-    cout << "float CharEndTable[] =" << endl << '{' << endl << '\t';
-
-    for (int i = 0; i < 256; i++)
-    {
-        cout << endTable[i] / float(charWidth) << ", ";
-        if (!((i + 1) % 16))
-            cout << endl << '\t';
-    }
-
-    cout << endl << "};" << endl;
-
-        
-    cout << charWidth << 'x' << charHeight << endl;
-}