diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-06-13 08:22:37 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-06-13 08:22:37 +0000 |
| commit | 69511102de9b0f3ec6ad555baf2a01d9ee1c3dfd (patch) | |
| tree | ebef66e5ab0cfd16e96026d8ac8d5a708eb68219 /src/base | |
| parent | 9254ca61f1e459cbaf137ce4511332365da9c225 (diff) | |
| download | zcatch-69511102de9b0f3ec6ad555baf2a01d9ee1c3dfd.tar.gz zcatch-69511102de9b0f3ec6ad555baf2a01d9ee1c3dfd.zip | |
improved the font system even futher. utf8 is now used everywhere. it uses less memory as well
Diffstat (limited to 'src/base')
| -rw-r--r-- | src/base/system.c | 133 | ||||
| -rw-r--r-- | src/base/system.h | 63 |
2 files changed, 196 insertions, 0 deletions
diff --git a/src/base/system.c b/src/base/system.c index 40d53e8a..c94e4cf9 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1188,6 +1188,139 @@ void gui_messagebox(const char *title, const char *message) int str_isspace(char c) { return c == ' ' || c == '\n' || c == '\t'; } + +static int str_utf8_isstart(char c) +{ + if((c&0xC0) == 0x80) /* 10xxxxxx */ + return 0; + return 1; +} + +int str_utf8_rewind(const char *str, int cursor) +{ + while(cursor) + { + cursor--; + if(str_utf8_isstart(*(str + cursor))) + break; + } + return cursor; +} + +int str_utf8_forward(const char *str, int cursor) +{ + const char *buf = str + cursor; + if(!buf[0]) + return cursor; + + if((*buf&0x80) == 0x0) /* 0xxxxxxx */ + return cursor+1; + else if((*buf&0xE0) == 0xC0) /* 110xxxxx */ + { + if(!buf[1]) return cursor+1; + return cursor+2; + } + else if((*buf & 0xF0) == 0xE0) /* 1110xxxx */ + { + if(!buf[1]) return cursor+1; + if(!buf[2]) return cursor+2; + return cursor+2; + } + else if((*buf & 0xF8) == 0xF0) /* 11110xxx */ + { + if(!buf[1]) return cursor+1; + if(!buf[2]) return cursor+2; + if(!buf[3]) return cursor+3; + return cursor+3; + } + + /* invalid */ + return cursor+1; +} + +int str_utf8_encode(char *ptr, int chr) +{ + /* encode */ + if(chr <= 0x7F) + { + ptr[0] = (char)chr; + return 1; + } + else if(chr <= 0x7FF) + { + ptr[0] = 0xC0|((chr>>6)&0x1F); + ptr[1] = 0x80|(chr&0x3F); + return 2; + } + else if(chr <= 0xFFFF) + { + ptr[0] = 0xE0|((chr>>12)&0x0F); + ptr[1] = 0xC0|((chr>>6)&0x3F); + ptr[2] = 0xC0|(chr&0x3F); + return 3; + } + else if(chr <= 0x10FFFF) + { + ptr[0] = 0xF0|((chr>>18)&0x07); + ptr[1] = 0xC0|((chr>>12)&0x3F); + ptr[2] = 0xC0|((chr>>6)&0x3F); + ptr[3] = 0xC0|(chr&0x3F); + return 4; + } + + return 0; +} + +int str_utf8_decode(const char **ptr) +{ + const 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 + { + /* invalid */ + buf++; + break; + } + + *ptr = buf; + return ch; + } while(0); + + /* out of bounds */ + *ptr = buf; + return -1; + +} + #if defined(__cplusplus) } #endif diff --git a/src/base/system.h b/src/base/system.h index 3aa01cab..87cae4a0 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -947,6 +947,69 @@ int str_isspace(char c); */ void gui_messagebox(const char *title, const char *message); + +/* + Function: str_utf8_rewind + Moves a cursor backwards in an utf8 string + + Parameters: + str - utf8 string + cursor - position in the string + + Returns: + New cursor position. + + Remarks: + - Won't move the cursor less then 0 +*/ +int str_utf8_rewind(const char *str, int cursor); + +/* + Function: str_utf8_forward + Moves a cursor forwards in an utf8 string + + Parameters: + str - utf8 string + cursor - position in the string + + Returns: + New cursor position. + + Remarks: + - Won't move the cursor beyond the zero termination marker +*/ +int str_utf8_forward(const char *str, int cursor); + +/* + Function: str_utf8_decode + Decodes an utf8 character + + Parameters: + ptr - pointer to an utf8 string. this pointer will be moved forward + + Returns: + Unicode value for the character. -1 for invalid characters and 0 for end of string. + + Remarks: + - This function will also move the pointer forward. +*/ +int str_utf8_decode(const char **ptr); + +/* + Function: str_utf8_encode + Encode an utf8 character + + Parameters: + ptr - Pointer to a buffer that should recive the data. Should be able to hold at least 4 bytes. + + Returns: + Number of bytes put into the buffer. + + Remarks: + - Does not do zero termination of the string. +*/ +int str_utf8_encode(char *ptr, int chr); + #ifdef __cplusplus } #endif |