about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2009-06-07 16:06:03 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2009-06-07 16:06:03 +0000
commit9254ca61f1e459cbaf137ce4511332365da9c225 (patch)
treeac23ac63c270d3426a6b7e9b39c104763ea701b5
parentd754cd9d19334fcd0c956ec3074547c621b1bbab (diff)
downloadzcatch-9254ca61f1e459cbaf137ce4511332365da9c225.tar.gz
zcatch-9254ca61f1e459cbaf137ce4511332365da9c225.zip
fixed utf8 support
-rw-r--r--src/engine/client/ec_gfx_text.c100
-rw-r--r--src/game/client/components/menus.cpp17
-rw-r--r--src/game/client/gameclient.cpp32
3 files changed, 131 insertions, 18 deletions
diff --git a/src/engine/client/ec_gfx_text.c b/src/engine/client/ec_gfx_text.c
index 313069c1..2dedd032 100644
--- a/src/engine/client/ec_gfx_text.c
+++ b/src/engine/client/ec_gfx_text.c
@@ -296,7 +296,7 @@ static int font_render_glyph(FONT *font, FONTSIZEDATA *sizedata, int chr)
 	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);
@@ -319,9 +319,21 @@ static int font_render_glyph(FONT *font, FONTSIZEDATA *sizedata, int chr)
 	/* 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(bitmap->pixel_mode == FT_PIXEL_MODE_GRAY)
+	{
+		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];
+	}
+	else if(bitmap->pixel_mode == FT_PIXEL_MODE_MONO)
+	{
+		for(py = 0; py < bitmap->rows; py++) 
+			for(px = 0; px < bitmap->width; px++)
+			{
+				if(bitmap->buffer[py*bitmap->pitch+px/8]&(1<<(7-(px%8))))
+					glyphdata[(py+y)*slot_w+px+x] = 255;
+			}
+	}
 
 	if(0) for(py = 0; py < slot_w; py++) 
 		for(px = 0; px < slot_h; px++) 
@@ -412,6 +424,52 @@ static float font_kerning(FONT *font, int left, int right)
 	return (kerning.x>>6);
 }
 
+static int utf8_decode(const unsigned char **ptr)
+{
+	const unsigned char *buf = *ptr;
+	int ch = 0;
+	
+	do
+	{
+		if((*buf&0x80) == 0x0)  /* 0xxxxxxx */
+		{
+			ch = *buf;
+			buf++;
+		}
+		else if((*buf&0xE0) == 0xC0) /* 110xxxxx */
+		{
+			ch  = (*buf++ & 0x3F) << 6; if(!(*buf)) break;
+			ch += (*buf++ & 0x3F);
+			if(ch == 0) ch = -1;
+		}
+		else  if((*buf & 0xF0) == 0xE0)	/* 1110xxxx */
+		{
+			ch  = (*buf++ & 0x1F) << 12; if(!(*buf)) break;
+			ch += (*buf++ & 0x3F) <<  6; if(!(*buf)) break;
+			ch += (*buf++ & 0x3F);
+			if(ch == 0) ch = -1;
+		}
+		else if((*buf & 0xF8) == 0xF0)	/* 11110xxx */
+		{
+			ch  = (*buf++ & 0x0F) << 18; if(!(*buf)) break;
+			ch += (*buf++ & 0x3F) << 12; if(!(*buf)) break;
+			ch += (*buf++ & 0x3F) <<  6; if(!(*buf)) break;
+			ch += (*buf++ & 0x3F);
+			if(ch == 0) ch = -1;
+		}
+		else
+			break;
+		
+		/* valid */
+		*ptr = buf;
+		return ch;
+	} while(0);
+
+	/* invalid */
+	*ptr = buf;
+	return -1;
+	
+}
 
 void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 {
@@ -457,7 +515,7 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 	font_setsize(font, actual_size);
 	
 	/* set length */
-	if (length < 0)
+	if(length < 0)
 		length = strlen(text);
 		
 	end = text + length;
@@ -470,7 +528,8 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 	for(;i < 2; i++)
 	{
 		const unsigned char *current = (unsigned char *)text;
-		int to_render = length;
+		const unsigned char *end = current+length;
+		//int to_render = length;
 		draw_x = cursor_x;
 		draw_y = cursor_y;
 
@@ -490,10 +549,11 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 				gfx_setcolor(text_r, text_g, text_b, text_a);
 		}
 
-		while(to_render > 0)
+		while(current < end)
 		{
 			int new_line = 0;
-			int this_batch = to_render;
+			//int this_batch = (int)(end-current);
+			const unsigned char *batch_end = end;
 			if(cursor->line_width > 0 && !(cursor->flags&TEXTFLAG_STOP_AT_END))
 			{
 				int wlen = word_length((char *)current);
@@ -527,31 +587,35 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 					wlen = 0;
 				}
 				
-				this_batch = wlen;
+				batch_end = current + wlen;
+				//this_batch = wlen;
 			}
 			
-			if((const char *)current+this_batch > end)
+			/*if((const char *)current+this_batch > end)
 				this_batch = (const char *)end-(const char *)current;
 			
-			to_render -= this_batch;
+			end = */
+			/*to_render -= this_batch;*/
 
-			while(this_batch-- > 0)
+			while(current < batch_end)
 			{
 				float advance = 0;
+				int character = 0;
 				FONTCHAR *chr;
 
 				// TODO: UTF-8 decode
-				if(*current == '\n')
+				character = utf8_decode(&current);
+				if(character == '\n')
 				{
 					draw_x = cursor->start_x;
 					draw_y += size;
 					draw_x = (int)(draw_x * fake_to_screen_x) / fake_to_screen_x; /* realign */
 					draw_y = (int)(draw_y * fake_to_screen_y) / fake_to_screen_y;
-					current++;
+					/* current++; */
 					continue;
 				}
 
-				chr = font_get_char(font, sizedata, *current);
+				chr = font_get_char(font, sizedata, character);
 
 				if(chr)
 				{
@@ -561,19 +625,19 @@ void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
 						gfx_quads_drawTL(draw_x+chr->offset_x*size, draw_y+chr->offset_y*size, chr->width*size, chr->height*size);
 					}
 
-					advance = chr->advance_x + font_kerning(font, *current, *(current+1));
+					advance = chr->advance_x; /* + font_kerning(font, character, *(current+1));*/
 				}
 								
 				if(cursor->flags&TEXTFLAG_STOP_AT_END && draw_x+advance*size-cursor->start_x > cursor->line_width)
 				{
 					/* we hit the end of the line, no more to render or count */
-					to_render = 0;
+					current = end;
 					break;
 				}
 
 				draw_x += advance*size;
 				cursor->charcount++;
-				current++;
+				/* current++; */
 			}
 			
 			if(new_line)
diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp
index 53b57e2c..050c7056 100644
--- a/src/game/client/components/menus.cpp
+++ b/src/game/client/components/menus.cpp
@@ -1003,6 +1003,23 @@ extern "C" void font_debug_render();
 
 void MENUS::on_render()
 {
+	/*
+	// text rendering test stuff
+	render_background();
+
+	TEXT_CURSOR cursor;
+	gfx_text_set_cursor(&cursor, 10, 10, 20, TEXTFLAG_RENDER);
+	gfx_text_ex(&cursor, "ようこそ - ガイド", -1);
+
+	gfx_text_set_cursor(&cursor, 10, 30, 15, TEXTFLAG_RENDER);
+	gfx_text_ex(&cursor, "ようこそ - ガイド", -1);
+	
+	//gfx_texture_set(-1);
+	gfx_quads_begin();
+	gfx_quads_drawTL(60, 60, 5000, 5000);
+	gfx_quads_end();
+	return;*/
+	
 	if(client_state() != CLIENTSTATE_ONLINE && client_state() != CLIENTSTATE_DEMOPLAYBACK)
 		set_active(true);
 
diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp
index a90cdc49..70aee255 100644
--- a/src/game/client/gameclient.cpp
+++ b/src/game/client/gameclient.cpp
@@ -183,8 +183,39 @@ void GAMECLIENT::on_console_init()
 	suppress_events = false;
 }
 
+/*
+unsigned char utf8lut[] = {}
+
+static int utf8_decode(unsigned char **ptr)
+{
+	unsigned char first = **ptr;
+	if(first&0x80 == 0)
+	{
+		*ptr += 1;
+		return first;
+	}
+	
+	if(first&(0x80|0x40|0x20) == (0x80|0x40))
+	{
+		// two bytes
+	}
+
+	if(first&(0x80|0x40|0x20|0x10) == (0x80|0x40|0x20))
+	{
+		// three bytes
+	}
+}*/
+
+#include <stdio.h>
+
 void GAMECLIENT::on_init()
 {
+	/*const char *p = "Hello World åäö ようこそ - ガイド ";
+	for(; *p; )
+	{
+		dbg_msg("", "%d", utf8_decode(&p));
+	}*/
+	
 	// init all components
 	for(int i = 0; i < all.num; i++)
 		all.components[i]->on_init();
@@ -197,6 +228,7 @@ void GAMECLIENT::on_init()
 	
 	// load default font	
 	static FONT *default_font;
+	//default_font = gfx_font_load("data/fonts/sazanami-gothic.ttf");
 	default_font = gfx_font_load("data/fonts/vera.ttf");
 	gfx_text_set_default_font(default_font);