From 24ebbd942c0cc2557b43fb54e058d967cc28f3b3 Mon Sep 17 00:00:00 2001 From: Dmitry Mikhirev Date: Wed, 29 Aug 2012 01:26:25 +0400 Subject: fix UTF-8 strings conversion --- brainuino.ino | 58 +++++++++++---------- font.h | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ font_en.h | 0 font_ru-en.h | 160 ---------------------------------------------------------- lcdprint.cpp | 16 +++--- lcdprint.h | 2 +- utf8.cpp | 41 ++++++++------- utf8.h | 3 +- 8 files changed, 220 insertions(+), 220 deletions(-) create mode 100644 font.h delete mode 100644 font_en.h delete mode 100644 font_ru-en.h diff --git a/brainuino.ino b/brainuino.ino index 7fb0233..557b023 100644 --- a/brainuino.ino +++ b/brainuino.ino @@ -1,7 +1,7 @@ /* Brainuino Aleph - Copyright (C) 2011 Dmitry Mikhirev + Copyright (C) 2011-2012 Dmitry Mikhirev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,10 +17,11 @@ along with this program. If not, see . */ +#include #include // undefine the following if your LCD does not support Russian font -//#define RUSSIAN +#define RUSSIAN #include "pinout.h" #include "game.h" @@ -51,12 +52,10 @@ void loop() timer = timer1; printGameType(); -/* // ensure that stop button is released while (digitalRead(CONTROL2) == LOW) { delay(20); } -*/ ask(); } @@ -69,7 +68,7 @@ void ask() digitalWrite(REDLAMP, LOW); #ifdef RUSSIAN - printState(convert("Задаётся вопрос ")); + printState("Задаётся вопрос "); #else printState("Asking question "); #endif @@ -131,7 +130,7 @@ void discuss() printGameType(); #ifdef RUSSIAN - printState(convert("Отсчёт: ")); + printState("Отсчёт: "); #else printState("Count: "); #endif @@ -183,7 +182,7 @@ void answer(uint8_t num) { printPlayer(num); #ifdef RUSSIAN - printState(convert("Ответ ")); + printState("Ответ "); #else printState("Answer "); #endif @@ -224,7 +223,7 @@ void falseStart(uint8_t num) { tone(SPEAKER, 1784, 1000); digitalWrite(REDLAMP, HIGH); #ifdef RUSSIAN - printState(convert(" Фальстарт ")); + printState(" Фальстарт "); #else printState(" False start "); #endif @@ -244,12 +243,12 @@ void refresh() { } -void printState(String state) { +void printState(char *state) { // displaying string in the beginning of LCD second row lcd.setCursor(0, 1); - lcd.print(state); + uprint(state, &lcd); } @@ -257,11 +256,11 @@ void printTime() { // displaying time passed after starting timer - String timestr; + char timestr[33]; - timestr = String(time/1000) + '.' + String((time%1000)/100); + sprintf(timestr, "%.1f", float(time)/1000; lcd.setCursor(8, 1); - lcd.print(timestr); + uprint(timestr, &lcd); } @@ -270,24 +269,24 @@ void printPreciseTime() { // displaying time passed after starting timer // or that it was not started yet - String timestr; + char timestr[33]; // if timer was started if (startTime > 0) { time = millis()-startTime; - timestr = String(time/1000) + '.' + String(time%1000); + sprintf(timestr, "%.3f", float(time)/1000); } // if it was not else #ifdef RUSSIAN - timestr = convert("досрочно"); + sprintf(timestr, "досрочно"); #else - timestr = "prematur"; + sprintf(timestr, "prematur"); #endif lcd.setCursor(8, 1); - lcd.print(timestr); + uprint(timestr, &lcd); } @@ -345,27 +344,27 @@ void printGameType() { case BRAIN: #ifdef RUSSIAN - lcd.print(convert(" Брейн-ринг ")); + uprint(" Брейн-ринг ", &lcd); #else - lcd.print(" Brain-ring "); + uprint(" Brain-ring ", &lcd); #endif break; case SI: #ifdef RUSSIAN - lcd.print(convert(" Своя игра ")); + uprint(" Своя игра ", &lcd); #else - lcd.print(" Jeopardy "); + uprint(" Jeopardy ", &lcd); #endif break; case CHGK: #ifdef RUSSIAN - lcd.print(convert("Что? Где? Когда?")); + uprint("Что? Где? Когда?", &lcd); #else - lcd.print("What?Where?When?"); + uprint("What?Where?When?", &lcd); #endif break; @@ -377,26 +376,29 @@ void printPlayer(uint8_t num) { // displaying number of player or team + char printstring[65]; + lcd.setCursor(0, 0); switch (gameType) { case BRAIN: #ifdef RUSSIAN - lcd.print(convert("Команда ") + String(int(num)) + " "); + sprintf(printstring, "Команда %u ", num); #else - lcd.print("Team " + String(int(num)) + " "); + sprintf(printstring, "Team %u ", num); #endif break; case SI: #ifdef RUSSIAN - lcd.print(convert("Игрок ") + String(int(num)) + " "); + sprintf(printstring, "Игрок %u ", num); #else - lcd.print("Player " + String(int(num) + " ")); + sprintf(printstring, "Player %u ", num); #endif break; } + uprint(printstring, &lcd); buttonPressed = 0; } diff --git a/font.h b/font.h new file mode 100644 index 0000000..b1a512e --- /dev/null +++ b/font.h @@ -0,0 +1,160 @@ +/* + Brainuino Aleph + + Copyright (C) 2012 Dmitry Mikhirev + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef font_h +#define font_h + +#include + +struct charcode { + const int32_t uni; + const char font; +}; + +charcode charmap[] PROGMEM = { +// tilde + {0x007e, 0xe9}, +// latin-1 supplement + {0x0083, 0xce}, + {0x00a2, 0x5c}, + {0x00a7, 0xfd}, + {0x00a8, 0xe8}, + {0x00ab, 0xc8}, + {0x00b4, 0xe7}, + {0x00b6, 0xfe}, + {0x00b7, 0xdf}, + {0x00bb, 0xc9}, + {0x00bc, 0xf0}, + {0x00bd, 0xf2}, + {0x00be, 0xf3}, + {0x00bf, 0xcd}, + {0x00d7, 0xd5}, + {0x00e7, 0xeb}, + {0x00e9, 0xea}, + {0x00eb, 0xb5}, +// greek + {0x0391, 0x41}, + {0x0392, 0x42}, + {0x0393, 0xa1}, + {0x0395, 0x45}, + {0x0396, 0x5a}, + {0x0397, 0x48}, + {0x0399, 0x49}, + {0x039a, 0x4b}, + {0x039c, 0x4d}, + {0x039d, 0x4e}, + {0x039f, 0x4f}, + {0x03a0, 0xa8}, + {0x03a1, 0x50}, + {0x03a4, 0x54}, + {0x03a5, 0x59}, + {0x03a6, 0xaa}, + {0x03a7, 0x58}, + {0x03ba, 0xba}, + {0x03bf, 0x6f}, + {0x03c0, 0xbe}, + {0x03c1, 0x70}, +// cyryllic + {0x0401, 0xa2}, + {0x0410, 0x41}, + {0x0411, 0xa0}, + {0x0412, 0x42}, + {0x0413, 0xa1}, + {0x0414, 0xe0}, + {0x0415, 0x45}, + {0x0416, 0xa3}, + {0x0417, 0xa4}, + {0x0418, 0xa5}, + {0x0419, 0xa6}, + {0x041a, 0x4b}, + {0x041b, 0xa7}, + {0x041c, 0x4d}, + {0x041e, 0x4f}, + {0x041f, 0xa8}, + {0x0420, 0x50}, + {0x0421, 0x43}, + {0x0422, 0x54}, + {0x0423, 0xa9}, + {0x0424, 0xaa}, + {0x0425, 0x58}, + {0x0426, 0xe1}, + {0x0427, 0xab}, + {0x0428, 0xac}, + {0x0429, 0xe2}, + {0x042a, 0xad}, + {0x042b, 0xae}, + {0x042c, 0x62}, + {0x042d, 0xaf}, + {0x042e, 0xb0}, + {0x042f, 0xb1}, + {0x0430, 0x61}, + {0x0431, 0xb2}, + {0x0432, 0xb3}, + {0x0433, 0xb4}, + {0x0434, 0xe3}, + {0x0435, 0x65}, + {0x0436, 0xb6}, + {0x0437, 0xb7}, + {0x0438, 0xb8}, + {0x0439, 0xb9}, + {0x043a, 0xba}, + {0x043b, 0xbb}, + {0x043c, 0xbc}, + {0x043d, 0xbd}, + {0x043e, 0x6f}, + {0x043f, 0xbe}, + {0x0440, 0x70}, + {0x0441, 0x63}, + {0x0442, 0xbf}, + {0x0443, 0x79}, + {0x0444, 0xe4}, + {0x0445, 0x78}, + {0x0446, 0xe5}, + {0x0447, 0xc0}, + {0x0448, 0xc1}, + {0x0449, 0xe6}, + {0x044a, 0xc2}, + {0x044b, 0xc3}, + {0x044c, 0xc4}, + {0x044d, 0xc5}, + {0x044e, 0xc6}, + {0x044f, 0xc7}, + {0x0451, 0xb5}, +// general punctuation + {0x2010, 0x2e}, + {0x2011, 0x2e}, + {0x2012, 0x2e}, + {0x2013, 0x2e}, + {0x2014, 0x2e}, + {0x2015, 0x2e}, + {0x201c, 0xca}, + {0x201d, 0xcb}, +// one third + {0x2153, 0xf1}, +// arrows + {0x2191, 0xd9}, + {0x2193, 0xda}, + {0x21b5, 0x7e}, +// mathematical operators + {0x2212, 0x2e}, + {0x2218, 0xef}, + {0x22c5, 0xdf} +}; + +#endif diff --git a/font_en.h b/font_en.h deleted file mode 100644 index e69de29..0000000 diff --git a/font_ru-en.h b/font_ru-en.h deleted file mode 100644 index 2b6c785..0000000 --- a/font_ru-en.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - Brainuino Aleph - - Copyright (C) 2012 Dmitry Mikhirev - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef en_ru_h -#define en_ru_h - -#include - -struct charcode { - const int32_t uni; - const char font; -}; - -const charcode charmap[] PROGMEM = { -// tilde - {0x007e, 0xe9}, -// latin-1 supplement - {0x0083, 0xce}, - {0x00a2, 0x5c}, - {0x00a7, 0xfd}, - {0x00a8, 0xe8}, - {0x00ab, 0xc8}, - {0x00b4, 0xe7}, - {0x00b6, 0xfe}, - {0x00b7, 0xdf}, - {0x00bb, 0xc9}, - {0x00bc, 0xf0}, - {0x00bd, 0xf2}, - {0x00be, 0xf3}, - {0x00bf, 0xcd}, - {0x00d7, 0xd5}, - {0x00e7, 0xeb}, - {0x00e9, 0xea}, - {0x00eb, 0xb5}, -// greek - {0x0391, 0x41}, - {0x0392, 0x42}, - {0x0393, 0xa1}, - {0x0395, 0x45}, - {0x0396, 0x5a}, - {0x0397, 0x48}, - {0x0399, 0x49}, - {0x039a, 0x4b}, - {0x039c, 0x4d}, - {0x039d, 0x4e}, - {0x039f, 0x4f}, - {0x03a0, 0xa8}, - {0x03a1, 0x50}, - {0x03a4, 0x54}, - {0x03a5, 0x59}, - {0x03a6, 0xaa}, - {0x03a7, 0x58}, - {0x03ba, 0xba}, - {0x03bf, 0x6f}, - {0x03c0, 0xbe}, - {0x03c1, 0x70}, -// cyryllic - {0x0401, 0xa2}, - {0x0410, 0x41}, - {0x0411, 0xa0}, - {0x0412, 0x42}, - {0x0413, 0xa1}, - {0x0414, 0xe0}, - {0x0415, 0x45}, - {0x0416, 0xa3}, - {0x0417, 0xa4}, - {0x0418, 0xa5}, - {0x0419, 0xa6}, - {0x041a, 0x4b}, - {0x041b, 0xa7}, - {0x041c, 0x4d}, - {0x041e, 0x4f}, - {0x041f, 0xa8}, - {0x0420, 0x50}, - {0x0421, 0x43}, - {0x0422, 0x54}, - {0x0423, 0xa9}, - {0x0424, 0xaa}, - {0x0425, 0x58}, - {0x0426, 0xe1}, - {0x0427, 0xab}, - {0x0428, 0xac}, - {0x0429, 0xe2}, - {0x042a, 0xad}, - {0x042b, 0xae}, - {0x042c, 0x62}, - {0x042d, 0xaf}, - {0x042e, 0xb0}, - {0x042f, 0xb1}, - {0x0430, 0x61}, - {0x0431, 0xb2}, - {0x0432, 0xb3}, - {0x0433, 0xb4}, - {0x0434, 0xe3}, - {0x0435, 0x65}, - {0x0436, 0xb6}, - {0x0437, 0xb7}, - {0x0438, 0xb8}, - {0x0439, 0xb9}, - {0x043a, 0xba}, - {0x043b, 0xbb}, - {0x043c, 0xbc}, - {0x043d, 0xbd}, - {0x043e, 0x6f}, - {0x043f, 0xbf}, - {0x0440, 0x70}, - {0x0441, 0x63}, - {0x0442, 0xbf}, - {0x0443, 0x79}, - {0x0444, 0xe4}, - {0x0445, 0x78}, - {0x0446, 0xe5}, - {0x0447, 0xc0}, - {0x0448, 0xc1}, - {0x0449, 0xe6}, - {0x044a, 0xc2}, - {0x044b, 0xc3}, - {0x044c, 0xc4}, - {0x044d, 0xc5}, - {0x044e, 0xc6}, - {0x044f, 0xc7}, - {0x0451, 0xb5}, -// general punctuation - {0x2010, 0x2e}, - {0x2011, 0x2e}, - {0x2012, 0x2e}, - {0x2013, 0x2e}, - {0x2014, 0x2e}, - {0x2015, 0x2e}, - {0x201c, 0xca}, - {0x201d, 0xcb}, -// one third - {0x2153, 0xf1}, -// arrows - {0x2191, 0xd9}, - {0x2193, 0xda}, - {0x21b5, 0x7e}, -// mathematical operators - {0x2212, 0x2e}, - {0x2218, 0xef}, - {0x22c5, 0xdf} -}; - -#endif diff --git a/lcdprint.cpp b/lcdprint.cpp index 585b2de..c79bb1c 100644 --- a/lcdprint.cpp +++ b/lcdprint.cpp @@ -17,12 +17,11 @@ along with this program. If not, see . */ - +#include #include "lcdprint.h" -#include "font_ru-en.h" -//#include "font_en.h" +#include "font.h" -char* convert(utf8 str) +size_t uprint(utf8 str, LiquidCrystal *lcd) { int32_t ucode; int i, j; @@ -36,9 +35,9 @@ char* convert(utf8 str) result[i] = char(ucode); } else { result[i] = 0xff; - for (j = 0; j < numcodes && charmap[j].uni < ucode; j++) { - if (charmap[j].uni == ucode) { - result[i] = charmap[j].font; + for (j = 0; (j < numcodes) && (pgm_read_dword(&charmap[j].uni) <= ucode); j++) { + if (pgm_read_dword(&charmap[j].uni) == ucode) { + result[i] = pgm_read_byte(&charmap[j].font); } } } @@ -47,6 +46,5 @@ char* convert(utf8 str) break; } } - - return result; + return lcd->print(result); } diff --git a/lcdprint.h b/lcdprint.h index b76c425..86dbfcc 100644 --- a/lcdprint.h +++ b/lcdprint.h @@ -22,6 +22,6 @@ #include "utf8.h" -char* convert (utf8); +size_t uprint (utf8, LiquidCrystal*); #endif diff --git a/utf8.cpp b/utf8.cpp index 026d16e..ea28922 100644 --- a/utf8.cpp +++ b/utf8.cpp @@ -20,23 +20,22 @@ #include "utf8.h" #include -utf8::utf8 (char* string) +utf8::utf8 (char* input) { - bytes = strlen(string); - _string = (char *)malloc(bytes + 1); - strcpy(_string, string); + bytes = strlen(input); + string = strdup(input); chars = 0; for (_index = 0; _index < bytes; _index++) { - if (_string[_index] & 0x80 == 0) { + if ((string[_index] & 0x80) == 0x00) { + chars++; + } else if ((string[_index] & 0x20) == 0x00) { + chars++; + _index ++; + } else if ((string[_index] & 0x10) == 0x00) { chars++; - } else if (_string[_index] & 0x20 == 0) { - chars += 2; - _index++; - } else if (_string[_index] & 0x10 == 0) { - chars += 3; _index += 2; - } else if (_string[_index] & 0x8 == 0) { - chars += 4; + } else if ((string[_index] & 0x08) == 0x00) { + chars++; _index += 3; } } @@ -46,18 +45,18 @@ utf8::utf8 (char* string) int32_t utf8::get() { int32_t code; - if (_string[_index] & 0x80 == 0) { - code = int32_t(_string[_index]); + if ((string[_index] & 0x80) == 0) { + code = int32_t(string[_index]); _index++; - } else if (_string[_index] & 0x20 == 0) { - code = int32_t(_string[_index] & 0x1f) << 6 | int32_t(_string[_index+1] & 0x3f); + } else if ((string[_index] & 0x20) == 0) { + code = int32_t(string[_index] & 0x1f) << 6 | int32_t(string[_index+1] & 0x3f); _index += 2; - } else if (_string[_index] & 0x10 == 0) { - code = int32_t(_string[_index] & 0xf) << 12 | int32_t(_string[_index+1] & 0x3f) << 6 | int32_t(_string[_index+2] & 0x3f); + } else if ((string[_index] & 0x10) == 0) { + code = int32_t(string[_index] & 0xf) << 12 | int32_t(string[_index+1] & 0x3f) << 6 | int32_t(string[_index+2] & 0x3f); _index += 3; - } else if (_string[_index] & 0x8 == 0) { - code = int32_t(_string[_index] & 0x7) << 18 | int32_t(_string[_index+1] & 0x3f) << 12 | int32_t(_string[_index+2] & 0x3f) << 6 | int32_t(_string[_index+3] & 0x3f); + } else if ((string[_index] & 0x8) == 0) { + code = int32_t(string[_index] & 0x7) << 18 | int32_t(string[_index+1] & 0x3f) << 12 | int32_t(string[_index+2] & 0x3f) << 6 | int32_t(string[_index+3] & 0x3f); } - if (_index > bytes) _index = 0; + if (_index >= bytes) _index = 0; return code; } diff --git a/utf8.h b/utf8.h index 5dbc221..dd4cd9b 100644 --- a/utf8.h +++ b/utf8.h @@ -28,8 +28,9 @@ class utf8 { uint16_t chars; uint16_t bytes; int32_t get(); + char* string; + private: - char* _string; uint16_t _index; }; -- cgit v1.2.1