summaryrefslogtreecommitdiff
path: root/firmware/common/unicode.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common/unicode.c')
-rw-r--r--firmware/common/unicode.c73
1 files changed, 52 insertions, 21 deletions
diff --git a/firmware/common/unicode.c b/firmware/common/unicode.c
index 34c11369f2..50caa55667 100644
--- a/firmware/common/unicode.c
+++ b/firmware/common/unicode.c
@@ -17,19 +17,20 @@
17#define O_BINARY 0 17#define O_BINARY 0
18#endif 18#endif
19 19
20#define NUM_TABLES 5 20#define CODEPAGE_DIR "/.rockbox/codepages"
21#define NUM_CODEPAGES 13
22
23static int default_codepage = 0; 21static int default_codepage = 0;
24static unsigned short codepage_table[MAX_CP_TABLE_SIZE];
25static int loaded_cp_table = 0; 22static int loaded_cp_table = 0;
26 23
24#ifdef HAVE_LCD_BITMAP
27 25
28static const unsigned char utf8comp[6] = 26#define MAX_CP_TABLE_SIZE 32768
29{ 27#define NUM_TABLES 5
30 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
31};
32 28
29enum {
30 ISO_8859_1 = 0, ISO_8859_7, ISO_8859_8, WIN_1251,
31 ISO_8859_11, WIN_1256, ISO_8859_9, ISO_8859_2,
32 SJIS, GB_2312, KSX_1001, BIG_5, UTF_8, NUM_CODEPAGES
33};
33static const char *filename[NUM_TABLES] = 34static const char *filename[NUM_TABLES] =
34{ 35{
35 CODEPAGE_DIR"/iso.cp", 36 CODEPAGE_DIR"/iso.cp",
@@ -38,12 +39,38 @@ static const char *filename[NUM_TABLES] =
38 CODEPAGE_DIR"/949.cp", /* KSX1001 */ 39 CODEPAGE_DIR"/949.cp", /* KSX1001 */
39 CODEPAGE_DIR"/950.cp" /* BIG5 */ 40 CODEPAGE_DIR"/950.cp" /* BIG5 */
40}; 41};
41
42static const char cp_2_table[NUM_CODEPAGES] = 42static const char cp_2_table[NUM_CODEPAGES] =
43{ 43{
44 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 0 44 0, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 0
45}; 45};
46 46
47#else /* !HAVE_LCD_BITMAP, reduced support */
48
49#define MAX_CP_TABLE_SIZE 512
50#define NUM_TABLES 1
51
52enum {
53 ISO_8859_1 = 0, ISO_8859_7, WIN_1251,
54 ISO_8859_9, ISO_8859_2, UTF_8, NUM_CODEPAGES
55};
56static const char *filename[NUM_TABLES] =
57{
58 CODEPAGE_DIR"/isomini.cp",
59};
60static const char cp_2_table[NUM_CODEPAGES] =
61{
62 0, 1, 1, 1, 1, 0
63};
64
65#endif
66
67static unsigned short codepage_table[MAX_CP_TABLE_SIZE];
68
69static const unsigned char utf8comp[6] =
70{
71 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
72};
73
47/* Load codepage file into memory */ 74/* Load codepage file into memory */
48static int load_cp_table(int cp) 75static int load_cp_table(int cp)
49{ 76{
@@ -113,34 +140,37 @@ unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8,
113 if (!load_cp_table(cp)) cp = 0; 140 if (!load_cp_table(cp)) cp = 0;
114 141
115 while (count--) { 142 while (count--) {
116 if (*iso < 128 || cp == 0x0C) /* Already UTF-8 */ 143 if (*iso < 128 || cp == UTF_8) /* Already UTF-8 */
117 *utf8++ = *iso++; 144 *utf8++ = *iso++;
118 145
119 else { 146 else {
120 147
121 /* cp tells us which codepage to convert from */ 148 /* cp tells us which codepage to convert from */
122 switch (cp) { 149 switch (cp) {
123 case 0x01: /* Greek (ISO-8859-7) */ 150 case ISO_8859_7: /* Greek */
124 case 0x02: /* Hebrew (ISO-8859-8) */ 151 case WIN_1251: /* Cyrillic */
125 case 0x03: /* Cyrillic (CP1251) */ 152 case ISO_8859_9: /* Turkish */
126 case 0x04: /* Thai (ISO-8859-11) */ 153 case ISO_8859_2: /* Latin Extended */
127 case 0x05: /* Arabic (CP1256) */ 154#ifdef HAVE_LCD_BITMAP
128 case 0x06: /* Turkish (ISO-8859-9) */ 155 case ISO_8859_8: /* Hebrew */
129 case 0x07: /* Latin Extended (ISO-8859-2) */ 156 case ISO_8859_11: /* Thai */
157 case WIN_1256: /* Arabic */
158#endif
130 tmp = ((cp-1)*128) + (*iso++ - 128); 159 tmp = ((cp-1)*128) + (*iso++ - 128);
131 ucs = codepage_table[tmp]; 160 ucs = codepage_table[tmp];
132 break; 161 break;
133 162
134 case 0x08: /* Japanese (SJIS) */ 163#ifdef HAVE_LCD_BITMAP
164 case SJIS: /* Japanese */
135 if (*iso > 0xA0 && *iso < 0xE0) { 165 if (*iso > 0xA0 && *iso < 0xE0) {
136 tmp = *iso++ | (0xA100 - 0x8000); 166 tmp = *iso++ | (0xA100 - 0x8000);
137 ucs = codepage_table[tmp]; 167 ucs = codepage_table[tmp];
138 break; 168 break;
139 } 169 }
140 170
141 case 0x09: /* Simplified Chinese (GB2312) */ 171 case GB_2312: /* Simplified Chinese */
142 case 0x0A: /* Korean (KSX1001) */ 172 case KSX_1001: /* Korean */
143 case 0x0B: /* Traditional Chinese (BIG5) */ 173 case BIG5: /* Traditional Chinese */
144 if (count < 1 || !iso[1]) { 174 if (count < 1 || !iso[1]) {
145 ucs = *iso++; 175 ucs = *iso++;
146 break; 176 break;
@@ -154,6 +184,7 @@ unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8,
154 ucs = codepage_table[tmp]; 184 ucs = codepage_table[tmp];
155 count--; 185 count--;
156 break; 186 break;
187#endif /* HAVE_LCD_BITMAP */
157 188
158 default: 189 default:
159 ucs = *iso++; 190 ucs = *iso++;