diff options
Diffstat (limited to 'firmware/common/unicode.c')
-rw-r--r-- | firmware/common/unicode.c | 73 |
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 | |||
23 | static int default_codepage = 0; | 21 | static int default_codepage = 0; |
24 | static unsigned short codepage_table[MAX_CP_TABLE_SIZE]; | ||
25 | static int loaded_cp_table = 0; | 22 | static int loaded_cp_table = 0; |
26 | 23 | ||
24 | #ifdef HAVE_LCD_BITMAP | ||
27 | 25 | ||
28 | static 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 | ||
29 | enum { | ||
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 | }; | ||
33 | static const char *filename[NUM_TABLES] = | 34 | static 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 | |||
42 | static const char cp_2_table[NUM_CODEPAGES] = | 42 | static 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 | |||
52 | enum { | ||
53 | ISO_8859_1 = 0, ISO_8859_7, WIN_1251, | ||
54 | ISO_8859_9, ISO_8859_2, UTF_8, NUM_CODEPAGES | ||
55 | }; | ||
56 | static const char *filename[NUM_TABLES] = | ||
57 | { | ||
58 | CODEPAGE_DIR"/isomini.cp", | ||
59 | }; | ||
60 | static const char cp_2_table[NUM_CODEPAGES] = | ||
61 | { | ||
62 | 0, 1, 1, 1, 1, 0 | ||
63 | }; | ||
64 | |||
65 | #endif | ||
66 | |||
67 | static unsigned short codepage_table[MAX_CP_TABLE_SIZE]; | ||
68 | |||
69 | static 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 */ |
48 | static int load_cp_table(int cp) | 75 | static 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++; |