From 4d21bcae1dce99776cd09db9ec1453eee3f3cb07 Mon Sep 17 00:00:00 2001 From: steffen Date: Thu, 6 Jun 2013 21:53:06 +0000 Subject: [PATCH] utf8 decode works fine. --- ChangeLog | 3 ++ android/jni/Android.mk | 2 +- android/jni/android_font.c | 12 +++++- base/Makefile | 3 +- base/utf8.c | 79 ++++++++++++++++++++++++++++++++++++-- base/utf8.h | 6 ++- sdlgl/sdl_font.c | 23 ++++++----- 7 files changed, 108 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4731f1b..c2f8e4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ Version 0.0.2: name changed to spOSMroute, since on there had been another OSMroute already. ============================================================================= +(2013-06-06): +- fixed: utf8 will be displayed on OpenGL and OpenGLES devices correctly. + (2013-05-28): - fixed: on android devices gps seems to work now fine. diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 9e1f5e7..f3a81b7 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -72,7 +72,7 @@ LOCAL_CFLAGS := -DANDROID -DSPOSMROUTE -I$(LOCAL_PATH)/base -I$(LOCAL_PATH)/gui -I$(LOCAL_PATH)/freetype2/include LOCAL_SRC_FILES := \ main.c android_gfx.c android_font.c \ - base/config.c base/memoryleak.c base/system.c base/vector.c \ + base/config.c base/memoryleak.c base/system.c base/vector.c base/utf8.c \ mapsys/map_area.c mapsys/map_hash.c mapsys/map_nodepois.c \ mapsys/map_webload.c mapsys/map_searchhash.c\ mapsys/map.c mapsys/map_loadsave.c mapsys/map_way.c \ diff --git a/android/jni/android_font.c b/android/jni/android_font.c index 3a32ff0..7d7bc24 100644 --- a/android/jni/android_font.c +++ b/android/jni/android_font.c @@ -4,6 +4,7 @@ #include "osmroute.h" #include "system.h" +#include "utf8.h" #include #include FT_FREETYPE_H @@ -70,6 +71,7 @@ struct font* font_load(char *fname) { void font_draw (struct font *f, char *text, float x, float y, float sx, float sy) { char *p; int i; + uint32_t u8chr; GLfloat vp[12] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -100,10 +102,16 @@ void font_draw (struct font *f, char *text, float x, float y, float sx, float sy glUniform1i(engine.gles_txsampler, 0); /* Loop through all characters */ - for (p = text; *p; p++) { + for (p = text; *p;) { + u8chr = u8_decode (p, &i); + if (i == 0) { + p++; + continue; + } + p = p + i; /* Try to load and render the character */ - if ((i = FT_Load_Char(f->face, *p, FT_LOAD_RENDER))) { + if ((i = FT_Load_Char(f->face, u8chr, FT_LOAD_RENDER))) { d_printf ("error:%d", i); continue; } diff --git a/base/Makefile b/base/Makefile index 9ca2aa4..312bf7a 100644 --- a/base/Makefile +++ b/base/Makefile @@ -3,7 +3,8 @@ include ../Makefile.rules OBJBASE = config.o \ system.o \ vector.o \ - memoryleak.o + memoryleak.o \ + utf8.o OBJ = $(OBJBASE) SRC = $(OBJ:%.o=%.c) diff --git a/base/utf8.c b/base/utf8.c index a27236b..26a54ed 100644 --- a/base/utf8.c +++ b/base/utf8.c @@ -1,4 +1,4 @@ -/* $Id: utf8.c,v 1.1 2013/06/05 22:16:06 steffen Exp $ */ +/* $Id: utf8.c,v 1.2 2013/06/06 21:53:06 steffen Exp $ */ /* utf8.c * Copyright (C) Steffen Pohle 2013 * @@ -16,8 +16,81 @@ * with this program. If not, see . */ -#include + #include -#include +#include +#include "system.h" #include "utf8.h" +uint32_t u8_decode (char *str, int *charsize) { + uint32_t chr = 0; + int block = 0; + uint8_t c = 0; + + /* check how many elements */ + c = *str; + if ((c & 0x80) == 0) { + block = 0; + chr = c; + } + else if ((c & 0xE0) == 0xC0) { // (str[0] & 111x xxxx) == 110x xxxx + block = 1; + chr = c & 0x1F; + } + else if ((c & 0xF0) == 0xE0) { // (str[0] & 1111 xxxx) == 1110 xxxx + block = 2; + chr = c & 0x0F; + } + else if ((c & 0xF8) == 0xF0) { // (str[0] & 1111 1xxx) == 1111 0xxx + block = 3; + chr = c & 0x07; + } + else if ((c & 0xFC) == 0xF8) { // (str[0] & 1111 11xx) == 1111 10xx + block = 4; + chr = c & 0x03; + } + else if ((c & 0xFE) == 0xFC) { // (str[0] & 1111 111x) == 1111 110x + block = 5; + chr = c & 0x01; + } + else { + /* error: no valid code */ + *charsize = 0; + return 0; + } + + *charsize = block+1; /* return size in bytes for utf8 char */ + str++; + + for (;block > 0; block--) { + c = *str; + if ((c & 0xC0) != 0X80) { + /* error: no valid code */ + *charsize = 0; + return 0; + } + chr <<= 6; + chr |= (c & 0x3F); + str++; + } + + return chr; +}; + + +/* return the size in chars not in bytes. */ +int u8_strlen (char *str) { + int cnt, i, j; + int bytelen = strlen (str); + + for (cnt = 0, i = 0; i < bytelen;) { + u8_decode (str+i, &j); + cnt++; + i += j; + } + + return cnt; +}; + + +void u8_strcpy (char *dest, char *src, int pos, int size); diff --git a/base/utf8.h b/base/utf8.h index 2f80754..73ea22f 100644 --- a/base/utf8.h +++ b/base/utf8.h @@ -1,4 +1,4 @@ -/* $Id: utf8.h,v 1.1 2013/06/05 22:16:06 steffen Exp $ */ +/* $Id: utf8.h,v 1.2 2013/06/06 21:53:07 steffen Exp $ */ /* utf8.h * Copyright (C) Steffen Pohle 2013 * @@ -19,7 +19,11 @@ #ifndef _UTF8_H_ #define _UTF8_H_ +#include +uint32_t u8_decode (char *str, int *size); +int u8_strlen (char *str); +void u8_strcpy (char *dest, char *src, int pos, int size); #endif diff --git a/sdlgl/sdl_font.c b/sdlgl/sdl_font.c index 73ff66a..3383d8e 100644 --- a/sdlgl/sdl_font.c +++ b/sdlgl/sdl_font.c @@ -2,6 +2,7 @@ #include "osmroute.h" #include "system.h" #include "memoryleak.h" +#include "utf8.h" #include #include FT_FREETYPE_H @@ -29,7 +30,7 @@ int font_init () { struct font* font_load(char *name) { - int fd, i; + int fd; struct font *f = NULL; char fname[LEN_FILENAME]; struct stat st_buf; @@ -58,16 +59,9 @@ struct font* font_load(char *name) { FT_Set_Pixel_Sizes(f->face, 0, 12); d_printf ("font loaded (size:%d).", f->buffersize); - d_printf ("charmap: %d == %d (unicode)", f->face->charmap->encoding, FT_ENCODING_UNICODE); - if (FT_Select_Charmap(f->face, FT_ENCODING_UNICODE)) d_printf ("FT_Select_Charmap: error"); - for (i = 0; i < f->face->num_charmaps; i++) - d_printf (" %d : encoding: %d", i, f->face->charmap[i].encoding); - - d_printf ("charmap: %d == %d (unicode)", f->face->charmap->encoding, FT_ENCODING_UNICODE); - return f; } @@ -78,6 +72,7 @@ struct font* font_load(char *name) { */ void font_draw (struct font *f, char *text, float x, float y, float sx, float sy) { char *p; + uint32_t u8chr; int i; GLfloat vp[8]; GLfloat vt[8] = {0, 1, @@ -86,8 +81,6 @@ void font_draw (struct font *f, char *text, float x, float y, float sx, float sy 0, 0}; FT_GlyphSlot g = f->face->glyph; - if (strncmp ("Than", text, 4) == 0) d_printf ("'%s' drawing", text); - /* Create a texture that will be used to hold one "glyph" */ GLuint tex; glGenTextures(1, &tex); @@ -105,10 +98,16 @@ void font_draw (struct font *f, char *text, float x, float y, float sx, float sy glEnableClientState(GL_TEXTURE_COORD_ARRAY); /* Loop through all characters */ - for (p = text; *p; p++) { + for (p = text; *p;) { + u8chr = u8_decode (p, &i); + if (i == 0) { + p++; + continue; + } + p = p + i; /* Try to load and render the character */ - if ((i = FT_Load_Char(f->face, *p, FT_LOAD_RENDER))) { + if ((i = FT_Load_Char(f->face, u8chr, FT_LOAD_RENDER))) { d_printf ("error:%d", i); continue; }