diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-06-07 16:06:03 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-06-07 16:06:03 +0000 |
| commit | 9254ca61f1e459cbaf137ce4511332365da9c225 (patch) | |
| tree | ac23ac63c270d3426a6b7e9b39c104763ea701b5 /src | |
| parent | d754cd9d19334fcd0c956ec3074547c621b1bbab (diff) | |
| download | zcatch-9254ca61f1e459cbaf137ce4511332365da9c225.tar.gz zcatch-9254ca61f1e459cbaf137ce4511332365da9c225.zip | |
fixed utf8 support
Diffstat (limited to 'src')
| -rw-r--r-- | src/engine/client/ec_gfx_text.c | 100 | ||||
| -rw-r--r-- | src/game/client/components/menus.cpp | 17 | ||||
| -rw-r--r-- | src/game/client/gameclient.cpp | 32 |
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(¤t); + 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); |