diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/fat.c | 165 | ||||
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 26 | ||||
-rw-r--r-- | firmware/drivers/lcd-h100-remote.c | 26 | ||||
-rw-r--r-- | firmware/drivers/lcd-h100.c | 18 | ||||
-rw-r--r-- | firmware/drivers/lcd-player.c | 40 | ||||
-rw-r--r-- | firmware/drivers/lcd-recorder.c | 18 |
6 files changed, 105 insertions, 188 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index fd09bff0da..559d00b2b9 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "system.h" | 28 | #include "system.h" |
29 | #include "timefuncs.h" | 29 | #include "timefuncs.h" |
30 | #include "kernel.h" | 30 | #include "kernel.h" |
31 | #include "rbunicode.h" | ||
31 | 32 | ||
32 | #define BYTES2INT16(array,pos) \ | 33 | #define BYTES2INT16(array,pos) \ |
33 | (array[pos] | (array[pos+1] << 8 )) | 34 | (array[pos] | (array[pos+1] << 8 )) |
@@ -115,74 +116,6 @@ | |||
115 | #define FAT_BAD_MARK 0x0ffffff7 | 116 | #define FAT_BAD_MARK 0x0ffffff7 |
116 | #define FAT_EOF_MARK 0x0ffffff8 | 117 | #define FAT_EOF_MARK 0x0ffffff8 |
117 | 118 | ||
118 | /* filename charset conversion table */ | ||
119 | static const unsigned char unicode2iso8859_2[] = { | ||
120 | 0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xb1, 0xc6, 0xe6, /* 0x0100 */ | ||
121 | 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x0108 */ | ||
122 | 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0110 */ | ||
123 | 0xca, 0xea, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x0118 */ | ||
124 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0120 */ | ||
125 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0128 */ | ||
126 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0130 */ | ||
127 | 0x00, 0xc5, 0xe5, 0x00, 0x00, 0xa5, 0xb5, 0x00, /* 0x0138 */ | ||
128 | 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0xd2, /* 0x0140 */ | ||
129 | 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0148 */ | ||
130 | 0xd5, 0xf5, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, /* 0x0150 */ | ||
131 | 0xd8, 0xf8, 0xa6, 0xb6, 0x00, 0x00, 0xaa, 0xba, /* 0x0158 */ | ||
132 | 0xa9, 0xb9, 0xde, 0xfe, 0xab, 0xbb, 0x00, 0x00, /* 0x0160 */ | ||
133 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xf9, /* 0x0168 */ | ||
134 | 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0170 */ | ||
135 | 0x00, 0xac, 0xbc, 0xaf, 0xbf, 0xae, 0xbe, 0x00, /* 0x0178 */ | ||
136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0180 */ | ||
137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0188 */ | ||
138 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0190 */ | ||
139 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0198 */ | ||
140 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01a0 */ | ||
141 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01a8 */ | ||
142 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01b0 */ | ||
143 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01b8 */ | ||
144 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c0 */ | ||
145 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c8 */ | ||
146 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01d0 */ | ||
147 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01d8 */ | ||
148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01e0 */ | ||
149 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01e8 */ | ||
150 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01f0 */ | ||
151 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01f8 */ | ||
152 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0200 */ | ||
153 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0208 */ | ||
154 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0210 */ | ||
155 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0218 */ | ||
156 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0220 */ | ||
157 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0228 */ | ||
158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0230 */ | ||
159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0238 */ | ||
160 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0240 */ | ||
161 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0248 */ | ||
162 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0250 */ | ||
163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0258 */ | ||
164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0260 */ | ||
165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0268 */ | ||
166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0270 */ | ||
167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0278 */ | ||
168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0280 */ | ||
169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0288 */ | ||
170 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0290 */ | ||
171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0298 */ | ||
172 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02a0 */ | ||
173 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02a8 */ | ||
174 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02b0 */ | ||
175 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02b8 */ | ||
176 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0x02c0 */ | ||
177 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c8 */ | ||
178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02d0 */ | ||
179 | 0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0x02d8 */ | ||
180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02e0 */ | ||
181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02e8 */ | ||
182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02f0 */ | ||
183 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x02f8 */ | ||
184 | }; | ||
185 | |||
186 | struct fsinfo { | 119 | struct fsinfo { |
187 | unsigned long freecount; /* last known free cluster count */ | 120 | unsigned long freecount; /* last known free cluster count */ |
188 | unsigned long nextfree; /* first cluster to start looking for free | 121 | unsigned long nextfree; /* first cluster to start looking for free |
@@ -1106,10 +1039,11 @@ static int write_long_name(struct fat_file* file, | |||
1106 | unsigned char* entry; | 1039 | unsigned char* entry; |
1107 | unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR; | 1040 | unsigned int idx = firstentry % DIR_ENTRIES_PER_SECTOR; |
1108 | unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR; | 1041 | unsigned int sector = firstentry / DIR_ENTRIES_PER_SECTOR; |
1109 | unsigned int i, j=0; | ||
1110 | unsigned char chksum = 0; | 1042 | unsigned char chksum = 0; |
1111 | int nameidx=0, namelen = strlen(name); | 1043 | unsigned int i, j=0; |
1044 | unsigned int nameidx=0, namelen = utf8length(name); | ||
1112 | int rc; | 1045 | int rc; |
1046 | unsigned short name_utf16[namelen + 1]; | ||
1113 | 1047 | ||
1114 | LDEBUGF("write_long_name(file:%lx, first:%d, num:%d, name:%s)\n", | 1048 | LDEBUGF("write_long_name(file:%lx, first:%d, num:%d, name:%s)\n", |
1115 | file->firstcluster, firstentry, numentries, name); | 1049 | file->firstcluster, firstentry, numentries, name); |
@@ -1132,6 +1066,11 @@ static int write_long_name(struct fat_file* file, | |||
1132 | nameidx < (namelen - NAME_BYTES_PER_ENTRY); | 1066 | nameidx < (namelen - NAME_BYTES_PER_ENTRY); |
1133 | nameidx += NAME_BYTES_PER_ENTRY); | 1067 | nameidx += NAME_BYTES_PER_ENTRY); |
1134 | 1068 | ||
1069 | /* we need to convert the name first */ | ||
1070 | /* since it is written in reverse order */ | ||
1071 | for (i = 0; i <= namelen; i++) | ||
1072 | name = utf8decode(name, &name_utf16[i]); | ||
1073 | |||
1135 | for (i=0; i < numentries; i++) { | 1074 | for (i=0; i < numentries; i++) { |
1136 | /* new sector? */ | 1075 | /* new sector? */ |
1137 | if ( idx >= DIR_ENTRIES_PER_SECTOR ) { | 1076 | if ( idx >= DIR_ENTRIES_PER_SECTOR ) { |
@@ -1170,7 +1109,7 @@ static int write_long_name(struct fat_file* file, | |||
1170 | memset(entry, 0, DIR_ENTRY_SIZE); | 1109 | memset(entry, 0, DIR_ENTRY_SIZE); |
1171 | if ( i+1 < numentries ) { | 1110 | if ( i+1 < numentries ) { |
1172 | /* longname entry */ | 1111 | /* longname entry */ |
1173 | int k, l = nameidx; | 1112 | unsigned int k, l = nameidx; |
1174 | 1113 | ||
1175 | entry[FATLONG_ORDER] = numentries-i-1; | 1114 | entry[FATLONG_ORDER] = numentries-i-1; |
1176 | if (i==0) { | 1115 | if (i==0) { |
@@ -1178,22 +1117,22 @@ static int write_long_name(struct fat_file* file, | |||
1178 | entry[FATLONG_ORDER] |= 0x40; | 1117 | entry[FATLONG_ORDER] |= 0x40; |
1179 | 1118 | ||
1180 | /* pad name with 0xffff */ | 1119 | /* pad name with 0xffff */ |
1181 | for (k=1; k<12; k++) entry[k] = 0xff; | 1120 | for (k=1; k<11; k++) entry[k] = 0xff; |
1182 | for (k=14; k<26; k++) entry[k] = 0xff; | 1121 | for (k=14; k<26; k++) entry[k] = 0xff; |
1183 | for (k=28; k<32; k++) entry[k] = 0xff; | 1122 | for (k=28; k<32; k++) entry[k] = 0xff; |
1184 | }; | 1123 | }; |
1185 | /* set name */ | 1124 | /* set name */ |
1186 | for (k=0; k<5 && l <= namelen; k++) { | 1125 | for (k=0; k<5 && l <= namelen; k++) { |
1187 | entry[k*2 + 1] = name[l++]; | 1126 | entry[k*2 + 1] = (unsigned char)(name_utf16[l] & 0xff); |
1188 | entry[k*2 + 2] = 0; | 1127 | entry[k*2 + 2] = (unsigned char)(name_utf16[l++] >> 8); |
1189 | } | 1128 | } |
1190 | for (k=0; k<6 && l <= namelen; k++) { | 1129 | for (k=0; k<6 && l <= namelen; k++) { |
1191 | entry[k*2 + 14] = name[l++]; | 1130 | entry[k*2 + 14] = (unsigned char)(name_utf16[l] & 0xff); |
1192 | entry[k*2 + 15] = 0; | 1131 | entry[k*2 + 15] = (unsigned char)(name_utf16[l++] >> 8); |
1193 | } | 1132 | } |
1194 | for (k=0; k<2 && l <= namelen; k++) { | 1133 | for (k=0; k<2 && l <= namelen; k++) { |
1195 | entry[k*2 + 28] = name[l++]; | 1134 | entry[k*2 + 28] = (unsigned char)(name_utf16[l] & 0xff); |
1196 | entry[k*2 + 29] = 0; | 1135 | entry[k*2 + 29] = (unsigned char)(name_utf16[l++] >> 8); |
1197 | } | 1136 | } |
1198 | 1137 | ||
1199 | entry[FATDIR_ATTR] = FAT_ATTR_LONG_NAME; | 1138 | entry[FATDIR_ATTR] = FAT_ATTR_LONG_NAME; |
@@ -1291,7 +1230,7 @@ static int add_dir_entry(struct fat_dir* dir, | |||
1291 | 1230 | ||
1292 | /* one dir entry needed for every 13 bytes of filename, | 1231 | /* one dir entry needed for every 13 bytes of filename, |
1293 | plus one entry for the short name */ | 1232 | plus one entry for the short name */ |
1294 | entries_needed = (strlen(name) + (NAME_BYTES_PER_ENTRY-1)) | 1233 | entries_needed = (utf8length(name) + (NAME_BYTES_PER_ENTRY-1)) |
1295 | / NAME_BYTES_PER_ENTRY + 1; | 1234 | / NAME_BYTES_PER_ENTRY + 1; |
1296 | } | 1235 | } |
1297 | 1236 | ||
@@ -2226,58 +2165,6 @@ int fat_opendir(IF_MV2(int volume,) | |||
2226 | return 0; | 2165 | return 0; |
2227 | } | 2166 | } |
2228 | 2167 | ||
2229 | /* convert from unicode to a single-byte charset */ | ||
2230 | static void unicode2iso(const unsigned char* unicode, unsigned char* iso, | ||
2231 | int count) | ||
2232 | { | ||
2233 | int i; | ||
2234 | |||
2235 | for (i=0; i<count; i++) { | ||
2236 | int x = i*2; | ||
2237 | switch (unicode[x+1]) { | ||
2238 | case 0x01: /* latin extended. convert to ISO 8859-2 */ | ||
2239 | case 0x02: | ||
2240 | iso[i] = unicode2iso8859_2[unicode[x]]; | ||
2241 | break; | ||
2242 | |||
2243 | case 0x03: /* greek, convert to ISO 8859-7 */ | ||
2244 | iso[i] = unicode[x] + 0x30; | ||
2245 | break; | ||
2246 | |||
2247 | /* Sergei says most russians use Win1251, so we will too. | ||
2248 | Win1251 differs from ISO 8859-5 by an offset of 0x10. */ | ||
2249 | case 0x04: /* cyrillic, convert to Win1251 */ | ||
2250 | switch (unicode[x]) { | ||
2251 | case 1: | ||
2252 | iso[i] = 168; | ||
2253 | break; | ||
2254 | |||
2255 | case 81: | ||
2256 | iso[i] = 184; | ||
2257 | break; | ||
2258 | |||
2259 | default: | ||
2260 | iso[i] = unicode[x] + 0xb0; /* 0xa0 for ISO 8859-5 */ | ||
2261 | break; | ||
2262 | } | ||
2263 | break; | ||
2264 | |||
2265 | case 0x05: /* hebrew, convert to ISO 8859-8 */ | ||
2266 | iso[i] = unicode[x] + 0x10; | ||
2267 | break; | ||
2268 | |||
2269 | case 0x06: /* arabic, convert to ISO 8859-6 */ | ||
2270 | case 0x0e: /* thai, convert to ISO 8859-11 */ | ||
2271 | iso[i] = unicode[x] + 0xa0; | ||
2272 | break; | ||
2273 | |||
2274 | default: | ||
2275 | iso[i] = unicode[x]; | ||
2276 | break; | ||
2277 | } | ||
2278 | } | ||
2279 | } | ||
2280 | |||
2281 | int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) | 2168 | int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) |
2282 | { | 2169 | { |
2283 | bool done = false; | 2170 | bool done = false; |
@@ -2348,7 +2235,8 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) | |||
2348 | 2235 | ||
2349 | /* replace shortname with longname? */ | 2236 | /* replace shortname with longname? */ |
2350 | if ( longs ) { | 2237 | if ( longs ) { |
2351 | int j,l=0; | 2238 | int j; |
2239 | unsigned char* utf8 = entry->name; | ||
2352 | /* iterate backwards through the dir entries */ | 2240 | /* iterate backwards through the dir entries */ |
2353 | for (j=longs-1; j>=0; j--) { | 2241 | for (j=longs-1; j>=0; j--) { |
2354 | unsigned char* ptr = cached_buf; | 2242 | unsigned char* ptr = cached_buf; |
@@ -2370,16 +2258,11 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) | |||
2370 | index &= SECTOR_SIZE-1; | 2258 | index &= SECTOR_SIZE-1; |
2371 | } | 2259 | } |
2372 | 2260 | ||
2373 | /* names are stored in unicode, but we | 2261 | utf8 = utf16LEdecode(ptr + index + 1, utf8, 5); |
2374 | only grab the low byte (iso8859-1). */ | 2262 | utf8 = utf16LEdecode(ptr + index + 14, utf8, 6); |
2375 | unicode2iso(ptr + index + 1, entry->name + l, 5); | 2263 | utf8 = utf16LEdecode(ptr + index + 28, utf8, 2); |
2376 | l+= 5; | ||
2377 | unicode2iso(ptr + index + 14, entry->name + l, 6); | ||
2378 | l+= 6; | ||
2379 | unicode2iso(ptr + index + 28, entry->name + l, 2); | ||
2380 | l+= 2; | ||
2381 | } | 2264 | } |
2382 | entry->name[l]=0; | 2265 | *utf8 = 0; |
2383 | } | 2266 | } |
2384 | done = true; | 2267 | done = true; |
2385 | sectoridx = 0; | 2268 | sectoridx = 0; |
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index a4ae6cd553..582050c878 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "debug.h" | 30 | #include "debug.h" |
31 | #include "system.h" | 31 | #include "system.h" |
32 | #include "font.h" | 32 | #include "font.h" |
33 | #include "rbunicode.h" | ||
33 | #include "bidi.h" | 34 | #include "bidi.h" |
34 | 35 | ||
35 | #define SCROLLABLE_LINES 26 | 36 | #define SCROLLABLE_LINES 26 |
@@ -542,13 +543,13 @@ void lcd_bitmap(const fb_data *src, int x, int y, int width, int height) | |||
542 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 543 | /* put a string at a given pixel position, skipping first ofs pixel columns */ |
543 | static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | 544 | static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) |
544 | { | 545 | { |
545 | int ch; | 546 | unsigned short ch; |
547 | unsigned short *ucs; | ||
546 | struct font* pf = font_get(curfont); | 548 | struct font* pf = font_get(curfont); |
547 | 549 | ||
548 | if (bidi_support_enabled) | 550 | ucs = bidi_l2v(str, 1); |
549 | str = bidi_l2v(str, 1); | ||
550 | 551 | ||
551 | while ((ch = *str++) != '\0' && x < LCD_WIDTH) | 552 | while ((ch = *ucs++) != 0 && x < LCD_WIDTH) |
552 | { | 553 | { |
553 | int width; | 554 | int width; |
554 | const unsigned char *bits; | 555 | const unsigned char *bits; |
@@ -559,7 +560,7 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
559 | ch -= pf->firstchar; | 560 | ch -= pf->firstchar; |
560 | 561 | ||
561 | /* get proportional width and glyph bits */ | 562 | /* get proportional width and glyph bits */ |
562 | width = pf->width ? pf->width[ch] : pf->maxwidth; | 563 | width = font_get_width(pf,ch); |
563 | 564 | ||
564 | if (ofs > width) | 565 | if (ofs > width) |
565 | { | 566 | { |
@@ -567,8 +568,7 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
567 | continue; | 568 | continue; |
568 | } | 569 | } |
569 | 570 | ||
570 | bits = pf->bits + (pf->offset ? | 571 | bits = font_get_bits(pf, ch); |
571 | pf->offset[ch] : ((pf->height + 7) / 8 * pf->maxwidth * ch)); | ||
572 | 572 | ||
573 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); | 573 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); |
574 | 574 | ||
@@ -597,7 +597,7 @@ void lcd_puts_style(int x, int y, const unsigned char *str, int style) | |||
597 | return; | 597 | return; |
598 | 598 | ||
599 | lcd_getstringsize(str, &w, &h); | 599 | lcd_getstringsize(str, &w, &h); |
600 | xpos = xmargin + x*w / strlen(str); | 600 | xpos = xmargin + x*w / utf8length(str); |
601 | ypos = ymargin + y*h; | 601 | ypos = ymargin + y*h; |
602 | lcd_putsxy(xpos, ypos, str); | 602 | lcd_putsxy(xpos, ypos, str); |
603 | drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); | 603 | drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); |
@@ -707,7 +707,7 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style) | |||
707 | end = strchr(s->line, '\0'); | 707 | end = strchr(s->line, '\0'); |
708 | strncpy(end, string, LCD_WIDTH/2); | 708 | strncpy(end, string, LCD_WIDTH/2); |
709 | 709 | ||
710 | s->len = strlen(string); | 710 | s->len = utf8length(string); |
711 | s->offset = 0; | 711 | s->offset = 0; |
712 | s->startx = x; | 712 | s->startx = x; |
713 | s->backward = false; | 713 | s->backward = false; |
@@ -765,9 +765,11 @@ static void scroll_thread(void) | |||
765 | } | 765 | } |
766 | } | 766 | } |
767 | else { | 767 | else { |
768 | /* scroll forward the whole time */ | 768 | /* pause at beginning of line */ |
769 | if (s->offset >= s->width) | 769 | if (s->offset >= s->width) { |
770 | s->offset %= s->width; | 770 | s->offset = 0; |
771 | s->start_tick = current_tick + scroll_delay * 2; | ||
772 | } | ||
771 | } | 773 | } |
772 | 774 | ||
773 | lastmode = drawmode; | 775 | lastmode = drawmode; |
diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c index 33a8b3790d..a2fe63ee97 100644 --- a/firmware/drivers/lcd-h100-remote.c +++ b/firmware/drivers/lcd-h100-remote.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "debug.h" | 29 | #include "debug.h" |
30 | #include "system.h" | 30 | #include "system.h" |
31 | #include "font.h" | 31 | #include "font.h" |
32 | #include "rbunicode.h" | ||
32 | #include "bidi.h" | 33 | #include "bidi.h" |
33 | 34 | ||
34 | /*** definitions ***/ | 35 | /*** definitions ***/ |
@@ -1091,13 +1092,13 @@ void lcd_remote_bitmap(const unsigned char *src, int x, int y, int width, | |||
1091 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 1092 | /* put a string at a given pixel position, skipping first ofs pixel columns */ |
1092 | static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) | 1093 | static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) |
1093 | { | 1094 | { |
1094 | int ch; | 1095 | unsigned short ch; |
1096 | unsigned short *ucs; | ||
1095 | struct font* pf = font_get(curfont); | 1097 | struct font* pf = font_get(curfont); |
1096 | 1098 | ||
1097 | if (bidi_support_enabled) | 1099 | ucs = bidi_l2v(str, 1); |
1098 | str = bidi_l2v(str, 1); | ||
1099 | 1100 | ||
1100 | while ((ch = *str++) != '\0' && x < LCD_REMOTE_WIDTH) | 1101 | while ((ch = *ucs++) != 0 && x < LCD_REMOTE_WIDTH) |
1101 | { | 1102 | { |
1102 | int width; | 1103 | int width; |
1103 | const unsigned char *bits; | 1104 | const unsigned char *bits; |
@@ -1108,7 +1109,7 @@ static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str | |||
1108 | ch -= pf->firstchar; | 1109 | ch -= pf->firstchar; |
1109 | 1110 | ||
1110 | /* get proportional width and glyph bits */ | 1111 | /* get proportional width and glyph bits */ |
1111 | width = pf->width ? pf->width[ch] : pf->maxwidth; | 1112 | width = font_get_width(pf, ch); |
1112 | 1113 | ||
1113 | if (ofs > width) | 1114 | if (ofs > width) |
1114 | { | 1115 | { |
@@ -1116,8 +1117,7 @@ static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str | |||
1116 | continue; | 1117 | continue; |
1117 | } | 1118 | } |
1118 | 1119 | ||
1119 | bits = pf->bits + (pf->offset ? | 1120 | bits = font_get_bits(pf, ch); |
1120 | pf->offset[ch] : ((pf->height + 7) / 8 * pf->maxwidth * ch)); | ||
1121 | 1121 | ||
1122 | lcd_remote_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, | 1122 | lcd_remote_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, |
1123 | pf->height); | 1123 | pf->height); |
@@ -1153,7 +1153,7 @@ void lcd_remote_puts_style(int x, int y, const unsigned char *str, int style) | |||
1153 | return; | 1153 | return; |
1154 | 1154 | ||
1155 | lcd_remote_getstringsize(str, &w, &h); | 1155 | lcd_remote_getstringsize(str, &w, &h); |
1156 | xpos = xmargin + x*w / strlen((char *)str); | 1156 | xpos = xmargin + x*w / utf8length((char *)str); |
1157 | ypos = ymargin + y*h; | 1157 | ypos = ymargin + y*h; |
1158 | lcd_remote_putsxy(xpos, ypos, str); | 1158 | lcd_remote_putsxy(xpos, ypos, str); |
1159 | drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); | 1159 | drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); |
@@ -1256,7 +1256,7 @@ void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *string, int | |||
1256 | end = strchr(s->line, '\0'); | 1256 | end = strchr(s->line, '\0'); |
1257 | strncpy(end, (char *)string, LCD_REMOTE_WIDTH/2); | 1257 | strncpy(end, (char *)string, LCD_REMOTE_WIDTH/2); |
1258 | 1258 | ||
1259 | s->len = strlen((char *)string); | 1259 | s->len = utf8length((char *)string); |
1260 | s->offset = 0; | 1260 | s->offset = 0; |
1261 | s->startx = x; | 1261 | s->startx = x; |
1262 | s->backward = false; | 1262 | s->backward = false; |
@@ -1323,9 +1323,11 @@ static void scroll_thread(void) | |||
1323 | } | 1323 | } |
1324 | } | 1324 | } |
1325 | else { | 1325 | else { |
1326 | /* scroll forward the whole time */ | 1326 | /* pause at beginning of line */ |
1327 | if (s->offset >= s->width) | 1327 | if (s->offset >= s->width) { |
1328 | s->offset %= s->width; | 1328 | s->offset = 0; |
1329 | s->start_tick = current_tick + scroll_delay * 2; | ||
1330 | } | ||
1329 | } | 1331 | } |
1330 | 1332 | ||
1331 | lastmode = drawmode; | 1333 | lastmode = drawmode; |
diff --git a/firmware/drivers/lcd-h100.c b/firmware/drivers/lcd-h100.c index ba959d23de..1199bf04a1 100644 --- a/firmware/drivers/lcd-h100.c +++ b/firmware/drivers/lcd-h100.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "debug.h" | 28 | #include "debug.h" |
29 | #include "system.h" | 29 | #include "system.h" |
30 | #include "font.h" | 30 | #include "font.h" |
31 | #include "rbunicode.h" | ||
31 | #include "bidi.h" | 32 | #include "bidi.h" |
32 | 33 | ||
33 | /*** definitions ***/ | 34 | /*** definitions ***/ |
@@ -1014,13 +1015,13 @@ void lcd_bitmap(const unsigned char *src, int x, int y, int width, int height) | |||
1014 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 1015 | /* put a string at a given pixel position, skipping first ofs pixel columns */ |
1015 | static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | 1016 | static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) |
1016 | { | 1017 | { |
1017 | int ch; | 1018 | unsigned short ch; |
1019 | unsigned short *ucs; | ||
1018 | struct font* pf = font_get(curfont); | 1020 | struct font* pf = font_get(curfont); |
1019 | 1021 | ||
1020 | if (bidi_support_enabled) | 1022 | ucs = bidi_l2v(str, 1); |
1021 | str = bidi_l2v(str, 1); | ||
1022 | 1023 | ||
1023 | while ((ch = *str++) != '\0' && x < LCD_WIDTH) | 1024 | while ((ch = *ucs++) != 0 && x < LCD_WIDTH) |
1024 | { | 1025 | { |
1025 | int width; | 1026 | int width; |
1026 | const unsigned char *bits; | 1027 | const unsigned char *bits; |
@@ -1031,7 +1032,7 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
1031 | ch -= pf->firstchar; | 1032 | ch -= pf->firstchar; |
1032 | 1033 | ||
1033 | /* get proportional width and glyph bits */ | 1034 | /* get proportional width and glyph bits */ |
1034 | width = pf->width ? pf->width[ch] : pf->maxwidth; | 1035 | width = font_get_width(pf,ch); |
1035 | 1036 | ||
1036 | if (ofs > width) | 1037 | if (ofs > width) |
1037 | { | 1038 | { |
@@ -1039,8 +1040,7 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
1039 | continue; | 1040 | continue; |
1040 | } | 1041 | } |
1041 | 1042 | ||
1042 | bits = pf->bits + (pf->offset ? | 1043 | bits = font_get_bits(pf, ch); |
1043 | pf->offset[ch] : ((pf->height + 7) / 8 * pf->maxwidth * ch)); | ||
1044 | 1044 | ||
1045 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); | 1045 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); |
1046 | 1046 | ||
@@ -1069,7 +1069,7 @@ void lcd_puts_style(int x, int y, const unsigned char *str, int style) | |||
1069 | return; | 1069 | return; |
1070 | 1070 | ||
1071 | lcd_getstringsize(str, &w, &h); | 1071 | lcd_getstringsize(str, &w, &h); |
1072 | xpos = xmargin + x*w / strlen((char *)str); | 1072 | xpos = xmargin + x*w / utf8length((char *)str); |
1073 | ypos = ymargin + y*h; | 1073 | ypos = ymargin + y*h; |
1074 | lcd_putsxy(xpos, ypos, str); | 1074 | lcd_putsxy(xpos, ypos, str); |
1075 | drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); | 1075 | drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); |
@@ -1178,7 +1178,7 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style) | |||
1178 | end = strchr(s->line, '\0'); | 1178 | end = strchr(s->line, '\0'); |
1179 | strncpy(end, (char *)string, LCD_WIDTH/2); | 1179 | strncpy(end, (char *)string, LCD_WIDTH/2); |
1180 | 1180 | ||
1181 | s->len = strlen((char *)string); | 1181 | s->len = utf8length((char *)string); |
1182 | s->offset = 0; | 1182 | s->offset = 0; |
1183 | s->startx = x; | 1183 | s->startx = x; |
1184 | s->backward = false; | 1184 | s->backward = false; |
diff --git a/firmware/drivers/lcd-player.c b/firmware/drivers/lcd-player.c index 566c868d7f..d01ec3447f 100644 --- a/firmware/drivers/lcd-player.c +++ b/firmware/drivers/lcd-player.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "system.h" | 31 | #include "system.h" |
32 | #include "font.h" | 32 | #include "font.h" |
33 | #include "lcd-player-charset.h" | 33 | #include "lcd-player-charset.h" |
34 | #include "rbunicode.h" | ||
34 | 35 | ||
35 | /*** definitions ***/ | 36 | /*** definitions ***/ |
36 | 37 | ||
@@ -323,9 +324,24 @@ static void lcd_puts_cont_scroll(int x, int y, const unsigned char *string) | |||
323 | } | 324 | } |
324 | void lcd_puts(int x, int y, const unsigned char *string) | 325 | void lcd_puts(int x, int y, const unsigned char *string) |
325 | { | 326 | { |
327 | int i=0; | ||
328 | unsigned short ucs; | ||
329 | const unsigned char *utf8 = string; | ||
330 | unsigned char tmp[12]; | ||
331 | |||
332 | while (*utf8 && i<11) { | ||
333 | utf8 = utf8decode(utf8, &ucs); | ||
334 | if (ucs < 256) | ||
335 | tmp[i++] = ucs; | ||
336 | else | ||
337 | tmp[i++] = '?'; | ||
338 | } | ||
339 | |||
340 | tmp[i] = 0; | ||
341 | |||
326 | DEBUGF("lcd_puts(%d, %d) -> ", x, y); | 342 | DEBUGF("lcd_puts(%d, %d) -> ", x, y); |
327 | scroll[y].mode=SCROLL_MODE_OFF; | 343 | scroll[y].mode=SCROLL_MODE_OFF; |
328 | return lcd_puts_cont_scroll(x, y, string); | 344 | return lcd_puts_cont_scroll(x, y, tmp); |
329 | } | 345 | } |
330 | 346 | ||
331 | void lcd_put_cursor(int x, int y, char cursor_char) | 347 | void lcd_put_cursor(int x, int y, char cursor_char) |
@@ -627,14 +643,28 @@ void lcd_bidir_scroll(int percent) | |||
627 | void lcd_puts_scroll(int x, int y, const unsigned char* string ) | 643 | void lcd_puts_scroll(int x, int y, const unsigned char* string ) |
628 | { | 644 | { |
629 | struct scrollinfo* s; | 645 | struct scrollinfo* s; |
630 | int i; | 646 | int i=0; |
647 | unsigned short ucs; | ||
648 | const unsigned char *utf8 = string; | ||
649 | unsigned char tmp[utf8length(string)+1]; | ||
650 | |||
651 | while (*utf8) { | ||
652 | utf8 = utf8decode(utf8, &ucs); | ||
653 | if (ucs < 256) | ||
654 | tmp[i++] = ucs; | ||
655 | else | ||
656 | tmp[i++] = '?'; | ||
657 | } | ||
658 | |||
659 | tmp[i] = 0; | ||
660 | |||
631 | 661 | ||
632 | DEBUGF("lcd_puts_scroll(%d, %d, %s)\n", x, y, string); | 662 | DEBUGF("lcd_puts_scroll(%d, %d, %s)\n", x, y, string); |
633 | 663 | ||
634 | s = &scroll[y]; | 664 | s = &scroll[y]; |
635 | 665 | ||
636 | lcd_puts_cont_scroll(x,y,string); | 666 | lcd_puts_cont_scroll(x,y,tmp); |
637 | s->textlen = strlen(string); | 667 | s->textlen = strlen(tmp); |
638 | 668 | ||
639 | if ( s->textlen > 11-x ) { | 669 | if ( s->textlen > 11-x ) { |
640 | s->mode = SCROLL_MODE_RUN; | 670 | s->mode = SCROLL_MODE_RUN; |
@@ -649,7 +679,7 @@ void lcd_puts_scroll(int x, int y, const unsigned char* string ) | |||
649 | s->jump_scroll_steps=11-x; | 679 | s->jump_scroll_steps=11-x; |
650 | s->jump_scroll=jump_scroll; | 680 | s->jump_scroll=jump_scroll; |
651 | } | 681 | } |
652 | strncpy(s->text,string,sizeof s->text); | 682 | strncpy(s->text,tmp,sizeof s->text); |
653 | s->turn_offset=-1; | 683 | s->turn_offset=-1; |
654 | if (bidir_limit && (s->textlen < ((11-x)*(100+bidir_limit))/100)) { | 684 | if (bidir_limit && (s->textlen < ((11-x)*(100+bidir_limit))/100)) { |
655 | s->turn_offset=s->textlen+x-11; | 685 | s->turn_offset=s->textlen+x-11; |
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c index 7e064b8001..081a7a5267 100644 --- a/firmware/drivers/lcd-recorder.c +++ b/firmware/drivers/lcd-recorder.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "system.h" | 28 | #include "system.h" |
29 | #include "font.h" | 29 | #include "font.h" |
30 | #include "hwcompat.h" | 30 | #include "hwcompat.h" |
31 | #include "rbunicode.h" | ||
31 | #include "bidi.h" | 32 | #include "bidi.h" |
32 | 33 | ||
33 | /*** definitions ***/ | 34 | /*** definitions ***/ |
@@ -844,13 +845,13 @@ void lcd_bitmap(const unsigned char *src, int x, int y, int width, int height) | |||
844 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 845 | /* put a string at a given pixel position, skipping first ofs pixel columns */ |
845 | static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | 846 | static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) |
846 | { | 847 | { |
847 | int ch; | 848 | unsigned short ch; |
849 | unsigned short *ucs; | ||
848 | struct font* pf = font_get(curfont); | 850 | struct font* pf = font_get(curfont); |
849 | 851 | ||
850 | if (bidi_support_enabled) | 852 | ucs = bidi_l2v(str, 1); |
851 | str = bidi_l2v(str, 1); | ||
852 | 853 | ||
853 | while ((ch = *str++) != '\0' && x < LCD_WIDTH) | 854 | while ((ch = *ucs++) != 0 && x < LCD_WIDTH) |
854 | { | 855 | { |
855 | int width; | 856 | int width; |
856 | const unsigned char *bits; | 857 | const unsigned char *bits; |
@@ -861,7 +862,7 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
861 | ch -= pf->firstchar; | 862 | ch -= pf->firstchar; |
862 | 863 | ||
863 | /* get proportional width and glyph bits */ | 864 | /* get proportional width and glyph bits */ |
864 | width = pf->width ? pf->width[ch] : pf->maxwidth; | 865 | width = font_get_width(pf,ch); |
865 | 866 | ||
866 | if (ofs > width) | 867 | if (ofs > width) |
867 | { | 868 | { |
@@ -869,8 +870,7 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
869 | continue; | 870 | continue; |
870 | } | 871 | } |
871 | 872 | ||
872 | bits = pf->bits + (pf->offset ? | 873 | bits = font_get_bits(pf, ch); |
873 | pf->offset[ch] : ((pf->height + 7) / 8 * pf->maxwidth * ch)); | ||
874 | 874 | ||
875 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); | 875 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); |
876 | 876 | ||
@@ -898,7 +898,7 @@ void lcd_puts_style(int x, int y, const unsigned char *str, int style) | |||
898 | return; | 898 | return; |
899 | 899 | ||
900 | lcd_getstringsize(str, &w, &h); | 900 | lcd_getstringsize(str, &w, &h); |
901 | xpos = xmargin + x*w / strlen(str); | 901 | xpos = xmargin + x*w / utf8length(str); |
902 | ypos = ymargin + y*h; | 902 | ypos = ymargin + y*h; |
903 | lcd_putsxy(xpos, ypos, str); | 903 | lcd_putsxy(xpos, ypos, str); |
904 | drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); | 904 | drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); |
@@ -1007,7 +1007,7 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style) | |||
1007 | end = strchr(s->line, '\0'); | 1007 | end = strchr(s->line, '\0'); |
1008 | strncpy(end, string, LCD_WIDTH/2); | 1008 | strncpy(end, string, LCD_WIDTH/2); |
1009 | 1009 | ||
1010 | s->len = strlen(string); | 1010 | s->len = utf8length(string); |
1011 | s->offset = 0; | 1011 | s->offset = 0; |
1012 | s->startx = x; | 1012 | s->startx = x; |
1013 | s->backward = false; | 1013 | s->backward = false; |