From 2b265ea0eb5825eccd3b9b072b5014bacf0d16d7 Mon Sep 17 00:00:00 2001 From: Oxore Date: Wed, 11 Jul 2018 07:04:47 +0300 Subject: Migrate displayable text to utf32 --- src/engine.c | 15 ++++++++++----- src/painter.c | 4 ++-- src/text.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/engine.c b/src/engine.c index 59de551..a087fd2 100644 --- a/src/engine.c +++ b/src/engine.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "common.h" #include "idlist.h" @@ -75,8 +74,11 @@ static void render_score_value(void *obj) struct text *text = obj; if (!strcmp(text->type, "score.value")) { if (!text->text) - text->text = malloc(sizeof(char) * BUFSIZ); - sprintf(text->text, "%d", game.scoreCurrent); + text->text = calloc(BUFSIZ, sizeof(char)); + char *a = calloc(BUFSIZ, sizeof(char)); + sprintf(a, "%d", game.scoreCurrent); + utf8to32_strcpy(text->text, a); + free(a); } } @@ -85,8 +87,11 @@ static void render_level_value(void *obj) struct text *text = obj; if (!strcmp(text->type, "level.value")) { if (!text->text) - text->text = malloc(sizeof(char) * BUFSIZ); - sprintf(text->text, "%d", game.level); + text->text = calloc(BUFSIZ, sizeof(char)); + char *a = calloc(BUFSIZ, sizeof(char)); + sprintf(a, "%d", game.level); + utf8to32_strcpy(text->text, a); + free(a); } } diff --git a/src/painter.c b/src/painter.c index c0e93ea..9dabeb8 100644 --- a/src/painter.c +++ b/src/painter.c @@ -185,7 +185,7 @@ unsigned long painter_register_text(struct text *txt) sfText_setCharacterSize(t->text, txt->size); sfVector2f pos = (sfVector2f){.x = txt->pos.x, .y = txt->pos.y}; sfText_setPosition(t->text, pos); - sfText_setString(t->text, txt->text); + sfText_setUnicodeString(t->text, (unsigned int *)txt->text); last->obj = t; return last->id; @@ -201,7 +201,7 @@ void painter_update_text(unsigned long id, struct text *txt) sfText_setCharacterSize(t->text, txt->size); sfVector2f pos = (sfVector2f){.x = txt->pos.x, .y = txt->pos.y}; sfText_setPosition(t->text, pos); - sfText_setString(t->text, txt->text); + sfText_setUnicodeString(t->text, (unsigned int *)txt->text); } static void draw_text_drawable(struct drawable *d) diff --git a/src/text.c b/src/text.c index a61d28a..6d7cc83 100644 --- a/src/text.c +++ b/src/text.c @@ -11,11 +11,62 @@ #include "vector.h" #include "text.h" +static inline unsigned int utf8_char_len(unsigned char c) +{ + if (c > 0x00 && c < 0xC0) + return 1; + else if (c >= 0xC2 && c < 0xE0) + return 2; + else if (c >= 0xE0 && c < 0xF0) + return 3; + else if (c >= 0xF0 && c < 0xF5) + return 4; + else + return 0; +} + +unsigned long utf8_strlen(void *string) +{ + unsigned long len = 0, keep = 0; + for (unsigned char *c = string; *c; (keep ? --keep : ++len), ++c) + if (!keep) + keep = (keep = utf8_char_len(*c)) ? keep - 1 : keep; + return len; +} + +void utf8to32_strcpy(wchar_t *dest, char *src) +{ + wchar_t *dc = dest; + char *c = src; + unsigned long len = 0; + while (*c) { + int clen = utf8_char_len(*c); + if (clen == 1) { + dc[len] = c[0] & 0x7f; + c += 1; + } else if (clen == 2) { + dc[len] = ((c[0] & 0x1f) << 6) | ((c[1] & 0x3f) << 0); + c += 2; + } else if (clen == 3) { + dc[len] = ((c[0] & 0x0f) << 12) | ((c[1] & 0x3f) << 6) | ((c[2] & 0x3f) << 0); + c += 3; + } else if (clen == 4) { + dc[len] = ((c[0] & 0x07) << 18) | ((c[1] & 0x3f) << 12) | ((c[2] & 0x3f) << 6) | ((c[3] & 0x3f) << 0); + c += 4; + } else { + dc[len] = 0; + return; + } + ++len; + } + dc[len] = 0; +} + static FILE *openFile(char *filename) { FILE *file; if (!(file = fopen(filename, "rb"))){ - printf("ERROR: fild \"%s\"cannot be opened\n", filename); + printf("ERROR: file \"%s\"cannot be opened\n", filename); exit(EXIT_FAILURE); } return file; @@ -65,8 +116,8 @@ struct idlist *load_texts(char *filename) text->scene = malloc(sizeof(char) * (strlen((char *)ev.data.scalar.value) + 1)); strcpy(text->scene, (char *)ev.data.scalar.value); } else if (!strcmp((char *)event.data.scalar.value, "text")) { - text->text = malloc(sizeof(char) * (strlen((char *)ev.data.scalar.value) + 1)); - strcpy(text->text, (char *)ev.data.scalar.value); + text->text = calloc((utf8_strlen(ev.data.scalar.value)) + 1, sizeof(unsigned int)); + utf8to32_strcpy(text->text, (char *)ev.data.scalar.value); } else if (!strcmp((char *)event.data.scalar.value, "font")) { text->font = malloc(sizeof(char) * (strlen((char *)ev.data.scalar.value) + 1)); strcpy(text->font, (char *)ev.data.scalar.value); -- cgit v1.2.3